From e7537fc60958dea2ffaaac8297c50eb963f8d2d9 Mon Sep 17 00:00:00 2001 From: Giovanni Moratto Date: Tue, 3 Aug 2021 13:47:28 -0300 Subject: [PATCH] =?UTF-8?q?notifica=C3=A7=C3=A3o=20de=20bloqueio=20v1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Bloqueio/BloqueioController.java | 43 +++++++++++++++---- .../Bloqueio/BloqueioModel.java | 7 +++ .../Bloqueio/BloqueioRequest.java | 18 ++++++++ .../Bloqueio/BloqueioResponse.java | 23 ++++++++++ .../Bloqueio/BloqueioStatus.java | 10 +++++ .../biometria/BiometriaModel.java | 2 + .../desafioproposta/cartao/CartaoModel.java | 21 ++++++++- .../desafioproposta/cartao/CartaoStatus.java | 10 +++++ .../feign/CartoesFeignClient.java | 6 +++ 9 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioRequest.java create mode 100644 src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioResponse.java create mode 100644 src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioStatus.java create mode 100644 src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoStatus.java diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioController.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioController.java index e399a7dd..20397fde 100644 --- a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioController.java +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioController.java @@ -2,6 +2,8 @@ import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoModel; import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoRepository; +import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoStatus; +import br.com.zupacademy.giovannimoratto.desafioproposta.feign.CartoesFeignClient; import br.com.zupacademy.giovannimoratto.desafioproposta.proposta.PropostaController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +16,7 @@ import javax.transaction.Transactional; import java.util.Optional; +import static br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio.BloqueioStatus.FALHA; import static org.springframework.http.HttpStatus.NOT_FOUND; import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; @@ -31,22 +34,30 @@ public class BloqueioController { private CartaoRepository cartaoRepository; @Autowired private BloqueioRepository bloqueioRepository; + @Autowired + private CartoesFeignClient api; @PostMapping("/cartoes/bloqueio/{id}") @Transactional public ResponseEntity solicitacaoDeBloqueio(@PathVariable Long id, - @RequestHeader(value = "User-Agent") String userAgent, - HttpServletRequest request) { + @RequestHeader(value = "User-Agent") String userAgent, + HttpServletRequest request) { CartaoModel cartao = verificaSeCartaoExiste(id); logger.info("Cartão encontrado"); verificaSeCartaoJaEstaBloqueado(cartao); - logger.info("Nenhum bloqueio ativo no cartão"); - BloqueioModel cartaoBloqueado = new BloqueioModel(request.getRemoteAddr(), userAgent, + notificaBloqueio(cartao); + + BloqueioModel solicitacaoBloqueio = new BloqueioModel(request.getRemoteAddr(), userAgent, cartao.getNumero(), cartao); + logger.info("Requisição de bloqueio convertida em classe de dominio"); - bloqueioRepository.save(cartaoBloqueado); + bloqueioRepository.save(solicitacaoBloqueio); logger.info("Requisição de bloqueio persistida no banco de dados"); + cartao.bloquear(); + logger.info("Cartão bloqueado"); + cartaoRepository.save(cartao); + logger.info("Status do cartão atualizado no banco de dados"); return ResponseEntity.ok().build(); } @@ -58,9 +69,25 @@ private CartaoModel verificaSeCartaoExiste(Long id) { private void verificaSeCartaoJaEstaBloqueado(CartaoModel cartao) { logger.info("Verificando se o cartão já está bloqueado..."); - Optional optionalBloqueio = bloqueioRepository.findByNumero(cartao.getNumero()); - if (optionalBloqueio.isPresent()) { - throw new ResponseStatusException(UNPROCESSABLE_ENTITY, "Cartão já está bloqueado"); + Optional optionalCartao = cartaoRepository.findById(cartao.getId()); + if (optionalCartao.get().getStatus().equals(CartaoStatus.BLOQUEADO)) { + throw new ResponseStatusException(UNPROCESSABLE_ENTITY, "Este cartão já foi bloqueado"); + } + logger.info("Verificando se o cartão possui solicitação de bloqueio..."); + BloqueioModel solicitacaoBloqueio = bloqueioRepository.findByNumero(cartao.getNumero()).orElseThrow(); + if (solicitacaoBloqueio.isAtivo()) { + throw new ResponseStatusException(UNPROCESSABLE_ENTITY, "Já foi solicitado o bloqueio deste cartão"); + } + logger.info("Nenhum bloqueio ativo no cartão"); + } + + private void notificaBloqueio(CartaoModel cartao) { + logger.info("Notificação de tentativa de bloqueio enviada ao cliente"); + BloqueioResponse resultado = api.notificacaoDeBloqueio( + cartao.getNumero(), new BloqueioRequest("api-proposta")); + logger.info("Resultado da notificação: {}", resultado.getResultado()); + if (resultado.getResultado().equals(FALHA)) { + throw new ResponseStatusException(UNPROCESSABLE_ENTITY, "Falha no sistema"); } } diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioModel.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioModel.java index 216e811a..ba0367e1 100644 --- a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioModel.java +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioModel.java @@ -1,6 +1,7 @@ package br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio; import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoModel; +import com.fasterxml.jackson.annotation.JsonBackReference; import org.hibernate.annotations.CreationTimestamp; import javax.persistence.*; @@ -28,8 +29,10 @@ public class BloqueioModel { @CreationTimestamp private LocalDateTime bloqueadoEm; @NotNull + @JsonBackReference @OneToOne(cascade = CascadeType.MERGE, fetch = FetchType.EAGER) private CartaoModel cartao; + private boolean ativo = false; @Deprecated public BloqueioModel() { @@ -40,6 +43,7 @@ public BloqueioModel(String ipCliente, String userAgent, String numero, CartaoMo this.userAgent = userAgent; this.numero = numero; this.cartao = cartao; + this.ativo = true; } public Long getId() { @@ -66,4 +70,7 @@ public CartaoModel getCartao() { return cartao; } + public boolean isAtivo() { + return ativo; + } } diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioRequest.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioRequest.java new file mode 100644 index 00000000..9aa7c496 --- /dev/null +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioRequest.java @@ -0,0 +1,18 @@ +package br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio; + +/** + * @Author giovanni.moratto + */ + +public class BloqueioRequest { + + private final String sistemaResponsavel; + + public BloqueioRequest(String sistemaResponsavel) { + this.sistemaResponsavel = sistemaResponsavel; + } + + public String getSistemaResponsavel() { + return sistemaResponsavel; + } +} diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioResponse.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioResponse.java new file mode 100644 index 00000000..ea470c64 --- /dev/null +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioResponse.java @@ -0,0 +1,23 @@ +package br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio; + +/** + * @Author giovanni.moratto + */ + +public class BloqueioResponse { + + private BloqueioStatus resultado; + + @Deprecated + public BloqueioResponse() { + } + + public BloqueioResponse(BloqueioStatus resultado) { + this.resultado = resultado; + } + + public BloqueioStatus getResultado() { + return resultado; + } + +} diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioStatus.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioStatus.java new file mode 100644 index 00000000..23e610c0 --- /dev/null +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/Bloqueio/BloqueioStatus.java @@ -0,0 +1,10 @@ +package br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio; + +/** + * @Author giovanni.moratto + */ + +public enum BloqueioStatus { + BLOQUEADO, + FALHA; +} diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/biometria/BiometriaModel.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/biometria/BiometriaModel.java index a9a08f4a..85415fb0 100644 --- a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/biometria/BiometriaModel.java +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/biometria/BiometriaModel.java @@ -1,6 +1,7 @@ package br.com.zupacademy.giovannimoratto.desafioproposta.biometria; import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoModel; +import com.fasterxml.jackson.annotation.JsonBackReference; import org.hibernate.annotations.CreationTimestamp; import javax.persistence.*; @@ -25,6 +26,7 @@ public class BiometriaModel { private String fingerprint; @NotNull @ManyToOne + @JsonBackReference @JoinColumn(nullable = false) private CartaoModel cartao; @CreationTimestamp diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoModel.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoModel.java index 17aad099..f8ffd387 100644 --- a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoModel.java +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoModel.java @@ -4,12 +4,15 @@ import br.com.zupacademy.giovannimoratto.desafioproposta.biometria.BiometriaModel; import br.com.zupacademy.giovannimoratto.desafioproposta.proposta.PropostaModel; import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; import javax.persistence.*; import java.time.LocalDateTime; import java.util.HashSet; import java.util.Set; +import static br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoStatus.ATIVO; +import static br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoStatus.BLOQUEADO; import static javax.persistence.GenerationType.IDENTITY; /** @@ -31,10 +34,14 @@ public class CartaoModel { @JsonBackReference @OneToOne(mappedBy = "cartao") private PropostaModel proposta; - @OneToMany(mappedBy = "cartao") - private Set biometria = new HashSet <>(); + @JsonManagedReference + @OneToMany(mappedBy = "cartao", cascade = CascadeType.MERGE, fetch = FetchType.EAGER) + private Set biometrias = new HashSet <>(); + @JsonManagedReference @OneToOne(mappedBy = "cartao") private BloqueioModel bloqueio; + @Enumerated(EnumType.STRING) + private CartaoStatus status = ATIVO; /* Constructors */ @Deprecated @@ -49,6 +56,12 @@ public CartaoModel(String numero, LocalDateTime emitidoEm, String titular, Integ this.proposta = proposta; } + /* Methods */ + public void bloquear() { + this.status = BLOQUEADO; + } + + /* Getters */ public PropostaModel getProposta() { return proposta; } @@ -60,4 +73,8 @@ public Long getId() { public String getNumero() { return numero; } + + public CartaoStatus getStatus() { + return status; + } } \ No newline at end of file diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoStatus.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoStatus.java new file mode 100644 index 00000000..cd5a75e5 --- /dev/null +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/cartao/CartaoStatus.java @@ -0,0 +1,10 @@ +package br.com.zupacademy.giovannimoratto.desafioproposta.cartao; + +/** + * @Author giovanni.moratto + */ + +public enum CartaoStatus { + BLOQUEADO, + ATIVO; +} diff --git a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/feign/CartoesFeignClient.java b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/feign/CartoesFeignClient.java index 47e1b36f..720d9a97 100644 --- a/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/feign/CartoesFeignClient.java +++ b/src/main/java/br/com/zupacademy/giovannimoratto/desafioproposta/feign/CartoesFeignClient.java @@ -1,8 +1,11 @@ package br.com.zupacademy.giovannimoratto.desafioproposta.feign; +import br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio.BloqueioRequest; +import br.com.zupacademy.giovannimoratto.desafioproposta.Bloqueio.BloqueioResponse; import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.AnaliseRequest; import br.com.zupacademy.giovannimoratto.desafioproposta.cartao.CartaoResponse; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -16,4 +19,7 @@ public interface CartoesFeignClient { @PostMapping("/api/cartoes") CartaoResponse associaCartao(@RequestBody AnaliseRequest request); + @PostMapping("/api/cartoes/{id}/bloqueios") + BloqueioResponse notificacaoDeBloqueio(@PathVariable("id") String id, @RequestBody BloqueioRequest request); + }