Compare commits
7 Commits
user
...
cancel-res
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c13e60f42b | ||
|
|
58978def54 | ||
|
|
273dfed81e | ||
|
|
62c683fb63 | ||
|
|
943693bd1d | ||
|
|
dbe12c918f | ||
|
|
6f4c938a85 |
17
pom.xml
17
pom.xml
@@ -17,14 +17,14 @@
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
<spring-cloud.version>Hoxton.M3</spring-cloud.version>
|
||||
<surefire.and.failsafe.report.dir>target/test-report</surefire.and.failsafe.report.dir>
|
||||
<code.coverage.exclusions>
|
||||
**/io/wkrzywiec/hexagonal/library/borrowing/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/email/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/inventory/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/user/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/infrastructure/repository/*Entity.java
|
||||
**/io/wkrzywiec/hexagonal/library/domain/borrowing/core/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/domain/email/core/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/domain/inventory/core/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/domain/user/core/model/**,
|
||||
**/io/wkrzywiec/hexagonal/library/**/*Entity.java,
|
||||
**/io/wkrzywiec/hexagonal/library/LibraryHexagonalApplication.java
|
||||
</code.coverage.exclusions>
|
||||
</properties>
|
||||
|
||||
@@ -58,11 +58,6 @@
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vavr</groupId>
|
||||
<artifactId>vavr</artifactId>
|
||||
<version>0.10.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.wkrzywiec.hexagonal.library.BookTestData;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.infrastructure.BookRepository;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure.BookRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1,9 +1,9 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.ValidatableResponse;
|
||||
import io.wkrzywiec.hexagonal.library.BookTestData;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.AddNewBookCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.AddNewBookCommand;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.user;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.AddUserCommand;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1,28 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.email.EmailFacade;
|
||||
import io.wkrzywiec.hexagonal.library.email.infrastructure.EmailDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.email.infrastructure.SendGridEmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.incoming.SendReservationConfirmation;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.outgoing.EmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.outgoing.EmailDatabase;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class EmailDomainConfig {
|
||||
|
||||
@Bean
|
||||
public EmailSender emailSender() {
|
||||
return new SendGridEmailSender();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EmailDatabase libraryDatabase(JdbcTemplate jdbcTemplate){
|
||||
return new EmailDatabaseAdapter(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SendReservationConfirmation sendReservationConfirmation(EmailSender emailSender, EmailDatabase database){
|
||||
return new EmailFacade(emailSender, database);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.infrastructure.BorrowingDomainConfig;
|
||||
import io.wkrzywiec.hexagonal.library.infrastructure.EmailDomainConfig;
|
||||
import io.wkrzywiec.hexagonal.library.infrastructure.InventoryDomainConfig;
|
||||
import io.wkrzywiec.hexagonal.library.infrastructure.LibraryHexagonalConfig;
|
||||
import io.wkrzywiec.hexagonal.library.infrastructure.UserDomainConfig;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@Import({
|
||||
LibraryHexagonalConfig.class,
|
||||
InventoryDomainConfig.class,
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.UserFacade;
|
||||
import io.wkrzywiec.hexagonal.library.user.infrastructure.UserDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.user.infrastructure.UserRepository;
|
||||
import io.wkrzywiec.hexagonal.library.user.ports.incoming.AddNewUser;
|
||||
import io.wkrzywiec.hexagonal.library.user.ports.outgoing.UserDatabase;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
public class UserDomainConfig {
|
||||
|
||||
@Bean
|
||||
public UserDatabase userDatabase(UserRepository userRepository){
|
||||
return new UserDatabaseAdapter(userRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AddNewUser addNewUser(UserDatabase userDatabase){
|
||||
return new UserFacade(userDatabase);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.wkrzywiec.hexagonal.library.application;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/")
|
||||
public class LibraryHexagonalController {
|
||||
|
||||
@GetMapping("")
|
||||
public String getAppRoot(){
|
||||
return "Library Hexagonal REST API";
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ActiveUser;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.MakeBookAvailableCommand;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservationDetails;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.exception.ActiveUserNotFoundException;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.AvailableBook;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.exception.AvailableBookNotFoundExeption;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservedBook;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.incoming.MakeBookAvailable;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.incoming.ReserveBook;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing.BorrowingDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing.BorrowingEventPublisher;
|
||||
|
||||
public class BorrowingFacade implements MakeBookAvailable, ReserveBook {
|
||||
|
||||
private final BorrowingDatabase database;
|
||||
private final BorrowingEventPublisher eventPublisher;
|
||||
|
||||
public BorrowingFacade(BorrowingDatabase database, BorrowingEventPublisher eventPublisher) {
|
||||
this.database = database;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MakeBookAvailableCommand bookAvailableCommand) {
|
||||
database.setBookAvailable(bookAvailableCommand.getBookId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long handle(BookReservationCommand bookReservation) {
|
||||
AvailableBook availableBook =
|
||||
database.getAvailableBook(bookReservation.getBookId())
|
||||
.orElseThrow(() -> new AvailableBookNotFoundExeption(bookReservation.getBookId()));
|
||||
|
||||
ActiveUser activeUser =
|
||||
database.getActiveUser(bookReservation.getUserId())
|
||||
.orElseThrow(() -> new ActiveUserNotFoundException(bookReservation.getUserId()));
|
||||
|
||||
ReservedBook reservedBook = activeUser.reserve(availableBook);
|
||||
ReservationDetails reservationDetails = database.save(reservedBook);
|
||||
eventPublisher.publish(new BookReservedEvent(reservationDetails));
|
||||
return reservationDetails.getReservationId().getIdAsLong();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
|
||||
interface Book {
|
||||
Long getIdAsLong();
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.incoming;
|
||||
|
||||
public interface BorrowBook {
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.incoming;
|
||||
|
||||
public interface CancelReservation {
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.incoming;
|
||||
|
||||
public interface GiveBackBook {
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.MakeBookAvailableCommand;
|
||||
|
||||
public interface MakeBookAvailable {
|
||||
void handle(MakeBookAvailableCommand bookAvailableCommand);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservationCommand;
|
||||
|
||||
public interface ReserveBook {
|
||||
Long handle(BookReservationCommand bookReservation);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ActiveUser;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.AvailableBook;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservationDetails;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservedBook;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface BorrowingDatabase {
|
||||
void setBookAvailable(Long bookId);
|
||||
Optional<AvailableBook> getAvailableBook(Long bookId);
|
||||
Optional<ActiveUser> getActiveUser(Long userId);
|
||||
ReservationDetails save(ReservedBook reservedBook);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservedEvent;
|
||||
|
||||
public interface BorrowingEventPublisher {
|
||||
public void publish(BookReservedEvent event);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.application;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.application;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.MakeBookAvailableCommand;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.incoming.MakeBookAvailable;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.NewBookWasAddedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.MakeBookAvailableCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.MakeBookAvailable;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.NewBookWasAddedEvent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.application;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.CancelOverdueReservations;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class OverdueReservationScheduler {
|
||||
|
||||
private final CancelOverdueReservations overdueReservations;
|
||||
|
||||
@Scheduled(fixedRate = 10 * 1000)
|
||||
public void checkOverdueReservations(){
|
||||
overdueReservations.cancelOverdueReservations();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.application;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.application;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.incoming.ReserveBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.ReserveBook;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -0,0 +1,62 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ActiveUser;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.AvailableBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.DueDate;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.MakeBookAvailableCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.OverdueReservation;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservationDetails;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservedBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.exception.ActiveUserNotFoundException;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.exception.AvailableBookNotFoundExeption;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.CancelOverdueReservations;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.MakeBookAvailable;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.ReserveBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing.BorrowingDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing.BorrowingEventPublisher;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
|
||||
public class BorrowingFacade implements MakeBookAvailable, ReserveBook, CancelOverdueReservations {
|
||||
|
||||
private final BorrowingDatabase database;
|
||||
private final BorrowingEventPublisher eventPublisher;
|
||||
|
||||
public BorrowingFacade(BorrowingDatabase database, BorrowingEventPublisher eventPublisher) {
|
||||
this.database = database;
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(MakeBookAvailableCommand bookAvailableCommand) {
|
||||
database.setBookAvailable(bookAvailableCommand.getBookId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long handle(BookReservationCommand bookReservation) {
|
||||
AvailableBook availableBook =
|
||||
database.getAvailableBook(bookReservation.getBookId())
|
||||
.orElseThrow(() -> new AvailableBookNotFoundExeption(bookReservation.getBookId()));
|
||||
|
||||
ActiveUser activeUser =
|
||||
database.getActiveUser(bookReservation.getUserId())
|
||||
.orElseThrow(() -> new ActiveUserNotFoundException(bookReservation.getUserId()));
|
||||
|
||||
ReservedBook reservedBook = activeUser.reserve(availableBook);
|
||||
ReservationDetails reservationDetails = database.save(reservedBook);
|
||||
eventPublisher.publish(new BookReservedEvent(reservationDetails));
|
||||
return reservationDetails.getReservationId().getIdAsLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelOverdueReservations() {
|
||||
DueDate dueDate = new DueDate(Instant.now().plus(3L, ChronoUnit.DAYS));
|
||||
List<OverdueReservation> overdueReservationList = database.findReservationsAfter(dueDate);
|
||||
overdueReservationList.forEach(
|
||||
overdue -> database.setBookAvailable(overdue.getBookIdentificationAsLong()));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.exception.TooManyBooksAssignedToUserException;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.exception.TooManyBooksAssignedToUserException;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
interface Book {
|
||||
Long getIdAsLong();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BookIdentification {
|
||||
private final Long value;
|
||||
|
||||
public Long getValueAsLong(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DueDate {
|
||||
private final Instant timeStamp;
|
||||
|
||||
public Instant asInstant(){
|
||||
return timeStamp;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class OverdueReservation {
|
||||
private Long reservationId;
|
||||
private Long bookIdentification;
|
||||
|
||||
public Long getBookIdentificationAsLong() {
|
||||
return bookIdentification;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class ReservedBook implements Book {
|
||||
|
||||
private final Long bookId;
|
||||
private final Long userId;
|
||||
private final Instant reservedDate;
|
||||
|
||||
public ReservedBook(Long bookId, Long userId) {
|
||||
this.bookId = bookId;
|
||||
this.userId = userId;
|
||||
this.reservedDate = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -21,4 +25,8 @@ public class ReservedBook implements Book {
|
||||
public Long getAssignedUserIdAsLong(){
|
||||
return userId;
|
||||
}
|
||||
|
||||
public Instant getReservedDateAsInstant(){
|
||||
return reservedDate;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model.exception;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.exception;
|
||||
|
||||
public class ActiveUserNotFoundException extends RuntimeException {
|
||||
public ActiveUserNotFoundException(Long bookId){
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model.exception;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.exception;
|
||||
|
||||
public class AvailableBookNotFoundExeption extends RuntimeException {
|
||||
public AvailableBookNotFoundExeption(Long bookId){
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.model.exception;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.exception;
|
||||
|
||||
public class TooManyBooksAssignedToUserException extends RuntimeException {
|
||||
public TooManyBooksAssignedToUserException(Long userId){
|
||||
@@ -0,0 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming;
|
||||
|
||||
public interface BorrowBook {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming;
|
||||
|
||||
public interface CancelOverdueReservations {
|
||||
void cancelOverdueReservations();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming;
|
||||
|
||||
public interface GiveBackBook {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.MakeBookAvailableCommand;
|
||||
|
||||
public interface MakeBookAvailable {
|
||||
void handle(MakeBookAvailableCommand bookAvailableCommand);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservationCommand;
|
||||
|
||||
public interface ReserveBook {
|
||||
Long handle(BookReservationCommand bookReservation);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ActiveUser;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.AvailableBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.DueDate;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.OverdueReservation;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservationDetails;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservedBook;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface BorrowingDatabase {
|
||||
void setBookAvailable(Long bookId);
|
||||
Optional<AvailableBook> getAvailableBook(Long bookId);
|
||||
Optional<ActiveUser> getActiveUser(Long userId);
|
||||
ReservationDetails save(ReservedBook reservedBook);
|
||||
List<OverdueReservation> findReservationsAfter(DueDate dueDate);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservedEvent;
|
||||
|
||||
public interface BorrowingEventPublisher {
|
||||
public void publish(BookReservedEvent event);
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ActiveUser;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.AvailableBook;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservationDetails;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservationId;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.ReservedBook;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing.BorrowingDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.infrastructure.entity.OverdueReservationEntity;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ActiveUser;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.AvailableBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.DueDate;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.OverdueReservation;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservationDetails;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservationId;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.ReservedBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing.BorrowingDatabase;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BorrowingDatabaseAdapter implements BorrowingDatabase {
|
||||
@@ -24,6 +30,14 @@ public class BorrowingDatabaseAdapter implements BorrowingDatabase {
|
||||
jdbcTemplate.update(
|
||||
"INSERT INTO available (book_id) VALUES (?)",
|
||||
bookId);
|
||||
|
||||
jdbcTemplate.update(
|
||||
"DELETE FROM reserved WHERE book_id = ?",
|
||||
bookId);
|
||||
|
||||
jdbcTemplate.update(
|
||||
"DELETE FROM borrowed WHERE book_id = ?",
|
||||
bookId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,9 +83,14 @@ public class BorrowingDatabaseAdapter implements BorrowingDatabase {
|
||||
@Override
|
||||
public ReservationDetails save(ReservedBook reservedBook) {
|
||||
jdbcTemplate.update(
|
||||
"INSERT INTO reserved (book_id, user_id) VALUES (?, ?)",
|
||||
"INSERT INTO reserved (book_id, user_id, reserved_date) VALUES (?, ?, ?)",
|
||||
reservedBook.getIdAsLong(),
|
||||
reservedBook.getAssignedUserIdAsLong());
|
||||
reservedBook.getAssignedUserIdAsLong(),
|
||||
reservedBook.getReservedDateAsInstant());
|
||||
|
||||
jdbcTemplate.update(
|
||||
"DELETE FROM available WHERE book_id = ?",
|
||||
reservedBook.getIdAsLong());
|
||||
|
||||
ReservationId reservationId = jdbcTemplate.queryForObject(
|
||||
"SELECT id FROM reserved WHERE book_id = ?",
|
||||
@@ -79,4 +98,15 @@ public class BorrowingDatabaseAdapter implements BorrowingDatabase {
|
||||
reservedBook.getIdAsLong());
|
||||
return new ReservationDetails(reservationId, reservedBook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OverdueReservation> findReservationsAfter(DueDate dueDate) {
|
||||
List<OverdueReservationEntity> entities = jdbcTemplate.query(
|
||||
"SELECT id AS reservationId, book_id AS bookIdentification FROM reserved WHERE reserved_date > ?",
|
||||
new BeanPropertyRowMapper<OverdueReservationEntity>(OverdueReservationEntity.class),
|
||||
Timestamp.from(dueDate.asInstant()));
|
||||
return entities.stream()
|
||||
.map(entity -> new OverdueReservation(entity.getReservationId(), entity.getBookIdentification()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.borrowing.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing.BorrowingEventPublisher;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing.BorrowingEventPublisher;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -0,0 +1,9 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.borrowing.infrastructure.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OverdueReservationEntity {
|
||||
private Long reservationId;
|
||||
private Long bookIdentification;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.application;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.application;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.model.BookReservedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.email.model.SendReservationConfirmationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.incoming.SendReservationConfirmation;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.model.BookReservedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.SendReservationConfirmationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.incoming.SendReservationConfirmation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.email;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.email.model.EmailAddress;
|
||||
import io.wkrzywiec.hexagonal.library.email.model.ReservationConfirmEmail;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.EmailAddress;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.ReservationConfirmEmail;
|
||||
|
||||
class EmailCreator {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.wkrzywiec.hexagonal.library.email;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.email.model.ReservationConfirmEmail;
|
||||
import io.wkrzywiec.hexagonal.library.email.model.SendReservationConfirmationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.incoming.SendReservationConfirmation;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.outgoing.EmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.outgoing.EmailDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.ReservationConfirmEmail;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.SendReservationConfirmationCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.incoming.SendReservationConfirmation;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing.EmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing.EmailDatabase;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core.model;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core.model;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core.model;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.SendReservationConfirmationCommand;
|
||||
|
||||
public interface SendReservationConfirmation {
|
||||
void handle(SendReservationConfirmationCommand reservationConfirmationCommand);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.ports.outgoing;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing;
|
||||
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.ReservationConfirmEmail;
|
||||
|
||||
public interface EmailSender {
|
||||
void sendReservationConfirmationEmail(ReservationConfirmEmail reservationConfirmEmail);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.outgoing.EmailDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing.EmailDatabase;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.email.infrastructure;
|
||||
|
||||
import com.sendgrid.Method;
|
||||
import com.sendgrid.Request;
|
||||
@@ -6,8 +6,8 @@ import com.sendgrid.SendGrid;
|
||||
import com.sendgrid.helpers.mail.Mail;
|
||||
import com.sendgrid.helpers.mail.objects.Content;
|
||||
import com.sendgrid.helpers.mail.objects.Email;
|
||||
import io.wkrzywiec.hexagonal.library.email.model.ReservationConfirmEmail;
|
||||
import io.wkrzywiec.hexagonal.library.email.ports.outgoing.EmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.model.ReservationConfirmEmail;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing.EmailSender;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.application;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.application;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.AddNewBookCommand;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.incoming.AddNewBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.AddNewBookCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.incoming.AddNewBook;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -1,12 +1,12 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.AddNewBookCommand;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.NewBookWasAddedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.incoming.AddNewBook;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.outgoing.InventoryEventPublisher;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.outgoing.GetBookDetails;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.outgoing.InventoryDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.AddNewBookCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.NewBookWasAddedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.incoming.AddNewBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing.InventoryEventPublisher;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing.GetBookDetails;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing.InventoryDatabase;
|
||||
|
||||
|
||||
public class InventoryFacade implements AddNewBook{
|
||||
@@ -1,8 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embeddable;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.AddNewBookCommand;
|
||||
|
||||
public interface AddNewBook {
|
||||
void handle(AddNewBookCommand addNewBookCommand);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
|
||||
public interface GetBookDetails {
|
||||
Book handle(String bookId);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
|
||||
public interface InventoryDatabase {
|
||||
Book save(Book book);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.NewBookWasAddedEvent;
|
||||
|
||||
public interface InventoryEventPublisher {
|
||||
void publishNewBookWasAddedEvent(NewBookWasAddedEvent event);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Author;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.BookIdentification;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Isbn10;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Isbn13;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.outgoing.GetBookDetails;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Author;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.BookIdentification;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Isbn10;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Isbn13;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing.GetBookDetails;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.outgoing.InventoryDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing.InventoryDatabase;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.NewBookWasAddedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.outgoing.InventoryEventPublisher;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.NewBookWasAddedEvent;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.outgoing.InventoryEventPublisher;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.application;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.application;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.user.ports.incoming.AddNewUser;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.ports.incoming.AddNewUser;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.EmailAddress;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.UserIdentifier;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.ports.incoming.AddNewUser;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.ports.outgoing.UserDatabase;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class UserFacade implements AddNewUser {
|
||||
|
||||
private final UserDatabase database;
|
||||
|
||||
@Override
|
||||
public UserIdentifier handle(AddUserCommand addUserCommand) {
|
||||
User user = new User(
|
||||
new EmailAddress(addUserCommand.getEmail()),
|
||||
addUserCommand.getFirstName(),
|
||||
addUserCommand.getLastName()
|
||||
);
|
||||
return database.save(user);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core.model;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.persistence.Column;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.model;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core.model;
|
||||
|
||||
|
||||
public class UserIdentifier {
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.UserIdentifier;
|
||||
|
||||
public interface AddNewUser {
|
||||
UserIdentifier handle(AddUserCommand addUserCommand);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.core.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.UserIdentifier;
|
||||
|
||||
public interface UserDatabase {
|
||||
UserIdentifier save(User user);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.UserIdentifier;
|
||||
import io.wkrzywiec.hexagonal.library.user.ports.outgoing.UserDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.UserIdentifier;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.ports.outgoing.UserDatabase;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.infrastructure;
|
||||
package io.wkrzywiec.hexagonal.library.domain.user.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.model.User;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.email.model.SendReservationConfirmationCommand;
|
||||
|
||||
public interface SendReservationConfirmation {
|
||||
void handle(SendReservationConfirmationCommand reservationConfirmationCommand);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.email.ports.outgoing;
|
||||
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.email.model.ReservationConfirmEmail;
|
||||
|
||||
public interface EmailSender {
|
||||
void sendReservationConfirmationEmail(ReservationConfirmEmail reservationConfirmEmail);
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
package io.wkrzywiec.hexagonal.library.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.BorrowingFacade;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.infrastructure.BorrowingDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.infrastructure.SpringBorrowingEventPublisherAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.incoming.MakeBookAvailable;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing.BorrowingDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.borrowing.ports.outgoing.BorrowingEventPublisher;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.BorrowingFacade;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.infrastructure.BorrowingDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.infrastructure.SpringBorrowingEventPublisherAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.incoming.MakeBookAvailable;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing.BorrowingDatabase;
|
||||
import io.wkrzywiec.hexagonal.library.domain.borrowing.core.ports.outgoing.BorrowingEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.wkrzywiec.hexagonal.library.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.EmailFacade;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.infrastructure.EmailDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.infrastructure.SendGridEmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.incoming.SendReservationConfirmation;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing.EmailSender;
|
||||
import io.wkrzywiec.hexagonal.library.domain.email.core.ports.outgoing.EmailDatabase;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
public class EmailDomainConfig {
|
||||
|
||||
@Bean
|
||||
public EmailSender emailSender() {
|
||||
return new SendGridEmailSender();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EmailDatabase libraryDatabase(JdbcTemplate jdbcTemplate){
|
||||
return new EmailDatabaseAdapter(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SendReservationConfirmation sendReservationConfirmation(EmailSender emailSender, EmailDatabase database){
|
||||
return new EmailFacade(emailSender, database);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
package io.wkrzywiec.hexagonal.library.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.InventoryFacade;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.infrastructure.BookRepository;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.infrastructure.GoogleBooksAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.infrastructure.InventoryDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.infrastructure.SpringInventoryEventPublisherAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.ports.incoming.AddNewBook;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.InventoryFacade;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure.BookRepository;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure.GoogleBooksAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure.InventoryDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.infrastructure.SpringInventoryEventPublisherAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.ports.incoming.AddNewBook;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
class InventoryDomainConfig {
|
||||
public class InventoryDomainConfig {
|
||||
|
||||
@Bean
|
||||
SpringInventoryEventPublisherAdapter springInventoryEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
package io.wkrzywiec.hexagonal.library.infrastructure;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.wkrzywiec.hexagonal.library.infrastructure;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.UserFacade;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.infrastructure.UserDatabaseAdapter;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.infrastructure.UserRepository;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.ports.incoming.AddNewUser;
|
||||
import io.wkrzywiec.hexagonal.library.domain.user.core.ports.outgoing.UserDatabase;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
public class UserDomainConfig {
|
||||
|
||||
@Bean
|
||||
public UserDatabase userDatabase(UserRepository userRepository){
|
||||
return new UserDatabaseAdapter(userRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AddNewUser addNewUser(UserDatabase userDatabase){
|
||||
return new UserFacade(userDatabase);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.AddNewBookCommand;
|
||||
|
||||
public interface AddNewBook {
|
||||
void handle(AddNewBookCommand addNewBookCommand);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
|
||||
public interface GetBookDetails {
|
||||
Book handle(String bookId);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
|
||||
public interface InventoryDatabase {
|
||||
Book save(Book book);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.inventory.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.NewBookWasAddedEvent;
|
||||
|
||||
public interface InventoryEventPublisher {
|
||||
void publishNewBookWasAddedEvent(NewBookWasAddedEvent event);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.user;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.EmailAddress;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.UserIdentifier;
|
||||
import io.wkrzywiec.hexagonal.library.user.ports.incoming.AddNewUser;
|
||||
import io.wkrzywiec.hexagonal.library.user.ports.outgoing.UserDatabase;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class UserFacade implements AddNewUser {
|
||||
|
||||
private final UserDatabase database;
|
||||
|
||||
@Override
|
||||
public UserIdentifier handle(AddUserCommand addUserCommand) {
|
||||
User user = new User(
|
||||
new EmailAddress(addUserCommand.getEmail()),
|
||||
addUserCommand.getFirstName(),
|
||||
addUserCommand.getLastName()
|
||||
);
|
||||
return database.save(user);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.ports.incoming;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.model.AddUserCommand;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.UserIdentifier;
|
||||
|
||||
public interface AddNewUser {
|
||||
UserIdentifier handle(AddUserCommand addUserCommand);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.wkrzywiec.hexagonal.library.user.ports.outgoing;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.user.model.User;
|
||||
import io.wkrzywiec.hexagonal.library.user.model.UserIdentifier;
|
||||
|
||||
public interface UserDatabase {
|
||||
UserIdentifier save(User user);
|
||||
}
|
||||
@@ -4,13 +4,15 @@ CREATE TABLE IF NOT EXISTS public.available (
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.reserved (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
book_id BIGINT NOT NULL REFERENCES public.book,
|
||||
user_id BIGINT NOT NULL REFERENCES public.user
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
reserved_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
book_id BIGINT NOT NULL REFERENCES public.book,
|
||||
user_id BIGINT NOT NULL REFERENCES public.user
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.borrowed (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
book_id BIGINT NOT NULL REFERENCES public.book,
|
||||
user_id BIGINT NOT NULL REFERENCES public.user
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
borrowed_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
book_id BIGINT NOT NULL REFERENCES public.book,
|
||||
user_id BIGINT NOT NULL REFERENCES public.user
|
||||
);
|
||||
@@ -1,10 +1,10 @@
|
||||
package io.wkrzywiec.hexagonal.library;
|
||||
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Author;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.BookIdentification;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Isbn10;
|
||||
import io.wkrzywiec.hexagonal.library.inventory.model.Isbn13;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Author;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Book;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.BookIdentification;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Isbn10;
|
||||
import io.wkrzywiec.hexagonal.library.domain.inventory.core.model.Isbn13;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user