diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index bb7c649..3cced03 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -5,7 +5,7 @@ services: book-a-book-eureka: image: aleixmt/book-a-book-eureka:latest ports: - - "0.0.0.0:8761:8761" + - "0.0.0.0:8762:8761" restart: unless-stopped pull_policy: always healthcheck: diff --git a/pom.xml b/pom.xml index 5b37a70..4ac0b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -66,6 +66,12 @@ org.springframework.boot spring-boot-starter-data-jpa + + + io.github.openfeign + feign-okhttp + 13.2 + diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/clients/BuscadorClient.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/clients/BuscadorClient.java index c04aee1..b5a2d59 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/clients/BuscadorClient.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/clients/BuscadorClient.java @@ -1,5 +1,6 @@ package net.unir.missi.desarrollowebfullstack.bookabook.operador.clients; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.FeignConfig; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.*; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.ResponseEntity; @@ -9,9 +10,10 @@ import java.util.List; import java.util.Map; -@FeignClient(name = "buscador") +@FeignClient(name = "buscador", url = "http://localhost:8082/",configuration = FeignConfig.class) public interface BuscadorClient { + // Authors @GetMapping("/authors") diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/FeignConfig.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/FeignConfig.java index fa91680..2e1b22f 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/FeignConfig.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/FeignConfig.java @@ -1,8 +1,12 @@ package net.unir.missi.desarrollowebfullstack.bookabook.operador.config; -import org.springframework.cloud.openfeign.EnableFeignClients; +import feign.Logger; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignConfig { + + @Bean + Logger.Level feingLoggerLevel(){ return Logger.Level.FULL; } } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanMerger.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanMerger.java new file mode 100644 index 0000000..8028669 --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanMerger.java @@ -0,0 +1,18 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.config; + +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql.Loan; +import org.springframework.context.annotation.Configuration; +@Configuration +public class LoanMerger { + public Loan merge(Loan destiny, Loan source) + { + destiny.setBookId(source.getBookId()); + destiny.setClientId(source.getClientId()); + destiny.setDueDate(source.getDueDate()); + destiny.setLoanDate(source.getLoanDate()); + destiny.setIsReturned(source.getIsReturned()); + destiny.setRenewalCount(source.getRenewalCount()); + destiny.setReturnDate(source.getReturnDate()); + return destiny; + } +} \ No newline at end of file diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanMergerNonEmpty.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanMergerNonEmpty.java new file mode 100644 index 0000000..be84b91 --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanMergerNonEmpty.java @@ -0,0 +1,46 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.config; + +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql.Loan; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class LoanMergerNonEmpty { + public Loan merge(Loan destiny, Loan source) + { + if (source.getBookId() != null && source.getBookId() != 0) + { + destiny.setBookId(source.getBookId()); + } + + if (source.getClientId() != null && source.getClientId() != 0) + { + destiny.setClientId(source.getClientId()); + } + + if (source.getDueDate() != null) + { + destiny.setDueDate(source.getDueDate()); + } + + if (source.getLoanDate() != null) + { + destiny.setLoanDate(source.getLoanDate()); + } + + if (source.getIsReturned() != null) + { + destiny.setIsReturned(source.getIsReturned()); + } + + if (source.getRenewalCount() != null) + { + destiny.setRenewalCount(source.getRenewalCount()); + } + + if (source.getReturnDate() != null) + { + destiny.setReturnDate(source.getReturnDate()); + } + return destiny; + } +} \ No newline at end of file diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java new file mode 100644 index 0000000..3a4a860 --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanRequestToLoanConverter.java @@ -0,0 +1,22 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.config; + +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanRequest; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql.Loan; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; + +@Configuration +public class LoanRequestToLoanConverter implements Converter { + @Override + public Loan convert(LoanRequest source) { + return Loan.builder() + .bookId(source.getBookId()) + .clientId(source.getClientId()) + .loanDate(source.getLoanDate()) + .dueDate(source.getDueDate()) + .returnDate(source.getReturnDate()) + .isReturned(source.getIsReturned()) + .renewalCount(source.getRenewalCount()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanToLoanResponseConverter.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanToLoanResponseConverter.java new file mode 100644 index 0000000..5f33084 --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/config/LoanToLoanResponseConverter.java @@ -0,0 +1,23 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.config; + +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanResponse; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql.Loan; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; + +@Configuration +public class LoanToLoanResponseConverter implements Converter { + @Override + public LoanResponse convert(Loan source) { + return LoanResponse.builder() + .id(source.getId()) + .bookId(source.getBookId()) + .clientId(source.getClientId()) + .loanDate(source.getLoanDate()) + .dueDate(source.getDueDate()) + .returnDate(source.getReturnDate()) + .isReturned(source.getIsReturned()) + .renewalCount(source.getRenewalCount()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java index 8c76078..a596104 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/controller/LoansController.java @@ -3,6 +3,8 @@ import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.BadParametersException; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.EntityNotFoundException; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanRequest; import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanResponse; import net.unir.missi.desarrollowebfullstack.bookabook.operador.service.LoanService; @@ -22,7 +24,7 @@ public class LoansController { private final LoanService service; @GetMapping("/loans") - public ResponseEntity> getAllLoans( + public ResponseEntity> getLoans( @Parameter(name="bookId", example = "") @RequestParam(required = false) Long bookId, @Parameter(name="clientId", example = "") @@ -39,52 +41,129 @@ public ResponseEntity> getAllLoans( @RequestParam(required = false)Integer renewalCount ) { - try { - List response = service.getAllLoans(bookId, clientId, loanDate, returnDate, dueDate, isReturned, renewalCount); - return ResponseEntity.ok(Objects.requireNonNullElse(response, Collections.emptyList())); - } - catch(Exception e) { - return ResponseEntity.internalServerError().build(); - } + try + { + List response = this.service.getAllLoans(bookId, clientId, loanDate, returnDate, dueDate, isReturned, renewalCount); + return ResponseEntity.ok(Objects.requireNonNullElse(response, Collections.emptyList())); + } + catch (EntityNotFoundException e) + { + return ResponseEntity.notFound().build(); + } + catch (BadParametersException e) + { + return ResponseEntity.badRequest().build(); + } + catch (Exception e) + { + return ResponseEntity.internalServerError().build(); + } + } + + @GetMapping("/loans/{id}") + public ResponseEntity getLoan(@PathVariable String id) { + try + { + LoanResponse response = this.service.getLoanById(Long.valueOf(id)); + return ResponseEntity.ok(response); + } + catch (EntityNotFoundException e) + { + return ResponseEntity.notFound().build(); + } + catch (BadParametersException e) + { + return ResponseEntity.badRequest().build(); + } + catch (Exception e) + { + return ResponseEntity.internalServerError().build(); + } } @PostMapping("/loans") public ResponseEntity addLoan(@RequestBody LoanRequest loanRequest) { - try { - if(loanRequest != null) { - if(!service.validateLoan(loanRequest)) { - return ResponseEntity.notFound().build(); - } - LoanResponse newLoan = service.createLoan(loanRequest); - return ResponseEntity.status(HttpStatus.CREATED).body(newLoan); - } - else + try + { + if (loanRequest == null) { return ResponseEntity.badRequest().build(); } - } catch(Exception e) { + LoanResponse newLoan = this.service.createLoan(loanRequest); + return ResponseEntity.status(HttpStatus.CREATED).body(newLoan); + } + catch (EntityNotFoundException e) + { + return ResponseEntity.notFound().build(); + } + catch (BadParametersException e) + { + return ResponseEntity.badRequest().build(); + } + catch (Exception e) + { return ResponseEntity.internalServerError().build(); } } - @GetMapping("/loans/{id}") - public ResponseEntity getLoanById(Long id) { - try { - LoanResponse response = service.getLoanById(id); - return ResponseEntity.ok(response); + @DeleteMapping("/loans/{id}") + public ResponseEntity deleteLoan(@PathVariable String id) { + try + { + return ResponseEntity.ok(this.service.deleteLoan(id)); + } + catch (EntityNotFoundException e) + { + return ResponseEntity.notFound().build(); + } + catch (Exception e) + { + return ResponseEntity.internalServerError().build(); + } + } + + @PatchMapping("/loans/{id}") + public ResponseEntity patchLoan(@RequestBody LoanRequest loanRequest, @PathVariable String id) { + try + { + if (loanRequest == null) + { + return ResponseEntity.badRequest().build(); + } + LoanResponse newLoan = this.service.modifyLoan(loanRequest, Long.valueOf(id)); + return ResponseEntity.status(HttpStatus.CREATED).body(newLoan); } - catch(Exception e) { + catch (EntityNotFoundException e) + { + return ResponseEntity.notFound().build(); + } + catch (BadParametersException e) + { + return ResponseEntity.badRequest().build(); + } + catch (Exception e) + { return ResponseEntity.internalServerError().build(); } } @GetMapping("/loans/client/{clientId}") - public ResponseEntity> getLoanByClientId(Long clientId) { - try { - List response = service.getLoansByClientId(clientId); + public ResponseEntity> getLoanByClientId(@PathVariable String clientId) { + try + { + List response = service.getLoansByClientId(Long.valueOf(clientId)); return ResponseEntity.ok(Objects.requireNonNullElse(response, Collections.emptyList())); } - catch(Exception e) { + catch (EntityNotFoundException e) + { + return ResponseEntity.notFound().build(); + } + catch (BadParametersException e) + { + return ResponseEntity.badRequest().build(); + } + catch(Exception e) + { return ResponseEntity.internalServerError().build(); } } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/BadParametersException.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/BadParametersException.java new file mode 100644 index 0000000..d582f9b --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/BadParametersException.java @@ -0,0 +1,8 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions; + +public class BadParametersException extends RuntimeException{ + public BadParametersException(String errorMessage, Throwable err) + { + super(errorMessage, err); + } +} diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityNotFoundException.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityNotFoundException.java new file mode 100644 index 0000000..96a99cf --- /dev/null +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/exceptions/EntityNotFoundException.java @@ -0,0 +1,8 @@ +package net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions; + +public class EntityNotFoundException extends RuntimeException{ + public EntityNotFoundException(String errorMessage, Throwable err) + { + super(errorMessage, err); + } +} \ No newline at end of file diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java index 282c4a6..9f15221 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/model/sql/Loan.java @@ -1 +1,44 @@ - private Long bookId; \ No newline at end of file +package net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql; + +import java.util.Date; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + + +@Entity +@Table(name = "loans") +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@ToString +public class Loan { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(name = "bookId") + private Long bookId; + @Column(name = "clientId") + private Long clientId; + @Column(name = "loanDate") + private Date loanDate; + @Column(name = "returnDate") + private Date returnDate; + @Column(name = "dueDate") + private Date dueDate; + @Column(name = "isReturned") + private Boolean isReturned; + @Column(name = "renewalCount") + private Integer renewalCount; +} diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java index 020c0f9..24a1fed 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/repository/LoanRepository.java @@ -11,6 +11,7 @@ import java.util.Date; import java.util.List; +import java.util.Optional; @Repository @Slf4j @@ -26,7 +27,12 @@ public LoanRepository(LoanJpaRepository loanJpaRepository) { public Loan findById(Long id) { return loanJpaRepository.findById(id).orElse(null); } public List findByClientId(Long clientId){ return loanJpaRepository.findByClientId(clientId); } public Loan save(Loan loan){ return loanJpaRepository.save(loan); } - public void delete(Loan loan) { loanJpaRepository.delete(loan); } + public Loan delete(Loan loan) + { + Optional l = this.loanJpaRepository.findById(loan.getId()); + loanJpaRepository.delete(loan); + return l.get(); + } public List search(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount) { SearchCriteria spec = new SearchCriteria<>(); diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java index 87d11f9..430fb72 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/ILoanService.java @@ -7,11 +7,14 @@ import java.util.List; public interface ILoanService { - List getAllLoans(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount) throws RuntimeException; - LoanResponse createLoan(LoanRequest request) throws RuntimeException; - LoanResponse getLoanById(Long id) throws RuntimeException; - List getLoansByClientId(Long clientId) throws RuntimeException; - LoanResponse modifyAllLoanData(LoanRequest preData, LoanRequest loanData) throws RuntimeException; - LoanResponse modifyLoan(LoanRequest preData, LoanRequest loanData) throws RuntimeException; - LoanResponse deleteLoan(LoanRequest preData, LoanRequest loanData) throws RuntimeException; + // CRUD + List getAllLoans(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount); + LoanResponse createLoan(LoanRequest request); + LoanResponse getLoanById(Long id); + LoanResponse modifyAllLoanData(LoanRequest loan, Long id); + LoanResponse modifyLoan(LoanRequest loan, Long id); + LoanResponse deleteLoan(String id); + + // SPECIALIZATIONS + List getLoansByClientId(Long clientId); } diff --git a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java index 6e70efb..5850872 100644 --- a/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java +++ b/src/main/java/net/unir/missi/desarrollowebfullstack/bookabook/operador/service/LoanService.java @@ -1 +1,255 @@ - public LoanResponse modifyAllLoanData(LoanRequest preData, LoanRequest loanData) throws RuntimeException { \ No newline at end of file +package net.unir.missi.desarrollowebfullstack.bookabook.operador.service; + +import lombok.extern.slf4j.Slf4j; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.clients.BuscadorClient; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.LoanMerger; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.LoanMergerNonEmpty; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.LoanRequestToLoanConverter; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.config.LoanToLoanResponseConverter; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.BadParametersException; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.exceptions.EntityNotFoundException; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.BookResponse; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.ClientResponse; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanRequest; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.api.LoanResponse; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.model.sql.Loan; +import net.unir.missi.desarrollowebfullstack.bookabook.operador.repository.LoanRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.awt.print.Book; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class LoanService implements ILoanService { + + @Autowired + private LoanRepository loanRepository; + + @Autowired + private BuscadorClient buscadorClient; + + @Autowired + private LoanRequestToLoanConverter loanRequestToLoanConverter; + + @Autowired + private LoanToLoanResponseConverter loanToLoanResponseConverter; + + @Autowired + private LoanMerger loanMerger; + + @Autowired + private LoanMergerNonEmpty loanMergerNonEmpty; + + // CRUD + + @Override + public List getAllLoans(Long bookId, Long clientId, Date loanDate, Date returnDate, Date dueDate, Boolean isReturned, Integer renewalCount) { + Loan loan = new Loan(null, bookId, clientId, loanDate, returnDate, dueDate, isReturned, renewalCount); + List loanList; + if (this.isValidSyntaxLoanForNulls(loan)) { + loanList = loanRepository.search(bookId, clientId, loanDate, returnDate, dueDate, isReturned, renewalCount); + } + else { + loanList = loanRepository.findAll(); + } + return loanList.stream().map((Loan l) -> this.loanToLoanResponseConverter.convert(l)).collect(Collectors.toList()); + } + + @Override + public LoanResponse createLoan(LoanRequest request) { + // Convert to in-memory loan + Loan loan = this.loanRequestToLoanConverter.convert(request); + + // If loan has null values or wrong values throw 400 + if (!this.isValidSyntaxLoanForNulls(Objects.requireNonNull(loan)) + || ! this.isValidSyntaxLoanForZeroes(loan)) + { + throw new BadParametersException("One or more parameters of the request are wrong", null); + } + + // If loan referencing non-existing books throw 404 + if (! isExistingBook(loan.getBookId().toString())) + { + throw new EntityNotFoundException("Book id " + loan.getBookId() + " does not exist.", null); + } + + // If loan referencing non-existing clients throw 404 + if(! isExistingClient(loan.getClientId().toString())) + { + throw new EntityNotFoundException("Client id " + loan.getClientId() + " does not exist.", null); + } + + // Implicit else: valid loan is saved in the DB + Loan createdLoan = loanRepository.save(loan); + return this.loanToLoanResponseConverter.convert(createdLoan); + } + + @Override + public LoanResponse getLoanById(Long id) { + // If loan does not exist throw 404 + Loan loan = loanRepository.findById(id); + if (loan == null) + { + throw new EntityNotFoundException("Loan with id " + id.toString() + " does not exist", null); + } + + return this.loanToLoanResponseConverter.convert(loan); + } + + @Override + public LoanResponse modifyAllLoanData(LoanRequest loanRequest, Long id) { + Loan loan = this.loanRequestToLoanConverter.convert(loanRequest); + + // If loan has null values or wrong values throw 400 + if ( + ! this.isValidSyntaxLoanForNulls(Objects.requireNonNull(loan)) + || ! this.isValidSyntaxLoanForZeroes(loan)) + { + throw new BadParametersException("One or more parameters of the request are wrong", null); + } + + // If loan does not exist throw 404 + Loan loanMatched = loanRepository.findById(id); + if (loanMatched == null) + { + throw new EntityNotFoundException("Loan with id " + id.toString() + " does not exist", null); + } + + // If loan referencing non-existing books throw 404 + if (! isExistingBook(loan.getBookId().toString())) + { + throw new EntityNotFoundException("Book id " + loan.getBookId() + " does not exist.", null); + } + + // If loan referencing non-existing clients throw 404 + if(! isExistingClient(loan.getClientId().toString())) + { + throw new EntityNotFoundException("Client id " + loan.getClientId() + " does not exist.", null); + } + + // Update values of matched loan with values of received request + Loan mergedLoan = this.loanMerger.merge(loanMatched, loan); + + // Save updated loan + mergedLoan = this.loanRepository.save(mergedLoan); + + // Return response + return this.loanToLoanResponseConverter.convert(mergedLoan); + } + + @Override + public LoanResponse modifyLoan(LoanRequest loanRequest, Long id) { + Loan loan = this.loanRequestToLoanConverter.convert(loanRequest); + + // If loan has null values or wrong values throw 400 + if ( + ! this.isValidSyntaxLoanForNulls(Objects.requireNonNull(loan)) + || ! this.isValidSyntaxLoanForZeroes(loan)) + { + throw new BadParametersException("One or more parameters of the request are wrong", null); + } + + // If loan does not exist throw 404 + Loan loanMatched = loanRepository.findById(id); + if (loanMatched == null) + { + throw new EntityNotFoundException("Loan with id " + id.toString() + " does not exist", null); + } + + // If loan referencing non-existing books throw 404 + if (! isExistingBook(loan.getBookId().toString())) + { + throw new EntityNotFoundException("Book id " + loan.getBookId() + " does not exist.", null); + } + + // If loan referencing non-existing clients throw 404 + if(! isExistingClient(loan.getClientId().toString())) + { + throw new EntityNotFoundException("Client id " + loan.getClientId() + " does not exist.", null); + } + + // Update values of matched loan with values of received request + Loan mergedLoan = this.loanMergerNonEmpty.merge(loanMatched, loan); + + // Save updated loan + mergedLoan = this.loanRepository.save(mergedLoan); + + // Return response + return this.loanToLoanResponseConverter.convert(mergedLoan); + } + + @Override + public LoanResponse deleteLoan(String id) { + // If loan does not exist throw 404 + Loan loanMatched = loanRepository.findById(Long.valueOf(id)); + if (loanMatched == null) + { + throw new EntityNotFoundException("Loan with id " + id.toString() + " does not exist", null); + } + + // Create search instance + Loan l = new Loan(); + l.setId(Long.valueOf(id)); + + Loan loan = this.loanRepository.delete(l); + return this.loanToLoanResponseConverter.convert(loan); + } + + + // SPECIALIZATION + + @Override + public List getLoansByClientId(Long clientId) { + List loansList = loanRepository.findByClientId(clientId); + return loansList.stream().map((Loan l) -> this.loanToLoanResponseConverter.convert(l)).collect(Collectors.toList()); + } + + // PRIVATE METHODS + + private boolean isExistingBook(String id) { + try { + ResponseEntity book = buscadorClient.getBook(id); + Logger.global.info("MyText"); + return book != null; + } + catch(Exception e) { + return false; + } + } + + private boolean isExistingClient(String id) { + try { + ResponseEntity client = buscadorClient.getClient(id); + Logger.global.info("MyText"); + return client != null; + } + catch(Exception e) { + return false; + } + } + + private boolean isValidSyntaxLoanForNulls(Loan loan) + { + return loan.getBookId() != null + && loan.getClientId() != null + && loan.getLoanDate() != null + && loan.getReturnDate() != null + && loan.getDueDate() != null + && loan.getIsReturned() != null + && loan.getRenewalCount() != null; + } + + private boolean isValidSyntaxLoanForZeroes(Loan loan) + { + return loan.getBookId() != 0 + && loan.getClientId() != 0; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c154b25..aa124c4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -61,9 +61,10 @@ springdoc.swagger-ui.path=/swagger-ui.html # Configure application name for spring.application.name=operador # URL of the Eureka service -eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8761/eureka} +eureka.client.serviceUrl.defaultZone=${EUREKA_URI:http://localhost:8762/eureka} # Use IP address eureka.instance.preferIpAddress=true +eureka.client.register-with-eureka=false ############### ### LOGGING ###