├── cqrswithes ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── pl │ │ │ └── altkom │ │ │ └── asc │ │ │ └── lab │ │ │ └── cqrs │ │ │ └── intro │ │ │ └── cqrswithes │ │ │ ├── cqs │ │ │ ├── Command.java │ │ │ ├── Query.java │ │ │ ├── QueryHandler.java │ │ │ ├── CommandHandler.java │ │ │ ├── Bus.java │ │ │ ├── QueryProvider.java │ │ │ ├── CommandProvider.java │ │ │ ├── SpringBus.java │ │ │ └── Registry.java │ │ │ ├── domain │ │ │ ├── policy │ │ │ │ ├── PolicyStatus.java │ │ │ │ ├── PolicyVersionStatus.java │ │ │ │ ├── PolicyRepository.java │ │ │ │ ├── UnitPrice.java │ │ │ │ ├── PolicyState.java │ │ │ │ ├── events │ │ │ │ │ ├── TerminalPolicyVersionConfirmed.java │ │ │ │ │ ├── CoverageExtendedPolicyVersionConfirmed.java │ │ │ │ │ ├── CoverageExtendedPolicyVersionCreated.java │ │ │ │ │ ├── PolicyEventsData.java │ │ │ │ │ ├── TerminalPolicyVersionCreated.java │ │ │ │ │ └── InitialPolicyVersionCreated.java │ │ │ │ ├── PolicyVersions.java │ │ │ │ └── PolicyCover.java │ │ │ ├── common │ │ │ │ ├── BusinessException.java │ │ │ │ ├── Person.java │ │ │ │ ├── Car.java │ │ │ │ └── DateRange.java │ │ │ ├── offer │ │ │ │ ├── OfferRepository.java │ │ │ │ ├── Covers.java │ │ │ │ ├── CoverPrice.java │ │ │ │ └── Offer.java │ │ │ ├── product │ │ │ │ ├── ProductRepository.java │ │ │ │ ├── Cover.java │ │ │ │ └── Product.java │ │ │ └── base │ │ │ │ ├── Event.java │ │ │ │ └── AggregateRoot.java │ │ │ ├── init │ │ │ ├── InitCarsBuilder.java │ │ │ ├── InitPersonsBuilder.java │ │ │ ├── InitProductsBuilder.java │ │ │ ├── InitDatabase.java │ │ │ └── InitOffersBuilder.java │ │ │ ├── db │ │ │ ├── EventStore.java │ │ │ ├── InMemoryEventStore.java │ │ │ ├── InMemoryOfferRepository.java │ │ │ ├── InMemoryProductRepository.java │ │ │ └── InMemoryPolicyRepository.java │ │ │ ├── commands │ │ │ ├── confirmtermination │ │ │ │ ├── ConfirmTerminationResult.java │ │ │ │ ├── ConfirmTerminationCommand.java │ │ │ │ └── ConfirmTerminationHandler.java │ │ │ ├── terminatepolicy │ │ │ │ ├── TerminatePolicyResult.java │ │ │ │ ├── TerminatePolicyCommand.java │ │ │ │ └── TerminatePolicyHandler.java │ │ │ ├── buyadditionalcover │ │ │ │ ├── BuyAdditionalCoverResult.java │ │ │ │ ├── BuyAdditionalCoverCommand.java │ │ │ │ └── BuyAdditionalCoverHandler.java │ │ │ ├── confirmbuyadditionalcover │ │ │ │ ├── ConfirmBuyAdditionalCoverResult.java │ │ │ │ ├── ConfirmBuyAdditionalCoverCommand.java │ │ │ │ └── ConfirmBuyAdditionalCoverHandler.java │ │ │ └── createpolicy │ │ │ │ ├── CreatePolicyResult.java │ │ │ │ ├── CreatePolicyCommand.java │ │ │ │ └── CreatePolicyHandler.java │ │ │ ├── CQRSwithESApplication.java │ │ │ └── controllers │ │ │ └── PoliciesController.java │ └── test │ │ └── groovy │ │ └── pl │ │ └── altkom │ │ └── asc │ │ └── lab │ │ └── cqrs │ │ └── intro │ │ └── cqrswithes │ │ ├── testdatabuilders │ │ ├── CarsTestDataBuilder.groovy │ │ ├── PersonsTestDataBuilder.groovy │ │ ├── ProductsTestDataBuilder.groovy │ │ ├── OffersTestDataBuilder.groovy │ │ └── PoliciesTestDataBuilder.groovy │ │ └── domain │ │ └── PolicyCreationSpec.groovy └── .gitignore ├── readme-images ├── 1_no_cqrs.png ├── 5_event_sourcing.png ├── 2_separe_commands_queries.png ├── 4_separate_storage_engines.png └── 3_separate_models_commands_queries.png ├── separatemodels ├── src │ ├── main │ │ ├── java │ │ │ └── pl │ │ │ │ └── altkom │ │ │ │ └── asc │ │ │ │ └── lab │ │ │ │ └── cqrs │ │ │ │ └── intro │ │ │ │ └── separatemodels │ │ │ │ ├── cqs │ │ │ │ ├── Command.java │ │ │ │ ├── Query.java │ │ │ │ ├── QueryHandler.java │ │ │ │ ├── CommandHandler.java │ │ │ │ ├── Bus.java │ │ │ │ ├── QueryProvider.java │ │ │ │ ├── CommandProvider.java │ │ │ │ ├── SpringBus.java │ │ │ │ └── Registry.java │ │ │ │ ├── domain │ │ │ │ ├── PolicyRepository.java │ │ │ │ ├── BusinessException.java │ │ │ │ ├── OfferRepository.java │ │ │ │ ├── ProductRepository.java │ │ │ │ ├── Covers.java │ │ │ │ ├── Cover.java │ │ │ │ ├── Person.java │ │ │ │ ├── Car.java │ │ │ │ ├── Product.java │ │ │ │ ├── CoverPrice.java │ │ │ │ ├── primitives │ │ │ │ │ └── DateRange.java │ │ │ │ ├── PolicyVersions.java │ │ │ │ ├── PolicyEvents.java │ │ │ │ └── PolicyCover.java │ │ │ │ ├── events │ │ │ │ ├── Event.java │ │ │ │ └── EventPublisher.java │ │ │ │ ├── init │ │ │ │ ├── InitCarsBuilder.java │ │ │ │ ├── InitPersonsBuilder.java │ │ │ │ ├── InitProductsBuilder.java │ │ │ │ ├── InitDatabase.java │ │ │ │ └── InitOffersBuilder.java │ │ │ │ ├── commands │ │ │ │ ├── cancellastannex │ │ │ │ │ ├── CancelLastAnnexResult.java │ │ │ │ │ ├── CancelLastAnnexCommand.java │ │ │ │ │ └── CancelLastAnnexHandler.java │ │ │ │ ├── confirmtermination │ │ │ │ │ ├── ConfirmTerminationResult.java │ │ │ │ │ ├── ConfirmTerminationCommand.java │ │ │ │ │ └── ConfirmTerminationHandler.java │ │ │ │ ├── terminatepolicy │ │ │ │ │ ├── TerminatePolicyResult.java │ │ │ │ │ ├── TerminatePolicyCommand.java │ │ │ │ │ └── TerminatePolicyHandler.java │ │ │ │ ├── buyadditionalcover │ │ │ │ │ ├── BuyAdditionalCoverResult.java │ │ │ │ │ ├── BuyAdditionalCoverCommand.java │ │ │ │ │ └── BuyAdditionalCoverHandler.java │ │ │ │ ├── confirmbuyadditionalcover │ │ │ │ │ ├── ConfirmBuyAdditionalCoverResult.java │ │ │ │ │ ├── ConfirmBuyAdditionalCoverCommand.java │ │ │ │ │ └── ConfirmBuyAdditionalCoverHandler.java │ │ │ │ └── createpolicy │ │ │ │ │ ├── CreatePolicyResult.java │ │ │ │ │ ├── CreatePolicyCommand.java │ │ │ │ │ └── CreatePolicyHandler.java │ │ │ │ ├── readmodel │ │ │ │ ├── PolicyFilter.java │ │ │ │ ├── PolicyVersionDtoFinder.java │ │ │ │ ├── PolicyInfoDtoFinder.java │ │ │ │ ├── PolicyInfoDtoRepository.java │ │ │ │ ├── PolicyVersionsListDto.java │ │ │ │ ├── PolicyInfoDtoProjection.java │ │ │ │ ├── PolicyInfoDto.java │ │ │ │ ├── PolicyVersionDtoRepository.java │ │ │ │ └── PolicyVersionDtoProjection.java │ │ │ │ ├── queries │ │ │ │ ├── GetPolicyVersionsListQuery.java │ │ │ │ ├── GetPolicyVersionDetailsQuery.java │ │ │ │ ├── FindPoliciesQuery.java │ │ │ │ ├── GetPolicyVersionsListHandler.java │ │ │ │ ├── GetPolicyVersionDetailsHandler.java │ │ │ │ └── FindPoliciesHandler.java │ │ │ │ ├── db │ │ │ │ ├── InMemoryPolicyRepository.java │ │ │ │ ├── JpaPolicyRepository.java │ │ │ │ ├── InMemoryOfferRepository.java │ │ │ │ ├── InMemoryProductRepository.java │ │ │ │ ├── JpaOfferRepository.java │ │ │ │ └── JpaProductRepository.java │ │ │ │ ├── SeparateModelsApplication.java │ │ │ │ └── eventhandlers │ │ │ │ └── PolicyEventsProjectionsHandler.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── schema.sql │ └── test │ │ └── java │ │ └── pl │ │ └── altkom │ │ └── asc │ │ └── lab │ │ └── cqrs │ │ └── intro │ │ └── separatemodels │ │ ├── testdatabuilders │ │ ├── CarsTestDataBuilder.java │ │ ├── PersonsTestDataBuilder.java │ │ ├── CoverPriceTestDataBuilder.java │ │ ├── ProductsTestDataBuilder.java │ │ ├── PoliciesTestDataBuilder.java │ │ └── OffersTestDataBuilder.java │ │ ├── asserts │ │ └── PolicyAsserts.java │ │ ├── readmodel │ │ ├── PolicyVersionDtoFinderTestMock.java │ │ ├── PolicyInfoDtoProjectionTest.java │ │ └── PolicyVersionDtoFinderTest.java │ │ └── domain │ │ └── PoliciesVersionTestDataBuilder.java └── pom.xml ├── nocqrs └── src │ ├── main │ ├── java │ │ └── pl │ │ │ └── altkom │ │ │ └── asc │ │ │ └── lab │ │ │ └── cqrs │ │ │ └── intro │ │ │ └── nocqrs │ │ │ ├── services │ │ │ ├── CancelLastAnnexRequest.java │ │ │ ├── CreatePolicyResult.java │ │ │ ├── ConfirmTerminationRequest.java │ │ │ ├── ConfirmBuyAdditionalCoverRequest.java │ │ │ ├── TerminatePolicyRequest.java │ │ │ ├── CancelLastAnnexResult.java │ │ │ ├── ConfirmTerminationResult.java │ │ │ ├── TerminatePolicyResult.java │ │ │ ├── BuyAdditionalCoverResult.java │ │ │ ├── ConfirmBuyAdditionalCoverResult.java │ │ │ ├── CreatePolicyRequest.java │ │ │ ├── SearchPolicyRequest.java │ │ │ ├── BuyAdditionalCoverRequest.java │ │ │ ├── PolicyInfoDto.java │ │ │ ├── PolicyInfoDtoAssembler.java │ │ │ └── PolicyDto.java │ │ │ ├── domain │ │ │ ├── exceptions │ │ │ │ └── BusinessException.java │ │ │ ├── OfferRepository.java │ │ │ ├── ProductRepository.java │ │ │ ├── Covers.java │ │ │ ├── Person.java │ │ │ ├── Car.java │ │ │ ├── Cover.java │ │ │ ├── PolicyRepository.java │ │ │ ├── Product.java │ │ │ ├── CoverPrice.java │ │ │ ├── primitives │ │ │ │ └── DateRange.java │ │ │ ├── PolicyVersions.java │ │ │ └── PolicyCover.java │ │ │ ├── init │ │ │ ├── InitCarsBuilder.java │ │ │ ├── InitPersonsBuilder.java │ │ │ ├── InitProductsBuilder.java │ │ │ ├── InitDatabase.java │ │ │ └── InitOffersBuilder.java │ │ │ ├── db │ │ │ ├── specifications │ │ │ │ ├── BaseSpecification.java │ │ │ │ └── PolicySpecification.java │ │ │ ├── InMemoryOfferRepository.java │ │ │ ├── InMemoryProductRepository.java │ │ │ ├── JpaOfferRepository.java │ │ │ ├── JpaProductRepository.java │ │ │ ├── InMemoryPolicyRepository.java │ │ │ └── JpaPolicyRepository.java │ │ │ ├── NocqrsApplication.java │ │ │ └── controllers │ │ │ └── PoliciesController.java │ └── resources │ │ └── application.properties │ └── test │ └── groovy │ └── pl │ └── altkom │ └── asc │ └── lab │ └── cqrs │ └── intro │ └── nocqrs │ ├── testdatabuilders │ ├── CarsTestDataBuilder.groovy │ ├── PersonsTestDataBuilder.groovy │ ├── ProductsTestDataBuilder.groovy │ ├── PoliciesTestDataBuilder.groovy │ └── OffersTestDataBuilder.groovy │ └── domain │ ├── PolicyCancelAnnexSpec.groovy │ └── PolicyTerminationSpec.groovy ├── .gitignore └── README.md /cqrswithes/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /readme-images/1_no_cqrs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asc-lab/java-cqrs-intro/HEAD/readme-images/1_no_cqrs.png -------------------------------------------------------------------------------- /readme-images/5_event_sourcing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asc-lab/java-cqrs-intro/HEAD/readme-images/5_event_sourcing.png -------------------------------------------------------------------------------- /readme-images/2_separe_commands_queries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asc-lab/java-cqrs-intro/HEAD/readme-images/2_separe_commands_queries.png -------------------------------------------------------------------------------- /readme-images/4_separate_storage_engines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asc-lab/java-cqrs-intro/HEAD/readme-images/4_separate_storage_engines.png -------------------------------------------------------------------------------- /readme-images/3_separate_models_commands_queries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asc-lab/java-cqrs-intro/HEAD/readme-images/3_separate_models_commands_queries.png -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/Command.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | public interface Command { 4 | } 5 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/Query.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | 4 | public interface Query { 5 | } 6 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/Command.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | public interface Command { 4 | } 5 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/Query.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | 4 | public interface Query { 5 | } 6 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/PolicyStatus.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | public enum PolicyStatus { 4 | Active, Terminated 5 | } 6 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/QueryHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | public interface QueryHandler> { 4 | R handle(C query); 5 | } 6 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/CommandHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | public interface CommandHandler> { 4 | R handle(C command); 5 | } 6 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/PolicyVersionStatus.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | public enum PolicyVersionStatus { 4 | Draft, Active, Cancelled 5 | } 6 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/QueryHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | public interface QueryHandler> { 4 | R handle(C query); 5 | } 6 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/CommandHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | public interface CommandHandler> { 4 | R handle(C command); 5 | } 6 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/CancelLastAnnexRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public class CancelLastAnnexRequest { 7 | private String policyNumber; 8 | } 9 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/Bus.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | public interface Bus { 4 | > R executeCommand(C command); 5 | > R executeQuery(Q query); 6 | } 7 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/PolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | public interface PolicyRepository { 4 | Policy withNumber(String number); 5 | 6 | void add(Policy policy); 7 | } 8 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/Bus.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | public interface Bus { 4 | > R executeCommand(C command); 5 | > R executeQuery(Q query); 6 | } 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | */target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | */*.iws 5 | */*.iml 6 | */*.ipr 7 | */.mvn/* 8 | */.idea/* 9 | */*.iws 10 | */out/ 11 | */.idea_modules/ 12 | */atlassian-ide-plugin.xml 13 | */target/ 14 | !.mvn/wrapper/maven-wrapper.jar 15 | */*.iws 16 | */*.iml 17 | */*.ipr -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/exceptions/BusinessException.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.exceptions; 2 | 3 | public class BusinessException extends RuntimeException { 4 | public BusinessException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/common/BusinessException.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common; 2 | 3 | public class BusinessException extends RuntimeException { 4 | public BusinessException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/BusinessException.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | public class BusinessException extends RuntimeException { 4 | public BusinessException(String msg) { 5 | super(msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/OfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import java.util.List; 4 | 5 | public interface OfferRepository { 6 | Offer withNumber(String offerNumber); 7 | List all(); 8 | void add(Offer offer); 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import java.util.List; 4 | 5 | public interface ProductRepository { 6 | void add(Product product); 7 | Product withCode(String code); 8 | List all(); 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/CreatePolicyResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.*; 4 | 5 | @Getter 6 | @Setter 7 | @AllArgsConstructor 8 | @NoArgsConstructor 9 | public class CreatePolicyResult { 10 | private String policyNumber; 11 | } 12 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/ConfirmTerminationRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public class ConfirmTerminationRequest { 7 | private String policyNumber; 8 | private int versionToConfirmNumber; 9 | } 10 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/PolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | import java.util.UUID; 4 | 5 | public interface PolicyRepository { 6 | Policy getById(UUID number); 7 | 8 | void save(Policy policy, int expectedVersion); 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/init/InitCarsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Car; 4 | 5 | class InitCarsBuilder { 6 | static Car oldFordFocus() { 7 | return new Car("Ford Focus", "WAW1010", 2005); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/ConfirmBuyAdditionalCoverRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public class ConfirmBuyAdditionalCoverRequest { 7 | private String policyNumber; 8 | private int versionToConfirmNumber; 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/init/InitPersonsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Person; 4 | 5 | class InitPersonsBuilder { 6 | static Person kowalski() { 7 | return new Person("Jan", "Kowalski", "11111116"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/offer/OfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer; 2 | 3 | import java.util.List; 4 | 5 | public interface OfferRepository { 6 | Offer withNumber(String offerNumber); 7 | 8 | List all(); 9 | 10 | void add(Offer offer); 11 | } 12 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/OfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import java.util.List; 4 | 5 | public interface OfferRepository { 6 | Offer withNumber(String offerNumber); 7 | 8 | List all(); 9 | 10 | void add(Offer offer); 11 | } 12 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/events/Event.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.events; 2 | 3 | import org.springframework.context.ApplicationEvent; 4 | 5 | public abstract class Event extends ApplicationEvent { 6 | public Event(Object source) { 7 | super(source); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/TerminatePolicyRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | 5 | import java.time.LocalDate; 6 | 7 | @Getter 8 | public class TerminatePolicyRequest { 9 | private String policyNumber; 10 | private LocalDate terminationDate; 11 | } 12 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import java.util.List; 4 | 5 | public interface ProductRepository { 6 | void add(Product product); 7 | 8 | Product withCode(String code); 9 | 10 | List all(); 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/product/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product; 2 | 3 | import java.util.List; 4 | 5 | public interface ProductRepository { 6 | void add(Product product); 7 | 8 | Product withCode(String code); 9 | 10 | List all(); 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/init/InitCarsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.init; 2 | 3 | 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Car; 5 | 6 | class InitCarsBuilder { 7 | static Car oldFordFocus() { 8 | return new Car("Ford Focus", "WAW1010", 2005); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/init/InitPersonsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Person; 4 | 5 | class InitPersonsBuilder { 6 | static Person kowalski() { 7 | return new Person("Jan", "Kowalski", "11111116"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/testdatabuilders/CarsTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Car 4 | 5 | class CarsTestDataBuilder { 6 | static Car oldFordFocus() { 7 | return new Car("Ford Focus", "WAW1010", 2005) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/init/InitCarsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Car; 4 | 5 | class InitCarsBuilder { 6 | static Car oldFordFocus() { 7 | return new Car("Ford Focus", "WAW1010", 2005); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/testdatabuilders/PersonsTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Person 4 | 5 | class PersonsTestDataBuilder { 6 | static Person kowalski() { 7 | return new Person("Jan", "Kowalski", "11111116") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/init/InitPersonsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Person; 4 | 5 | class InitPersonsBuilder { 6 | static Person kowalski() { 7 | return new Person("Jan", "Kowalski", "11111116"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/CancelLastAnnexResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class CancelLastAnnexResult { 9 | private String policyNumber; 10 | private int lastActiveVersionNumber; 11 | } 12 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/ConfirmTerminationResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class ConfirmTerminationResult { 9 | private String policyNumber; 10 | private int versionConfirmed; 11 | } 12 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/TerminatePolicyResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class TerminatePolicyResult { 9 | private String policyNumber; 10 | private int versionWithTerminationNumber; 11 | } 12 | -------------------------------------------------------------------------------- /nocqrs/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8088 2 | # H2 3 | spring.h2.console.enabled=true 4 | spring.h2.console.path=/h2 5 | # Datasource 6 | spring.datasource.url=jdbc:h2:file:~/test 7 | spring.datasource.username=sa 8 | spring.datasource.password= 9 | spring.datasource.driver-class-name=org.h2.Driver 10 | # JPA 11 | spring.jpa.show-sql=true 12 | spring.jpa.open-in-view=false -------------------------------------------------------------------------------- /cqrswithes/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/cqrswithes/testdatabuilders/CarsTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Car 4 | 5 | class CarsTestDataBuilder { 6 | static Car oldFordFocus() { 7 | return new Car("Ford Focus", "WAW1010", 2005) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/BuyAdditionalCoverResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class BuyAdditionalCoverResult { 9 | private String policyNumber; 10 | private int versionWithAdditionalCoverNumber; 11 | } 12 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/ConfirmBuyAdditionalCoverResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class ConfirmBuyAdditionalCoverResult { 9 | private String policyNumber; 10 | private int versionConfirmed; 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/cqrswithes/testdatabuilders/PersonsTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Person 4 | 5 | class PersonsTestDataBuilder { 6 | static Person kowalski() { 7 | return new Person("Jan", "Kowalski", "11111116") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/base/Event.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base; 2 | 3 | import lombok.Getter; 4 | 5 | import java.util.UUID; 6 | 7 | @Getter 8 | public abstract class Event { 9 | private UUID id = UUID.randomUUID(); 10 | private int version = 1; 11 | 12 | protected abstract void applyOn(T aggregate); 13 | } 14 | -------------------------------------------------------------------------------- /cqrswithes/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | /target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | .sts4-cache 13 | 14 | ### IntelliJ IDEA ### 15 | .idea 16 | *.iws 17 | *.iml 18 | *.ipr 19 | 20 | ### NetBeans ### 21 | /nbproject/private/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ 26 | /build/ 27 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/CreatePolicyRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | import java.time.LocalDate; 7 | 8 | @Getter 9 | @Setter 10 | public class CreatePolicyRequest { 11 | private String offerNumber; 12 | private LocalDate purchaseDate; 13 | private LocalDate policyStartDate; 14 | } 15 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/cancellastannex/CancelLastAnnexResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.cancellastannex; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class CancelLastAnnexResult { 9 | private String policyNumber; 10 | private int lastActiveVersionNumber; 11 | } 12 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/cancellastannex/CancelLastAnnexCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.cancellastannex; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Command; 5 | 6 | @Getter 7 | public class CancelLastAnnexCommand implements Command { 8 | private String policyNumber; 9 | } 10 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/confirmtermination/ConfirmTerminationResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.confirmtermination; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class ConfirmTerminationResult { 9 | private String policyNumber; 10 | private int versionConfirmed; 11 | } 12 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/terminatepolicy/TerminatePolicyResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.terminatepolicy; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class TerminatePolicyResult { 9 | private String policyNumber; 10 | private int versionWithTerminationNumber; 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/db/EventStore.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | public interface EventStore { 9 | List getEventsForAggregate(UUID aggregateId); 10 | void saveEvents(UUID aggregateId, long version, List events); 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/confirmtermination/ConfirmTerminationResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmtermination; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | import java.util.UUID; 7 | 8 | @Getter 9 | @AllArgsConstructor 10 | public class ConfirmTerminationResult { 11 | private UUID policyId; 12 | private int versionConfirmed; 13 | } 14 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/terminatepolicy/TerminatePolicyResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.terminatepolicy; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | import java.util.UUID; 7 | 8 | @Getter 9 | @AllArgsConstructor 10 | public class TerminatePolicyResult { 11 | private UUID policyId; 12 | private int versionWithTerminationNumber; 13 | } 14 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/buyadditionalcover/BuyAdditionalCoverResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.buyadditionalcover; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class BuyAdditionalCoverResult { 9 | private String policyNumber; 10 | private int versionWithAdditionalCoverNumber; 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/product/Cover.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.UUID; 8 | 9 | @Getter 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class Cover { 13 | private UUID id; 14 | private String code; 15 | private String name; 16 | } 17 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/confirmbuyadditionalcover/ConfirmBuyAdditionalCoverResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.confirmbuyadditionalcover; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @AllArgsConstructor 8 | public class ConfirmBuyAdditionalCoverResult { 9 | private String policyNumber; 10 | private int versionConfirmed; 11 | } 12 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/buyadditionalcover/BuyAdditionalCoverResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.buyadditionalcover; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | import java.util.UUID; 7 | 8 | @Getter 9 | @AllArgsConstructor 10 | public class BuyAdditionalCoverResult { 11 | private UUID policyId; 12 | private int versionWithAdditionalCoverNumber; 13 | } 14 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/createpolicy/CreatePolicyResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.createpolicy; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class CreatePolicyResult { 13 | private String policyNumber; 14 | } 15 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/confirmbuyadditionalcover/ConfirmBuyAdditionalCoverResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmbuyadditionalcover; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | 6 | import java.util.UUID; 7 | 8 | @Getter 9 | @AllArgsConstructor 10 | public class ConfirmBuyAdditionalCoverResult { 11 | private UUID policyId; 12 | private int versionConfirmed; 13 | } 14 | -------------------------------------------------------------------------------- /separatemodels/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # H2 2 | spring.h2.console.enabled=true 3 | spring.h2.console.path=/h2 4 | # Datasource 5 | spring.datasource.url=jdbc:h2:file:~/test 6 | spring.datasource.username=sa 7 | spring.datasource.password= 8 | spring.datasource.driver-class-name=org.h2.Driver 9 | # Logging 10 | logging.level.org.springframework.data=INFO 11 | #logging.level.org.springframework.jdbc.core=TRACE 12 | # JPA 13 | spring.jpa.show-sql=true 14 | spring.jpa.open-in-view=false -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/confirmtermination/ConfirmTerminationCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.confirmtermination; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Command; 5 | 6 | @Getter 7 | public class ConfirmTerminationCommand implements Command { 8 | private String policyNumber; 9 | private int versionToConfirmNumber; 10 | } 11 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/confirmtermination/ConfirmTerminationCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmtermination; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Command; 5 | 6 | import java.util.UUID; 7 | 8 | @Getter 9 | public class ConfirmTerminationCommand implements Command { 10 | private UUID policyId; 11 | private int versionToConfirmNumber; 12 | } 13 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/UnitPrice.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 6 | 7 | import java.time.Period; 8 | 9 | @Getter 10 | @RequiredArgsConstructor 11 | public class UnitPrice { 12 | private final MonetaryAmount price; 13 | private final Period pricePeriod; 14 | } 15 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/terminatepolicy/TerminatePolicyCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.terminatepolicy; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Command; 5 | 6 | import java.time.LocalDate; 7 | 8 | @Getter 9 | public class TerminatePolicyCommand implements Command { 10 | private String policyNumber; 11 | private LocalDate terminationDate; 12 | } 13 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/SearchPolicyRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | 5 | import java.time.LocalDate; 6 | 7 | @Getter 8 | public class SearchPolicyRequest { 9 | private String policyNumber; 10 | private LocalDate policyStartFrom; 11 | private LocalDate policyStartTo; 12 | private String carPlateNumber; 13 | private String policyHolderFirstName; 14 | private String policyHolderLastName; 15 | } 16 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/terminatepolicy/TerminatePolicyCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.terminatepolicy; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Command; 5 | 6 | import java.time.LocalDate; 7 | import java.util.UUID; 8 | 9 | @Getter 10 | public class TerminatePolicyCommand implements Command { 11 | private UUID policyId; 12 | private LocalDate terminationDate; 13 | } 14 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/createpolicy/CreatePolicyResult.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.createpolicy; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | import java.util.UUID; 9 | 10 | @Getter 11 | @Setter 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class CreatePolicyResult { 15 | private UUID policyId; 16 | private String policyNumber; 17 | } 18 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/confirmbuyadditionalcover/ConfirmBuyAdditionalCoverCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.confirmbuyadditionalcover; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Command; 5 | 6 | @Getter 7 | public class ConfirmBuyAdditionalCoverCommand implements Command { 8 | private String policyNumber; 9 | private int versionToConfirmNumber; 10 | } 11 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/confirmbuyadditionalcover/ConfirmBuyAdditionalCoverCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmbuyadditionalcover; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Command; 5 | 6 | import java.util.UUID; 7 | 8 | @Getter 9 | public class ConfirmBuyAdditionalCoverCommand implements Command { 10 | private UUID policyId; 11 | private int versionToConfirmNumber; 12 | } 13 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/Covers.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | @RequiredArgsConstructor 9 | public class Covers { 10 | 11 | private final List covers; 12 | 13 | public Optional withCode(String code) { 14 | return covers.stream() 15 | .filter(c -> c.getCode().equals(code)) 16 | .findAny(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/specifications/BaseSpecification.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db.specifications; 2 | 3 | import org.springframework.data.jpa.domain.Specification; 4 | 5 | public abstract class BaseSpecification { 6 | 7 | private final String wildcard = "%"; 8 | 9 | public abstract Specification getFilter(U request); 10 | 11 | protected String containsLowerCase(String searchField) { 12 | return wildcard + searchField.toLowerCase() + wildcard; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/BuyAdditionalCoverRequest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.Getter; 4 | 5 | import java.math.BigDecimal; 6 | import java.time.LocalDate; 7 | import java.time.Period; 8 | 9 | @Getter 10 | public class BuyAdditionalCoverRequest { 11 | private String policyNumber; 12 | private LocalDate effectiveDateOfChange; 13 | private String newCoverCode; 14 | private BigDecimal newCoverPrice; 15 | private Period newCoverPriceUnit; 16 | } 17 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyFilter.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | import java.time.LocalDate; 7 | 8 | @Getter 9 | @Builder 10 | public class PolicyFilter { 11 | private String number; 12 | private String holderFirstName; 13 | private String holderLastName; 14 | private LocalDate startDateFrom; 15 | private LocalDate startDateTo; 16 | private String carPlateNumber; 17 | } 18 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/common/Person.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Getter 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Person { 11 | private String firstName; 12 | private String lastName; 13 | private String taxId; 14 | 15 | public Person copy() { 16 | return new Person(firstName, lastName, taxId); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/common/Car.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Getter 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class Car { 11 | 12 | private String make; 13 | private String plateNumber; 14 | private int productionYear; 15 | 16 | public Car copy() { 17 | return new Car(make, plateNumber, productionYear); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/createpolicy/CreatePolicyCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.createpolicy; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Command; 6 | 7 | import java.time.LocalDate; 8 | 9 | @Getter 10 | @Setter 11 | public class CreatePolicyCommand implements Command { 12 | private String offerNumber; 13 | private LocalDate purchaseDate; 14 | private LocalDate policyStartDate; 15 | } 16 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/Covers.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | @RequiredArgsConstructor 9 | public class Covers { 10 | 11 | private final List covers; 12 | 13 | public Optional withCode(String code) { 14 | return covers.stream() 15 | .filter(c -> c.getCode().equals(code)) 16 | .findAny(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/queries/GetPolicyVersionsListQuery.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.queries; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Query; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionsListDto; 7 | 8 | @Getter 9 | @RequiredArgsConstructor 10 | public class GetPolicyVersionsListQuery implements Query { 11 | private final String policyNumber; 12 | } 13 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/createpolicy/CreatePolicyCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.createpolicy; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Command; 6 | 7 | import java.time.LocalDate; 8 | 9 | @Getter 10 | @Setter 11 | public class CreatePolicyCommand implements Command { 12 | private String offerNumber; 13 | private LocalDate purchaseDate; 14 | private LocalDate policyStartDate; 15 | } 16 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/Person.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Embeddable; 8 | 9 | @Embeddable 10 | @Getter 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Person { 14 | private String firstName; 15 | private String lastName; 16 | private String taxId; 17 | 18 | Person copy() { 19 | return new Person(firstName, lastName, taxId); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/events/EventPublisher.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.events; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.stereotype.Component; 6 | 7 | @Component 8 | @RequiredArgsConstructor 9 | public class EventPublisher { 10 | 11 | private final ApplicationEventPublisher eventPublisher; 12 | 13 | public void publish(Event event) { 14 | eventPublisher.publishEvent(event); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/queries/GetPolicyVersionDetailsQuery.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.queries; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Query; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionDto; 7 | 8 | @Getter 9 | @AllArgsConstructor 10 | public class GetPolicyVersionDetailsQuery implements Query { 11 | private String policyNumber; 12 | private int versionNumber; 13 | } 14 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/Car.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Embeddable; 8 | 9 | @Embeddable 10 | @Getter 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Car { 14 | 15 | private String make; 16 | private String plateNumber; 17 | private int productionYear; 18 | 19 | Car copy() { 20 | return new Car(make, plateNumber, productionYear); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/PolicyState.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.DateRange; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 5 | 6 | import java.util.Collection; 7 | 8 | public interface PolicyState { 9 | PolicyStatus getPolicyStatus(); 10 | DateRange getCoverPeriod(); 11 | DateRange getVersionPeriod(); 12 | Collection getCovers(); 13 | MonetaryAmount getTotalPremium(); 14 | } 15 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/Cover.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.Id; 10 | import java.util.UUID; 11 | 12 | @Entity 13 | @Getter 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Cover { 17 | @Id 18 | @GeneratedValue 19 | private UUID id; 20 | private String code; 21 | private String name; 22 | } 23 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/Cover.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.Id; 10 | import java.util.UUID; 11 | 12 | @Entity 13 | @Getter 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class Cover { 17 | @Id 18 | @GeneratedValue 19 | private UUID id; 20 | private String code; 21 | private String name; 22 | } 23 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/offer/Covers.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Cover; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | @RequiredArgsConstructor 10 | public class Covers { 11 | 12 | private final List covers; 13 | 14 | public Optional withCode(String code) { 15 | return covers.stream() 16 | .filter(c -> c.getCode().equals(code)) 17 | .findAny(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/QueryProvider.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | 5 | public class QueryProvider> { 6 | private final ApplicationContext applicationContext; 7 | private final Class type; 8 | 9 | QueryProvider(ApplicationContext applicationContext, Class type) { 10 | this.applicationContext = applicationContext; 11 | this.type = type; 12 | } 13 | 14 | public H get() { 15 | return applicationContext.getBean(type); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/CommandProvider.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | 5 | public class CommandProvider> { 6 | private final ApplicationContext applicationContext; 7 | private final Class type; 8 | 9 | CommandProvider(ApplicationContext applicationContext, Class type) { 10 | this.applicationContext = applicationContext; 11 | this.type = type; 12 | } 13 | 14 | public H get() { 15 | return applicationContext.getBean(type); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/QueryProvider.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | 5 | public class QueryProvider> { 6 | private final ApplicationContext applicationContext; 7 | private final Class type; 8 | 9 | QueryProvider(ApplicationContext applicationContext, Class type) { 10 | this.applicationContext = applicationContext; 11 | this.type = type; 12 | } 13 | 14 | public H get() { 15 | return applicationContext.getBean(type); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/CommandProvider.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | 5 | public class CommandProvider> { 6 | private final ApplicationContext applicationContext; 7 | private final Class type; 8 | 9 | CommandProvider(ApplicationContext applicationContext, Class type) { 10 | this.applicationContext = applicationContext; 11 | this.type = type; 12 | } 13 | 14 | public H get() { 15 | return applicationContext.getBean(type); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/PolicyInfoDto.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.math.BigDecimal; 8 | import java.time.LocalDate; 9 | import java.util.UUID; 10 | 11 | @Getter 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class PolicyInfoDto { 15 | private UUID policyId; 16 | private String policyNumber; 17 | private LocalDate coverFrom; 18 | private LocalDate coverTo; 19 | private String vehicle; 20 | private String policyHolder; 21 | private BigDecimal totalPremiumAmount; 22 | } 23 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/Person.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Embeddable; 8 | 9 | @Embeddable 10 | @Getter 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Person { 14 | private String firstName; 15 | private String lastName; 16 | private String taxId; 17 | 18 | Person copy() { 19 | return new Person(firstName, lastName, taxId); 20 | } 21 | 22 | public String getFullName() { 23 | return firstName + " " + lastName; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/buyadditionalcover/BuyAdditionalCoverCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.buyadditionalcover; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Command; 5 | 6 | import java.math.BigDecimal; 7 | import java.time.LocalDate; 8 | import java.time.Period; 9 | 10 | @Getter 11 | public class BuyAdditionalCoverCommand implements Command { 12 | private String policyNumber; 13 | private LocalDate effectiveDateOfChange; 14 | private String newCoverCode; 15 | private BigDecimal newCoverPrice; 16 | private Period newCoverPriceUnit; 17 | } 18 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/buyadditionalcover/BuyAdditionalCoverCommand.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.buyadditionalcover; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Command; 5 | 6 | import java.math.BigDecimal; 7 | import java.time.LocalDate; 8 | import java.time.Period; 9 | import java.util.UUID; 10 | 11 | @Getter 12 | public class BuyAdditionalCoverCommand implements Command { 13 | private UUID policyId; 14 | private LocalDate effectiveDateOfChange; 15 | private String newCoverCode; 16 | private BigDecimal newCoverPrice; 17 | private Period newCoverPriceUnit; 18 | } 19 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/Car.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Embeddable; 8 | 9 | @Embeddable 10 | @Getter 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Car { 14 | 15 | private String make; 16 | private String plateNumber; 17 | private int productionYear; 18 | 19 | Car copy() { 20 | return new Car(make, plateNumber, productionYear); 21 | } 22 | 23 | public String getPlaceNumberWithMake() { 24 | return plateNumber + " " + make; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/testdatabuilders/CarsTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Car; 4 | 5 | public class CarsTestDataBuilder { 6 | 7 | public static final String OLD_FORD_FOCUS_PLATE_NUMBER = "WAW1010"; 8 | public static final String OLD_SKODA_FABIA_PLATE_NUMBER = "RZN1213"; 9 | 10 | public static Car oldFordFocus() { 11 | return new Car("Ford Focus", OLD_FORD_FOCUS_PLATE_NUMBER, 2005); 12 | } 13 | 14 | public static Car oldSkodaFabia() { 15 | return new Car("Skoda Fabia", OLD_SKODA_FABIA_PLATE_NUMBER, 2009); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/PolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | import java.time.LocalDate; 7 | import java.util.List; 8 | 9 | public interface PolicyRepository { 10 | void add(Policy policy); 11 | Policy withNumber(String number); 12 | List find(PolicyFilter filter); 13 | 14 | @Getter 15 | @Builder 16 | public class PolicyFilter { 17 | private String number; 18 | private String holderFirstName; 19 | private String holderLastName; 20 | private LocalDate startDateFrom; 21 | private LocalDate startDateTo; 22 | private String carPlateNumber; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/testdatabuilders/PersonsTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Person; 4 | 5 | public class PersonsTestDataBuilder { 6 | 7 | public static final String FIRST_NAME_JAN = "Jan"; 8 | public static final String LAST_NAME_KOWALSKI = "Kowalski"; 9 | public static final String FIRST_NAME_KAZIMIERZ = "Kazimierz"; 10 | 11 | public static Person kowalski() { 12 | return new Person(FIRST_NAME_JAN, LAST_NAME_KOWALSKI, "11111116"); 13 | } 14 | 15 | public static Person nowak() { 16 | return new Person(FIRST_NAME_KAZIMIERZ, "Nowak", "11111116"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/queries/FindPoliciesQuery.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.queries; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Query; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyInfoDto; 7 | 8 | import java.time.LocalDate; 9 | import java.util.List; 10 | 11 | @Getter 12 | @Setter 13 | public class FindPoliciesQuery implements Query> { 14 | private String policyNumber; 15 | private LocalDate policyStartFrom; 16 | private LocalDate policyStartTo; 17 | private String carPlateNumber; 18 | private String policyHolderFirstName; 19 | private String policyHolderLastName; 20 | } 21 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/db/InMemoryPolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyRepository; 5 | 6 | import java.util.Map; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | //@Component 10 | public class InMemoryPolicyRepository implements PolicyRepository { 11 | 12 | private Map POLICIES = new ConcurrentHashMap<>(); 13 | 14 | @Override 15 | public Policy withNumber(String offerNumber) { 16 | return POLICIES.get(offerNumber); 17 | } 18 | 19 | @Override 20 | public void add(Policy policy) { 21 | POLICIES.put(policy.getNumber(), policy); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/SpringBus.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | public class SpringBus implements Bus { 4 | private final Registry registry; 5 | 6 | public SpringBus(Registry registry) { 7 | this.registry = registry; 8 | } 9 | 10 | @Override 11 | public > R executeCommand(C command) { 12 | CommandHandler commandHandler = (CommandHandler) registry.getCmd(command.getClass()); 13 | return commandHandler.handle(command); 14 | } 15 | 16 | @Override 17 | public > R executeQuery(Q query) { 18 | QueryHandler queryHandler = (QueryHandler) registry.getQuery(query.getClass()); 19 | return queryHandler.handle(query); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/SpringBus.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | public class SpringBus implements Bus { 4 | private final Registry registry; 5 | 6 | public SpringBus(Registry registry) { 7 | this.registry = registry; 8 | } 9 | 10 | @Override 11 | public > R executeCommand(C command) { 12 | CommandHandler commandHandler = (CommandHandler) registry.getCmd(command.getClass()); 13 | return commandHandler.handle(command); 14 | } 15 | 16 | @Override 17 | public > R executeQuery(Q query) { 18 | QueryHandler queryHandler = (QueryHandler) registry.getQuery(query.getClass()); 19 | return queryHandler.handle(query); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/testdatabuilders/ProductsTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Cover 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Product 5 | 6 | 7 | class ProductsTestDataBuilder { 8 | 9 | static Product standardCarInsurance() { 10 | return new Product( 11 | UUID.randomUUID(), 12 | "STD_CAR_INSURANCE", 13 | "Standard Car Insurance", 14 | Arrays.asList( 15 | new Cover(UUID.randomUUID(), "OC", "Third party liability"), 16 | new Cover(UUID.randomUUID(), "AC", "Auto casco"), 17 | new Cover(UUID.randomUUID(), "ASSITANCE", "Assistance") 18 | ) 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/testdatabuilders/CoverPriceTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.Period; 5 | import java.util.UUID; 6 | 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Cover; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.CoverPrice; 9 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 10 | 11 | public class CoverPriceTestDataBuilder { 12 | 13 | public static CoverPrice buildCoverPrice() { 14 | Cover cover = new Cover(UUID.randomUUID(), "uiop", "cover"); 15 | MonetaryAmount price = new MonetaryAmount(new BigDecimal("400")); 16 | Period coverPeriod = Period.of(2018, 1, 1); 17 | return new CoverPrice(cover, price, coverPeriod); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/db/InMemoryEventStore.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.UUID; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | public class InMemoryEventStore implements EventStore { 12 | 13 | private Map> events = new ConcurrentHashMap<>(); 14 | 15 | @Override 16 | public List getEventsForAggregate(UUID aggregateId) { 17 | return events.get(aggregateId); 18 | } 19 | 20 | @Override 21 | public void saveEvents(UUID aggregateId, long version, List events) { 22 | this.events.computeIfAbsent(aggregateId, id -> new ArrayList<>()).addAll(events); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/init/InitProductsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Cover; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Product; 5 | 6 | import java.util.Arrays; 7 | import java.util.UUID; 8 | 9 | class InitProductsBuilder { 10 | static Product standardCarInsurance() { 11 | return new Product( 12 | UUID.randomUUID(), 13 | "STD_CAR_INSURANCE", 14 | "Standard Car Insurance", 15 | Arrays.asList( 16 | new Cover(UUID.randomUUID(), "OC", "Third party liability"), 17 | new Cover(UUID.randomUUID(), "AC", "Auto casco"), 18 | new Cover(UUID.randomUUID(), "ASSITANCE", "Assistance") 19 | ) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /cqrswithes/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/cqrswithes/testdatabuilders/ProductsTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Cover 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Product 5 | 6 | 7 | class ProductsTestDataBuilder { 8 | 9 | static Product standardCarInsurance() { 10 | return new Product( 11 | UUID.randomUUID(), 12 | "STD_CAR_INSURANCE", 13 | "Standard Car Insurance", 14 | Arrays.asList( 15 | new Cover(UUID.randomUUID(), "OC", "Third party liability"), 16 | new Cover(UUID.randomUUID(), "AC", "Auto casco"), 17 | new Cover(UUID.randomUUID(), "ASSITANCE", "Assistance") 18 | ) 19 | ) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/NocqrsApplication.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.boot.ApplicationArguments; 5 | import org.springframework.boot.ApplicationRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.init.InitDatabase; 9 | 10 | @RequiredArgsConstructor 11 | @SpringBootApplication 12 | public class NocqrsApplication implements ApplicationRunner { 13 | 14 | private final InitDatabase dbInitializer; 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(NocqrsApplication.class, args); 18 | } 19 | 20 | @Override 21 | public void run(ApplicationArguments args) { 22 | dbInitializer.init(); 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/events/TerminalPolicyVersionConfirmed.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyVersionStatus; 7 | 8 | @Getter 9 | public class TerminalPolicyVersionConfirmed extends Event { 10 | private int versionNumber; 11 | private PolicyVersionStatus versionStatus; 12 | 13 | public TerminalPolicyVersionConfirmed(int versionNumber) { 14 | this.versionNumber = versionNumber; 15 | this.versionStatus = PolicyVersionStatus.Active; 16 | } 17 | 18 | @Override 19 | public void applyOn(Policy aggregate) { 20 | aggregate.apply(this); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/init/InitProductsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Cover; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Product; 5 | 6 | import java.util.Arrays; 7 | import java.util.UUID; 8 | 9 | class InitProductsBuilder { 10 | static Product standardCarInsurance() { 11 | return new Product( 12 | UUID.randomUUID(), 13 | "STD_CAR_INSURANCE", 14 | "Standard Car Insurance", 15 | Arrays.asList( 16 | new Cover(UUID.randomUUID(), "OC", "Third party liability"), 17 | new Cover(UUID.randomUUID(), "AC", "Auto casco"), 18 | new Cover(UUID.randomUUID(), "ASSITANCE", "Assistance") 19 | ) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/testdatabuilders/PoliciesTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Policy 4 | 5 | import java.time.LocalDate 6 | 7 | class PoliciesTestDataBuilder { 8 | 9 | static Policy standardOneYearPolicy(LocalDate policyStartDate) { 10 | def offer = OffersTestDataBuilder.standardOneYearOCOfferValidUntil(policyStartDate.plusDays(10)) 11 | 12 | return Policy.convertOffer(offer, "POL0001", policyStartDate.minusDays(1), policyStartDate) 13 | } 14 | 15 | static Policy standardOneYearPolicyTerminated(LocalDate policyStartDate, LocalDate policyTerminationDate) { 16 | def policy = standardOneYearPolicy(policyStartDate) 17 | policy.terminatePolicy(policyTerminationDate) 18 | policy.confirmChanges(2); 19 | 20 | return policy 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/init/InitProductsBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Cover; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Product; 5 | 6 | import java.util.Arrays; 7 | import java.util.UUID; 8 | 9 | class InitProductsBuilder { 10 | static Product standardCarInsurance() { 11 | return new Product( 12 | UUID.randomUUID(), 13 | "STD_CAR_INSURANCE", 14 | "Standard Car Insurance", 15 | Arrays.asList( 16 | new Cover(UUID.randomUUID(), "OC", "Third party liability"), 17 | new Cover(UUID.randomUUID(), "AC", "Auto casco"), 18 | new Cover(UUID.randomUUID(), "ASSITANCE", "Assistance") 19 | ) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/db/JpaPolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.db; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.query.Param; 6 | import org.springframework.stereotype.Repository; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyRepository; 9 | 10 | import java.util.UUID; 11 | 12 | @Repository 13 | public interface JpaPolicyRepository extends PolicyRepository, JpaRepository { 14 | 15 | @Override 16 | default void add(Policy policy) { 17 | save(policy); 18 | } 19 | 20 | @Query("select p from Policy p where p.number = :number") 21 | @Override 22 | Policy withNumber(@Param("number") String number); 23 | } 24 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/events/CoverageExtendedPolicyVersionConfirmed.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyVersionStatus; 7 | 8 | @Getter 9 | public class CoverageExtendedPolicyVersionConfirmed extends Event { 10 | private int versionNumber; 11 | private PolicyVersionStatus versionStatus; 12 | 13 | public CoverageExtendedPolicyVersionConfirmed(int versionNumber) { 14 | this.versionNumber = versionNumber; 15 | this.versionStatus = PolicyVersionStatus.Active; 16 | } 17 | 18 | @Override 19 | public void applyOn(Policy aggregate) { 20 | aggregate.apply(this); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/InMemoryOfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Offer; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.OfferRepository; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | //@Component 12 | public class InMemoryOfferRepository implements OfferRepository { 13 | 14 | private Map OFFERS = new ConcurrentHashMap<>(); 15 | 16 | @Override 17 | public Offer withNumber(String offerNumber) { 18 | return OFFERS.get(offerNumber); 19 | } 20 | 21 | @Override 22 | public List all() { 23 | return new ArrayList<>(OFFERS.values()); 24 | } 25 | 26 | @Override 27 | public void add(Offer offer) { 28 | OFFERS.put(offer.getNumber(), offer); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/product/Product.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.Covers; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.UUID; 11 | 12 | @Getter 13 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 14 | public class Product { 15 | private UUID id; 16 | private String code; 17 | private String name; 18 | private List covers = new ArrayList<>(); 19 | 20 | public Product(UUID id, String code, String name, List covers) { 21 | this.id = id; 22 | this.code = code; 23 | this.name = name; 24 | this.covers.addAll(covers); 25 | } 26 | 27 | public Covers getCovers() { 28 | return new Covers(covers); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/InMemoryProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Product; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.ProductRepository; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | //@Component 12 | public class InMemoryProductRepository implements ProductRepository { 13 | 14 | private Map PRODUCTS = new ConcurrentHashMap<>(); 15 | 16 | @Override 17 | public void add(Product product) { 18 | PRODUCTS.put(product.getCode(), product); 19 | } 20 | 21 | @Override 22 | public Product withCode(String code) { 23 | return PRODUCTS.get(code); 24 | } 25 | 26 | @Override 27 | public List all() { 28 | return new ArrayList<>(PRODUCTS.values()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/queries/GetPolicyVersionsListHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.queries; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.QueryHandler; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionDtoFinder; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionsListDto; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class GetPolicyVersionsListHandler implements QueryHandler { 12 | 13 | private final PolicyVersionDtoFinder policyVersionDtoFinder; 14 | 15 | @Override 16 | public PolicyVersionsListDto handle(GetPolicyVersionsListQuery query) { 17 | return policyVersionDtoFinder.findVersionsByPolicyNumber(query.getPolicyNumber()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/testdatabuilders/ProductsTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Cover; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Product; 5 | 6 | import java.util.Arrays; 7 | import java.util.UUID; 8 | 9 | public class ProductsTestDataBuilder { 10 | static Product standardCarInsurance() { 11 | return new Product( 12 | UUID.randomUUID(), 13 | "STD_CAR_INSURANCE", 14 | "Standard Car Insurance", 15 | Arrays.asList( 16 | new Cover(UUID.randomUUID(), "OC", "Third party liability"), 17 | new Cover(UUID.randomUUID(), "AC", "Auto casco"), 18 | new Cover(UUID.randomUUID(), "ASSITANCE", "Assistance") 19 | ) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/Product.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.UUID; 11 | 12 | @Entity 13 | @Getter 14 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 15 | public class Product { 16 | @Id 17 | @GeneratedValue 18 | private UUID id; 19 | private String code; 20 | private String name; 21 | @OneToMany(cascade = CascadeType.ALL) 22 | private List covers = new ArrayList<>(); 23 | 24 | public Product(UUID id, String code, String name, List covers) { 25 | this.id = id; 26 | this.code = code; 27 | this.name = name; 28 | this.covers.addAll(covers); 29 | } 30 | 31 | public Covers getCovers() { 32 | return new Covers(covers); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/db/InMemoryOfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Offer; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.OfferRepository; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | //@Component 12 | public class InMemoryOfferRepository implements OfferRepository { 13 | 14 | private Map OFFERS = new ConcurrentHashMap<>(); 15 | 16 | @Override 17 | public Offer withNumber(String offerNumber) { 18 | return OFFERS.get(offerNumber); 19 | } 20 | 21 | @Override 22 | public List all() { 23 | return new ArrayList<>(OFFERS.values()); 24 | } 25 | 26 | @Override 27 | public void add(Offer offer) { 28 | OFFERS.put(offer.getNumber(), offer); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/queries/GetPolicyVersionDetailsHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.queries; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.QueryHandler; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionDto; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionDtoFinder; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class GetPolicyVersionDetailsHandler implements QueryHandler { 12 | 13 | private final PolicyVersionDtoFinder policyVersionDtoFinder; 14 | 15 | @Override 16 | public PolicyVersionDto handle(GetPolicyVersionDetailsQuery query) { 17 | return policyVersionDtoFinder.findByPolicyNumberAndVersionNumber(query.getPolicyNumber(), query.getVersionNumber()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/base/AggregateRoot.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.UUID; 11 | 12 | @NoArgsConstructor 13 | public class AggregateRoot { 14 | @Getter 15 | @Setter(value = AccessLevel.PROTECTED) 16 | private UUID id; 17 | @Getter 18 | private int version = -1; 19 | @Getter 20 | private final List changes = new ArrayList<>(); 21 | 22 | protected void loadsFromHistory(List history) { 23 | history.forEach(e -> { 24 | e.applyOn(this); 25 | changes.add(e); 26 | version += 1; 27 | }); 28 | } 29 | 30 | protected void applyChange(Event event) { 31 | event.applyOn(this); 32 | changes.add(event); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/db/InMemoryProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.db; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Product; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.ProductRepository; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | //@Component 12 | public class InMemoryProductRepository implements ProductRepository { 13 | 14 | private Map PRODUCTS = new ConcurrentHashMap<>(); 15 | 16 | @Override 17 | public void add(Product product) { 18 | PRODUCTS.put(product.getCode(), product); 19 | } 20 | 21 | @Override 22 | public Product withCode(String code) { 23 | return PRODUCTS.get(code); 24 | } 25 | 26 | @Override 27 | public List all() { 28 | return new ArrayList<>(PRODUCTS.values()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/Product.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.*; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.UUID; 11 | 12 | @Entity 13 | @Getter 14 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 15 | public class Product { 16 | @Id 17 | @GeneratedValue 18 | private UUID id; 19 | private String code; 20 | private String name; 21 | @OneToMany(cascade = CascadeType.ALL) 22 | private List covers = new ArrayList<>(); 23 | 24 | public Product(UUID id, String code, String name, List covers) { 25 | this.id = id; 26 | this.code = code; 27 | this.name = name; 28 | this.covers.addAll(covers); 29 | } 30 | 31 | public Covers getCovers() { 32 | return new Covers(covers); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/JpaOfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.query.Param; 6 | import org.springframework.stereotype.Repository; 7 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Offer; 8 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.OfferRepository; 9 | 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | @Repository 14 | public interface JpaOfferRepository extends OfferRepository, JpaRepository { 15 | @Override 16 | default void add(Offer offer) { 17 | save(offer); 18 | } 19 | 20 | @Query("select o from Offer o where o.number = :offerNumber") 21 | @Override 22 | Offer withNumber(@Param("offerNumber") String offerNumber); 23 | 24 | @Override 25 | default List all() { 26 | return findAll(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/JpaProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.query.Param; 6 | import org.springframework.stereotype.Repository; 7 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Product; 8 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.ProductRepository; 9 | 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | @Repository 14 | public interface JpaProductRepository extends ProductRepository, JpaRepository { 15 | 16 | @Override 17 | default void add(Product product) { 18 | save(product); 19 | } 20 | 21 | @Query("select p from Product p where p.code = :code") 22 | @Override 23 | Product withCode(@Param("code") String code); 24 | 25 | @Override 26 | default List all() { 27 | return findAll(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/db/InMemoryOfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.db; 2 | 3 | import org.springframework.stereotype.Component; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.Offer; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.OfferRepository; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | @Component 13 | public class InMemoryOfferRepository implements OfferRepository { 14 | 15 | private Map OFFERS = new ConcurrentHashMap<>(); 16 | 17 | @Override 18 | public Offer withNumber(String offerNumber) { 19 | return OFFERS.get(offerNumber); 20 | } 21 | 22 | @Override 23 | public List all() { 24 | return new ArrayList<>(OFFERS.values()); 25 | } 26 | 27 | @Override 28 | public void add(Offer offer) { 29 | OFFERS.put(offer.getNumber(), offer); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/db/InMemoryProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.db; 2 | 3 | import org.springframework.stereotype.Component; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Product; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.ProductRepository; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | @Component 13 | public class InMemoryProductRepository implements ProductRepository { 14 | 15 | private Map PRODUCTS = new ConcurrentHashMap<>(); 16 | 17 | @Override 18 | public void add(Product product) { 19 | PRODUCTS.put(product.getCode(), product); 20 | } 21 | 22 | @Override 23 | public Product withCode(String code) { 24 | return PRODUCTS.get(code); 25 | } 26 | 27 | @Override 28 | public List all() { 29 | return new ArrayList<>(PRODUCTS.values()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/db/JpaOfferRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.db; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.query.Param; 6 | import org.springframework.stereotype.Repository; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Offer; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.OfferRepository; 9 | 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | @Repository 14 | public interface JpaOfferRepository extends OfferRepository, JpaRepository { 15 | @Override 16 | default void add(Offer offer) { 17 | save(offer); 18 | } 19 | 20 | @Query("select o from Offer o where o.number = :offerNumber") 21 | @Override 22 | Offer withNumber(@Param("offerNumber") String offerNumber); 23 | 24 | @Override 25 | default List all() { 26 | return findAll(); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/db/JpaProductRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.db; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.query.Param; 6 | import org.springframework.stereotype.Repository; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Product; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.ProductRepository; 9 | 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | @Repository 14 | public interface JpaProductRepository extends ProductRepository, JpaRepository { 15 | 16 | @Override 17 | default void add(Product product) { 18 | save(product); 19 | } 20 | 21 | @Query("select p from Product p where p.code = :code") 22 | @Override 23 | Product withCode(@Param("code") String code); 24 | 25 | @Override 26 | default List all() { 27 | return findAll(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/InMemoryPolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db; 2 | 3 | import org.springframework.stereotype.Component; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Policy; 5 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.PolicyRepository; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | //@Component 13 | public class InMemoryPolicyRepository implements PolicyRepository { 14 | 15 | private Map POLICIES = new ConcurrentHashMap<>(); 16 | 17 | @Override 18 | public Policy withNumber(String offerNumber) { 19 | return POLICIES.get(offerNumber); 20 | } 21 | 22 | @Override 23 | public void add(Policy policy) { 24 | POLICIES.put(policy.getNumber(), policy); 25 | } 26 | 27 | @Override 28 | public List find(PolicyFilter filter) { 29 | //TODO: add filtering 30 | return new ArrayList<>(POLICIES.values()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/CoverPrice.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.MonetaryAmount; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | import javax.persistence.ManyToOne; 12 | import java.time.Period; 13 | import java.util.UUID; 14 | 15 | @Entity 16 | @Getter 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class CoverPrice { 20 | @Id 21 | @GeneratedValue 22 | private UUID id; 23 | @ManyToOne(optional = false) 24 | private Cover cover; 25 | private MonetaryAmount price; 26 | private Period coverPeriod; 27 | 28 | public CoverPrice(Cover cover, MonetaryAmount price, Period coverPeriod) { 29 | this.id = UUID.randomUUID(); 30 | this.cover = cover; 31 | this.price = price; 32 | this.coverPeriod = coverPeriod; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/testdatabuilders/PoliciesTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Car; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Person; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 6 | 7 | import java.time.LocalDate; 8 | 9 | public class PoliciesTestDataBuilder { 10 | 11 | public static Policy standardOneYearPolicy(LocalDate policyStartDate, String policyNumber, Person customer, Car car) { 12 | var offer = OffersTestDataBuilder.oneYearOCOffer(policyStartDate.plusDays(10), customer, car); 13 | return Policy.convertOffer(offer, policyNumber, policyStartDate.minusDays(1), policyStartDate); 14 | } 15 | 16 | public static Policy standardOneYearPolicy(LocalDate policyStartDate, String policyNumber) { 17 | return standardOneYearPolicy(policyStartDate, policyNumber, PersonsTestDataBuilder.kowalski(), CarsTestDataBuilder.oldFordFocus()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyVersionDtoFinder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.List; 7 | 8 | @Component 9 | @RequiredArgsConstructor 10 | public class PolicyVersionDtoFinder { 11 | 12 | private final PolicyVersionDtoRepository repository; 13 | 14 | public PolicyVersionsListDto findVersionsByPolicyNumber(String policyNumber) { 15 | return new PolicyVersionsListDto(policyNumber, repository.findVersionsByPolicyNumber(policyNumber)); 16 | } 17 | 18 | public PolicyVersionDto findByPolicyNumberAndVersionNumber(String policyNumber, int versionNumber) { 19 | PolicyVersionDto dto = repository.findByPolicyNumberAndVersionNumber(policyNumber, versionNumber); 20 | List coversInVersion = repository.getCoversInVersion(dto.getId()); 21 | dto.setCovers(coversInVersion); 22 | 23 | return dto; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/JpaPolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | import org.springframework.data.jpa.repository.Query; 5 | import org.springframework.data.repository.query.Param; 6 | import org.springframework.stereotype.Repository; 7 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Policy; 8 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.PolicyRepository; 9 | 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | @Repository 14 | public interface JpaPolicyRepository extends PolicyRepository, JpaRepository { 15 | 16 | @Override 17 | default void add(Policy policy) { 18 | save(policy); 19 | } 20 | 21 | @Query("select p from Policy p where p.number = :number") 22 | @Override 23 | Policy withNumber(@Param("number") String number); 24 | 25 | @Override 26 | default List find(PolicyFilter filter) { 27 | //TODO add filtering with Specification 28 | return findAll(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/db/InMemoryPolicyRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.db; 2 | 3 | import org.springframework.stereotype.Component; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyRepository; 7 | 8 | import java.util.List; 9 | import java.util.UUID; 10 | 11 | @Component 12 | public class InMemoryPolicyRepository implements PolicyRepository { 13 | 14 | private final EventStore eventStore; 15 | 16 | public InMemoryPolicyRepository() { 17 | this.eventStore = new InMemoryEventStore(); 18 | } 19 | 20 | @Override 21 | public Policy getById(UUID id) { 22 | List events = eventStore.getEventsForAggregate(id); 23 | return new Policy(id, events); 24 | } 25 | 26 | @Override 27 | public void save(Policy policy, int expectedVersion) { 28 | eventStore.saveEvents(policy.getId(), expectedVersion, policy.getChanges()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/CoverPrice.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 7 | 8 | import javax.persistence.Entity; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | import javax.persistence.ManyToOne; 12 | import java.time.Period; 13 | import java.util.UUID; 14 | 15 | @Entity 16 | @Getter 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class CoverPrice { 20 | @Id 21 | @GeneratedValue 22 | private UUID id; 23 | @ManyToOne(optional = false) 24 | private Cover cover; 25 | private MonetaryAmount price; 26 | private Period coverPeriod; 27 | 28 | public CoverPrice(Cover cover, MonetaryAmount price, Period coverPeriod) { 29 | this.id = UUID.randomUUID(); 30 | this.cover = cover; 31 | this.price = price; 32 | this.coverPeriod = coverPeriod; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/db/specifications/PolicySpecification.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.db.specifications; 2 | 3 | import org.springframework.data.jpa.domain.Specification; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Policy; 5 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.PolicyRepository; 6 | 7 | public class PolicySpecification extends BaseSpecification { 8 | 9 | @Override 10 | public Specification getFilter(PolicyRepository.PolicyFilter request) { 11 | return null; 12 | } 13 | 14 | private Specification numberContains(String number) { 15 | return policyAttributeContains("number", number); 16 | } 17 | 18 | private Specification policyAttributeContains(String attribute, String value) { 19 | return (root, query, cb) -> { 20 | if(value == null) { 21 | return null; 22 | } 23 | 24 | return cb.like( 25 | cb.lower(root.get(attribute)), 26 | containsLowerCase(value) 27 | ); 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/terminatepolicy/TerminatePolicyHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.terminatepolicy; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.CommandHandler; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class TerminatePolicyHandler implements CommandHandler { 12 | 13 | private final PolicyRepository policyRepository; 14 | 15 | @Override 16 | public TerminatePolicyResult handle(TerminatePolicyCommand command) { 17 | Policy policy = policyRepository.getById(command.getPolicyId()); 18 | 19 | policy.terminatePolicy(command.getTerminationDate()); 20 | policyRepository.save(policy, policy.getVersion()); 21 | 22 | return new TerminatePolicyResult(policy.getId(), policy.getPolicyVersions().last().getVersionNumber()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/offer/CoverPrice.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Cover; 8 | 9 | import java.time.Period; 10 | import java.util.UUID; 11 | 12 | @Getter 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class CoverPrice { 16 | private UUID id; 17 | private String coverCode; 18 | private MonetaryAmount price; 19 | private Period coverPeriod; 20 | 21 | public CoverPrice(String coverCode, MonetaryAmount price, Period coverPeriod) { 22 | this.id = UUID.randomUUID(); 23 | this.coverCode = coverCode; 24 | this.price = price; 25 | this.coverPeriod = coverPeriod; 26 | } 27 | 28 | public CoverPrice(Cover cover, MonetaryAmount price, Period coverPeriod) { 29 | this.coverCode = cover.getCode(); 30 | this.price = price; 31 | this.coverPeriod = coverPeriod; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyInfoDtoFinder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.List; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class PolicyInfoDtoFinder { 12 | 13 | private final NamedParameterJdbcTemplate jdbcTemplate; 14 | 15 | public List findByFilter(PolicyFilter filter) { 16 | return new PolicyFilterQueryBuilder() 17 | .where() 18 | .policyNumberEquals(filter.getNumber()) 19 | .policyHolderLike(filter.getHolderFirstName()) 20 | .policyHolderLike(filter.getHolderLastName()) 21 | .policyStartDateFrom(filter.getStartDateFrom()) 22 | .policyStartDateTo(filter.getStartDateTo()) 23 | .policyCarPlateNumberLike(filter.getCarPlateNumber()) 24 | .execute(jdbcTemplate, new PolicyInfoDto.PolicyInfoDtoRowMapper()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/terminatepolicy/TerminatePolicyHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.terminatepolicy; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyRepository; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.CommandHandler; 9 | 10 | @Component 11 | @Transactional 12 | @RequiredArgsConstructor 13 | public class TerminatePolicyHandler implements CommandHandler { 14 | 15 | private final PolicyRepository policyRepository; 16 | 17 | @Override 18 | public TerminatePolicyResult handle(TerminatePolicyCommand command) { 19 | Policy policy = policyRepository.withNumber(command.getPolicyNumber()); 20 | policy.terminatePolicy(command.getTerminationDate()); 21 | return new TerminatePolicyResult(policy.getNumber(), policy.getPolicyVersions().last().getVersionNumber()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyInfoDtoRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import org.springframework.data.jdbc.repository.query.Modifying; 4 | import org.springframework.data.jdbc.repository.query.Query; 5 | import org.springframework.data.repository.CrudRepository; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import java.util.Optional; 9 | import java.util.UUID; 10 | 11 | public interface PolicyInfoDtoRepository extends CrudRepository { 12 | 13 | @Modifying 14 | @Query("UPDATE policy_info_dto " + 15 | "SET " + 16 | "cover_from = :policy.coverFrom, " + 17 | "cover_to = :policy.coverTo, " + 18 | "vehicle = :policy.vehicle, " + 19 | "policy_holder = :policy.policyHolder, " + 20 | "total_premium = :policy.totalPremium " + 21 | "WHERE " + 22 | "policy_id = :policy.policyId") 23 | void update(@Param("policy") PolicyInfoDto policy); 24 | 25 | @Query("SELECT * FROM policy_info_dto p WHERE p.policy_id = :policyId") 26 | Optional findByPolicyId(@Param("policyId") UUID policyId); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/common/DateRange.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.time.LocalDate; 9 | 10 | import static java.time.temporal.ChronoUnit.DAYS; 11 | 12 | @Getter 13 | @AllArgsConstructor 14 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 15 | public class DateRange { 16 | private LocalDate from; 17 | private LocalDate to; 18 | 19 | public static DateRange between(LocalDate from, LocalDate to) { 20 | return new DateRange(from, to); 21 | } 22 | 23 | public boolean contains(LocalDate eventDate) { 24 | if (eventDate.isAfter(to)) 25 | return false; 26 | 27 | if (eventDate.isBefore(from)) 28 | return false; 29 | 30 | return true; 31 | } 32 | 33 | public DateRange clone() { 34 | return new DateRange(from, to); 35 | } 36 | 37 | public DateRange endOn(LocalDate endDate) { 38 | return new DateRange(from, endDate); 39 | } 40 | 41 | public long days() { 42 | return DAYS.between(from, to); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/confirmtermination/ConfirmTerminationHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmtermination; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.CommandHandler; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class ConfirmTerminationHandler implements CommandHandler { 12 | 13 | private final PolicyRepository policyRepository; 14 | 15 | @Override 16 | public ConfirmTerminationResult handle(ConfirmTerminationCommand command) { 17 | Policy policy = policyRepository.getById(command.getPolicyId()); 18 | 19 | policy.confirmTermination(command.getVersionToConfirmNumber()); 20 | policyRepository.save(policy, policy.getVersion()); 21 | 22 | return new ConfirmTerminationResult( 23 | policy.getId(), 24 | policy.getPolicyVersions().latestActive().getVersionNumber() 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/testdatabuilders/OffersTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.*; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 5 | 6 | import java.time.LocalDate; 7 | import java.time.Period; 8 | import java.util.HashMap; 9 | import java.util.UUID; 10 | 11 | public class OffersTestDataBuilder { 12 | static Offer oneYearOCOffer(LocalDate validityEnd, Person customer, Car car) { 13 | Product product = ProductsTestDataBuilder.standardCarInsurance(); 14 | 15 | var coversPrices = new HashMap(); 16 | coversPrices.put(product.getCovers().withCode("OC").get(), MonetaryAmount.from("500")); 17 | 18 | return new Offer( 19 | UUID.randomUUID(), 20 | "1", 21 | product, 22 | customer, 23 | PersonsTestDataBuilder.kowalski(), 24 | car, 25 | Period.ofDays(365), 26 | MonetaryAmount.from("500"), 27 | validityEnd.minusDays(30), 28 | coversPrices 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/asserts/PolicyAsserts.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.asserts; 2 | 3 | import org.junit.Assert; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyVersion; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyInfoDto; 8 | 9 | public class PolicyAsserts { 10 | public static void assertPolicyWithPolicyInfoDto(Policy expected, PolicyInfoDto actual) { 11 | Assert.assertNotNull(actual); 12 | PolicyVersion policyVersion = expected.getPolicyVersions().withNumber(1).get(); 13 | Assert.assertEquals(policyVersion.getCoverPeriod().getFrom(), actual.getCoverFrom()); 14 | Assert.assertEquals(policyVersion.getCoverPeriod().getTo(), actual.getCoverTo()); 15 | Assert.assertEquals(policyVersion.getPolicyHolder().getFullName(), actual.getPolicyHolder()); 16 | Assert.assertEquals(policyVersion.getCar().getPlaceNumberWithMake(), actual.getVehicle()); 17 | Assert.assertEquals(policyVersion.getTotalPremium(), MonetaryAmount.from(actual.getTotalPremiumAmount())); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/primitives/DateRange.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.Embeddable; 9 | import java.time.LocalDate; 10 | 11 | import static java.time.temporal.ChronoUnit.DAYS; 12 | 13 | @Embeddable 14 | @Getter 15 | @AllArgsConstructor 16 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 17 | public class DateRange { 18 | private LocalDate from; 19 | private LocalDate to; 20 | 21 | public static DateRange between(LocalDate from, LocalDate to) { 22 | return new DateRange(from, to); 23 | } 24 | 25 | public boolean contains(LocalDate eventDate) { 26 | if (eventDate.isAfter(to)) 27 | return false; 28 | 29 | if (eventDate.isBefore(from)) 30 | return false; 31 | 32 | return true; 33 | } 34 | 35 | public DateRange clone() { 36 | return new DateRange(from, to); 37 | } 38 | 39 | public DateRange endOn(LocalDate endDate) { 40 | return new DateRange(from, endDate); 41 | } 42 | 43 | public long days() { 44 | return DAYS.between(from, to); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/init/InitDatabase.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.init; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.OfferRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Product; 8 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.ProductRepository; 9 | 10 | import java.time.LocalDate; 11 | 12 | @Component 13 | @RequiredArgsConstructor 14 | public class InitDatabase { 15 | 16 | private final ProductRepository productRepository; 17 | private final OfferRepository offerRepository; 18 | 19 | @Transactional 20 | public void init() { 21 | Product standardCarInsurance = InitProductsBuilder.standardCarInsurance(); 22 | productRepository.add(standardCarInsurance); 23 | 24 | Product productFromRepo = productRepository.withCode(standardCarInsurance.getCode()); 25 | 26 | offerRepository.add(InitOffersBuilder.standardOneYearOCOfferValidUntil(productFromRepo, "OFF-001", LocalDate.now().plusDays(15))); 27 | offerRepository.add(InitOffersBuilder.standardOneYearOCOfferValidUntil(productFromRepo, "OFF-002", LocalDate.now().minusDays(3))); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/primitives/DateRange.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.Embeddable; 9 | import java.time.LocalDate; 10 | 11 | import static java.time.temporal.ChronoUnit.DAYS; 12 | 13 | @Embeddable 14 | @Getter 15 | @AllArgsConstructor 16 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 17 | public class DateRange { 18 | private LocalDate from; 19 | private LocalDate to; 20 | 21 | public static DateRange between(LocalDate from, LocalDate to) { 22 | return new DateRange(from, to); 23 | } 24 | 25 | public boolean contains(LocalDate eventDate) { 26 | if (eventDate.isAfter(to)) 27 | return false; 28 | 29 | if (eventDate.isBefore(from)) 30 | return false; 31 | 32 | return true; 33 | } 34 | 35 | public DateRange clone() { 36 | return new DateRange(from, to); 37 | } 38 | 39 | public DateRange endOn(LocalDate endDate) { 40 | return new DateRange(from, endDate); 41 | } 42 | 43 | public long days() { 44 | return DAYS.between(from, to); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/confirmbuyadditionalcover/ConfirmBuyAdditionalCoverHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmbuyadditionalcover; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.CommandHandler; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class ConfirmBuyAdditionalCoverHandler implements CommandHandler { 12 | 13 | private final PolicyRepository policyRepository; 14 | 15 | @Override 16 | public ConfirmBuyAdditionalCoverResult handle(ConfirmBuyAdditionalCoverCommand command) { 17 | Policy policy = policyRepository.getById(command.getPolicyId()); 18 | 19 | policy.confirmTermination(command.getVersionToConfirmNumber()); 20 | policyRepository.save(policy, policy.getVersion()); 21 | 22 | return new ConfirmBuyAdditionalCoverResult( 23 | policy.getId(), 24 | policy.getPolicyVersions().latestActive().getVersionNumber() 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/createpolicy/CreatePolicyHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.createpolicy; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.Offer; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.OfferRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 8 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyRepository; 9 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.CommandHandler; 10 | 11 | @Component 12 | @RequiredArgsConstructor 13 | public class CreatePolicyHandler implements CommandHandler { 14 | 15 | private final OfferRepository offerRepository; 16 | private final PolicyRepository policyRepository; 17 | 18 | @Override 19 | public CreatePolicyResult handle(CreatePolicyCommand command) { 20 | Offer offer = offerRepository.withNumber(command.getOfferNumber()); 21 | 22 | Policy policy = Policy.convertOffer(offer, command.getPurchaseDate(), command.getPolicyStartDate()); 23 | policyRepository.save(policy, -1); 24 | 25 | return new CreatePolicyResult(policy.getId(), policy.getNumber()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/init/InitDatabase.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.init; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.OfferRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Product; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.ProductRepository; 9 | 10 | import java.time.LocalDate; 11 | 12 | @Component 13 | @RequiredArgsConstructor 14 | public class InitDatabase { 15 | 16 | private final ProductRepository productRepository; 17 | private final OfferRepository offerRepository; 18 | 19 | @Transactional 20 | public void init() { 21 | Product standardCarInsurance = InitProductsBuilder.standardCarInsurance(); 22 | productRepository.add(standardCarInsurance); 23 | 24 | Product productFromRepo = productRepository.withCode(standardCarInsurance.getCode()); 25 | 26 | offerRepository.add(InitOffersBuilder.standardOneYearOCOfferValidUntil(productFromRepo, "OFF-001", LocalDate.now().plusDays(15))); 27 | offerRepository.add(InitOffersBuilder.standardOneYearOCOfferValidUntil(productFromRepo, "OFF-002", LocalDate.now().minusDays(3))); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyVersionsListDto.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import org.springframework.jdbc.core.RowMapper; 6 | 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | 12 | @Getter 13 | @AllArgsConstructor 14 | public class PolicyVersionsListDto { 15 | private String policyNumber; 16 | private List versionsInfo; 17 | 18 | @Getter 19 | @AllArgsConstructor 20 | public static class PolicyVersionInfoDto { 21 | private int number; 22 | private LocalDate versionFrom; 23 | private LocalDate versionTo; 24 | private String versionStatus; 25 | } 26 | 27 | static class PolicyVersionInfoDtoRowMapper implements RowMapper { 28 | 29 | @Override 30 | public PolicyVersionInfoDto mapRow(ResultSet rs, int i) throws SQLException { 31 | return new PolicyVersionInfoDto( 32 | rs.getInt("version_number"), 33 | rs.getDate("version_from").toLocalDate(), 34 | rs.getDate("version_to").toLocalDate(), 35 | rs.getString("version_status") 36 | ); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/PolicyInfoDtoAssembler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Car; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Person; 5 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.PolicyVersion; 7 | 8 | class PolicyInfoDtoAssembler { 9 | 10 | static PolicyInfoDto assemble(Policy policy) { 11 | PolicyVersion policyVersion = policy.getPolicyVersions().latestActive(); 12 | 13 | return new PolicyInfoDto( 14 | policy.getId(), 15 | policy.getNumber(), 16 | policyVersion.getCoverPeriod().getFrom(), 17 | policyVersion.getCoverPeriod().getTo(), 18 | assembleVehicleDescription(policyVersion.getCar()), 19 | assemblePolicyHolderDescription(policyVersion.getPolicyHolder()), 20 | policyVersion.getTotalPremium().getAmount() 21 | ); 22 | } 23 | 24 | private static String assemblePolicyHolderDescription(Person policyHolder) { 25 | return policyHolder.getLastName() + " " + policyHolder.getFirstName(); 26 | } 27 | 28 | private static String assembleVehicleDescription(Car car) { 29 | return car.getMake() + " " + car.getProductionYear() + " " + car.getPlateNumber(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/init/InitDatabase.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.init; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.OfferRepository; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Product; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.ProductRepository; 8 | 9 | import java.time.LocalDate; 10 | 11 | @Component 12 | @RequiredArgsConstructor 13 | public class InitDatabase { 14 | 15 | private final ProductRepository productRepository; 16 | private final OfferRepository offerRepository; 17 | 18 | public void init() { 19 | Product standardCarInsurance = InitProductsBuilder.standardCarInsurance(); 20 | productRepository.add(standardCarInsurance); 21 | 22 | Product productFromRepo = productRepository.withCode(standardCarInsurance.getCode()); 23 | 24 | offerRepository.add(InitOffersBuilder.standardOneYearOCOfferValidUntil( 25 | productFromRepo, 26 | "OFF-001", 27 | LocalDate.now().plusDays(15) 28 | )); 29 | offerRepository.add(InitOffersBuilder.standardOneYearOCOfferValidUntil( 30 | productFromRepo, 31 | "OFF-002", 32 | LocalDate.now().minusDays(3) 33 | )); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/commands/buyadditionalcover/BuyAdditionalCoverHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.buyadditionalcover; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyRepository; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.CommandHandler; 8 | 9 | @Component 10 | @RequiredArgsConstructor 11 | public class BuyAdditionalCoverHandler implements CommandHandler { 12 | 13 | private final PolicyRepository policyRepository; 14 | 15 | @Override 16 | public BuyAdditionalCoverResult handle(BuyAdditionalCoverCommand command) { 17 | Policy policy = policyRepository.getById(command.getPolicyId()); 18 | 19 | policy.extendCoverage( 20 | command.getEffectiveDateOfChange(), 21 | command.getNewCoverCode(), 22 | command.getNewCoverPrice(), 23 | command.getNewCoverPriceUnit() 24 | ); 25 | policyRepository.save(policy, policy.getVersion()); 26 | 27 | return new BuyAdditionalCoverResult( 28 | policy.getId(), 29 | policy.getPolicyVersions().last().getVersionNumber() 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/queries/FindPoliciesHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.queries; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.QueryHandler; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyFilter; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyInfoDto; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyInfoDtoFinder; 9 | 10 | import java.util.List; 11 | 12 | @Component 13 | @RequiredArgsConstructor 14 | public class FindPoliciesHandler implements QueryHandler, FindPoliciesQuery> { 15 | 16 | private final PolicyInfoDtoFinder policyInfoDtoFinder; 17 | 18 | @Override 19 | public List handle(FindPoliciesQuery query) { 20 | PolicyFilter filter = PolicyFilter.builder() 21 | .number(query.getPolicyNumber()) 22 | .holderFirstName(query.getPolicyHolderFirstName()) 23 | .holderLastName(query.getPolicyHolderLastName()) 24 | .carPlateNumber(query.getCarPlateNumber()) 25 | .startDateFrom(query.getPolicyStartFrom()) 26 | .startDateTo(query.getPolicyStartTo()) 27 | .build(); 28 | 29 | return policyInfoDtoFinder.findByFilter(filter); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/createpolicy/CreatePolicyHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.createpolicy; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.*; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.CommandHandler; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.events.EventPublisher; 9 | 10 | import java.util.UUID; 11 | 12 | @Component 13 | @Transactional 14 | @RequiredArgsConstructor 15 | public class CreatePolicyHandler implements CommandHandler { 16 | 17 | private final OfferRepository offerRepository; 18 | private final PolicyRepository policyRepository; 19 | private final EventPublisher eventPublisher; 20 | 21 | @Override 22 | public CreatePolicyResult handle(CreatePolicyCommand command) { 23 | Offer offer = offerRepository.withNumber(command.getOfferNumber()); 24 | Policy policy = Policy.convertOffer(offer, UUID.randomUUID().toString(), command.getPurchaseDate(), command.getPolicyStartDate()); 25 | policyRepository.add(policy); 26 | 27 | eventPublisher.publish(new PolicyEvents.PolicyCreated(this, policy)); 28 | 29 | return new CreatePolicyResult(policy.getNumber()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyVersionDtoFinderTestMock.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import static org.mockito.Mockito.when; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.junit.Assert; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.mockito.Mock; 12 | import org.mockito.MockitoAnnotations; 13 | 14 | public class PolicyVersionDtoFinderTestMock { 15 | 16 | @Mock 17 | PolicyVersionDtoRepository repository; 18 | 19 | private PolicyVersionDtoFinder policyVersionDtoFinder; 20 | private final static String policyNumber = "POL0001"; 21 | 22 | @Before 23 | public void setUp() { 24 | MockitoAnnotations.initMocks(this); 25 | this.policyVersionDtoFinder = new PolicyVersionDtoFinder(this.repository); 26 | } 27 | 28 | @Test 29 | public void test() { 30 | //given 31 | List policyVersionListDto = new ArrayList<>(); 32 | when(repository.findVersionsByPolicyNumber(policyNumber)).thenReturn(policyVersionListDto); 33 | 34 | //when 35 | PolicyVersionsListDto result = policyVersionDtoFinder.findVersionsByPolicyNumber(policyNumber); 36 | 37 | //then 38 | Assert.assertEquals(0, result.getVersionsInfo().size()); 39 | Assert.assertEquals(policyNumber, result.getPolicyNumber()); 40 | Assert.assertSame(policyVersionListDto, result.getVersionsInfo()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/CQRSwithESApplication.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.boot.ApplicationArguments; 5 | import org.springframework.boot.ApplicationRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.context.annotation.Bean; 10 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Bus; 11 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Registry; 12 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.SpringBus; 13 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.init.InitDatabase; 14 | 15 | @SpringBootApplication 16 | @RequiredArgsConstructor 17 | public class CQRSwithESApplication implements ApplicationRunner { 18 | 19 | private final InitDatabase dbInitializer; 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(CQRSwithESApplication.class, args); 23 | } 24 | 25 | @Bean 26 | public Registry registry(ApplicationContext applicationContext) { 27 | return new Registry(applicationContext); 28 | } 29 | 30 | @Bean 31 | public Bus commandBus(Registry registry) { 32 | return new SpringBus(registry); 33 | } 34 | 35 | @Override 36 | public void run(ApplicationArguments args) { 37 | dbInitializer.init(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/init/InitOffersBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.Offer; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Cover; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Product; 7 | 8 | import java.time.LocalDate; 9 | import java.time.Period; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.UUID; 13 | 14 | class InitOffersBuilder { 15 | static Offer standardOneYearOCOfferValidUntil(Product product, String number, LocalDate validityEnd) { 16 | return new Offer( 17 | UUID.randomUUID(), 18 | number, 19 | product, 20 | InitPersonsBuilder.kowalski(), 21 | InitPersonsBuilder.kowalski(), 22 | InitCarsBuilder.oldFordFocus(), 23 | Period.ofDays(365), 24 | MonetaryAmount.from(500), 25 | validityEnd.minusDays(30), 26 | createCoversPrices(product) 27 | ); 28 | } 29 | 30 | private static Map createCoversPrices(Product product) { 31 | Map coversPrices = new HashMap<>(); 32 | coversPrices.put(product.getCovers().withCode("OC").get(), MonetaryAmount.from("500")); 33 | return coversPrices; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/services/PolicyDto.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.services; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.math.BigDecimal; 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | import java.util.UUID; 12 | 13 | @Getter 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class PolicyDto { 17 | 18 | private UUID policyId; 19 | private String policyNumber; 20 | private PolicyVersionDto currentVersion; 21 | private List versions; 22 | 23 | @Getter 24 | @Builder 25 | public static class PolicyVersionDto { 26 | private int versionNumber; 27 | private String versionStatus; 28 | private String policyStatus; 29 | private String policyHolder; 30 | private String insured; 31 | private String car; 32 | private LocalDate coverFrom; 33 | private LocalDate coverTo; 34 | private LocalDate versionFrom; 35 | private LocalDate versionTo; 36 | private BigDecimal totalPremium; 37 | private List covers; 38 | private List changes; 39 | } 40 | 41 | @Getter 42 | @NoArgsConstructor 43 | @AllArgsConstructor 44 | public static class CoverDto { 45 | private String code; 46 | private LocalDate coverFrom; 47 | private LocalDate coverTo; 48 | private BigDecimal premiumAmount; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/buyadditionalcover/BuyAdditionalCoverHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.buyadditionalcover; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.*; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.CommandHandler; 9 | 10 | @Component 11 | @Transactional 12 | @RequiredArgsConstructor 13 | public class BuyAdditionalCoverHandler implements CommandHandler { 14 | 15 | private final PolicyRepository policyRepository; 16 | 17 | @Override 18 | public BuyAdditionalCoverResult handle(BuyAdditionalCoverCommand command) { 19 | Policy policy = policyRepository.withNumber(command.getPolicyNumber()); 20 | Cover newCover = policy.getProduct().getCovers().withCode(command.getNewCoverCode()).get(); 21 | policy.extendCoverage( 22 | command.getEffectiveDateOfChange(), 23 | new CoverPrice(newCover, MonetaryAmount.from(command.getNewCoverPrice()), command.getNewCoverPriceUnit()) 24 | ); 25 | PolicyVersion newPolicyVersion = policy.getPolicyVersions().last(); 26 | return new BuyAdditionalCoverResult(policy.getNumber(), newPolicyVersion.getVersionNumber()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /cqrswithes/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/PolicyCreationSpec.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyStatus 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyVersionStatus 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.testdatabuilders.OffersTestDataBuilder 8 | import spock.lang.Specification 9 | 10 | import java.time.LocalDate 11 | 12 | class PolicyCreationSpec extends Specification { 13 | 14 | def "can convert offer to policy before it expires"() { 15 | given: 16 | def offer = OffersTestDataBuilder.standardOneYearOCOfferValidUntil(LocalDate.of(2019, 1, 31)) 17 | def purchaseDate = LocalDate.of(2019, 1, 12) 18 | def policyStartDate = LocalDate.of(2019, 1, 15) 19 | 20 | when: 21 | def policy = Policy.convertOffer(offer, purchaseDate, policyStartDate) 22 | 23 | then: 24 | policy != null 25 | policy.getPolicyVersions().size() == 1 26 | def firstVersion = policy.getPolicyVersions().withNumber(1).get() 27 | firstVersion.getPolicyStatus() == PolicyStatus.Active 28 | firstVersion.getVersionStatus() == PolicyVersionStatus.Active 29 | firstVersion.getTotalPremium() == MonetaryAmount.from("500") 30 | 31 | def changes = policy.getChanges() 32 | changes.size() == 1 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/events/CoverageExtendedPolicyVersionCreated.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyCover; 8 | 9 | import java.time.LocalDate; 10 | 11 | @Getter 12 | @AllArgsConstructor 13 | public class CoverageExtendedPolicyVersionCreated extends Event { 14 | private int versionNumber; 15 | private int baseVersionNumber; 16 | private LocalDate versionFrom; 17 | private LocalDate versionTo; 18 | private PolicyEventsData.PolicyCoverData newCover; 19 | 20 | public CoverageExtendedPolicyVersionCreated(int versionNumber, 21 | int baseVersionNumber, 22 | LocalDate versionFrom, 23 | LocalDate versionTo, 24 | PolicyCover newCover) { 25 | this.versionNumber = versionNumber; 26 | this.baseVersionNumber = baseVersionNumber; 27 | this.versionFrom = versionFrom; 28 | this.versionTo = versionTo; 29 | this.newCover = PolicyEventsData.PolicyCoverData.from(newCover); 30 | } 31 | 32 | @Override 33 | public void applyOn(Policy aggregate) { 34 | aggregate.apply(this); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/testdatabuilders/OffersTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Offer 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.MonetaryAmount 5 | 6 | import java.time.LocalDate 7 | import java.time.Period 8 | 9 | class OffersTestDataBuilder { 10 | 11 | static Offer standardOneYearOCOfferValidUntil(LocalDate validityEnd) { 12 | def product = ProductsTestDataBuilder.standardCarInsurance() 13 | 14 | def coversPrices = new HashMap<>(); 15 | coversPrices.put(product.getCovers().withCode("OC").get(), MonetaryAmount.from("500")) 16 | 17 | return new Offer( 18 | UUID.randomUUID(), 19 | "1", 20 | product, 21 | PersonsTestDataBuilder.kowalski(), 22 | PersonsTestDataBuilder.kowalski(), 23 | CarsTestDataBuilder.oldFordFocus(), 24 | Period.ofDays(365), 25 | MonetaryAmount.from("500"), 26 | validityEnd.minusDays(30), 27 | coversPrices 28 | ) 29 | } 30 | 31 | static Offer rejectedOfferValidUntil(LocalDate validityEnd) { 32 | def offer = standardOneYearOCOfferValidUntil(validityEnd) 33 | offer.reject() 34 | return offer 35 | } 36 | 37 | static Offer convertedOfferValidUntil(LocalDate validityEnd) { 38 | Offer offer = standardOneYearOCOfferValidUntil(validityEnd) 39 | offer.convert() 40 | return offer 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /cqrswithes/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/cqrswithes/testdatabuilders/OffersTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.Offer 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount 5 | 6 | import java.time.LocalDate 7 | import java.time.Period 8 | 9 | class OffersTestDataBuilder { 10 | 11 | static Offer standardOneYearOCOfferValidUntil(LocalDate validityEnd) { 12 | def product = ProductsTestDataBuilder.standardCarInsurance() 13 | 14 | def coversPrices = new HashMap<>(); 15 | coversPrices.put(product.getCovers().withCode("OC").get(), MonetaryAmount.from("500")) 16 | 17 | return new Offer( 18 | UUID.randomUUID(), 19 | "1", 20 | product, 21 | PersonsTestDataBuilder.kowalski(), 22 | PersonsTestDataBuilder.kowalski(), 23 | CarsTestDataBuilder.oldFordFocus(), 24 | Period.ofDays(365), 25 | MonetaryAmount.from("500"), 26 | validityEnd.minusDays(30), 27 | coversPrices 28 | ) 29 | } 30 | 31 | static Offer rejectedOfferValidUntil(LocalDate validityEnd) { 32 | def offer = standardOneYearOCOfferValidUntil(validityEnd) 33 | offer.reject() 34 | return offer 35 | } 36 | 37 | static Offer convertedOfferValidUntil(LocalDate validityEnd) { 38 | Offer offer = standardOneYearOCOfferValidUntil(validityEnd) 39 | offer.convert() 40 | return offer 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/PolicyCancelAnnexSpec.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.MonetaryAmount 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders.PoliciesTestDataBuilder 5 | import spock.lang.Specification 6 | 7 | import java.time.LocalDate 8 | 9 | class PolicyCancelAnnexSpec extends Specification { 10 | 11 | def "can undo termination"() { 12 | given: 13 | def policyStartedAt = LocalDate.of(2019, 1, 1) 14 | def policyTerminatedAt = LocalDate.of(2019, 7, 1) 15 | def policy = PoliciesTestDataBuilder.standardOneYearPolicyTerminated(policyStartedAt, policyTerminatedAt) 16 | 17 | when: 18 | policy.cancelLastAnnex() 19 | 20 | then: 21 | policy.getVersions().size() == 2 22 | 23 | def firstVersion = policy.getPolicyVersions().withNumber(1).get() 24 | firstVersion.getVersionStatus() == PolicyVersion.PolicyVersionStatus.Active 25 | firstVersion.getTotalPremium() == MonetaryAmount.from("500") 26 | 27 | def secondVersion = policy.getPolicyVersions().withNumber(2).get() 28 | secondVersion.getPolicyStatus() == Policy.PolicyStatus.Terminated 29 | secondVersion.getVersionStatus() == PolicyVersion.PolicyVersionStatus.Cancelled 30 | secondVersion.getVersionValidityPeriod().getFrom() == policyTerminatedAt 31 | secondVersion.getCoverPeriod().getTo() == policyTerminatedAt.minusDays(1) 32 | secondVersion.getCoverPeriod().getFrom() == LocalDate.of(2019, 1, 1) 33 | secondVersion.getTotalPremium() == MonetaryAmount.from("250") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/confirmtermination/ConfirmTerminationHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.confirmtermination; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyEvents; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyRepository; 9 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.CommandHandler; 10 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.events.EventPublisher; 11 | 12 | @Component 13 | @Transactional 14 | @RequiredArgsConstructor 15 | public class ConfirmTerminationHandler implements CommandHandler { 16 | 17 | private final PolicyRepository policyRepository; 18 | private final EventPublisher eventPublisher; 19 | 20 | @Override 21 | public ConfirmTerminationResult handle(ConfirmTerminationCommand command) { 22 | Policy policy = policyRepository.withNumber(command.getPolicyNumber()); 23 | policy.confirmChanges(command.getVersionToConfirmNumber()); 24 | 25 | eventPublisher.publish(new PolicyEvents.PolicyTerminated(this, 26 | policy, 27 | policy.getPolicyVersions().withNumber(command.getVersionToConfirmNumber()).get()) 28 | ); 29 | 30 | return new ConfirmTerminationResult( 31 | policy.getNumber(), 32 | policy.getPolicyVersions().latestActive().getVersionNumber() 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/events/PolicyEventsData.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyCover; 7 | 8 | import java.time.LocalDate; 9 | import java.time.Period; 10 | 11 | public class PolicyEventsData { 12 | @Getter 13 | @AllArgsConstructor 14 | public static class PersonData { 15 | private String firstName; 16 | private String lastName; 17 | private String taxId; 18 | } 19 | 20 | @Getter 21 | @AllArgsConstructor 22 | public static class CarData { 23 | private String make; 24 | private String plateNumber; 25 | private int productionYear; 26 | } 27 | 28 | @Getter 29 | @AllArgsConstructor 30 | public static class PolicyCoverData { 31 | private String code; 32 | private LocalDate coverFrom; 33 | private LocalDate coverTo; 34 | private MonetaryAmount amount; 35 | private MonetaryAmount price; 36 | private Period priceUnit; 37 | 38 | public static PolicyCoverData from(PolicyCover cover) { 39 | return new PolicyEventsData.PolicyCoverData( 40 | cover.getCoverCode(), 41 | cover.getCoverPeriod().getFrom(), 42 | cover.getCoverPeriod().getTo(), 43 | cover.getAmount(), 44 | cover.getPrice().getPrice(), 45 | cover.getPrice().getPricePeriod() 46 | ); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/PolicyVersions.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import java.time.LocalDate; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | @RequiredArgsConstructor 11 | public class PolicyVersions { 12 | 13 | private final List versions; 14 | 15 | public Optional effectiveAtDate(LocalDate effectiveDate) { 16 | return versions.stream() 17 | .filter(v -> v.isEffectiveOn(effectiveDate) && !v.isDraft()) 18 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)); 19 | } 20 | 21 | public int maxVersionNumber() { 22 | return versions.stream() 23 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber).reversed()) 24 | .get() //TODO: ifPresent 25 | .getVersionNumber(); 26 | } 27 | 28 | public Optional withNumber(int versionNumber) { 29 | return versions.stream() 30 | .filter(v -> v.getVersionNumber() == versionNumber) 31 | .findFirst(); 32 | } 33 | 34 | public PolicyVersion latestActive() { 35 | return versions.stream() 36 | .filter(v -> PolicyVersion.PolicyVersionStatus.Active.equals(v.getVersionStatus())) 37 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)) 38 | .get(); 39 | } 40 | 41 | public PolicyVersion last() { 42 | return versions.stream() 43 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)) 44 | .get(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyInfoDtoProjection.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyVersion; 8 | 9 | @Component 10 | @Transactional 11 | @RequiredArgsConstructor 12 | public class PolicyInfoDtoProjection { 13 | 14 | private final PolicyInfoDtoRepository policyInfoDtoRepository; 15 | 16 | public void createPolicyInfoDto(Policy policy) { 17 | PolicyVersion policyVersion = policy.getPolicyVersions().withNumber(1).get(); 18 | PolicyInfoDto policyInfo = buildPolicyInfoDto(policy, policyVersion); 19 | policyInfoDtoRepository.save(policyInfo); 20 | } 21 | 22 | public void updatePolicyInfoDto(Policy policy, PolicyVersion currentVersion) { 23 | PolicyInfoDto policyInfo = buildPolicyInfoDto(policy, currentVersion); 24 | policyInfoDtoRepository.update(policyInfo); 25 | } 26 | 27 | private PolicyInfoDto buildPolicyInfoDto(Policy policy, PolicyVersion policyVersion) { 28 | return new PolicyInfoDto( 29 | policy.getId(), 30 | policy.getNumber(), 31 | policyVersion.getCoverPeriod().getFrom(), 32 | policyVersion.getCoverPeriod().getTo(), 33 | policyVersion.getCar().getPlaceNumberWithMake(), 34 | policyVersion.getPolicyHolder().getFullName(), 35 | policyVersion.getTotalPremium().getAmount() 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/PolicyVersions.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import java.time.LocalDate; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | @RequiredArgsConstructor 11 | public class PolicyVersions { 12 | 13 | private final List versions; 14 | 15 | public Optional effectiveAtDate(LocalDate effectiveDate) { 16 | return versions.stream() 17 | .filter(v -> v.isEffectiveOn(effectiveDate) && !v.isDraft()) 18 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)); 19 | } 20 | 21 | public int maxVersionNumber() { 22 | return versions.stream() 23 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber).reversed()) 24 | .get() //TODO: ifPresent 25 | .getVersionNumber(); 26 | } 27 | 28 | public Optional withNumber(int versionNumber) { 29 | return versions.stream() 30 | .filter(v -> v.getVersionNumber() == versionNumber) 31 | .findFirst(); 32 | } 33 | 34 | public PolicyVersion latestActive() { 35 | return versions.stream() 36 | .filter(v -> PolicyVersion.PolicyVersionStatus.Active.equals(v.getVersionStatus())) 37 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)) 38 | .get(); 39 | } 40 | 41 | public PolicyVersion last() { 42 | return versions.stream() 43 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)) 44 | .get(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /cqrswithes/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/cqrswithes/testdatabuilders/PoliciesTestDataBuilder.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.testdatabuilders 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyStatus 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events.InitialPolicyVersionCreated 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events.PolicyEventsData 8 | 9 | import java.time.LocalDate 10 | import java.time.Period 11 | 12 | class PoliciesTestDataBuilder { 13 | 14 | static Policy standardOneYearPolicy(LocalDate policyStartDate) { 15 | def product = ProductsTestDataBuilder.standardCarInsurance() 16 | 17 | def events = Arrays.asList(new InitialPolicyVersionCreated( 18 | "POL01", 19 | PolicyStatus.Active, 20 | product.getCode(), 21 | policyStartDate, 22 | policyStartDate.plusDays(365), 23 | policyStartDate.minusDays(-1), 24 | new PolicyEventsData.PersonData("A", "B", "C"), 25 | new PolicyEventsData.CarData("A", "B", 2018), 26 | Arrays.asList(new PolicyEventsData.PolicyCoverData( 27 | "OC", 28 | policyStartDate, 29 | policyStartDate.plusDays(365), 30 | MonetaryAmount.from(500), 31 | MonetaryAmount.from(500), 32 | Period.ofDays(365) 33 | )) 34 | )) 35 | def policy = new Policy(UUID.randomUUID(), events) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/confirmbuyadditionalcover/ConfirmBuyAdditionalCoverHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.confirmbuyadditionalcover; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyEvents; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyRepository; 9 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.CommandHandler; 10 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.events.EventPublisher; 11 | 12 | @Component 13 | @Transactional 14 | @RequiredArgsConstructor 15 | public class ConfirmBuyAdditionalCoverHandler implements CommandHandler { 16 | 17 | private final PolicyRepository policyRepository; 18 | private final EventPublisher eventPublisher; 19 | 20 | @Override 21 | public ConfirmBuyAdditionalCoverResult handle(ConfirmBuyAdditionalCoverCommand command) { 22 | Policy policy = policyRepository.withNumber(command.getPolicyNumber()); 23 | policy.confirmChanges(command.getVersionToConfirmNumber()); 24 | 25 | eventPublisher.publish(new PolicyEvents.PolicyAnnexed(this, 26 | policy, 27 | policy.getPolicyVersions().withNumber(command.getVersionToConfirmNumber()).get()) 28 | ); 29 | 30 | return new ConfirmBuyAdditionalCoverResult( 31 | policy.getNumber(), 32 | policy.getPolicyVersions().latestActive().getVersionNumber() 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/PolicyVersions.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import java.time.LocalDate; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | @RequiredArgsConstructor 11 | public class PolicyVersions { 12 | 13 | private final List versions; 14 | 15 | public Optional effectiveAtDate(LocalDate effectiveDate) { 16 | return versions.stream() 17 | .filter(v -> v.isEffectiveOn(effectiveDate) && !v.isDraft()) 18 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)); 19 | } 20 | 21 | public int size() { 22 | return versions.size(); 23 | } 24 | 25 | public int maxVersionNumber() { 26 | return versions.stream() 27 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber).reversed()) 28 | .get() //TODO: ifPresent 29 | .getVersionNumber(); 30 | } 31 | 32 | public Optional withNumber(int versionNumber) { 33 | return versions.stream() 34 | .filter(v -> v.getVersionNumber() == versionNumber) 35 | .findFirst(); 36 | } 37 | 38 | public PolicyVersion latestActive() { 39 | return versions.stream() 40 | .filter(v -> PolicyVersionStatus.Active.equals(v.getVersionStatus())) 41 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)) 42 | .get(); 43 | } 44 | 45 | public PolicyVersion last() { 46 | return versions.stream() 47 | .max(Comparator.comparingInt(PolicyVersion::getVersionNumber)) 48 | .get(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/commands/cancellastannex/CancelLastAnnexHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.commands.cancellastannex; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyEvents; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyRepository; 9 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyVersion; 10 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.CommandHandler; 11 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.events.EventPublisher; 12 | 13 | @Component 14 | @Transactional 15 | @RequiredArgsConstructor 16 | public class CancelLastAnnexHandler implements CommandHandler { 17 | 18 | private final PolicyRepository policyRepository; 19 | private final EventPublisher eventPublisher; 20 | 21 | @Override 22 | public CancelLastAnnexResult handle(CancelLastAnnexCommand command) { 23 | Policy policy = policyRepository.withNumber(command.getPolicyNumber()); 24 | PolicyVersion lastAnnex = policy.getPolicyVersions().latestActive(); 25 | policy.cancelLastAnnex(); 26 | 27 | eventPublisher.publish( 28 | new PolicyEvents.PolicyAnnexCancelled(this, 29 | policy, 30 | lastAnnex, 31 | policy.getPolicyVersions().latestActive()) 32 | ); 33 | 34 | return new CancelLastAnnexResult( 35 | policy.getNumber(), 36 | policy.getPolicyVersions().latestActive().getVersionNumber() 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/SeparateModelsApplication.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.boot.ApplicationArguments; 5 | import org.springframework.boot.ApplicationRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.context.ApplicationContext; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories; 11 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 12 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Bus; 13 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.Registry; 14 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs.SpringBus; 15 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.init.InitDatabase; 16 | 17 | @EnableJpaRepositories("pl.altkom.asc.lab.cqrs.intro.separatemodels.db") 18 | @EnableJdbcRepositories(basePackages = "pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel") 19 | @SpringBootApplication 20 | @RequiredArgsConstructor 21 | public class SeparateModelsApplication implements ApplicationRunner { 22 | 23 | private final InitDatabase dbInitializer; 24 | 25 | public static void main(String[] args) { 26 | SpringApplication.run(SeparateModelsApplication.class, args); 27 | } 28 | 29 | @Bean 30 | public Registry registry(ApplicationContext applicationContext) { 31 | return new Registry(applicationContext); 32 | } 33 | 34 | @Bean 35 | public Bus commandBus(Registry registry) { 36 | return new SpringBus(registry); 37 | } 38 | 39 | @Override 40 | public void run(ApplicationArguments args) { 41 | dbInitializer.init(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyInfoDtoProjectionTest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.test.context.ContextConfiguration; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.SeparateModelsApplication; 9 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.asserts.PolicyAsserts; 10 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 11 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders.CarsTestDataBuilder; 12 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders.PersonsTestDataBuilder; 13 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders.PoliciesTestDataBuilder; 14 | 15 | import java.time.LocalDate; 16 | 17 | @RunWith(SpringRunner.class) 18 | @ContextConfiguration(classes = SeparateModelsApplication.class) 19 | public class PolicyInfoDtoProjectionTest { 20 | 21 | private static String policyNumber = "POL0003"; 22 | 23 | @Autowired 24 | PolicyInfoDtoRepository repository; 25 | 26 | @Test 27 | public void test_create_policyInfoDto() { 28 | //given 29 | Policy policy = PoliciesTestDataBuilder.standardOneYearPolicy(LocalDate.of(2019, 1, 1), policyNumber, PersonsTestDataBuilder.kowalski(), CarsTestDataBuilder.oldFordFocus()); 30 | PolicyInfoDtoProjection projection = new PolicyInfoDtoProjection(repository); 31 | 32 | //when 33 | projection.createPolicyInfoDto(policy); 34 | 35 | //then 36 | PolicyInfoDto byPolicyId = repository.findByPolicyId(policy.getId()).orElse(null); 37 | PolicyAsserts.assertPolicyWithPolicyInfoDto(policy, byPolicyId); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/events/TerminalPolicyVersionCreated.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyCover; 8 | 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | 13 | @Getter 14 | @AllArgsConstructor 15 | public class TerminalPolicyVersionCreated extends Event { 16 | private int versionNumber; 17 | private int baseVersionNumber; 18 | private LocalDate versionFrom; 19 | private LocalDate versionTo; 20 | private LocalDate coverFrom; 21 | private LocalDate coverTo; 22 | private List covers; 23 | 24 | public TerminalPolicyVersionCreated(int versionNumber, 25 | int baseVersionNumber, 26 | List covers, 27 | LocalDate versionFrom, 28 | LocalDate versionTo, 29 | LocalDate coverFrom, 30 | LocalDate coverTo) { 31 | this.versionNumber = versionNumber; 32 | this.baseVersionNumber = baseVersionNumber; 33 | this.versionFrom = versionFrom; 34 | this.versionTo = versionTo; 35 | this.coverFrom = coverFrom; 36 | this.coverTo = coverTo; 37 | this.covers = covers.stream() 38 | .map(PolicyEventsData.PolicyCoverData::from) 39 | .collect(Collectors.toList()); 40 | } 41 | 42 | @Override 43 | public void applyOn(Policy aggregate) { 44 | aggregate.apply(this); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/init/InitOffersBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Cover; 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Offer; 5 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.Product; 6 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.MonetaryAmount; 7 | 8 | import java.time.LocalDate; 9 | import java.time.Period; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.UUID; 13 | 14 | class InitOffersBuilder { 15 | static Offer standardOneYearOCOfferValidUntil(Product product, String number, LocalDate validityEnd) { 16 | return new Offer( 17 | UUID.randomUUID(), 18 | number, 19 | product, 20 | InitPersonsBuilder.kowalski(), 21 | InitPersonsBuilder.kowalski(), 22 | InitCarsBuilder.oldFordFocus(), 23 | Period.ofDays(365), 24 | MonetaryAmount.from(500), 25 | validityEnd.minusDays(30), 26 | createCoversPrices(product) 27 | ); 28 | } 29 | 30 | private static Map createCoversPrices(Product product) { 31 | Map coversPrices = new HashMap<>(); 32 | coversPrices.put(product.getCovers().withCode("OC").get(), MonetaryAmount.from("500")); 33 | return coversPrices; 34 | } 35 | 36 | static Offer rejectedOfferValidUntil(Product product, String number, LocalDate validityEnd) { 37 | Offer offer = standardOneYearOCOfferValidUntil(product, number, validityEnd); 38 | offer.reject(); 39 | return offer; 40 | } 41 | 42 | static Offer convertedOfferValidUntil(Product product, String number, LocalDate validityEnd) { 43 | Offer offer = standardOneYearOCOfferValidUntil(product, number, validityEnd); 44 | offer.convert(); 45 | return offer; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/PolicyCover.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.DateRange; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer.CoverPrice; 8 | 9 | import java.math.BigDecimal; 10 | import java.math.RoundingMode; 11 | import java.time.LocalDate; 12 | 13 | @Getter 14 | @NoArgsConstructor 15 | public class PolicyCover { 16 | private String coverCode; 17 | private DateRange coverPeriod; 18 | private UnitPrice price; 19 | private MonetaryAmount amount; 20 | 21 | public PolicyCover(String coverCode, 22 | DateRange coverPeriod, 23 | UnitPrice price) { 24 | this.coverCode = coverCode; 25 | this.coverPeriod = coverPeriod; 26 | this.price = price; 27 | this.amount = calculateAmount(); 28 | } 29 | 30 | public static PolicyCover forPrice(CoverPrice coverPrice, DateRange coverPeriod) { 31 | return new PolicyCover( 32 | coverPrice.getCoverCode(), 33 | coverPeriod, 34 | new UnitPrice(coverPrice.getPrice(), coverPrice.getCoverPeriod()) 35 | ); 36 | } 37 | 38 | public PolicyCover endOn(LocalDate lastDayOfCover) { 39 | return new PolicyCover( 40 | coverCode, 41 | coverPeriod.endOn(lastDayOfCover), 42 | price 43 | ); 44 | } 45 | 46 | private MonetaryAmount calculateAmount() { 47 | BigDecimal coverPeriodInDays = BigDecimal.valueOf(coverPeriod.days()); 48 | BigDecimal pricePeriodInDays = BigDecimal.valueOf(price.getPricePeriod().getDays()); 49 | BigDecimal multiplier = coverPeriodInDays.divide(pricePeriodInDays, 2, RoundingMode.HALF_UP); 50 | return price.getPrice().multiply(multiplier); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/init/InitOffersBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.init; 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Cover; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Offer; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Product; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 7 | 8 | import java.time.LocalDate; 9 | import java.time.Period; 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | import java.util.UUID; 13 | 14 | class InitOffersBuilder { 15 | static Offer standardOneYearOCOfferValidUntil(Product product, String number, LocalDate validityEnd) { 16 | return new Offer( 17 | UUID.randomUUID(), 18 | number, 19 | product, 20 | InitPersonsBuilder.kowalski(), 21 | InitPersonsBuilder.kowalski(), 22 | InitCarsBuilder.oldFordFocus(), 23 | Period.ofDays(365), 24 | MonetaryAmount.from(500), 25 | validityEnd.minusDays(30), 26 | createCoversPrices(product) 27 | ); 28 | } 29 | 30 | private static Map createCoversPrices(Product product) { 31 | Map coversPrices = new HashMap<>(); 32 | coversPrices.put(product.getCovers().withCode("OC").get(), MonetaryAmount.from("500")); 33 | return coversPrices; 34 | } 35 | 36 | static Offer rejectedOfferValidUntil(Product product, String number, LocalDate validityEnd) { 37 | Offer offer = standardOneYearOCOfferValidUntil(product, number, validityEnd); 38 | offer.reject(); 39 | return offer; 40 | } 41 | 42 | static Offer convertedOfferValidUntil(Product product, String number, LocalDate validityEnd) { 43 | Offer offer = standardOneYearOCOfferValidUntil(product, number, validityEnd); 44 | offer.convert(); 45 | return offer; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/PoliciesVersionTestDataBuilder.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.UUID; 8 | 9 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy.PolicyStatus; 10 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.DateRange; 11 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 12 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders.CoverPriceTestDataBuilder; 13 | 14 | public class PoliciesVersionTestDataBuilder { 15 | 16 | public static PolicyVersion createPolicyVersion() { 17 | List covers = new ArrayList<>(); 18 | covers.add(CoverPriceTestDataBuilder.buildCoverPrice()); 19 | return new PolicyVersion(UUID.randomUUID(), 1, 20 | PolicyStatus.Active, 21 | DateRange.between(LocalDate.of(2019,1,1), LocalDate.of(2020,1,1)), 22 | DateRange.between(LocalDate.of(2019,1,1), LocalDate.of(2020,1,1)), 23 | new Person("Piotr", "Nowak", "555555"), 24 | new Person("Wojciech","Kowalski","333333"), new Car("Ford","Focus",2005), 25 | new MonetaryAmount(new BigDecimal("14000")), 26 | covers); 27 | 28 | } 29 | 30 | public static PolicyVersion updateStatusOfPolicyVersion(PolicyVersion policyVersionOld, Policy.PolicyStatus policyStatus) { 31 | return new PolicyVersion(policyVersionOld.getId(), 32 | policyVersionOld.getVersionNumber(), 33 | policyStatus, 34 | policyVersionOld.getVersionValidityPeriod(), 35 | policyVersionOld.getCoverPeriod(), 36 | policyVersionOld.getPolicyHolder(), 37 | policyVersionOld.getDriver(), 38 | policyVersionOld.getCar(), 39 | policyVersionOld.getTotalPremium(), 40 | new ArrayList<>()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CQRS and Event Sourcing Intro for Developers 2 | 3 | We live in a world of dynamically changing technologies. New ways of architecturing our solutions, new frameworks and libraries seem to appear on almost daily basis. 4 | 5 | 6 | **But good software engineering is not about fancy frameworks and solutions aggressively promoted by their vendors.** It is not about doing something because Netflix or Google did it. It is about taking well-thought-out decisions based on facts and knowledge. That’s why it is important to be familiar basic architectural concepts like CQRS. It is one of the tools we use in our software house every day. We mentioned CQRS in the article which is part of the series about [Microservices on .NET Core](https://altkomsoftware.pl/en/blog/building-microservices-on-net-core-1/), but it was presented from technical perspective and here we want to focus on basics concepts explanation with visualisation and examples. 7 | 8 | 9 | [Check our article!](https://altkomsoftware.pl/en/blog/cqrs-event-sourcing/) 10 | 11 | ## No CQRS 12 | 13 |

14 | No CQRS 15 |

16 | 17 | ## Separate Commands and Queries 18 | 19 |

20 | Separate Commands and Queries 21 |

22 | 23 | ## Separate Models Commands and Queries 24 | 25 |

26 | Separate Models Commands and Queries 27 |

28 | 29 | ## Separate Storage Engines 30 | 31 |

32 | Separate Storage Engines 33 |

34 | 35 | ## Event Sourcing 36 | 37 |

38 | Event Sourcing 39 |

40 | -------------------------------------------------------------------------------- /nocqrs/src/test/groovy/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/PolicyTerminationSpec.groovy: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain 2 | 3 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.exceptions.BusinessException 4 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.MonetaryAmount 5 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.testdatabuilders.PoliciesTestDataBuilder 6 | import spock.lang.Specification 7 | 8 | import java.time.LocalDate 9 | 10 | class PolicyTerminationSpec extends Specification { 11 | 12 | def "can terminate policy in the middle"() { 13 | given: 14 | def policy = PoliciesTestDataBuilder.standardOneYearPolicy(LocalDate.of(2019, 1, 1)) 15 | def terminationDate = LocalDate.of(2019, 7, 1) 16 | 17 | when: 18 | policy.terminatePolicy(terminationDate) 19 | 20 | then: 21 | policy.getVersions().size() == 2 22 | 23 | def firstVersion = policy.getPolicyVersions().withNumber(1).get() 24 | firstVersion.getVersionStatus() == PolicyVersion.PolicyVersionStatus.Active 25 | firstVersion.getTotalPremium() == MonetaryAmount.from("500") 26 | 27 | def secondVersion = policy.getPolicyVersions().withNumber(2).get() 28 | secondVersion.getPolicyStatus() == Policy.PolicyStatus.Terminated 29 | secondVersion.getVersionStatus() == PolicyVersion.PolicyVersionStatus.Draft 30 | secondVersion.getVersionValidityPeriod().getFrom() == terminationDate 31 | secondVersion.getCoverPeriod().getTo() == terminationDate.minusDays(1) 32 | secondVersion.getCoverPeriod().getFrom() == LocalDate.of(2019, 1, 1) 33 | secondVersion.getTotalPremium() == MonetaryAmount.from("250") 34 | } 35 | 36 | def "cannot terminate policy after cover ends"() { 37 | given: 38 | def policy = PoliciesTestDataBuilder.standardOneYearPolicy(LocalDate.of(2019,1,1)) 39 | def terminationDate = LocalDate.of(2020, 1, 2) 40 | 41 | when: 42 | policy.terminatePolicy(terminationDate) 43 | 44 | then: 45 | def ex = thrown(BusinessException) 46 | ex.message == "No active version at given date" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/eventhandlers/PolicyEventsProjectionsHandler.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.eventhandlers; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.context.event.EventListener; 5 | import org.springframework.stereotype.Component; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyEvents; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyInfoDtoProjection; 8 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel.PolicyVersionDtoProjection; 9 | 10 | @Component 11 | @RequiredArgsConstructor 12 | public class PolicyEventsProjectionsHandler { 13 | 14 | private final PolicyInfoDtoProjection policyInfoDtoProjection; 15 | private final PolicyVersionDtoProjection policyVersionDtoProjection; 16 | 17 | @EventListener 18 | public void handlePolicyCreated(PolicyEvents.PolicyCreated event) { 19 | policyInfoDtoProjection.createPolicyInfoDto(event.getNewPolicy()); 20 | policyVersionDtoProjection.createPolicyVersionDto(event.getNewPolicy(), event.getNewPolicy().getPolicyVersions().withNumber(1).get()); 21 | } 22 | 23 | @EventListener 24 | public void handlePolicyTerminated(PolicyEvents.PolicyTerminated event) { 25 | policyInfoDtoProjection.updatePolicyInfoDto(event.getTerminatedPolicy(), event.getTerminatedVersion()); 26 | policyVersionDtoProjection.createPolicyVersionDto(event.getTerminatedPolicy(), event.getTerminatedVersion()); 27 | } 28 | 29 | @EventListener 30 | public void handlePolicyAnnexed(PolicyEvents.PolicyAnnexed event) { 31 | policyInfoDtoProjection.updatePolicyInfoDto(event.getAnnexedPolicy(), event.getAnnexVersion()); 32 | policyVersionDtoProjection.createPolicyVersionDto(event.getAnnexedPolicy(), event.getAnnexVersion()); 33 | } 34 | 35 | @EventListener 36 | public void handlePolicyAnnexCancelled(PolicyEvents.PolicyAnnexCancelled event) { 37 | policyInfoDtoProjection.updatePolicyInfoDto(event.getPolicy(), event.getCurrentVersionAfterAnnexCancellation()); 38 | policyVersionDtoProjection.updatePolicyVersionDto(event.getCancelledAnnexVersion()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyInfoDto.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import org.springframework.data.annotation.Id; 6 | import org.springframework.jdbc.core.RowMapper; 7 | 8 | import java.math.BigDecimal; 9 | import java.sql.ResultSet; 10 | import java.sql.SQLException; 11 | import java.time.LocalDate; 12 | import java.util.UUID; 13 | 14 | @Getter 15 | @NoArgsConstructor 16 | public class PolicyInfoDto { 17 | @Id 18 | private Long id; 19 | private UUID policyId; 20 | private String policyNumber; 21 | private LocalDate coverFrom; 22 | private LocalDate coverTo; 23 | private String vehicle; 24 | private String policyHolder; 25 | private BigDecimal totalPremiumAmount; 26 | 27 | PolicyInfoDto(UUID policyId, 28 | String policyNumber, 29 | LocalDate coverFrom, 30 | LocalDate coverTo, 31 | String vehicle, 32 | String policyHolder, 33 | BigDecimal totalPremiumAmount) { 34 | this.policyId = policyId; 35 | this.policyNumber = policyNumber; 36 | this.coverFrom = coverFrom; 37 | this.coverTo = coverTo; 38 | this.vehicle = vehicle; 39 | this.policyHolder = policyHolder; 40 | this.totalPremiumAmount = totalPremiumAmount; 41 | } 42 | 43 | static class PolicyInfoDtoRowMapper implements RowMapper { 44 | @Override 45 | public PolicyInfoDto mapRow(ResultSet resultSet, int i) throws SQLException { 46 | return new PolicyInfoDto( 47 | UUID.fromString(resultSet.getString("policy_id")), 48 | resultSet.getString("policy_number"), 49 | resultSet.getDate("cover_from").toLocalDate(), 50 | resultSet.getDate("cover_to").toLocalDate(), 51 | resultSet.getString("vehicle"), 52 | resultSet.getString("policy_holder"), 53 | resultSet.getBigDecimal("total_premium_amount") 54 | ); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/PolicyEvents.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.events.Event; 5 | 6 | public class PolicyEvents { 7 | 8 | @Getter 9 | public static class PolicyCreated extends Event { 10 | private Policy newPolicy; 11 | 12 | public PolicyCreated(Object source, Policy newPolicy) { 13 | super(source); 14 | this.newPolicy = newPolicy; 15 | } 16 | } 17 | 18 | @Getter 19 | public static class PolicyAnnexed extends Event { 20 | private Policy annexedPolicy; 21 | private PolicyVersion annexVersion; 22 | 23 | public PolicyAnnexed(Object source, Policy annexedPolicy, PolicyVersion annexVersion) { 24 | super(source); 25 | this.annexedPolicy = annexedPolicy; 26 | this.annexVersion = annexVersion; 27 | } 28 | } 29 | 30 | @Getter 31 | public static class PolicyTerminated extends Event { 32 | private Policy terminatedPolicy; 33 | private PolicyVersion terminatedVersion; 34 | 35 | public PolicyTerminated(Object source, Policy terminatedPolicy, PolicyVersion terminatedVersion) { 36 | super(source); 37 | this.terminatedPolicy = terminatedPolicy; 38 | this.terminatedVersion = terminatedVersion; 39 | } 40 | } 41 | 42 | @Getter 43 | public static class PolicyAnnexCancelled extends Event { 44 | private Policy policy; 45 | private PolicyVersion cancelledAnnexVersion; 46 | private PolicyVersion currentVersionAfterAnnexCancellation; 47 | 48 | public PolicyAnnexCancelled(Object source, 49 | Policy policy, 50 | PolicyVersion cancelledAnnexVersion, 51 | PolicyVersion currentVersionAfterAnnexCancellation) { 52 | super(source); 53 | this.policy = policy; 54 | this.cancelledAnnexVersion = cancelledAnnexVersion; 55 | this.currentVersionAfterAnnexCancellation = currentVersionAfterAnnexCancellation; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/domain/PolicyCover.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.domain; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.DateRange; 6 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.domain.primitives.MonetaryAmount; 7 | 8 | import javax.persistence.*; 9 | import java.math.BigDecimal; 10 | import java.math.RoundingMode; 11 | import java.time.LocalDate; 12 | import java.time.Period; 13 | import java.util.UUID; 14 | 15 | @Entity 16 | @Getter 17 | @NoArgsConstructor 18 | public class PolicyCover { 19 | @Id 20 | @GeneratedValue 21 | private UUID id; 22 | @ManyToOne(optional = false) 23 | private Cover cover; 24 | @AttributeOverrides({ 25 | @AttributeOverride(name = "from", column = @Column(name = "cover_from")), 26 | @AttributeOverride(name = "to", column = @Column(name = "cover_to")) 27 | }) 28 | private DateRange coverPeriod; 29 | @Embedded 30 | @AttributeOverrides({ 31 | @AttributeOverride(name = "amount", column = @Column(name = "price")) 32 | }) 33 | private MonetaryAmount price; 34 | private Period pricePeriod; 35 | 36 | private MonetaryAmount amount; 37 | 38 | public PolicyCover(UUID uuid, 39 | Cover cover, 40 | DateRange coverPeriod, 41 | MonetaryAmount price, 42 | Period pricePeriod) { 43 | this.id = uuid; 44 | this.cover = cover; 45 | this.coverPeriod = coverPeriod; 46 | this.price = price; 47 | this.pricePeriod = pricePeriod; 48 | this.amount = calculateAmount(); 49 | } 50 | 51 | void endCoverOn(LocalDate lastDayOfCover) { 52 | coverPeriod = coverPeriod.endOn(lastDayOfCover); 53 | amount = calculateAmount(); 54 | } 55 | 56 | private MonetaryAmount calculateAmount() { 57 | BigDecimal coverPeriodInDays = BigDecimal.valueOf(coverPeriod.days()); 58 | BigDecimal pricePeriodInDays = BigDecimal.valueOf(pricePeriod.getDays()); 59 | BigDecimal multiplier = coverPeriodInDays.divide(pricePeriodInDays, 2, RoundingMode.HALF_UP); 60 | return price.multiply(multiplier); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /separatemodels/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | pl.altkom.asc.lab.cqrs.intro 8 | separatemodels 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 2.1.3.RELEASE 15 | 16 | 17 | 18 | 19 | 11 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.data 29 | spring-data-jdbc 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-data-jpa 34 | 35 | 36 | 37 | com.h2database 38 | h2 39 | runtime 40 | 41 | 42 | org.projectlombok 43 | lombok 44 | true 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-test 51 | test 52 | 53 | 54 | 55 | 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-maven-plugin 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /separatemodels/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | drop table IF EXISTS policy_info_dto; 2 | drop table IF EXISTS policy_version_cover_dto; 3 | drop table IF EXISTS policy_version_dto; 4 | 5 | create table policy_info_dto 6 | ( 7 | id bigserial primary key, 8 | policy_id uuid not null, 9 | policy_number character varying(50) not null, 10 | cover_from date not null, 11 | cover_to date not null, 12 | vehicle character varying(150) not null, 13 | policy_holder character varying(50) not null, 14 | total_premium_amount numeric(19, 2) not null 15 | ); 16 | 17 | create table policy_version_dto 18 | ( 19 | id bigserial primary key, 20 | policy_version_id uuid not null, 21 | policy_id uuid not null, 22 | policy_number character varying(50) not null, 23 | product_code character varying(50) not null, 24 | version_number int not null, 25 | version_status character varying(50) not null, 26 | policy_status character varying(50) not null, 27 | policy_holder character varying(250) not null, 28 | insured character varying(250) not null, 29 | car character varying(250) not null, 30 | cover_from date not null, 31 | cover_to date not null, 32 | version_from date not null, 33 | version_to date not null, 34 | total_premium_amount numeric(19, 2) not null 35 | ); 36 | 37 | create table policy_version_cover_dto 38 | ( 39 | id bigserial primary key, 40 | policy_version_dto bigint not null references policy_version_dto (id), 41 | -- This column is required if we want to use List<> instead Set<> in PolicyVersionDto. Check this: https://www.youtube.com/watch?v=ccxBXDAPdmo 42 | policy_version_dto_key integer not null, 43 | code character varying(50) not null, 44 | cover_from date not null, 45 | cover_to date not null, 46 | premium_amount numeric(19, 2) not null 47 | ); -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/domain/PolicyCover.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.domain; 2 | 3 | import lombok.Getter; 4 | import lombok.NoArgsConstructor; 5 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.DateRange; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.primitives.MonetaryAmount; 7 | 8 | import javax.persistence.*; 9 | import java.math.BigDecimal; 10 | import java.math.RoundingMode; 11 | import java.time.LocalDate; 12 | import java.time.Period; 13 | import java.util.UUID; 14 | 15 | @Entity 16 | @Getter 17 | @NoArgsConstructor 18 | public class PolicyCover { 19 | @Id 20 | @GeneratedValue 21 | private UUID id; 22 | @ManyToOne(optional = false) 23 | private Cover cover; 24 | @AttributeOverrides({ 25 | @AttributeOverride(name = "from", column = @Column(name = "cover_from")), 26 | @AttributeOverride(name = "to", column = @Column(name = "cover_to")) 27 | }) 28 | private DateRange coverPeriod; 29 | @Embedded 30 | @AttributeOverrides({ 31 | @AttributeOverride(name = "amount", column = @Column(name = "price")) 32 | }) 33 | private MonetaryAmount price; 34 | private Period pricePeriod; 35 | 36 | private MonetaryAmount amount; 37 | 38 | public PolicyCover(UUID uuid, 39 | Cover cover, 40 | DateRange coverPeriod, 41 | MonetaryAmount price, 42 | Period pricePeriod) { 43 | this.id = uuid; 44 | this.cover = cover; 45 | this.coverPeriod = coverPeriod; 46 | this.price = price; 47 | this.pricePeriod = pricePeriod; 48 | this.amount = calculateAmount(); 49 | } 50 | 51 | public void endCoverOn(LocalDate lastDayOfCover) { 52 | coverPeriod = coverPeriod.endOn(lastDayOfCover); 53 | amount = calculateAmount(); 54 | } 55 | 56 | private MonetaryAmount calculateAmount() { 57 | BigDecimal coverPeriodInDays = BigDecimal.valueOf(coverPeriod.days()); 58 | BigDecimal pricePeriodInDays = BigDecimal.valueOf(pricePeriod.getDays()); 59 | BigDecimal multiplier = coverPeriodInDays.divide(pricePeriodInDays, 2, RoundingMode.HALF_UP); 60 | return price.multiply(multiplier); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /separatemodels/src/test/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyVersionDtoFinderTest.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.SeparateModelsApplication; 11 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PoliciesVersionTestDataBuilder; 12 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 13 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyVersion; 14 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.testdatabuilders.PoliciesTestDataBuilder; 15 | 16 | import java.time.LocalDate; 17 | 18 | @RunWith(SpringRunner.class) 19 | @ContextConfiguration(classes = SeparateModelsApplication.class) 20 | public class PolicyVersionDtoFinderTest { 21 | 22 | @Autowired 23 | PolicyVersionDtoRepository repository; 24 | 25 | @Autowired 26 | PolicyVersionDtoProjection policyVersionDtoProjection; 27 | 28 | private static String policyNumber = "POL0002"; 29 | 30 | @Before 31 | public void setUp() { 32 | Policy policy = PoliciesTestDataBuilder.standardOneYearPolicy(LocalDate.of(2019, 1, 1), policyNumber); 33 | PolicyVersion policyVersion = PoliciesVersionTestDataBuilder.createPolicyVersion(); 34 | policyVersionDtoProjection.createPolicyVersionDto(policy, policyVersion); 35 | } 36 | 37 | @Test 38 | public void should_return_one_policy_version_with_selected_number() { 39 | //given 40 | PolicyVersionDtoFinder versionFinder = new PolicyVersionDtoFinder(repository); 41 | 42 | //when 43 | PolicyVersionsListDto actual = versionFinder.findVersionsByPolicyNumber(policyNumber); 44 | 45 | //then 46 | Assert.assertNotNull(actual); 47 | Assert.assertEquals(policyNumber, actual.getPolicyNumber()); 48 | Assert.assertEquals(1, actual.getVersionsInfo().size()); 49 | Assert.assertEquals(LocalDate.of(2019, 1, 1), actual.getVersionsInfo().get(0).getVersionFrom()); 50 | Assert.assertEquals(LocalDate.of(2020, 1, 1), actual.getVersionsInfo().get(0).getVersionTo()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/cqs/Registry.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.core.GenericTypeResolver; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class Registry { 10 | private Map, CommandProvider> commandProviderMap = new HashMap<>(); 11 | private Map, QueryProvider> queryProviderMap = new HashMap<>(); 12 | 13 | public Registry(ApplicationContext applicationContext) { 14 | String[] names = applicationContext.getBeanNamesForType(CommandHandler.class); 15 | for (String name : names) { 16 | registerCommand(applicationContext, name); 17 | } 18 | names = applicationContext.getBeanNamesForType(QueryHandler.class); 19 | for (String name : names) { 20 | registerQuery(applicationContext, name); 21 | } 22 | } 23 | 24 | private void registerCommand(ApplicationContext applicationContext, String name ){ 25 | Class> handlerClass = (Class>) applicationContext.getType(name); 26 | Class[] generics = GenericTypeResolver.resolveTypeArguments(handlerClass, CommandHandler.class); 27 | Class commandType = (Class) generics[1]; 28 | commandProviderMap.put(commandType, new CommandProvider(applicationContext, handlerClass)); 29 | } 30 | 31 | private void registerQuery(ApplicationContext applicationContext, String name ){ 32 | Class> handlerClass = (Class>) applicationContext.getType(name); 33 | Class[] generics = GenericTypeResolver.resolveTypeArguments(handlerClass, QueryHandler.class); 34 | Class queryType = (Class) generics[1]; 35 | queryProviderMap.put(queryType, new QueryProvider(applicationContext, handlerClass)); 36 | } 37 | 38 | @SuppressWarnings("unchecked") 39 | > CommandHandler getCmd(Class commandClass) { 40 | return commandProviderMap.get(commandClass).get(); 41 | } 42 | 43 | @SuppressWarnings("unchecked") 44 | > QueryHandler getQuery(Class commandClass) { 45 | return queryProviderMap.get(commandClass).get(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/cqs/Registry.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.cqs; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.core.GenericTypeResolver; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class Registry { 10 | private Map, CommandProvider> commandProviderMap = new HashMap<>(); 11 | private Map, QueryProvider> queryProviderMap = new HashMap<>(); 12 | 13 | public Registry(ApplicationContext applicationContext) { 14 | String[] names = applicationContext.getBeanNamesForType(CommandHandler.class); 15 | for (String name : names) { 16 | registerCommand(applicationContext, name); 17 | } 18 | names = applicationContext.getBeanNamesForType(QueryHandler.class); 19 | for (String name : names) { 20 | registerQuery(applicationContext, name); 21 | } 22 | } 23 | 24 | private void registerCommand(ApplicationContext applicationContext, String name ){ 25 | Class> handlerClass = (Class>) applicationContext.getType(name); 26 | Class[] generics = GenericTypeResolver.resolveTypeArguments(handlerClass, CommandHandler.class); 27 | Class commandType = (Class) generics[1]; 28 | commandProviderMap.put(commandType, new CommandProvider(applicationContext, handlerClass)); 29 | } 30 | 31 | private void registerQuery(ApplicationContext applicationContext, String name ){ 32 | Class> handlerClass = (Class>) applicationContext.getType(name); 33 | Class[] generics = GenericTypeResolver.resolveTypeArguments(handlerClass, QueryHandler.class); 34 | Class queryType = (Class) generics[1]; 35 | queryProviderMap.put(queryType, new QueryProvider(applicationContext, handlerClass)); 36 | } 37 | 38 | @SuppressWarnings("unchecked") 39 | > CommandHandler getCmd(Class commandClass) { 40 | return commandProviderMap.get(commandClass).get(); 41 | } 42 | 43 | @SuppressWarnings("unchecked") 44 | > QueryHandler getQuery(Class commandClass) { 45 | return queryProviderMap.get(commandClass).get(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyVersionDtoRepository.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import org.springframework.data.jdbc.repository.query.Modifying; 4 | import org.springframework.data.jdbc.repository.query.Query; 5 | import org.springframework.data.repository.CrudRepository; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import java.util.List; 9 | 10 | public interface PolicyVersionDtoRepository extends CrudRepository { 11 | 12 | @Modifying 13 | @Query("UPDATE policy_version_dto " + 14 | "SET " + 15 | "version_status = :versionStatus " + 16 | "WHERE " + 17 | "policy_version_id = :policyVersionId") 18 | void update(@Param("versionStatus") String versionStatus, @Param("policyVersionId") String policyVersionId); 19 | 20 | @Query(value = "SELECT " + 21 | "id, policy_version_id, policy_id, " + 22 | "policy_number, version_number, " + 23 | "product_code, " + 24 | "version_status, policy_status, " + 25 | "policy_holder, insured, car, " + 26 | "cover_from, cover_to, version_from, version_to, " + 27 | "total_premium_amount " + 28 | "FROM policy_version_dto " + 29 | "WHERE " + 30 | "policy_number = :policyNumber " + 31 | "AND version_number = :versionNumber", 32 | rowMapperClass = PolicyVersionDto.PolicyVersionDtoRowMapper.class) 33 | PolicyVersionDto findByPolicyNumberAndVersionNumber( 34 | @Param("policyNumber") String policyNumber, 35 | @Param("versionNumber") int versionNumber); 36 | 37 | @Query("SELECT * " + 38 | "FROM policy_version_cover_dto " + 39 | "WHERE " + 40 | "policy_version_dto = :policyVersionDtoId") 41 | List getCoversInVersion(@Param("policyVersionDtoId") Long policyVersionDtoId); 42 | 43 | @Query(value = "SELECT " + 44 | "version_number, " + 45 | "version_from, " + 46 | "version_to, " + 47 | "version_status " + 48 | "FROM policy_version_dto " + 49 | "WHERE " + 50 | "policy_number = :policyNumber", 51 | rowMapperClass = PolicyVersionsListDto.PolicyVersionInfoDtoRowMapper.class) 52 | List findVersionsByPolicyNumber(@Param("policyNumber") String policyNumber); 53 | } 54 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/offer/Offer.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.offer; 2 | 3 | import lombok.Getter; 4 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Car; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.MonetaryAmount; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Person; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Cover; 8 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.product.Product; 9 | 10 | import java.time.LocalDate; 11 | import java.time.Period; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.UUID; 16 | 17 | @Getter 18 | public class Offer { 19 | private UUID id; 20 | private String number; 21 | private OfferStatus status; 22 | private String productCode; 23 | private Person customer; 24 | private Car car; 25 | private Person driver; 26 | private Period coverPeriod; 27 | private MonetaryAmount totalCost; 28 | private LocalDate creationDate; 29 | private List covers = new ArrayList<>(); 30 | 31 | private LocalDate getValidityDate() { 32 | return creationDate.plusDays(30); 33 | } 34 | 35 | public Offer( 36 | UUID id, 37 | String number, 38 | Product product, 39 | Person customer, 40 | Person driver, 41 | Car car, 42 | Period coverPeriod, 43 | MonetaryAmount totalCost, 44 | LocalDate creationDate, 45 | Map coversPrices) { 46 | this.id = id; 47 | this.number = number; 48 | this.status = OfferStatus.New; 49 | this.productCode = product.getCode(); 50 | this.customer = customer; 51 | this.driver = driver; 52 | this.car = car; 53 | this.coverPeriod = coverPeriod; 54 | this.totalCost = totalCost; 55 | this.creationDate = creationDate; 56 | coversPrices.forEach((key, value) -> covers.add(new CoverPrice(key, value, coverPeriod))); 57 | } 58 | 59 | public boolean isConverted() { 60 | return OfferStatus.Converted.equals(status); 61 | } 62 | 63 | public boolean isExpired(LocalDate theDate) { 64 | return getValidityDate().isBefore(theDate); 65 | } 66 | 67 | public boolean isRejected() { 68 | return OfferStatus.Rejected.equals(status); 69 | } 70 | 71 | public enum OfferStatus { 72 | New, Converted, Rejected 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/domain/policy/events/InitialPolicyVersionCreated.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.events; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.base.Event; 6 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Car; 7 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.DateRange; 8 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.common.Person; 9 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.Policy; 10 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyCover; 11 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.domain.policy.PolicyStatus; 12 | 13 | import java.time.LocalDate; 14 | import java.util.List; 15 | import java.util.stream.Collectors; 16 | 17 | @Getter 18 | @AllArgsConstructor 19 | public class InitialPolicyVersionCreated extends Event { 20 | private String policyNumber; 21 | private PolicyStatus policyStatus; 22 | private String productCode; 23 | private LocalDate coverFrom; 24 | private LocalDate coverTo; 25 | private LocalDate purchaseDate; 26 | private PolicyEventsData.PersonData policyHolder; 27 | private PolicyEventsData.CarData car; 28 | private List covers; 29 | 30 | public InitialPolicyVersionCreated(String policyNumber, 31 | String productCode, 32 | DateRange coverPeriod, 33 | LocalDate purchaseDate, 34 | Person policyHolder, 35 | Car car, 36 | List covers) { 37 | this.policyNumber = policyNumber; 38 | this.productCode = productCode; 39 | this.coverFrom = coverPeriod.getFrom(); 40 | this.coverTo = coverPeriod.getTo(); 41 | this.purchaseDate = purchaseDate; 42 | this.policyHolder = new PolicyEventsData.PersonData(policyHolder.getFirstName(), policyHolder.getLastName(), policyHolder.getTaxId()); 43 | this.car = new PolicyEventsData.CarData(car.getMake(), car.getPlateNumber(), car.getProductionYear()); 44 | this.covers = covers.stream() 45 | .map(PolicyEventsData.PolicyCoverData::from) 46 | .collect(Collectors.toList()); 47 | } 48 | 49 | @Override 50 | public void applyOn(Policy aggregate) { 51 | aggregate.apply(this); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /separatemodels/src/main/java/pl/altkom/asc/lab/cqrs/intro/separatemodels/readmodel/PolicyVersionDtoProjection.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.separatemodels.readmodel; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.Policy; 7 | import pl.altkom.asc.lab.cqrs.intro.separatemodels.domain.PolicyVersion; 8 | 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Component 13 | @Transactional 14 | @RequiredArgsConstructor 15 | public class PolicyVersionDtoProjection { 16 | 17 | private final PolicyVersionDtoRepository repository; 18 | 19 | public void createPolicyVersionDto(Policy policy, PolicyVersion version) { 20 | PolicyVersionDto policyVersionDto = PolicyVersionDto.builder() 21 | .policyVersionId(version.getId()) 22 | .policyId(policy.getId()) 23 | .policyNumber(policy.getNumber()) 24 | .productCode(policy.getProduct().getCode()) 25 | .versionNumber(version.getVersionNumber()) 26 | .versionStatus(version.getVersionStatus().name()) 27 | .policyStatus(version.getPolicyStatus().name()) 28 | .policyHolder(version.getPolicyHolder().getFullName()) 29 | .insured("") 30 | .car(version.getCar().getPlaceNumberWithMake()) 31 | .coverFrom(version.getCoverPeriod().getFrom()) 32 | .coverTo(version.getCoverPeriod().getTo()) 33 | .versionFrom(version.getVersionValidityPeriod().getFrom()) 34 | .versionTo(version.getVersionValidityPeriod().getTo()) 35 | .totalPremiumAmount(version.getTotalPremium().getAmount()) 36 | .covers(buildCovers(version)) 37 | .build(); 38 | 39 | repository.save(policyVersionDto); 40 | } 41 | 42 | private List buildCovers(PolicyVersion version) { 43 | return version.getCovers().stream() 44 | .map(c -> new PolicyVersionDto.PolicyVersionCoverDto( 45 | c.getCover().getCode(), 46 | c.getCoverPeriod().getFrom(), 47 | c.getCoverPeriod().getTo(), 48 | c.getAmount().getAmount() 49 | )) 50 | .collect(Collectors.toList()); 51 | } 52 | 53 | public void updatePolicyVersionDto(PolicyVersion version) { 54 | repository.update(version.getVersionStatus().toString(), version.getId().toString()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /nocqrs/src/main/java/pl/altkom/asc/lab/cqrs/intro/nocqrs/controllers/PoliciesController.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.nocqrs.controllers; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.*; 6 | import pl.altkom.asc.lab.cqrs.intro.nocqrs.services.*; 7 | 8 | import java.util.Collection; 9 | 10 | import static org.springframework.http.ResponseEntity.ok; 11 | 12 | @RestController 13 | @RequiredArgsConstructor 14 | public class PoliciesController { 15 | 16 | private final PolicyService policyService; 17 | 18 | @PostMapping 19 | public ResponseEntity createPolicy(@RequestBody CreatePolicyRequest request) { 20 | CreatePolicyResult result = policyService.createPolicy(request); 21 | return ok(result); 22 | } 23 | 24 | @PostMapping("/buyAdditionalCover") 25 | public ResponseEntity buyAdditionalCover(@RequestBody BuyAdditionalCoverRequest request) { 26 | BuyAdditionalCoverResult result = policyService.buyAdditionalCover(request); 27 | return ok(result); 28 | } 29 | 30 | @PostMapping("/confirmBuyAdditionalCover") 31 | public ResponseEntity buyAdditionalCover(@RequestBody ConfirmBuyAdditionalCoverRequest request) { 32 | ConfirmBuyAdditionalCoverResult result = policyService.confirmBuyAdditionalCover(request); 33 | return ok(result); 34 | } 35 | 36 | @PostMapping("/terminate") 37 | public ResponseEntity terminatePolicy(@RequestBody TerminatePolicyRequest request) { 38 | TerminatePolicyResult result = policyService.terminatePolicy(request); 39 | return ok(result); 40 | } 41 | 42 | @PostMapping("/confirmTermination") 43 | public ResponseEntity terminatePolicy(@RequestBody ConfirmTerminationRequest request) { 44 | ConfirmTerminationResult result = policyService.confirmTermination(request); 45 | return ok(result); 46 | } 47 | 48 | @PostMapping("/cancelLastAnnex") 49 | public ResponseEntity cancelLastAnnex(@RequestBody CancelLastAnnexRequest request) { 50 | CancelLastAnnexResult result = policyService.cancelLastAnnex(request); 51 | return ok(result); 52 | } 53 | 54 | @GetMapping("/{policyNumber}") 55 | public ResponseEntity getPolicyDetails(@PathVariable String policyNumber) { 56 | PolicyDto policyDetails = policyService.getPolicyDetails(policyNumber); 57 | return ok(policyDetails); 58 | } 59 | 60 | @GetMapping("/find") 61 | public Collection find(@RequestBody SearchPolicyRequest request) { 62 | return policyService.searchPolicies(request); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cqrswithes/src/main/java/pl/altkom/asc/lab/cqrs/intro/cqrswithes/controllers/PoliciesController.java: -------------------------------------------------------------------------------- 1 | package pl.altkom.asc.lab.cqrs.intro.cqrswithes.controllers; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.http.ResponseEntity; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | import org.springframework.web.bind.annotation.RestController; 8 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.buyadditionalcover.BuyAdditionalCoverCommand; 9 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.buyadditionalcover.BuyAdditionalCoverResult; 10 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmbuyadditionalcover.ConfirmBuyAdditionalCoverCommand; 11 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmbuyadditionalcover.ConfirmBuyAdditionalCoverResult; 12 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmtermination.ConfirmTerminationCommand; 13 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.confirmtermination.ConfirmTerminationResult; 14 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.createpolicy.CreatePolicyCommand; 15 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.createpolicy.CreatePolicyResult; 16 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.terminatepolicy.TerminatePolicyCommand; 17 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.commands.terminatepolicy.TerminatePolicyResult; 18 | import pl.altkom.asc.lab.cqrs.intro.cqrswithes.cqs.Bus; 19 | 20 | import static org.springframework.http.ResponseEntity.ok; 21 | 22 | @RestController 23 | @RequiredArgsConstructor 24 | public class PoliciesController { 25 | 26 | private final Bus bus; 27 | 28 | @PostMapping 29 | public ResponseEntity createPolicy(@RequestBody CreatePolicyCommand command) { 30 | return ok(bus.executeCommand(command)); 31 | } 32 | 33 | @PostMapping("/buyAdditionalCover") 34 | public ResponseEntity buyAdditionalCover(@RequestBody BuyAdditionalCoverCommand command) { 35 | return ok(bus.executeCommand(command)); 36 | } 37 | 38 | @PostMapping("/confirmBuyAdditionalCover") 39 | public ResponseEntity buyAdditionalCover(@RequestBody ConfirmBuyAdditionalCoverCommand command) { 40 | return ok(bus.executeCommand(command)); 41 | } 42 | 43 | @PostMapping("/terminate") 44 | public ResponseEntity terminatePolicy(@RequestBody TerminatePolicyCommand command) { 45 | return ok(bus.executeCommand(command)); 46 | } 47 | 48 | @PostMapping("/confirmTermination") 49 | public ResponseEntity terminatePolicy(@RequestBody ConfirmTerminationCommand command) { 50 | return ok(bus.executeCommand(command)); 51 | } 52 | } 53 | --------------------------------------------------------------------------------