Bugfix: Check for existence of a new transfer requires a remote-call
[demos/kafka/demos-kafka-payment-system-transfer] / src / main / java / de / juplo / kafka / payment / transfer / adapter / TransferController.java
index b9a2fb0..e60ba94 100644 (file)
@@ -13,6 +13,8 @@ import org.springframework.validation.FieldError;
 import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.context.request.async.DeferredResult;
+import org.springframework.web.reactive.function.client.WebClient;
+import reactor.core.publisher.Mono;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
@@ -24,7 +26,8 @@ import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 
 
-@RestController
+@RequestMapping(TransferController.PATH)
+@ResponseBody
 @RequiredArgsConstructor
 @Slf4j
  public class TransferController
@@ -33,21 +36,37 @@ import java.util.concurrent.CompletableFuture;
 
   private final GetTransferUseCase getTransferUseCase;
   private final MessagingService messagingService;
+  private final TransferConsumer consumer;
+  private final WebClient webClient;
 
 
   @PostMapping(
-      path = PATH,
+      path = "",
       consumes = MediaType.APPLICATION_JSON_VALUE,
       produces = MediaType.APPLICATION_JSON_VALUE)
-  public DeferredResult<ResponseEntity<?>> transfer(
-      HttpServletRequest request,
-      @Valid @RequestBody TransferDTO transferDTO)
+  public DeferredResult<ResponseEntity<?>> transfer(@Valid @RequestBody TransferDTO transferDTO)
   {
     DeferredResult<ResponseEntity<?>> result = new DeferredResult<>();
 
-    getTransferUseCase
-        .get(transferDTO.getId())
-        .map(transfer ->
+    Long id = transferDTO.getId();
+
+    consumer
+        .uriForKey(id.toString())
+        .map(uri ->
+            webClient.get()
+                .uri(uri + PATH + "/" + id)
+                .accept(MediaType.APPLICATION_JSON)
+                .retrieve()
+                .onStatus(status -> true, bar -> Mono.empty())
+                .toBodilessEntity()
+                .blockOptional()
+                .flatMap(resp ->
+                    resp.getStatusCode().is2xxSuccessful()
+                        ? Optional.of(Boolean.TRUE)
+                        : Optional.<Boolean>empty()))
+        .or(() -> Optional.of(getTransferUseCase.get(transferDTO.getId()).map(transfer -> Boolean.TRUE)))
+        .flatMap(optional -> optional)
+        .map($ ->
             CompletableFuture.completedFuture(
                 ResponseEntity
                     .ok()
@@ -85,15 +104,27 @@ import java.util.concurrent.CompletableFuture;
   }
 
   @GetMapping(
-      path = PATH + "/{id}",
+      path = "/{id}",
       produces = MediaType.APPLICATION_JSON_VALUE)
   public ResponseEntity<TransferDTO> get(@PathVariable Long id)
   {
     return
-        getTransferUseCase
-            .get(id)
-            .map(transfer -> ResponseEntity.ok(TransferDTO.of(transfer)))
-            .orElse(ResponseEntity.notFound().build());
+        consumer
+            .uriForKey(Long.toString(id))
+            .map(uri ->
+            {
+              ResponseEntity<TransferDTO> response =
+                  ResponseEntity
+                      .status(HttpStatus.TEMPORARY_REDIRECT)
+                      .location(URI.create(uri + PATH + "/" + id))
+                      .build();
+              return response;
+            })
+            .orElseGet(() ->
+                getTransferUseCase
+                    .get(id)
+                    .map(transfer -> ResponseEntity.ok(TransferDTO.of(transfer)))
+                    .orElse(ResponseEntity.notFound().build()));
   }
 
   @ResponseStatus(HttpStatus.BAD_REQUEST)