1 package de.juplo.kafka.payment.transfer.adapter;
4 import de.juplo.kafka.payment.transfer.domain.Transfer;
5 import de.juplo.kafka.payment.transfer.ports.GetTransferUseCase;
6 import de.juplo.kafka.payment.transfer.ports.MessagingService;
7 import lombok.RequiredArgsConstructor;
8 import lombok.extern.slf4j.Slf4j;
9 import org.springframework.http.HttpStatus;
10 import org.springframework.http.MediaType;
11 import org.springframework.http.ResponseEntity;
12 import org.springframework.validation.FieldError;
13 import org.springframework.web.bind.MethodArgumentNotValidException;
14 import org.springframework.web.bind.annotation.*;
15 import org.springframework.web.context.request.async.DeferredResult;
17 import javax.servlet.http.HttpServletRequest;
18 import javax.validation.Valid;
20 import java.util.Date;
21 import java.util.HashMap;
23 import java.util.Optional;
24 import java.util.concurrent.CompletableFuture;
27 @RequestMapping(TransferController.PATH)
29 @RequiredArgsConstructor
31 public class TransferController
33 public final static String PATH = "/transfers";
35 private final GetTransferUseCase getTransferUseCase;
36 private final MessagingService messagingService;
37 private final TransferConsumer consumer;
42 consumes = MediaType.APPLICATION_JSON_VALUE,
43 produces = MediaType.APPLICATION_JSON_VALUE)
44 public DeferredResult<ResponseEntity<?>> transfer(
45 HttpServletRequest request,
46 @Valid @RequestBody TransferDTO transferDTO)
48 DeferredResult<ResponseEntity<?>> result = new DeferredResult<>();
51 .get(transferDTO.getId())
53 CompletableFuture.completedFuture(
56 .location(location(transferDTO))
64 .id(transferDTO.getId())
65 .payer(transferDTO.getPayer())
66 .payee(transferDTO.getPayee())
67 .amount(transferDTO.getAmount())
71 .created(location(transferDTO))
74 .thenAccept(responseEntity -> result.setResult(responseEntity))
77 result.setErrorResult(e);
84 private URI location(TransferDTO transferDTO)
86 return URI.create(PATH + "/" + transferDTO.getId());
91 produces = MediaType.APPLICATION_JSON_VALUE)
92 public ResponseEntity<TransferDTO> get(@PathVariable Long id)
96 .uriForKey(Long.toString(id))
99 ResponseEntity<TransferDTO> response =
101 .status(HttpStatus.TEMPORARY_REDIRECT)
102 .location(URI.create(uri + PATH + "/" + id))
109 .map(transfer -> ResponseEntity.ok(TransferDTO.of(transfer)))
110 .orElse(ResponseEntity.notFound().build()));
113 @ResponseStatus(HttpStatus.BAD_REQUEST)
114 @ExceptionHandler(MethodArgumentNotValidException.class)
115 public Map<String, Object> handleValidationExceptions(
116 HttpServletRequest request,
117 MethodArgumentNotValidException e)
119 Map<String, Object> errorAttributes = new HashMap<>();
120 errorAttributes.put("status", HttpStatus.BAD_REQUEST.value());
121 errorAttributes.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
122 errorAttributes.put("path", request.getRequestURI());
123 errorAttributes.put("method", request.getMethod());
124 errorAttributes.put("timestamp", new Date());
125 Map<String, String> errors = new HashMap<>();
126 e.getBindingResult().getAllErrors().forEach((error) -> {
127 String fieldName = ((FieldError) error).getField();
128 String errorMessage = error.getDefaultMessage();
129 errors.put(fieldName, errorMessage);
131 errorAttributes.put("errors", errors);
132 errorAttributes.put("message", "Validation failed: Invalid message format, error count: " + errors.size());
133 return errorAttributes;