I am new to jhipster. I generated a project with the terminal jhipster command. I have a gateway service, upon trying to start the application I am getting these errors, the funny thing is I did not modify anything just out of box this happened. I have java 15, :
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gatewayResource' defined in file : Unable to resolve Configuration with the provided Issuer of "http://localhost:9080/auth/realms/jhipster"
this is my gateway class:
package com.moniesta.admin.web.rest;
import com.moniesta.admin.web.rest.vm.RouteVM;
import java.util.ArrayList;
import java.util.List;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteLocator;
import reactor.core.publisher.Flux;
import org.springframework.http.*;
import org.springframework.security.access.annotation.Secured;
import com.moniesta.admin.security.AuthoritiesConstants;
import org.springframework.web.bind.annotation.*;
/**
* REST controller for managing Gateway configuration.
*/
#RestController
#RequestMapping("/api/gateway")
public class GatewayResource {
private final RouteLocator routeLocator;
private final DiscoveryClient discoveryClient;
#Value("${spring.application.name}")
private String appName;
public GatewayResource(RouteLocator routeLocator, DiscoveryClient discoveryClient) {
this.routeLocator = routeLocator;
this.discoveryClient = discoveryClient;
}
/**
* {#code GET /routes} : get the active routes.
*
* #return the {#link ResponseEntity} with status {#code 200 (OK)} and with body the list of routes.
*/
#GetMapping("/routes")
#Secured(AuthoritiesConstants.ADMIN)
public ResponseEntity<List<RouteVM>> activeRoutes() {
Flux<Route> routes = routeLocator.getRoutes();
List<RouteVM> routeVMs = new ArrayList<>();
routes.subscribe(route -> {
RouteVM routeVM = new RouteVM();
// Manipulate strings to make Gateway routes look like Zuul's
String predicate = route.getPredicate().toString();
String path = predicate.substring(predicate.indexOf("[") + 1, predicate.indexOf("]"));
routeVM.setPath(path);
String serviceId = route.getId().substring(route.getId().indexOf("_") + 1).toLowerCase();
routeVM.setServiceId(serviceId);
// Exclude gateway app from routes
if (!serviceId.equalsIgnoreCase(appName)) {
routeVM.setServiceInstances(discoveryClient.getInstances(serviceId));
routeVMs.add(routeVM);
}
});
return ResponseEntity.ok(routeVMs);
}
}
Related
Camunda normally uses UUIDs (e. g. 98631715-0b07-11ec-ab3b-68545a6e5055) as process instance IDs. In my project a process instance ID like 124 is being generated which looks suspicious to me.
This behavior can be reproduced as described below.
Step 1
Check out this repository and start the process engines
core-processes,
core-workflow and
domain-hello-world
so that all of them use the same shared database.
Step 2
Login to the Camunda UI at http://localhost:8080 and navigate to the tasklist.
Start the Starter process in tasklist.
Step 3
Go to the cockpit and navigate to Running process instances (http://localhost:8080/camunda/app/cockpit/default/#/processes).
Click on DomainProcess.
In column ID you will see a numeric (135 in the screenshot above) process instance ID, not a UUID.
Probable cause of the error
In core-processs engine I have the following Config class:
import org.camunda.bpm.engine.impl.history.HistoryLevel;
import org.camunda.bpm.engine.impl.history.event.HistoryEvent;
import org.camunda.bpm.engine.impl.history.handler.CompositeHistoryEventHandler;
import org.camunda.bpm.engine.impl.history.handler.HistoryEventHandler;
import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import static org.apache.commons.lang3.ArrayUtils.addAll;
#Configuration
public class Config {
private static final Logger LOGGER = LoggerFactory.getLogger(Config.class);
#Autowired
#Qualifier("camundaBpmDataSource")
private DataSource dataSource;
#Autowired
#Qualifier("camundaTxManager")
private PlatformTransactionManager txManager;
#Autowired
private ResourcePatternResolver resourceLoader;
#Bean
public SpringProcessEngineConfiguration processEngineConfiguration() {
final SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
config.setDataSource(dataSource);
config.setTransactionManager(txManager);
config.setDatabaseSchemaUpdate("true");
config.setHistory(HistoryLevel.HISTORY_LEVEL_FULL.getName());
config.setJobExecutorActivate(true);
config.setMetricsEnabled(false);
final Logger logger = LoggerFactory.getLogger("History Event Handler");
final HistoryEventHandler testHistoryEventHandler = new HistoryEventHandler() {
#Override
public void handleEvent(final HistoryEvent evt) {
LOGGER.debug("handleEvent | " + evt.getProcessInstanceId() + " | "
+ evt.toString());
}
#Override
public void handleEvents(final List<HistoryEvent> events) {
for (final HistoryEvent curEvent : events) {
handleEvent(curEvent);
}
}
};
config.setHistoryEventHandler(new CompositeHistoryEventHandler(Collections.singletonList(testHistoryEventHandler)));
try {
final Resource[] bpmnResources = resourceLoader.getResources("classpath:*.bpmn");
final Resource[] dmnResources = resourceLoader.getResources("classpath:*.dmn");
config.setDeploymentResources(addAll(bpmnResources, dmnResources));
} catch (final IOException exception) {
exception.printStackTrace();
LOGGER.error("An error occurred while trying to deploy BPMN and DMN files", exception);
}
return config;
}
}
If I remove this configuration (or comment the #Configuration line), the error disappears.
Questions
Why does Camunda generate a numeric process instance ID in this case (and not a UUID as in other cases)?
After adding the line
config.setIdGenerator(new StrongUuidGenerator());
in the configuration class
#Bean
public SpringProcessEngineConfiguration processEngineConfiguration() {
final SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
config.setIdGenerator(new StrongUuidGenerator());
config.setDataSource(dataSource);
the process instance IDs became UUIDs again.
For details see Camunda documentation on ID generators.
I am trying to write a proxy server with SparkJava that queries the Google Maps Directions API given parameters (i.e. location data, traffic model preference, departure time, etc...) from a client and returns various routing details such as distance, duration, and duration.
The server stalls when it tries to send a request to the API on behalf of the client. I placed print statements throughout the code to confirm that the hang was due to the API query. I have tried using different ports namely: 4567, 443, 80, and 8080 by using port() method but the problem persists. I am sure the server-side code conducting the API query is not the issue; everything works fine (proper route information is generated i.e. DirectionsApiRequest.await() returns properly) when I cut the client out, disable the endpoints, and run everything manually from the main method on the (deactivated) server's side.
Does anyone know why this could be happening?
(I use maven for dependency management)
The following shows the client trying to get the distance of the default route and the aforementioned error:
Server-side code:
Main class
package com.mycompany.app;
//import
// data structures
import java.util.ArrayList;
// google maps
import com.google.maps.model.DirectionsRoute;
import com.google.maps.model.LatLng;
// gson
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
// static API methods
import com.mycompany.app.DirectionsUtility;
import static spark.Spark.*;
// exceptions
import com.google.maps.errors.ApiException;
import java.io.IOException;
public class App
{
private static ArrayList<LatLng> locationsDatabase = new ArrayList<LatLng>();
private static DirectionsRoute defaultRoute = null;
public static void main( String[] args ) throws ApiException, InterruptedException, IOException
{
// client posts location data
post("routingEngine/sendLocations", (request,response) -> {
response.type("application/json");
ArrayList<LatLng> locations = new Gson().fromJson(request.body(),new TypeToken<ArrayList<LatLng>>(){}.getType());
locationsDatabase = locations;
return "OK";
});
// before any default route queries, the default route must be generated
before("routingEngine/getDefaultRoute/*",(request,response) ->{
RequestParameters requestParameters = new Gson().fromJson(request.body(),(java.lang.reflect.Type)RequestParameters.class);
defaultRoute = DirectionsUtility.getDefaultRoute(locationsDatabase,requestParameters);
});
// client gets default route distance
get("routingEngine/getDefaultRoute/distance", (request,response) ->{
response.type("application/json");
return new Gson().toJson(new Gson().toJson(DirectionsUtility.getDefaultRouteDistance(defaultRoute)));
});
DirectionsUtility.context.shutdown();
}
}
DirectionsUtility is the class responsible for consulting with Google Maps' API:
package com.mycompany.app;
// import
// data structures
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
// Google Directions API
import com.google.maps.GeoApiContext;
// request parameters
import com.google.maps.DirectionsApiRequest;
import com.google.maps.model.Unit;
import com.google.maps.model.TravelMode;
import com.google.maps.model.TrafficModel;
import com.google.maps.DirectionsApi.RouteRestriction;
import com.google.maps.model.Distance;
// result parameters
import com.google.maps.model.DirectionsResult;
import com.google.maps.model.LatLng;
import com.google.maps.model.DirectionsRoute;
import com.google.maps.model.DirectionsLeg;
// exceptions
import com.google.maps.errors.ApiException;
import java.io.IOException;
// time constructs
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Call;
import okhttp3.Response;
import okhttp3.MediaType;
import okhttp3.HttpUrl;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public final class DirectionsUtility{
/**
* Private constructor to prevent instantiation.
*/
private DirectionsUtility(){}
/**
* API key.
*/
private static final String API_KEY = "YOUR PERSONAL API KEY";
/**
* Queries per second limit (50 is max).
*/
private static int QPS = 50;
/**
* Singleton that facilitates Google Geo API queries; must be shutdown() for program termination.
*/
protected static GeoApiContext context = new GeoApiContext.Builder()
.apiKey(API_KEY)
.queryRateLimit(QPS)
.build();
// TESTING
// singleton client
private static final OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(700,TimeUnit.SECONDS)
.writeTimeout(700, TimeUnit.SECONDS)
.readTimeout(700, TimeUnit.SECONDS)
.build();
/**
* Generates the route judged by the Google API as being the most optimal. The main purpose of this method is to provide a fallback
* for the optimization engine should it ever find the traditional processes of this server (i.e. generation of all possible routes)
* too slow for its taste. In other words, if this server delays to an excessive degree in providing the optimization engine with the
* set of all possible routes, the optimization engine can terminate those processes and instead entrust the decision to the Google
* Maps API. This method suffers from a minor caveat; the Google Maps API refuses to compute the duration in traffic for any journey
* involving multiple locations if the intermediate points separating the origin and destination are assumed to be stopover points (i.e.
* if it is assumed that the driver will stop at each point) therefore this method assumes that the driver will not stop at the intermediate
* points. This may introduce some inaccuracies into the predictions.
* (it should be noted that this server has not yet been equipped with the ability to generate all possible routes so this method is, at the
* at the moment, the only option)
*
* #param requestParameters the parameters required for a Google Maps API query; see the RequestParameters class for more information
*
* #return the default route
*/
public static DirectionsRoute getDefaultRoute(ArrayList<LatLng> locations,RequestParameters requestParameters) throws ApiException, InterruptedException, IOException
{
LatLng origin = locations.get(0);
LatLng destination = locations.get(locations.size() - 1);
// separate waypoints
int numWaypoints = locations.size() - 2;
DirectionsApiRequest.Waypoint[] waypoints = new DirectionsApiRequest.Waypoint[numWaypoints];
for(int i = 0; i < waypoints.length; i++)
{
// ensure that each waypoint is not designated as a stopover point
waypoints[i] = new DirectionsApiRequest.Waypoint(locations.get(i + 1),false);
}
// send API query
// store API query response
DirectionsResult directionsResult = null;
try
{
// create DirectionsApiRequest object
DirectionsApiRequest directionsRequest = new DirectionsApiRequest(context);
// set request parameters
directionsRequest.units(requestParameters.getUnit());
directionsRequest.mode(TravelMode.DRIVING);
directionsRequest.trafficModel(requestParameters.getTrafficModel());
if(requestParameters.getRestrictions() != null)
{
directionsRequest.avoid(requestParameters.getRestrictions());
}
directionsRequest.region(requestParameters.getRegion());
directionsRequest.language(requestParameters.getLanguage());
directionsRequest.departureTime(requestParameters.getDepartureTime());
// always generate alternative routes
directionsRequest.alternatives(false);
directionsRequest.origin(origin);
directionsRequest.destination(destination);
directionsRequest.waypoints(waypoints);
directionsRequest.optimizeWaypoints(requestParameters.optimizeWaypoints());
// send request and store result
// testing - notification that a new api query is being sent
System.out.println("firing off API query...");
directionsResult = directionsRequest.await();
// testing - notification that api query was successful
System.out.println("API query successful");
}
catch(Exception e)
{
System.out.println(e);
}
// directionsResult.routes contains only a single, optimized route
// return the default route
return directionsResult.routes[0];
} // end method
/**
* Returns the distance of the default route.
*
* #param defaultRoute the default route
*
* #return the distance of the default route
*/
public static Distance getDefaultRouteDistance(DirectionsRoute defaultRoute)
{
// testing - simple notification
System.out.println("Computing distance...");
// each route has only 1 leg since all the waypoints are non-stopover points
return defaultRoute.legs[0].distance;
}
}
Here is the client-side code:
package com.mycompany.app;
import java.util.ArrayList;
import java.util.Arrays;
import com.google.maps.model.LatLng;
import com.google.maps.model.TrafficModel;
import com.google.maps.DirectionsApi.RouteRestriction;
import com.google.maps.model.TransitRoutingPreference;
import com.google.maps.model.TravelMode;
import com.google.maps.model.Unit;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonArray;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Call;
import okhttp3.Response;
import okhttp3.MediaType;
import okhttp3.HttpUrl;
// time constructs
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.concurrent.TimeUnit;
import com.google.maps.model.Distance;
import com.google.maps.model.Duration;
import java.io.IOException;
public class App
{
// model database
private static LatLng hartford_ct = new LatLng(41.7658,-72.6734);
private static LatLng loretto_pn = new LatLng(40.5031,-78.6303);
private static LatLng chicago_il = new LatLng(41.8781,-87.6298);
private static LatLng newyork_ny = new LatLng(40.7128,-74.0060);
private static LatLng newport_ri = new LatLng(41.4901,-71.3128);
private static LatLng concord_ma = new LatLng(42.4604,-71.3489);
private static LatLng washington_dc = new LatLng(38.8951,-77.0369);
private static LatLng greensboro_nc = new LatLng(36.0726,-79.7920);
private static LatLng atlanta_ga = new LatLng(33.7490,-84.3880);
private static LatLng tampa_fl = new LatLng(27.9506,-82.4572);
// singleton client
private static final OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(700,TimeUnit.SECONDS)
.writeTimeout(700, TimeUnit.SECONDS)
.readTimeout(700, TimeUnit.SECONDS)
.build();
private static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
public static void main( String[] args ) throws IOException
{
// post location data
// get locations from database
ArrayList<LatLng> locations = new ArrayList<LatLng>();
// origin
LatLng origin = hartford_ct;
locations.add(origin);
// waypoints
locations.add(loretto_pn);
locations.add(chicago_il);
locations.add(newyork_ny);
locations.add(newport_ri);
locations.add(concord_ma);
locations.add(washington_dc);
locations.add(greensboro_nc);
locations.add(atlanta_ga);
// destination
LatLng destination = tampa_fl;
locations.add(destination);
// serialize locations list to json
Gson gson = new GsonBuilder().create();
String locationsJson = gson.toJson(locations);
// post to routing engine
RequestBody postLocationsRequestBody = RequestBody.create(JSON,locationsJson);
Request postLocationsRequest = new Request.Builder()
.url("http://localhost:4567/routingEngine/sendLocations")
.post(postLocationsRequestBody)
.build();
Call postLocationsCall = httpClient.newCall(postLocationsRequest);
Response postLocationsResponse = postLocationsCall.execute();
// get distance of default route
// generate parameters
Unit unit = Unit.METRIC;
LocalDateTime temp = LocalDateTime.now();
Instant departureTime= temp.atZone(ZoneOffset.UTC)
.withYear(2025)
.withMonth(8)
.withDayOfMonth(18)
.withHour(10)
.withMinute(12)
.withSecond(10)
.withNano(900)
.toInstant();
boolean optimizeWaypoints = true;
String optimizeWaypointsString = (optimizeWaypoints == true) ? "true" : "false";
TrafficModel trafficModel = TrafficModel.BEST_GUESS;
// restrictions
RouteRestriction[] restrictions = {RouteRestriction.TOLLS,RouteRestriction.FERRIES};
String region = "us"; // USA
String language = "en-EN";
RequestParameters requestParameters = new RequestParameters(unit,departureTime,true,trafficModel,restrictions,region,language);
// build url
HttpUrl url = new HttpUrl.Builder()
.scheme("http")
.host("127.0.0.1")
.port(4567)
.addPathSegment("routingEngine")
.addPathSegment("getDefaultRoute")
.addPathSegment("distance")
.build();
// build request
Request getDefaultRouteDistanceRequest = new Request.Builder()
.url(url)
.post(RequestBody.create(JSON,gson.toJson(requestParameters)))
.build();
// send request
Call getDefaultRouteDistanceCall = httpClient.newCall(getDefaultRouteDistanceRequest);
Response getDefaultRouteDistanceResponse = getDefaultRouteDistanceCall.execute();
// store and print response
Distance defaultRouteDistance = gson.fromJson(getDefaultRouteDistanceResponse.body().string(),Distance.class);
System.out.println("Default Route Distance: " + defaultRouteDistance);
}
}
Both classes use the following class RequestParameters to package all the request parameters together (i.e. unit, departure time, region, language etc...) just for convenience
package com.mycompany.app;
import com.google.maps.model.Unit;
import java.time.Instant;
import com.google.maps.model.TrafficModel;
import com.google.maps.DirectionsApi.RouteRestriction;
public class RequestParameters
{
private Unit unit;
private Instant departureTime;
private boolean optimizeWaypoints;
private TrafficModel trafficModel;
private RouteRestriction[] restrictions;
private String region;
private String language;
public RequestParameters(Unit unit, Instant departureTime, boolean optimizeWaypoints, TrafficModel trafficModel, RouteRestriction[] restrictions, String region, String language)
{
this.unit = unit;
this.departureTime = departureTime;
this.optimizeWaypoints = optimizeWaypoints;
this.trafficModel = trafficModel;
this.restrictions = restrictions;
this.region = region;
this.language = language;
}
// getters
public Unit getUnit()
{
return this.unit;
}
public Instant getDepartureTime()
{
return this.departureTime;
}
public boolean optimizeWaypoints()
{
return this.optimizeWaypoints;
}
public TrafficModel getTrafficModel()
{
return this.trafficModel;
}
public RouteRestriction[] getRestrictions()
{
return this.restrictions;
}
public String getRegion()
{
return this.region;
}
public String getLanguage()
{
return this.language;
}
// setters
public void setTrafficModel(TrafficModel trafficModel)
{
this.trafficModel = trafficModel;
}
public void setRegion(String region)
{
this.region = region;
}
public void setLanguage(String language)
{
this.language = language;
}
}
Hopefully this provides the information necessary to investigate the problem.
In the server-side App class, the last line of the main method reads
DirectionsUtility.context.shutdown();
This effectively shuts down the ExecutorService that the Maps Services API uses (inside its RateLimitExecutorService) and that is responsible for actually executing requests to Google. So your request is enqueued, but never actually executed.
Also, instead of doing System.out.println(e) (inside the DirectionsUtility class) it may be better do something like e.printStacktrace() so you'll have access to the whole error + it's stack.
I am trying to download files from multiple SFTP servers then handle those files. But I can not get the information of remote SFTP server such as: IpAddress, remoteDirectory depending on which file MessageHandler handling. Instead Payload only contains the information of the dowloaded files at local. Here the source code I use from the guide:
How to dynamically define file filter pattern for Spring Integration SFTP Inbound Adapter?
SFTIntegration.java
import com.jcraft.jsch.ChannelSftp.LsEntry;
import java.io.File;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.Pollers;
import org.springframework.integration.dsl.SourcePollingChannelAdapterSpec;
import org.springframework.integration.expression.FunctionExpression;
import org.springframework.integration.file.remote.aop.RotatingServerAdvice;
import org.springframework.integration.file.remote.session.DelegatingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.scheduling.PollerMetadata;
import org.springframework.integration.sftp.dsl.Sftp;
import org.springframework.integration.sftp.dsl.SftpInboundChannelAdapterSpec;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.messaging.MessageChannel;
import org.springframework.stereotype.Component;
/**
* flow.
*/
#Configuration
#Component
public class SFTIntegration {
public static final String TIMEZONE_UTC = "UTC";
public static final String TIMESTAMP_FORMAT_OF_FILES = "yyyyMMddHHmmssSSS";
public static final String TEMPORARY_FILE_SUFFIX = ".part";
public static final int POLLER_FIXED_PERIOD_DELAY = 60000;
public static final int MAX_MESSAGES_PER_POLL = 100;
private static final Logger LOG = LoggerFactory.getLogger(SFTIntegration.class);
private static final String CHANNEL_INTERMEDIATE_STAGE = "intermediateChannel";
#Autowired
private ImportHandler importHandler;
/** database access repository */
private final SFTPServerConfigRepo SFTPServerConfigRepo;
#Value("${sftp.local.directory.download:${java.io.tmpdir}/localDownload}")
private String localTemporaryPath;
public SFTIntegration(final SFTPServerConfigRepo SFTPServerConfigRepo) {
this.SFTPServerConfigRepo = SFTPServerConfigRepo;
}
/**
* The default poller with 5s, 100 messages, RotatingServerAdvice and transaction.
*
* #return default poller.
*/
#Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers
.fixedDelay(POLLER_FIXED_PERIOD_DELAY)
.advice(advice())
.maxMessagesPerPoll(MAX_MESSAGES_PER_POLL)
.transactional()
.get();
}
/**
* The direct channel for the flow.
*
* #return MessageChannel
*/
#Bean
public MessageChannel stockIntermediateChannel() {
return new DirectChannel();
}
/**
* Get the files from a remote directory. Add a timestamp to the filename
* and write them to a local temporary folder.
*
* #return IntegrationFlow
*/
#Bean
public IntegrationFlow collectionInboundFlowFromSFTPServer() {
// Source definition
final SftpInboundChannelAdapterSpec sourceSpec = Sftp.inboundAdapter(delegatingSFtpSessionFactory())
.preserveTimestamp(true)
.patternFilter("*.*")
.deleteRemoteFiles(true)
.maxFetchSize(MAX_MESSAGES_PER_POLL)
.remoteDirectory("/")
.localDirectory(new File(localTemporaryPath))
.temporaryFileSuffix(TEMPORARY_FILE_SUFFIX)
.localFilenameExpression(new FunctionExpression<String>(s -> {
final int fileTypeSepPos = s.lastIndexOf('.');
return
DateTimeFormatter
.ofPattern(TIMESTAMP_FORMAT_OF_FILES)
.withZone(ZoneId.of(TIMEZONE_UTC))
.format(Instant.now())
+ "_"
+ s.substring(0, fileTypeSepPos)
+ s.substring(fileTypeSepPos);
}));
// Poller definition
final Consumer<SourcePollingChannelAdapterSpec> collectionInboundPoller = endpointConfigurer -> endpointConfigurer
.id("collectionInboundPoller")
.autoStartup(true)
.poller(poller());
return IntegrationFlows
.from(sourceSpec, collectionInboundPoller)
.transform(File.class, p -> {
// log step
LOG.info("flow=collectionInboundFlowFromSFTPServer, message=incoming file: " + p);
return p;
})
.channel(CHANNEL_INTERMEDIATE_STAGE)
.get();
}
#Bean
public IntegrationFlow collectionIntermediateStageChannel() {
return IntegrationFlows
.from(CHANNEL_INTERMEDIATE_STAGE)
.handle(importHandler)
.channel(new NullChannel())
.get();
}
public DefaultSftpSessionFactory createNewSftpSessionFactory(final SFTPServerConfig pc) {
final DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(
false);
factory.setHost(pc.getServerIp());
factory.setPort(pc.getPort());
factory.setUser(pc.getUsername());
factory.setPassword(pc.getPassword());
factory.setAllowUnknownKeys(true);
return factory;
}
#Bean
public DelegatingSessionFactory<LsEntry> delegatingSFtpSessionFactory() {
final List<SFTPServerConfig> partnerConnections = SFTPServerConfigRepo.findAll();
if (partnerConnections.isEmpty()) {
return null;
}
final Map<Object, SessionFactory<LsEntry>> factories = new LinkedHashMap<>(10);
for (SFTPServerConfig pc : partnerConnections) {
// create a factory for every key containing server type, url and port
if (factories.get(pc.getKey()) == null) {
factories.put(pc.getKey(), createNewSftpSessionFactory(pc));
}
}
// use the first SF as the default
return new DelegatingSessionFactory<>(factories, factories.values().iterator().next());
}
#Bean
public RotatingServerAdvice advice() {
final List<SFTPServerConfig> sftpConnections = SFTPServerConfigRepo.findAll();
final List<RotatingServerAdvice.KeyDirectory> keyDirectories = new ArrayList<>();
for (SFTPServerConfig pc : sftpConnections) {
keyDirectories
.add(new RotatingServerAdvice.KeyDirectory(pc.getKey(), pc.getServerPath()));
}
return new RotatingServerAdvice(delegatingSFtpSessionFactory(), keyDirectories, true);
}
}
ImportHandler.java
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;
#Service
public class ImportHandler {
public void handle(Message<?> message) {
System.out.println("Hello " + message);
System.out.println(message.getPayload());
System.out.println(message.getHeaders());
//How can I get the information of remote server Ip address, remoteDirectory here where the file comes from
}
}
If you have any ideas, please let me know. Thank you so much!.
It's not currently supported; please open a new feature request.
I've a very strange behavior, I think I have two issues, I put them together on the same post because they can be linked :
my code is :
VaadinSession.getCurrent().setAttribute("user", user);
System.out.println("User :"+ user);
getUI().getNavigator().navigateTo(HomePageView.HOMEPAGE);
1. First issue
I'm on the login page, I can see my user information, but I cannot navigate to the homepage.
I don't have any error !
If I delete the line with the vaadinSession, the navigator is working...
2. Second Issue
I tried to debug my code but I received a "source not found", to fix that, I follow Eclipse java debugging: source not found. But, seems to working for me.
What I did :
I recreated a new workspace without success.
I edited the source lookup path and I have my java project in it
In the preferences -> java -> installed JREs -> I've the 1.8.0 JDK
right click on the project -> maven -> download sources
right click on the project -> maven -> disable maven nature and after Configure -> project to maven
EDIT : SOLUTION for the issue 2 :
I was so blocked... I know it's an eclipse issue (configuration or something like that). I changed for IntelliJ. This IDE show me sources without problem.
INFO
I'm using Vaadin and REST web services (with the javax.ws.rs.client.ClientBuilder).
When I use SYSOUT, I have the good information. I received the information from the homepage (instead of the view seems to keep the login view).
Any hint will be very useful !
EDIT : Full LoginView class
package com.test.project.View;
import com.test.project.model.User;
import com.test.project.restclient.RestClient;
import com.vaadin.annotations.Title;
import com.vaadin.data.Binder;
import com.vaadin.data.validator.EmailValidator;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
/**
* Login View. The user should enter his email address. Extends {#link CustomComponent} and implements {#link View}
*
* #author Bob
*/
#Title("Sign Up")
public class LoginView extends CustomComponent implements
View {
private static final long serialVersionUID = 1L;
public static final String LOGIN = "";
private VerticalLayout vLayout = new VerticalLayout();
private static final String SIGNUP_LABEL = "Sign Up";
private static final String EMAIL_CAPTION = "Type your email here :";
private static final String SIGNIN_LABEL = "Sign In";
private TextField email;
private static final String TOKEN_ATTRIBUTE_LABEL = "token";
private final Binder<User> binder = new Binder<>();
private User user;
private Button loginButton;
/**
* Login view Constructor
*/
public LoginView() {
createLoginPanel();
addListener();
}
/**
* Add Listener concern by the Login View Fields
*/
private void addListener() {
loginButton.addClickListener(e -> {
RestClient rc = new RestClient();
user = rc.getUserInfo(email.getValue());
VaadinSession.getCurrent().setAttribute(TOKEN_ATTRIBUTE_LABEL, user.getToken());
System.out.println();
getUI().getNavigator().navigateTo(HomePageView.HOMEPAGE);
});
}
/**
* Create the login panel with the email field and the login button
*/
private void createLoginPanel() {
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
Panel panel = new Panel(SIGNUP_LABEL);
panel.setHeight(200, Unit.PIXELS);
panel.setWidth(300, Unit.PIXELS);
email = new TextField();
email.setCaption(EMAIL_CAPTION);
email.setHeight(30, Unit.PIXELS);
email.setWidth(275, Unit.PIXELS);
binder.forField(email).withValidator(new EmailValidator("This doesn't look like a valid email address")).bind(User::getEmail, User::setEmail);
loginButton = new Button(SIGNIN_LABEL);
loginButton.setIcon(VaadinIcons.SIGN_IN);
layout.addComponents(email, loginButton);
layout.setComponentAlignment(loginButton, Alignment.BOTTOM_RIGHT);
panel.setContent(layout);
vLayout.addComponent(panel);
vLayout.setSizeFull();
vLayout.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
setCompositionRoot(vLayout);
}
/* (non-Javadoc)
* #see com.vaadin.navigator.View#enter(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent)
*/
#Override
public void enter(ViewChangeEvent event) {
email.focus();
}
}
Rest client class :
package com.test.project.restclient;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.test.project.model.User;
/**
* Class contain the Rest Client which allow to use and call the rest web services.
*
* #author Bob
*/
public class RestClient {
private static final String EMAIL_LABEL = "email";
private static final Logger LOG = LoggerFactory.getLogger(RestClient.class);
private Client client;
public RestClient() {
client = ClientBuilder.newClient(new ClientConfig());
}
/**
* Get the user information from the user email
*
* #param email
* #return user
*/
#SuppressWarnings("unchecked")
#POST
#Path("http://IpAddress:8080/api/authentication/")
public User getUserInfo(String email) {
JSONObject obj = new JSONObject();
obj.put(EMAIL_LABEL, email);
WebTarget webtarget = client.target("http://IpAddress:8080/api/authentication/");
Response response = webtarget.request().accept(MediaType.APPLICATION_JSON).post(Entity.entity(obj, MediaType.APPLICATION_JSON));
String answer = response.readEntity(String.class);
LOG.info("User information are :" + answer);
Gson g = new Gson();
User user = g.fromJson(answer, User.class);
return user;
}
}
Home Page View :
package com.test.project.View;
import com.test.project.model.Action;
import com.test.project.restclient.RestClient;
import com.vaadin.data.Binder;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
/**
* Home page view.
*
* #author Bob
*/
public class HomePageView extends CustomComponent implements
View {
private static final long serialVersionUID = 1L;
public static final String HOMEPAGE = "home";
private final VerticalLayout layout;
private static final String TOKEN_ATTRIBUTE_LABEL = "token";
/**
* Home page View constructor
*/
public HomePageView() {
layout = new VerticalLayout();
layout.setSizeFull();
String CURRENT_USER_TOKEN = (String) VaadinSession.getCurrent().getAttribute(TOKEN_ATTRIBUTE_LABEL);
System.out.println("Current user token : " + CURRENT_USER_TOKEN);
createMenu();
setCompositionRoot(layout);
}
/**
* Create a Vertical Menu with the Home page and Actions page
*/
private void createMenu() {
MenuBar barmenu = new MenuBar();
barmenu.addItem("Homepage", VaadinIcons.HOME, null);
barmenu.addItem("Actions", VaadinIcons.TABLE, null);
layout.addComponent(barmenu);
}
/* (non-Javadoc)
* #see com.vaadin.navigator.View#enter(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent)
*/
#Override
public void enter(ViewChangeEvent event) {
}
}
Ok, I found the solution/workarround for the issues :
For the first issue : "token" seems to be a reserved word, "tokenEmployee" seems to be better and it's working perfectly...
For the second issue : I still don't know why it's not working in Eclipse, I've the source but in debug mode, I'm not able to see them. I changed for IntelliJ. I was not able to find any thing about reserved words for the Vaadin Session. If someone find a link or something, I'm very interested !
Too much time trying to fix it..
A bit thanks to #jay who tried to help me!
I am trying to deploy a webservice on my localhost, but it doesn't seem to produce the "Endpoint".
I don't know how I messed it up :(
I am using apache cxf 2.7.1 and glassfish 3.1. I even attempted to add ear libraries.
Here is my build path:
and my project explorer looks like this:
I have annotations on both my webservice and webservice interface, as shown below:
Code for webservice interface (I removed the other some parts to make the code shorter)
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import no.solarsoft.venus2.webservice.exception.WebServiceException;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQuery;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQueryParameterKey;
import no.solarsoft.venus2.webservice.queryoptions.QueryParameter;
#WebService()
public interface WebServiceVenus2Interface {
/**
* FETCHING DATA FROM DATABASE
*
*/
#WebMethod
public void Foo(ParticipantQueryParameterKey pqpk);
#WebMethod
public String test();
#WebMethod
public String sayHello(String string) throws WebServiceException;
The code for my web service:
import javax.annotation.Resource;
import javax.jws.WebParam;
import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import no.solarsoft.venus2.datamanager.CRUDOperation;
import no.solarsoft.venus2.datamanager.DataManager;
import no.solarsoft.venus2.entities.GradeScale;
import no.solarsoft.venus2.enums.ImageType;
import no.solarsoft.venus2.exception.DataAccessException;
import no.solarsoft.venus2.exception.InstanceNotFoundException;
import no.solarsoft.venus2.service.EmailService;
import no.solarsoft.venus2.webservice.exception.ParameterValidationException;
import no.solarsoft.venus2.webservice.exception.WebServiceException;
import no.solarsoft.venus2.webservice.exception.WebServiceFaultBean;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQuery;
import no.solarsoft.venus2.webservice.queryoptions.ParticipantQueryParameterKey;
import no.solarsoft.venus2.webservice.queryoptions.QueryParameter;
// #Stateless()
#javax.jws.WebService(endpointInterface = "no.solarsoft.venus2.webservice.WebServiceVenus2Interface", serviceName = "WebServiceVenus2Service")
public class WebServiceVenus2 implements WebServiceVenus2Interface {
private DataManager dataManager = DataManager.getInstance();
private static final Logger log = Logger.getAnonymousLogger();
#Resource
WebServiceContext wsContext;
#Override
public void Foo(ParticipantQueryParameterKey pqpk) {}
private void logEntered(String login) {
log.info(MessageFormat.format("{0}: ''{1}'' entered web service method ''{2}()''",
WebServiceVenus2.class.getSimpleName(), login, getMethodName()));
}
private String getClientIp() {
MessageContext mc = wsContext.getMessageContext();
HttpServletRequest req = (HttpServletRequest) mc.get(MessageContext.SERVLET_REQUEST);
return req.getRemoteAddr();
}
/**
* Get the method name for a depth in call stack. <br />
* Utility function
*
* #param depth
* depth in the call stack (0 means current method, 1 means call method, ...)
* #return method name
*/
public static String getMethodName() {
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[3].getMethodName(); // Thank you Tom Tresansky
}
/**
* FETCHING DATA FROM DATABASE
*/
#Override
public String test() {
String ip = getClientIp();
logEntered(ip);
return "WebService test succeded! Client IP: " + ip;
}
#Override
public String sayHello(String string) throws WebServiceException {
logEntered(null);
if (string == null || string.isEmpty()) {
log.severe("Throwing excetion...");
throw new WebServiceException("String can not be empty or NULL!", new WebServiceFaultBean());
}
log.exiting(WebServiceVenus2.class.getName(), WebServiceVenus2.getMethodName());
return "Hello " + string + "!";
}
and here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
</web-app>
I hope someone can help me. Thanks
I loaded this code nearly verbatim to a dynamic web module in eclipse and deployed to Glassfish4. When deployed (using eclipse "add to server") the WSDL is available at http://localhost:8181/Venus2WebService/WebServiceVenus2Service?wsdl
and the web service endpoint is http://localhost:8181/Venus2WebService/WebServiceVenus2Service
The only jars I included from CXF (not shown in your post) are, from reading WHICH_JARS readme within CXF binary distribution lib dir:
asm-3.3.1.jar
commons-logging-1.1.1.jar
cxf-2.7.17.jar
geronimo-javamail_1.4_spec-1.7.1.jar
geronimo-jaxws_2.2_spec-1.1.jar
jaxb-api-2.2.6.jar
jaxb-impl-2.2.6.jar
neethi-3.0.3.jar
stax2-api-3.1.4.jar
wsdl4j-1.6.3.jar
xmlschema-core-2.1.0.jar
I got the endpoint URL from watching the eclipse console for the server:
2015-09-09T21:45:40.683-0400|Info: Webservice Endpoint deployed WebServiceVenus2
listening at address at http://oc-mbp01.local:8181/Venus2WebService/WebServiceVenus2Service.
Classpath (all in WEB-INF/lib for me):