From c3bf6b4f6c61b51b3618901b76eba1d5c7ec8579 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Sun, 11 Dec 2016 23:04:57 +0100 Subject: [PATCH] Spring can already work with CompletableFuture No need of creating my own adapter :) See: org.springframework.web.servlet.mvc.method.annotation.DeferredResultMethodReturnValueHandler.CompletionStageAdapter --- .../controller/CompletableFutureCarController.java | 21 ++++-------- .../adapters/CompletableFutureAdapter.java | 40 ---------------------- 2 files changed, 6 insertions(+), 55 deletions(-) delete mode 100644 SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/adapters/CompletableFutureAdapter.java diff --git a/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/CompletableFutureCarController.java b/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/CompletableFutureCarController.java index 9b199f0..4e1ea8c 100644 --- a/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/CompletableFutureCarController.java +++ b/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/CompletableFutureCarController.java @@ -3,8 +3,6 @@ package de.spring.webservices.rest.controller; import java.util.Map; import java.util.concurrent.CompletableFuture; -import static de.spring.webservices.rest.controller.adapters.CompletableFutureAdapter.deferredAdapter; - import javax.inject.Inject; import org.slf4j.Logger; @@ -23,7 +21,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.context.request.async.DeferredResult; import de.spring.webservices.domain.Car; import de.spring.webservices.rest.business.service.CompletableFutureBusinessLogic; @@ -44,14 +41,14 @@ public class CompletableFutureCarController { @RequestMapping(produces = { MediaType.APPLICATION_JSON_UTF8_VALUE }, method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) - public DeferredResult> cars() { + public CompletableFuture> cars() { - return deferredAdapter(completableFutureBusinessLogic.findAll(new PageRequest(PAGE, PAGE_SIZE))); + return completableFutureBusinessLogic.findAll(new PageRequest(PAGE, PAGE_SIZE)); } @RequestMapping(value = "{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.GET) @ResponseStatus(HttpStatus.OK) - public DeferredResult car(@RequestHeader(value = "MY_HEADER", required = false) String specialHeader, + public CompletableFuture car(@RequestHeader(value = "MY_HEADER", required = false) String specialHeader, @PathVariable("id") long id, @RequestParam Map params, @RequestParam(value = "wheel", required = false) String[] wheelParams) { @@ -74,27 +71,21 @@ public class CompletableFutureCarController { } } - return deferredAdapter(completableFutureBusinessLogic.findById(id)); + return completableFutureBusinessLogic.findById(id); } @RequestMapping(consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) - public DeferredResult> create(@RequestBody Car car) { - - return deferredAdapter(createAsync(car)); - } - - - private CompletableFuture> createAsync(Car car) { + public CompletableFuture> create(@RequestBody Car car) { return completableFutureBusinessLogic .createThrowable(car) .thenComposeAsync(newCar -> CompletableFuture.supplyAsync(() -> createResponseCar(newCar)) - ); + ); } private ResponseEntity createResponseCar(Car car) { diff --git a/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/adapters/CompletableFutureAdapter.java b/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/adapters/CompletableFutureAdapter.java deleted file mode 100644 index c451bfb..0000000 --- a/SpringJava/RxJava/web-services-spring-rxjava-server/src/main/java/de/spring/webservices/rest/controller/adapters/CompletableFutureAdapter.java +++ /dev/null @@ -1,40 +0,0 @@ -package de.spring.webservices.rest.controller.adapters; - -import java.util.concurrent.CompletableFuture; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.context.request.async.DeferredResult; - -public class CompletableFutureAdapter { - private static final Logger LOGGER = LoggerFactory.getLogger(CompletableFutureAdapter.class); - - // With no value, we depend on the Tomcat/Jboss/Jetty/etc timeout value for asynchronous requests. - // Spring will answer after 60 secs with an empty response (by default) and HTTP 503 status (by default) when timeout. - private static final long ASYNC_TIMEOUT = 60000; /* milliseconds */ - - - public static final DeferredResult deferredAdapter(CompletableFuture completableFuture) { - - DeferredResult deferredResult = new DeferredResult<>(ASYNC_TIMEOUT); - - completableFuture - .thenAcceptAsync(deferredResult::setResult) - .exceptionally(exception -> { - Throwable realException = launderException(exception); - - LOGGER.error("error: ", realException); - - deferredResult.setErrorResult(exception); - return null; - }); - - return deferredResult; - } - - private static final Throwable launderException(Throwable exception) { - return exception.getCause() != null - ? exception.getCause() - : exception; - } -} -- 2.1.4