use of org.glassfish.jersey.examples.rx.domain.Recommendation in project jersey by jersey.
the class AsyncAgentResource method async.
@GET
@ManagedAsync
public void async(@Suspended final AsyncResponse async) {
final long time = System.nanoTime();
final AgentResponse response = new AgentResponse();
final CountDownLatch outerLatch = new CountDownLatch(2);
final Queue<String> errors = new ConcurrentLinkedQueue<>();
// Obtain visited destinations.
destination.path("visited").request().header("Rx-User", "Async").async().get(new InvocationCallback<List<Destination>>() {
@Override
public void completed(final List<Destination> destinations) {
response.setVisited(destinations);
outerLatch.countDown();
}
@Override
public void failed(final Throwable throwable) {
errors.offer("Visited: " + throwable.getMessage());
outerLatch.countDown();
}
});
// Obtain recommended destinations. (does not depend on visited ones)
destination.path("recommended").request().header("Rx-User", "Async").async().get(new InvocationCallback<List<Destination>>() {
@Override
public void completed(final List<Destination> recommended) {
final CountDownLatch innerLatch = new CountDownLatch(recommended.size() * 2);
// Forecasts. (depend on recommended destinations)
final Map<String, Forecast> forecasts = Collections.synchronizedMap(new HashMap<>());
for (final Destination dest : recommended) {
forecast.resolveTemplate("destination", dest.getDestination()).request().async().get(new InvocationCallback<Forecast>() {
@Override
public void completed(final Forecast forecast) {
forecasts.put(dest.getDestination(), forecast);
innerLatch.countDown();
}
@Override
public void failed(final Throwable throwable) {
errors.offer("Forecast: " + throwable.getMessage());
innerLatch.countDown();
}
});
}
// Calculations. (depend on recommended destinations)
final List<Future<Calculation>> futures = recommended.stream().map(dest -> calculation.resolveTemplate("from", "Moon").resolveTemplate("to", dest.getDestination()).request().async().get(Calculation.class)).collect(Collectors.toList());
final Map<String, Calculation> calculations = new HashMap<>();
while (!futures.isEmpty()) {
final Iterator<Future<Calculation>> iterator = futures.iterator();
while (iterator.hasNext()) {
final Future<Calculation> f = iterator.next();
if (f.isDone()) {
try {
final Calculation calculation = f.get();
calculations.put(calculation.getTo(), calculation);
innerLatch.countDown();
} catch (final Throwable t) {
errors.offer("Calculation: " + t.getMessage());
innerLatch.countDown();
} finally {
iterator.remove();
}
}
}
}
// Have to wait here for dependent requests ...
try {
if (!innerLatch.await(10, TimeUnit.SECONDS)) {
errors.offer("Inner: Waiting for requests to complete has timed out.");
}
} catch (final InterruptedException e) {
errors.offer("Inner: Waiting for requests to complete has been interrupted.");
}
// Recommendations.
final List<Recommendation> recommendations = new ArrayList<>(recommended.size());
for (final Destination dest : recommended) {
final Forecast fore = forecasts.get(dest.getDestination());
final Calculation calc = calculations.get(dest.getDestination());
recommendations.add(new Recommendation(dest.getDestination(), fore != null ? fore.getForecast() : "N/A", calc != null ? calc.getPrice() : -1));
}
response.setRecommended(recommendations);
outerLatch.countDown();
}
@Override
public void failed(final Throwable throwable) {
errors.offer("Recommended: " + throwable.getMessage());
outerLatch.countDown();
}
});
// ... and have to wait also here for independent requests.
try {
if (!outerLatch.await(10, TimeUnit.SECONDS)) {
errors.offer("Outer: Waiting for requests to complete has timed out.");
}
} catch (final InterruptedException e) {
errors.offer("Outer: Waiting for requests to complete has been interrupted.");
}
// Do something with errors.
// ...
response.setProcessingTime((System.nanoTime() - time) / 1000000);
async.resume(response);
}
use of org.glassfish.jersey.examples.rx.domain.Recommendation in project jersey by jersey.
the class CompletionStageAgentResource method recommended.
private CompletionStage<List<Recommendation>> recommended(final WebTarget destinationTarget, final ExecutorService executor, final Queue<String> errors) {
// Recommended places.
final CompletionStage<List<Destination>> recommended = destinationTarget.path("recommended").request().header("Rx-User", "CompletionStage").rx(executor).get(new GenericType<List<Destination>>() {
}).exceptionally(throwable -> {
errors.offer("Recommended: " + throwable.getMessage());
return Collections.emptyList();
});
return recommended.thenCompose(destinations -> {
final WebTarget finalForecast = forecastTarget;
final WebTarget finalCalculation = calculationTarget;
List<CompletionStage<Recommendation>> recommendations = destinations.stream().map(destination -> {
final CompletionStage<Forecast> forecast = finalForecast.resolveTemplate("destination", destination.getDestination()).request().rx(executor).get(Forecast.class).exceptionally(throwable -> {
errors.offer("Forecast: " + throwable.getMessage());
return new Forecast(destination.getDestination(), "N/A");
});
final CompletionStage<Calculation> calculation = finalCalculation.resolveTemplate("from", "Moon").resolveTemplate("to", destination.getDestination()).request().rx(executor).get(Calculation.class).exceptionally(throwable -> {
errors.offer("Calculation: " + throwable.getMessage());
return new Calculation("Moon", destination.getDestination(), -1);
});
return CompletableFuture.completedFuture(new Recommendation(destination)).thenCombine(forecast, Recommendation::forecast).thenCombine(calculation, Recommendation::calculation);
}).collect(Collectors.toList());
return sequence(recommendations);
});
}
use of org.glassfish.jersey.examples.rx.domain.Recommendation in project jersey by jersey.
the class ListenableFutureAgentResource method recommended.
private ListenableFuture<AgentResponse> recommended(final AgentResponse response) {
destination.register(RxListenableFutureInvokerProvider.class);
// Get a list of recommended destinations ...
final ListenableFuture<List<Destination>> destinations = destination.path("recommended").request().header("Rx-User", "Guava").rx(RxListenableFutureInvoker.class).get(new GenericType<List<Destination>>() {
});
// ... transform them to Recommendation instances ...
final ListenableFuture<List<Recommendation>> recommendations = Futures.transform(destinations, (AsyncFunction<List<Destination>, List<Recommendation>>) destinationList -> {
final List<Recommendation> recommendationList = Lists.newArrayList(Lists.transform(destinationList, destination -> new Recommendation(destination.getDestination(), null, 0)));
return Futures.immediateFuture(recommendationList);
});
// ... add forecasts and calculations ...
final ListenableFuture<List<List<Recommendation>>> filledRecommendations = Futures.successfulAsList(Arrays.asList(// Add Forecasts to Recommendations.
forecasts(recommendations), // Add Forecasts to Recommendations.
calculations(recommendations)));
// ... and transform the list into agent response with filled recommendations.
return Futures.transform(filledRecommendations, (AsyncFunction<List<List<Recommendation>>, AgentResponse>) input -> {
response.setRecommended(input.get(0));
return Futures.immediateFuture(response);
});
}
use of org.glassfish.jersey.examples.rx.domain.Recommendation in project jersey by jersey.
the class SyncAgentResource method sync.
@GET
public AgentResponse sync() {
final long time = System.nanoTime();
final AgentResponse response = new AgentResponse();
final Queue<String> errors = new ConcurrentLinkedQueue<>();
// Obtain visited destinations.
try {
response.setVisited(destination.path("visited").request().header("Rx-User", "Sync").get(new GenericType<List<Destination>>() {
}));
} catch (final Throwable throwable) {
errors.offer("Visited: " + throwable.getMessage());
}
// Obtain recommended destinations. (does not depend on visited ones)
List<Destination> recommended = Collections.emptyList();
try {
recommended = destination.path("recommended").request().header("Rx-User", "Sync").get(new GenericType<List<Destination>>() {
});
} catch (final Throwable throwable) {
errors.offer("Recommended: " + throwable.getMessage());
}
// Forecasts. (depend on recommended destinations)
final Map<String, Forecast> forecasts = new HashMap<>();
for (final Destination dest : recommended) {
try {
forecasts.put(dest.getDestination(), forecast.resolveTemplate("destination", dest.getDestination()).request().get(Forecast.class));
} catch (final Throwable throwable) {
errors.offer("Forecast: " + throwable.getMessage());
}
}
// Calculations. (depend on recommended destinations)
final Map<String, Calculation> calculations = new HashMap<>();
recommended.stream().forEach(destination -> {
try {
calculations.put(destination.getDestination(), calculation.resolveTemplate("from", "Moon").resolveTemplate("to", destination.getDestination()).request().get(Calculation.class));
} catch (final Throwable throwable) {
errors.offer("Calculation: " + throwable.getMessage());
}
});
// Recommendations.
final List<Recommendation> recommendations = new ArrayList<>(recommended.size());
for (final Destination dest : recommended) {
final Forecast fore = forecasts.get(dest.getDestination());
final Calculation calc = calculations.get(dest.getDestination());
recommendations.add(new Recommendation(dest.getDestination(), fore != null ? fore.getForecast() : "N/A", calc != null ? calc.getPrice() : -1));
}
// Do something with errors.
// ...
response.setRecommended(recommendations);
response.setProcessingTime((System.nanoTime() - time) / 1000000);
return response;
}
use of org.glassfish.jersey.examples.rx.domain.Recommendation in project jersey by jersey.
the class FlowableAgentResource method recommended.
private Flowable<List<Recommendation>> recommended(final Queue<String> errors) {
destination.register(RxFlowableInvokerProvider.class);
// Recommended places.
final Flowable<Destination> recommended = destination.path("recommended").request().header("Rx-User", "RxJava2").rx(RxFlowableInvoker.class).get(new GenericType<List<Destination>>() {
}).onErrorReturn(throwable -> {
errors.offer("Recommended: " + throwable.getMessage());
return Collections.emptyList();
}).flatMap(Flowable::fromIterable).cache();
forecast.register(RxFlowableInvokerProvider.class);
// Forecasts. (depend on recommended destinations)
final Flowable<Forecast> forecasts = recommended.flatMap(destination -> forecast.resolveTemplate("destination", destination.getDestination()).request().rx(RxFlowableInvoker.class).get(Forecast.class).onErrorReturn(throwable -> {
errors.offer("Forecast: " + throwable.getMessage());
return new Forecast(destination.getDestination(), "N/A");
}));
calculation.register(RxFlowableInvokerProvider.class);
// Calculations. (depend on recommended destinations)
final Flowable<Calculation> calculations = recommended.flatMap(destination -> {
return calculation.resolveTemplate("from", "Moon").resolveTemplate("to", destination.getDestination()).request().rx(RxFlowableInvoker.class).get(Calculation.class).onErrorReturn(throwable -> {
errors.offer("Calculation: " + throwable.getMessage());
return new Calculation("Moon", destination.getDestination(), -1);
});
});
return Flowable.zip(recommended, forecasts, calculations, Recommendation::new).buffer(Integer.MAX_VALUE);
}
Aggregations