MVP for transfer service
[demos/kafka/demos-kafka-payment-system-transfer] / src / main / java / de / juplo / kafka / payment / transfer / adapter / TransferController.java
1 package de.juplo.kafka.payment.transfer.adapter;
2
3
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.InitiateTransferUseCase;
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
16 import javax.servlet.http.HttpServletRequest;
17 import javax.validation.Valid;
18 import java.net.URI;
19 import java.util.Date;
20 import java.util.HashMap;
21 import java.util.Map;
22
23
24 @RestController
25 @RequiredArgsConstructor
26 @Slf4j
27  public class TransferController
28 {
29   public final static String PATH = "/transfers";
30
31   private final InitiateTransferUseCase initiateTransferUseCase;
32   private final GetTransferUseCase getTransferUseCase;
33
34
35   @PostMapping(
36       path = PATH,
37       consumes = MediaType.APPLICATION_JSON_VALUE,
38       produces = MediaType.APPLICATION_JSON_VALUE)
39   public ResponseEntity<?> transfer(@Valid @RequestBody TransferDTO transferDTO)
40   {
41     Transfer transfer =
42         Transfer
43             .builder()
44             .id(transferDTO.getId())
45             .payer(transferDTO.getPayer())
46             .payee(transferDTO.getPayee())
47             .amount(transferDTO.getAmount())
48             .build();
49
50     initiateTransferUseCase.initiate(transfer);
51
52     return ResponseEntity.created(URI.create(PATH + "/" + transferDTO.getId())).build();
53   }
54
55   @GetMapping(
56       path = PATH + "/{id}",
57       produces = MediaType.APPLICATION_JSON_VALUE)
58   public ResponseEntity<TransferDTO> get(@PathVariable Long id)
59   {
60     return
61         getTransferUseCase
62             .get(id)
63             .map(transfer -> ResponseEntity.ok(TransferDTO.of(transfer)))
64             .orElse(ResponseEntity.notFound().build());
65   }
66
67   @ResponseStatus(HttpStatus.BAD_REQUEST)
68   @ExceptionHandler(MethodArgumentNotValidException.class)
69   public Map<String, Object> handleValidationExceptions(
70       HttpServletRequest request,
71       MethodArgumentNotValidException e)
72   {
73     Map<String, Object> errorAttributes = new HashMap<>();
74     errorAttributes.put("status", HttpStatus.BAD_REQUEST.value());
75     errorAttributes.put("error", HttpStatus.BAD_REQUEST.getReasonPhrase());
76     errorAttributes.put("path", request.getRequestURI());
77     errorAttributes.put("method", request.getMethod());
78     errorAttributes.put("timestamp", new Date());
79     Map<String, String> errors = new HashMap<>();
80     e.getBindingResult().getAllErrors().forEach((error) -> {
81       String fieldName = ((FieldError) error).getField();
82       String errorMessage = error.getDefaultMessage();
83       errors.put(fieldName, errorMessage);
84     });
85     errorAttributes.put("errors", errors);
86     errorAttributes.put("message", "Validation failed: Invalid message format, error count: " + errors.size());
87     return errorAttributes;
88   }
89 }