27 Commits

Author SHA1 Message Date
Michael Schnell
c090178bbf Started conversion to jakarta namespace 2021-08-21 15:11:04 +02:00
Michael Schnell
e88922b3cd Changed badge 2020-12-20 13:54:52 +01:00
Michael Schnell
2dd2969901 Started migration to Java 11 2020-12-20 13:53:47 +01:00
Michael Schnell
074873012e Merge pull request #9 from fuinorg/dependabot/maven/aggregates/junit-junit-4.13.1
Bump junit from 4.12 to 4.13.1 in /aggregates
2020-12-20 07:41:15 +01:00
Michael Schnell
3d591d003c Merge pull request #8 from fuinorg/dependabot/maven/shared/junit-junit-4.13.1
Bump junit from 4.12 to 4.13.1 in /shared
2020-12-20 07:41:03 +01:00
dependabot[bot]
c9f21adeaf Bump junit from 4.12 to 4.13.1 in /aggregates
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 18:32:14 +00:00
dependabot[bot]
cc65808dac Bump junit from 4.12 to 4.13.1 in /shared
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 18:28:13 +00:00
Michael Schnell
64e95e8dc8 Create ES projection based on even type names. 2020-03-21 11:57:50 +01:00
Michael Schnell
b4114a97eb Create ES projection with hash based on event types. 2020-03-21 11:48:51 +01:00
Michael Schnell
7459eb3244 Switched to new iteration and Quarkus 1.2.0.Final 2020-02-02 19:57:32 +01:00
Michael Schnell
32565f7efd Use variables for log statements 2020-01-10 09:43:05 +01:00
Michael Schnell
89241fb66a Fixed transaction border 2020-01-10 09:41:56 +01:00
Michael Schnell
1abd8f7441 Merge pull request #5 from fuinorg/dependabot/maven/java-se-cdi/org.hibernate.validator-hibernate-validator-6.1.0.Final
Bump hibernate-validator from 6.0.10.Final to 6.1.0.Final in /java-se-cdi
2020-01-10 09:32:27 +01:00
Michael Schnell
a3f31864c4 Merge pull request #6 from fuinorg/dependabot/maven/shared/org.hibernate.validator-hibernate-validator-6.1.0.Final
Bump hibernate-validator from 6.0.10.Final to 6.1.0.Final in /shared
2020-01-10 09:32:16 +01:00
Michael Schnell
63ae4af2cf Merge pull request #7 from fuinorg/dependabot/maven/aggregates/org.hibernate.validator-hibernate-validator-6.1.0.Final
Bump hibernate-validator from 6.0.10.Final to 6.1.0.Final in /aggregates
2020-01-10 09:32:06 +01:00
dependabot[bot]
fbfeebc4d3 Bump hibernate-validator from 6.0.10.Final to 6.1.0.Final in /aggregates
Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.0.10.Final to 6.1.0.Final.
- [Release notes](https://github.com/hibernate/hibernate-validator/releases)
- [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt)
- [Commits](https://github.com/hibernate/hibernate-validator/compare/6.0.10.Final...6.1.0.Final)

Signed-off-by: dependabot[bot] <support@github.com>
2020-01-08 17:38:18 +00:00
dependabot[bot]
efc865109c Bump hibernate-validator from 6.0.10.Final to 6.1.0.Final in /shared
Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.0.10.Final to 6.1.0.Final.
- [Release notes](https://github.com/hibernate/hibernate-validator/releases)
- [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt)
- [Commits](https://github.com/hibernate/hibernate-validator/compare/6.0.10.Final...6.1.0.Final)

Signed-off-by: dependabot[bot] <support@github.com>
2020-01-08 17:38:13 +00:00
dependabot[bot]
f9fcb691d4 Bump hibernate-validator in /java-se-cdi
Bumps [hibernate-validator](https://github.com/hibernate/hibernate-validator) from 6.0.10.Final to 6.1.0.Final.
- [Release notes](https://github.com/hibernate/hibernate-validator/releases)
- [Changelog](https://github.com/hibernate/hibernate-validator/blob/master/changelog.txt)
- [Commits](https://github.com/hibernate/hibernate-validator/compare/6.0.10.Final...6.1.0.Final)

Signed-off-by: dependabot[bot] <support@github.com>
2020-01-08 17:35:48 +00:00
Michael Schnell
a0a12d4f0d Back to Java 8 2020-01-04 10:58:54 +01:00
Michael Schnell
854b4c5f0f Added Java version hint 2020-01-04 10:55:59 +01:00
Michael Schnell
5e9b4fe53c Merge branch 'master' of github.com:fuinorg/ddd-cqrs-4-java-example 2020-01-04 10:53:36 +01:00
Michael Schnell
048e3d066e Update README.md 2020-01-02 17:57:49 +01:00
Michael Schnell
9c6654d957 Update README.md 2020-01-02 17:56:17 +01:00
Michael Schnell
040fabcb6d Update README.md 2020-01-02 17:55:33 +01:00
Michael Schnell
45d58b8b66 Update README.md 2020-01-02 17:52:01 +01:00
Michael Schnell
1a3a05e8d1 Update README.md 2020-01-02 17:49:49 +01:00
Michael Schnell
00a245384f Update README.md 2020-01-02 17:49:23 +01:00
85 changed files with 1852 additions and 1077 deletions

View File

@@ -1,5 +1,7 @@
# ddd-cqrs-4-java-example
Example applications and microservices that use [ddd-4-java](https://github.com/fuinorg/ddd-4-java) and [cqrs-4-java](https://github.com/fuinorg/cqrs-4-java) libraries and an [EventStore](https://eventstore.org/) to store the events (Event Sourcing).
Example microservices that use [ddd-4-java](https://github.com/fuinorg/ddd-4-java) and [cqrs-4-java](https://github.com/fuinorg/cqrs-4-java) libraries and an [EventStore](https://eventstore.org/) to store the events (Event Sourcing).
[![Java Development Kit 11](https://img.shields.io/badge/JDK-11-green.svg)](https://openjdk.java.net/projects/jdk/11/)
## Background
This application shows how to implement [DDD](https://en.wikipedia.org/wiki/Domain-driven_design), [CQRS](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation) and [Event Sourcing](https://martinfowler.com/eaaDev/EventSourcing.html) without a DDD/CQRS framework. It uses just a few small libraries in addition to standard web application frameworks like [Quarkus](https://quarkus.io/) and [Spring Boot](https://spring.io/projects/spring-boot/).
@@ -15,14 +17,14 @@ Here is an overview of how such an application looks like:
## Components
- **[Shared](shared)** - Common code for all demo applications (commands, events, value objects and utilities).
- **[Aggregates](aggregates)** - DDD related code for all demo applications (aggregates, entities and business exceptions).
- **[Quarkus](quarkus)** - Two microservices (Command & Query) based on [Quarkus](https://quarkus.io/).
- **[Quarkus](quarkus)** - Two microservices (Command & Query) based on [Quarkus](https://quarkus.io/) that is the [successor of Wildfly Swarm/Thorntail](https://thorntail.io/posts/thorntail-community-announcement-on-quarkus/) and has CDI, JAX-RS and [SmallRye](https://smallrye.io/) ([Eclipse MicroProfile](http://microprofile.io/)).
- **[Spring Boot](spring-boot)** - Two microservices (Command & Query) based on [Spring Boot](https://spring.io/projects/spring-boot/).
- **[Java SE + CDI](java-se-cdi)** - Two standalone applications (Command & Query) using CDI for dependency injection.
## Getting started
### Prerequisites
#### Install everything yourself (Option 1)
#### Option 1: Install everything yourself
Make sure you have the following tools installed/configured:
* [git](https://git-scm.com/) (VCS)
* [Docker CE](https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/)
@@ -30,7 +32,7 @@ Make sure you have the following tools installed/configured:
* *OPTIONAL* [GraalVM](https://www.graalvm.org/)
* Hostname should be set in /etc/hosts (See [Find and Change Your Hostname in Ubuntu](https://helpdeskgeek.com/linux-tips/find-and-change-your-hostname-in-ubuntu/) for more information)
#### Use lubuntu-developer-vm (Option 2)
#### :star: Option 2: Use lubuntu-developer-vm :star:
The **[lubuntu-developer-vm](https://github.com/fuinorg/lubuntu-developer-vm)** has already (almost) everything installed. You only need to execute the following steps:
1. Download and install the [lubuntu-developer-vm](https://github.com/fuinorg/lubuntu-developer-vm) as described
2. OPTIONAL: Change memory of VM to 6 GB (instead of 4 GB default) if you want to create a native image with GraalVM

View File

@@ -4,20 +4,18 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuin.cqrs4j.example</groupId>
<parent>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>cqrs4j-example-aggregates</artifactId>
<version>0.1.0</version>
<name>cqrs4j-example-aggregates</name>
<description>DDD related code for all demo applications (aggregates, entities and business exceptions)</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<esc.version>0.3.1</esc.version>
</properties>
<dependencies>
<!-- Compile -->
@@ -25,37 +23,32 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
<version>0.6.9</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
<artifactId>jakarta.json</artifactId>
</dependency>
<!-- Test -->
@@ -63,79 +56,123 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.8.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>2.4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
<exclusion>
<artifactId>jaxb-api</artifactId>
<groupId>javax.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<repositories>
<build>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
<plugins>
</repositories>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>**/*</include>
</includes>
<archive>
<manifestEntries>
<Automatic-Module-Name>org.fuin.cqrs4j.example.shared</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
<versionRange>[3.1.2,)</versionRange>
<goals>
<goal>jdkinternals</goal>
<goal>test-jdkinternals</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -12,7 +12,7 @@
*/
package org.fuin.cqrs4j.example.aggregates;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonId;
import org.fuin.cqrs4j.example.shared.PersonName;

View File

@@ -15,7 +15,7 @@ package org.fuin.cqrs4j.example.aggregates;
import java.io.Serializable;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;
import org.fuin.cqrs4j.example.shared.PersonId;

View File

@@ -12,8 +12,8 @@
*/
package org.fuin.cqrs4j.example.aggregates;
import javax.annotation.concurrent.NotThreadSafe;
import javax.validation.constraints.NotNull;
import org.fuin.objects4j.common.NotThreadSafe;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonId;
import org.fuin.ddd4j.ddd.EntityType;

View File

@@ -4,7 +4,7 @@ Minimal standalone example application that uses the [ddd-4-java](https://github
## Starting the demo
1. Start an EventStore locally on your PC
* You can use the [EventStore Docker Image](https://hub.docker.com/r/eventstore/eventstore/): ```docker run --name eventstore-node -p 2113:2113 -p 1113:1113 --rm eventstore/eventstore:release-4.1.3```
* You can use the [EventStore Docker Image](https://hub.docker.com/r/eventstore/eventstore/): ```docker run --name eventstore-node -p 2113:2113 -p 1113:1113 --rm eventstore/eventstore:release-5.0.9```
* Or simply start an instance (See [Install and run Event Store](https://eventstore.org/docs/server/index.html?tabs=tabid-1) for more information)
2. Run the [QryExampleApp](src/main/java/org/fuin/cqrs4j/example/javasecdi/qry/app/QryExampleApp.java) to make the view/read part listen to new events
* You should see something like this on the console: ```INFO o.f.d.qry.handler.QryProjector - Create projection 'qry-person-stream' with events: [PersonCreatedEvent]```
@@ -12,7 +12,8 @@ Minimal standalone example application that uses the [ddd-4-java](https://github
3. Run the [CmdExampleApp](src/main/java/org/fuin/cqrs4j/example/javasecdi/cmd/app/CmdExampleApp.java) to create a [PersonCreatedEvent](src/main/java/org/fuin/cqrs4j/example/javasecdi/shared/domain/PersonCreatedEvent.java)
* You should see something like this on the console: ```INFO o.f.d.cmd.app.CmdExampleApp - Updated event store...```
* There should also be an update on the 'QryExampleApp' console: ```INFO o.f.d.q.h.PersonCreatedEventHandler - Handle Person 'Peter Parker Inc.' was created```
* If you open the [Event Store UI](http://localhost:2113/web/index.html#/projections) (User 'admin' / Password 'changeit') and open the projection details for 'qry-person-stream' it should show 'Events processed = 1'
* If you open the [Event Store UI](http://localhost:2113/web/index.html#/projections) (User 'admin' / Password 'changeit') and open the projection details for 'qry-person-stream' it should show 'Events processed = 1'
* Look at the person's aggregate event stream: ```http://localhost:2113/web/index.html#/streams/PERSON-00000000-0000-0000-0000-000000000000`` - Replace the zero UUID with the one shown in the event handler message 'Person 'Peter Parker Inc.' (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) was created'
4. Kill the [QryExampleApp](src/main/java/org/fuin/cqrs4j/example/javasecdi/qry/app/QryExampleApp.java)
5. Stop the event store

View File

@@ -5,15 +5,15 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fuin</groupId>
<artifactId>pom</artifactId>
<version>1.6.0</version>
</parent>
<parent>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.fuin.cqrs4j.example.javasecdi</groupId>
<artifactId>cqrs4j-javasecdi-example</artifactId>
<version>0.1.0</version>
<description>Minimal standalone example application that uses the 'ddd-4-java' and 'ddd-cqrs-4-java-example' libraries</description>
<scm>
@@ -28,10 +28,7 @@
</issueManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<esc.version>0.3.1</esc.version>
<esc.version>0.4.0</esc.version>
</properties>
<dependencyManagement>
@@ -41,7 +38,7 @@
<dependency>
<groupId>org.apache.deltaspike.distribution</groupId>
<artifactId>distributions-bom</artifactId>
<version>1.9.0</version>
<version>1.9.4</version>
<scope>import</scope>
<type>pom</type>
</dependency>
@@ -57,122 +54,104 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ext4logback</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
<optional>true</optional>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>3.0.4.Final</version>
<version>4.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.config</groupId>
<artifactId>microprofile-config-api</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-config</artifactId>
<version>1.3.5</version>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1.4</version>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
<artifactId>jakarta.json</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
@@ -188,41 +167,26 @@
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
<exclusion>
<artifactId>jaxb-api</artifactId>
<groupId>javax.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2</version>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.2.Final</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.4.1</version>
</dependency>
<!-- Test -->
@@ -230,7 +194,6 @@
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-mem</artifactId>
<version>${esc.version}</version>
<scope>test</scope>
</dependency>
@@ -243,32 +206,144 @@
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.8.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>2.4.6</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<build>
<plugins>
<pluginManagement>
</plugins>
<plugins>
</build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<multiRelease>base</multiRelease>
<failOnWarning>true</failOnWarning>
</configuration>
<executions>
<execution>
<goals>
<goal>jdkinternals</goal>
<goal>test-jdkinternals</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<includes>
<include>**/*</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce-java-and-maven-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>${java.version}</version>
<message>Java 11 or later is required!</message>
</requireJavaVersion>
<requireMavenVersion>
<version>3.6.0</version>
<message>Please use at least Maven 3.6.0 as older versions may cause problems with Java 11+</message>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@@ -14,11 +14,11 @@ package org.fuin.cqrs4j.example.javasecdi.cmd.app;
import java.util.UUID;
import javax.enterprise.context.control.ActivateRequestContext;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import javax.inject.Inject;
import jakarta.enterprise.context.control.ActivateRequestContext;
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import jakarta.inject.Inject;
import org.fuin.cqrs4j.example.javasecdi.cmd.domain.Person;
import org.fuin.cqrs4j.example.javasecdi.cmd.domain.PersonRepository;

View File

@@ -1,6 +1,6 @@
package org.fuin.cqrs4j.example.javasecdi.cmd.domain;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonId;
import org.fuin.cqrs4j.example.shared.PersonName;

View File

@@ -2,7 +2,7 @@ package org.fuin.cqrs4j.example.javasecdi.cmd.domain;
import java.io.Serializable;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;
import org.fuin.cqrs4j.example.shared.PersonId;

View File

@@ -1,7 +1,7 @@
package org.fuin.cqrs4j.example.javasecdi.cmd.domain;
import javax.annotation.concurrent.NotThreadSafe;
import javax.validation.constraints.NotNull;
import org.fuin.objects4j.common.NotThreadSafe;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonId;
import org.fuin.ddd4j.ddd.EntityType;

View File

@@ -1,8 +1,8 @@
package org.fuin.cqrs4j.example.javasecdi.cmd.domain;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.inject.Produces;
import org.fuin.esc.api.EventStore;

View File

@@ -1,11 +1,11 @@
package org.fuin.cqrs4j.example.javasecdi.qry.app;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import org.apache.deltaspike.jpa.api.transaction.TransactionScoped;

View File

@@ -17,8 +17,8 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;
import jakarta.enterprise.inject.se.SeContainer;
import jakarta.enterprise.inject.se.SeContainerInitializer;
import javax.inject.Inject;
import org.fuin.ext4logback.LogbackStandalone;

View File

@@ -4,10 +4,10 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ThreadFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@@ -40,8 +40,10 @@ public class QryProjectionAdminEventStoreFactory {
config.getEventStorePassword());
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
final SimpleSerializerDeserializerRegistry registry = new SimpleSerializerDeserializerRegistry();
final ProjectionAdminEventStore es = new ESHttpEventStore(threadFactory, new URL(url), ESEnvelopeType.JSON, registry, registry,
credentialsProvider);
final ProjectionAdminEventStore es = new ESHttpEventStore.Builder().threadFactory(threadFactory).url(new URL(url))
.envelopeType(ESEnvelopeType.JSON).serDesRegistry(registry).credentialsProvider(credentialsProvider).build();
es.open();
return es;
} catch (final MalformedURLException ex) {

View File

@@ -4,8 +4,8 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
/**
* CDI producer that creates an {@link ScheduledExecutorService}.

View File

@@ -3,8 +3,8 @@ package org.fuin.cqrs4j.example.javasecdi.qry.app;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
/**
* Creates an thread factory.

View File

@@ -1,7 +1,7 @@
package org.fuin.cqrs4j.example.javasecdi.qry.app;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Event;
import javax.inject.Inject;
@ApplicationScoped

View File

@@ -1,10 +1,10 @@
package org.fuin.cqrs4j.example.javasecdi.qry.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

View File

@@ -1,6 +1,6 @@
package org.fuin.cqrs4j.example.javasecdi.qry.handler;
import javax.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.apache.deltaspike.jpa.api.transaction.Transactional;

View File

@@ -1,6 +1,6 @@
package org.fuin.cqrs4j.example.javasecdi.qry.handler;
import javax.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.apache.deltaspike.jpa.api.transaction.Transactional;

View File

@@ -1,7 +1,7 @@
package org.fuin.cqrs4j.example.javasecdi.qry.handler;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import org.fuin.cqrs4j.EventDispatcher;
import org.fuin.cqrs4j.SimpleEventDispatcher;

View File

@@ -1,10 +1,10 @@
package org.fuin.cqrs4j.example.javasecdi.qry.handler;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import org.fuin.esc.api.SimpleStreamId;
import org.fuin.esc.api.StreamId;

View File

@@ -1,6 +1,6 @@
package org.fuin.cqrs4j.example.javasecdi.qry.handler;
import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.NotNull;
import org.apache.deltaspike.data.api.AbstractEntityRepository;
import org.apache.deltaspike.data.api.Repository;

View File

@@ -8,7 +8,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.Semaphore;
import javax.enterprise.event.ObservesAsync;
import jakarta.enterprise.event.ObservesAsync;
import javax.inject.Inject;
import org.fuin.cqrs4j.EventDispatcher;

View File

@@ -12,7 +12,7 @@
*/
package org.fuin.cqrs4j.example.javasecdi.shared.app;
import javax.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;

View File

@@ -14,8 +14,8 @@ package org.fuin.cqrs4j.example.javasecdi.shared.app;
import java.util.concurrent.Executors;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import com.github.msemys.esjc.EventStore;
import com.github.msemys.esjc.EventStoreBuilder;

View File

@@ -2,10 +2,10 @@ package org.fuin.cqrs4j.example.javasecdi.shared.app;
import java.nio.charset.Charset;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;
import org.fuin.esc.api.EventStore;
import org.fuin.esc.esjc.ESJCEventStore;
@@ -21,20 +21,22 @@ public class SharedEventStoreFactory {
/**
* Creates an event store.<br>
* <br>
* CAUTION: The returned event store instance is NOT thread safe.
* CAUTION: The returned event store instance is NOT thread safe.
*
* @param es Native event store API.
* @param registry Serialization registry.
* @param es
* Native event store API.
* @param registry
* Serialization registry.
*
* @return Dependent scope event store.
*/
*/
@Produces
@RequestScoped
public EventStore createEventStore(final com.github.msemys.esjc.EventStore es,
final SerDeserializerRegistry registry) {
public EventStore createEventStore(final com.github.msemys.esjc.EventStore es, final SerDeserializerRegistry registry) {
final EventStore eventstore = new ESJCEventStore.Builder().eventStore(es).serDesRegistry(registry)
.targetContentType(EnhancedMimeType.create("application", "json", Charset.forName("utf-8"))).build();
final EventStore eventstore = new ESJCEventStore(es, registry, registry,
EnhancedMimeType.create("application", "json", Charset.forName("utf-8")));
eventstore.open();
return eventstore;
@@ -43,7 +45,8 @@ public class SharedEventStoreFactory {
/**
* Closes the event store when the context is disposed.
*
* @param es Event store to close.
* @param es
* Event store to close.
*/
public void closeEventStore(@Disposes final EventStore es) {
es.close();

View File

@@ -15,8 +15,8 @@ package org.fuin.cqrs4j.example.javasecdi.shared.app;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
/**
* Creates an executor service.

View File

@@ -1,7 +1,7 @@
package org.fuin.cqrs4j.example.javasecdi.shared.app;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import org.fuin.esc.spi.JsonbDeSerializer;
import org.fuin.esc.spi.SerDeserializerRegistry;

View File

@@ -19,8 +19,6 @@ package org.fuin.cqrs4j.example.javasecdi.shared.app;
import java.nio.charset.Charset;
import javax.json.bind.adapter.JsonbAdapter;
import org.eclipse.yasson.FieldAccessStrategy;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;
import org.fuin.cqrs4j.example.shared.PersonId;
@@ -39,6 +37,8 @@ import org.fuin.esc.spi.SerializedDataTypeRegistry;
import org.fuin.esc.spi.SimpleSerializedDataTypeRegistry;
import org.fuin.esc.spi.SimpleSerializerDeserializerRegistry;
import jakarta.json.bind.adapter.JsonbAdapter;
/**
* Utility code shared between command (write) and query (read) module.

378
pom.xml
View File

@@ -1,20 +1,370 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-root</artifactId>
<version>0.1.0</version>
<packaging>pom</packaging>
<properties>
<java.version>11</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.parameters>true</maven.compiler.parameters>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<esc.version>0.5.0-SNAPSHOT</esc.version>
</properties>
<modules>
<module>shared</module>
<module>aggregates</module>
<module>java-se-cdi</module>
<module>quarkus</module>
<module>spring-boot</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
<version>0.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-api</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-mem</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ext4logback</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.json.bind</groupId>
<artifactId>jakarta.json.bind-api</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.config</groupId>
<artifactId>microprofile-config-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.4.26.Final</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.20.2</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>1.6.4</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<multiRelease>base</multiRelease>
<failOnWarning>true</failOnWarning>
</configuration>
<executions>
<execution>
<goals>
<goal>jdkinternals</goal>
<goal>test-jdkinternals</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<includes>
<include>**/*</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.34.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce-java-and-maven-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>${java.version}</version>
<message>Java 11 or later is required!</message>
</requireJavaVersion>
<requireMavenVersion>
<version>3.6.0</version>
<message>Please use at least Maven 3.6.0 as older versions may cause problems with Java 11+</message>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<modules>
<module>shared</module>
<module>aggregates</module>
<module>java-se-cdi</module>
<module>quarkus</module>
<module>spring-boot</module>
</modules>
</project>

View File

@@ -6,34 +6,14 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<parent>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>cqrs4j-quarkus-example-command</artifactId>
<version>0.1.0</version>
<properties>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<esc.version>0.3.1</esc.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-universe-bom</artifactId>
<version>1.0.1.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
@@ -77,37 +57,28 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-aggregates</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
<groupId>jakarta.mail</groupId>
<artifactId>jakarta.mail-api</artifactId>
</dependency>
<!-- test -->
@@ -133,7 +104,6 @@
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>1.0.1.Final</version>
<executions>
<execution>
<goals>
@@ -144,13 +114,13 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
@@ -159,8 +129,8 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<executions>
<execution>
<goals>
@@ -179,12 +149,11 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.31.0</version>
<configuration>
<images>
<image>
<name>eventstore/eventstore:release-4.1.3</name>
<name>eventstore/eventstore:release-${eventstore.version}</name>
<run>
<network>
<mode>bridge</mode>
@@ -241,21 +210,4 @@
</profile>
</profiles>
<repositories>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@@ -16,9 +16,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.fuin.objects4j.common.Nullable;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

View File

@@ -16,9 +16,9 @@ import java.util.Optional;
import java.util.Set;
import javax.inject.Inject;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;

View File

@@ -12,9 +12,9 @@
*/
package org.fuin.cqrs4j.example.quarkus.command.domain;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.inject.Produces;
import org.fuin.cqrs4j.example.aggregates.PersonRepository;
import org.fuin.esc.esjc.IESJCEventStore;

View File

@@ -12,7 +12,7 @@ import java.util.List;
import java.util.UUID;
import javax.inject.Inject;
import javax.json.bind.Jsonb;
import jakarta.json.bind.Jsonb;
import org.fuin.cqrs4j.ResultType;
import org.fuin.cqrs4j.SimpleResult;

View File

@@ -4,11 +4,50 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-root</artifactId>
<version>0.1.0</version>
<packaging>pom</packaging>
<properties>
<quarkus.version>2.1.3.Final</quarkus.version>
<eventstore.version>5.0.9</eventstore.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-universe-bom</artifactId>
<version>${quarkus.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>3.1.5.SP1</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>shared</module>
<module>query</module>

View File

@@ -16,6 +16,36 @@ Make sure you installed everything as described [here](../../../../).
## Overview
![Overview](https://raw.github.com/fuinorg/ddd-cqrs-4-java-example/master/quarkus/query/doc/cdi-view.png)
## Running test in IDE
In case you want to run the integration test inside your IDE (Eclipse or other), you need to start the Eventstore and MariaDB before.
1. Start the Eventstore Docker container:
```
docker run -d --name eventstore-node \
-p 2113:2113 \
-p 1113:1113 \
--rm \
eventstore/eventstore:release-5.0.9
```
2. Start the MariaDB Docker container:
```
docker run -d --name mariadb \
-p 3306:3306 \
-e MYSQL_INITDB_SKIP_TZINFO=1 \
-e MYSQL_ROOT_PASSWORD=xyz \
-e MYSQL_DATABASE=querydb \
-e MYSQL_USER=mary \
-e MYSQL_PASSWORD=abc \
--rm \
mariadb:10.4
```
3. Run the test: [QryPersonResourceIT.java](src/test/java/org/fuin/cqrs4j/example/quarkus/query/api/QryPersonResourceIT.java)
4. Run `docker ps` to see the CONTAINER IDs and stop the Eventstore and MariaDB with `docker stop <CONTAINER_ID>`
# TODO ... (Does currently not work)

View File

@@ -1,282 +1,235 @@
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-query</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<esc.version>0.3.1</esc.version>
</properties>
<artifactId>cqrs4j-quarkus-example-query</artifactId>
<dependencyManagement>
<dependencies>
<dependencies>
<!-- compile -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-universe-bom</artifactId>
<version>1.0.1.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
</dependencyManagement>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
<!-- compile -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mariadb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
<dependency>
<groupId>jakarta.security.jacc</groupId>
<artifactId>jakarta.security.jacc-api</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-aggregates</artifactId>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-scheduler</artifactId>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-shared</artifactId>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
</dependency>
<!-- <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency> -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-mariadb</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>jakarta.security.jacc</groupId>
<artifactId>jakarta.security.jacc-api</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-aggregates</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-shared</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- test -->
<build>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<plugins>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
<scope>test</scope>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</dependencies>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>1.0.1.Final</version>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<images>
<image>
<name>eventstore/eventstore:release-${eventstore.version}</name>
<run>
<network>
<mode>bridge</mode>
</network>
<ports>
<port>1113:1113</port>
<port>2113:2113</port>
</ports>
<log>
<enabled>false</enabled>
</log>
<wait>
<http>
<url>http://localhost:2113/web/index.html#/</url>
<method>GET</method>
</http>
<time>20000</time>
</wait>
</run>
</image>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<image>
<name>mariadb:10.4</name>
<run>
<network>
<mode>bridge</mode>
</network>
<ports>
<port>3306:3306</port>
</ports>
<log>
<enabled>false</enabled>
</log>
<env>
<MYSQL_INITDB_SKIP_TZINFO>1</MYSQL_INITDB_SKIP_TZINFO>
<MYSQL_ROOT_PASSWORD>xyz</MYSQL_ROOT_PASSWORD>
<MYSQL_DATABASE>querydb</MYSQL_DATABASE>
<MYSQL_USER>mary</MYSQL_USER>
<MYSQL_PASSWORD>abc</MYSQL_PASSWORD>
</env>
<wait>
<time>10000</time>
</wait>
</run>
</image>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</plugin>
</images>
</configuration>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemProperties>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
<executions>
<execution>
<id>start-images</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-images</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.31.0</version>
<configuration>
</plugin>
<images>
<image>
<name>eventstore/eventstore:release-4.1.3</name>
<run>
<network>
<mode>bridge</mode>
</network>
<ports>
<port>1113:1113</port>
<port>2113:2113</port>
</ports>
<log>
<enabled>false</enabled>
</log>
<wait>
<http>
<url>http://localhost:2113/web/index.html#/</url>
<method>GET</method>
</http>
<time>20000</time>
</wait>
</run>
</image>
</plugins>
<image>
<name>mariadb:10.4</name>
<run>
<network>
<mode>bridge</mode>
</network>
<ports>
<port>3306:3306</port>
</ports>
<log>
<enabled>false</enabled>
</log>
<env>
<MYSQL_INITDB_SKIP_TZINFO>1</MYSQL_INITDB_SKIP_TZINFO>
<MYSQL_ROOT_PASSWORD>xyz</MYSQL_ROOT_PASSWORD>
<MYSQL_DATABASE>querydb</MYSQL_DATABASE>
<MYSQL_USER>mary</MYSQL_USER>
<MYSQL_PASSWORD>abc</MYSQL_PASSWORD>
</env>
<wait>
<time>10000</time>
</wait>
</run>
</image>
</build>
</images>
</configuration>
<executions>
<execution>
<id>start-images</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-images</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
<repositories>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<profiles>
<profile>
<id>native</id>
<properties>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>

View File

@@ -15,7 +15,7 @@ package org.fuin.cqrs4j.example.quarkus.query.api;
import java.util.List;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

View File

@@ -12,8 +12,8 @@
*/
package org.fuin.cqrs4j.example.quarkus.query.app;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Event;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Event;
import javax.inject.Inject;
import io.quarkus.scheduler.Scheduled;

View File

@@ -12,11 +12,11 @@
*/
package org.fuin.cqrs4j.example.quarkus.query.views.common;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import org.fuin.esc.api.SimpleStreamId;
import org.fuin.esc.api.StreamId;

View File

@@ -12,10 +12,10 @@
*/
package org.fuin.cqrs4j.example.quarkus.query.views.common;
import javax.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.validation.constraints.NotNull;
import jakarta.persistence.EntityManager;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.ProjectionService;
import org.fuin.esc.api.StreamId;

View File

@@ -12,10 +12,9 @@
*/
package org.fuin.cqrs4j.example.quarkus.query.views.personlist;
import javax.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import jakarta.persistence.EntityManager;
import org.fuin.cqrs4j.EventHandler;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;
@@ -41,9 +40,8 @@ public class PersonCreatedEventHandler implements EventHandler<PersonCreatedEven
}
@Override
@Transactional
public void handle(final PersonCreatedEvent event) {
LOG.info("Handle " + event.getClass().getSimpleName() + ": " + event);
LOG.info("Handle {}: {}", event.getClass().getSimpleName() , event);
final PersonId personId = event.getEntityId();
if (em.find(PersonListEntry.class, personId.asString()) == null) {
em.persist(new PersonListEntry(personId, event.getName()));

View File

@@ -12,12 +12,12 @@
*/
package org.fuin.cqrs4j.example.quarkus.query.views.personlist;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

View File

@@ -12,12 +12,15 @@
*/
package org.fuin.cqrs4j.example.quarkus.query.views.personlist;
import javax.enterprise.context.ApplicationScoped;
import java.util.Set;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import org.fuin.cqrs4j.EventDispatcher;
import org.fuin.cqrs4j.ProjectionService;
import org.fuin.cqrs4j.example.shared.SharedUtils;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.api.ProjectionStreamId;
import org.fuin.esc.api.StreamEventsSlice;
import org.slf4j.Logger;
@@ -28,23 +31,36 @@ import org.slf4j.LoggerFactory;
public class PersonListEventChunkHandler {
private static final Logger LOG = LoggerFactory.getLogger(PersonListEventChunkHandler.class);
/** Unique name of the event store projection that is used. */
public static final ProjectionStreamId PROJECTION_STREAM_ID = new ProjectionStreamId("quarkus-qry-person-stream");
@Inject
EventDispatcher dispatcher;
PersonListEventDispatcher dispatcher;
@Inject
ProjectionService projectionService;
private ProjectionStreamId streamId;
/**
* Returns the name of the event store projection that is used by this handler.
*
* @return Unique projection stream name.
*/
public ProjectionStreamId getProjectionStreamId() {
if (streamId == null) {
final Set<EventType> eventTypes = dispatcher.getAllTypes();
final String name = "quarkus-qry-person-" + SharedUtils.calculateChecksum(eventTypes);
streamId = new ProjectionStreamId(name);
}
return streamId;
}
/**
* Returns the next event position to read.
*
* @return Number of the next event to read.
*/
public Long readNextEventNumber() {
return projectionService.readProjectionPosition(PROJECTION_STREAM_ID);
return projectionService.readProjectionPosition(getProjectionStreamId());
}
/**
@@ -53,10 +69,11 @@ public class PersonListEventChunkHandler {
* @param currentSlice
* Slice with events to dispatch.
*/
@Transactional
public void handleChunk(final StreamEventsSlice currentSlice) {
LOG.debug("Handle chunk: {}", currentSlice);
dispatcher.dispatchCommonEvents(currentSlice.getEvents());
projectionService.updateProjectionPosition(PROJECTION_STREAM_ID, currentSlice.getNextEventNumber());
projectionService.updateProjectionPosition(getProjectionStreamId(), currentSlice.getNextEventNumber());
}
}

View File

@@ -0,0 +1,67 @@
/**
* Copyright (C) 2015 Michael Schnell. All rights reserved. http://www.fuin.org/
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library. If not, see
* http://www.gnu.org/licenses/.
*/
package org.fuin.cqrs4j.example.quarkus.query.views.personlist;
import java.util.List;
import java.util.Set;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.EventDispatcher;
import org.fuin.cqrs4j.SimpleEventDispatcher;
import org.fuin.ddd4j.ddd.Event;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.api.CommonEvent;
/**
* Dispatches events for the person list view.
*/
@ApplicationScoped
public class PersonListEventDispatcher implements EventDispatcher {
private final SimpleEventDispatcher delegate;
/**
* Constructor with all events to be dispatched.
*
* @param createdHandler
* PersonCreatedEventHandler.
*/
public PersonListEventDispatcher(final PersonCreatedEventHandler createdHandler) {
super();
this.delegate = new SimpleEventDispatcher(createdHandler);
}
@Override
@NotNull
public Set<EventType> getAllTypes() {
return delegate.getAllTypes();
}
@Override
public void dispatchCommonEvents(@NotNull final List<CommonEvent> commonEvents) {
delegate.dispatchCommonEvents(commonEvents);
}
@Override
public void dispatchEvents(@NotNull final List<Event> events) {
delegate.dispatchEvents(events);
}
@Override
public void dispatchEvent(@NotNull final Event event) {
delegate.dispatchEvent(event);
}
}

View File

@@ -1,33 +0,0 @@
/**
* Copyright (C) 2015 Michael Schnell. All rights reserved. http://www.fuin.org/
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library. If not, see
* http://www.gnu.org/licenses/.
*/
package org.fuin.cqrs4j.example.quarkus.query.views.personlist;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import org.fuin.cqrs4j.EventDispatcher;
import org.fuin.cqrs4j.SimpleEventDispatcher;
/**
* Create an {@link EventDispatcher}.
*/
@ApplicationScoped
public class PersonListEventDispatcherFactory {
@Produces
@ApplicationScoped
public EventDispatcher createDispatcher(final PersonCreatedEventHandler createdHandler) {
return new SimpleEventDispatcher(createdHandler);
}
}

View File

@@ -13,18 +13,16 @@
package org.fuin.cqrs4j.example.quarkus.query.views.personlist;
import static org.fuin.cqrs4j.Cqrs4JUtils.tryLocked;
import static org.fuin.cqrs4j.example.quarkus.query.views.personlist.PersonListEventChunkHandler.PROJECTION_STREAM_ID;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Semaphore;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.ObservesAsync;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.ObservesAsync;
import javax.inject.Inject;
import org.fuin.cqrs4j.EventDispatcher;
import org.fuin.cqrs4j.example.quarkus.query.app.QryCheckForViewUpdatesEvent;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.api.TypeName;
@@ -53,7 +51,7 @@ public class PersonListProjector {
PersonListEventChunkHandler chunkHandler;
@Inject
EventDispatcher dispatcher;
PersonListEventDispatcher dispatcher;
/**
* Listens for timer events. If a second timer event occurs while the previous call is still being executed, the method will simply be
@@ -74,24 +72,33 @@ public class PersonListProjector {
private void readStreamEvents() {
// TODO Make sure a projection with the correct events exists
// We must update the projection if new events are defined or some are removed!
if (!eventstore.projectionExists(PROJECTION_STREAM_ID)) {
final Set<EventType> eventTypes = dispatcher.getAllTypes();
final List<TypeName> typeNames = new ArrayList<>();
for (final EventType eventType : eventTypes) {
typeNames.add(new TypeName(eventType.asBaseType()));
}
LOG.info("Create projection '{}' with events: {}", PROJECTION_STREAM_ID, typeNames);
eventstore.createProjection(PROJECTION_STREAM_ID, true, typeNames);
// Create an event store projection if it does not exist.
if (!eventstore.projectionExists(chunkHandler.getProjectionStreamId())) {
final List<TypeName> typeNames = getEventTypeNames();
LOG.info("Create projection '{}' with events: {}", chunkHandler.getProjectionStreamId(), typeNames);
eventstore.createProjection(chunkHandler.getProjectionStreamId(), true, typeNames);
}
// Read and dispatch events
final Long nextEventNumber = chunkHandler.readNextEventNumber();
eventstore.readAllEventsForward(PROJECTION_STREAM_ID, nextEventNumber, 100, (currentSlice) -> {
eventstore.readAllEventsForward(chunkHandler.getProjectionStreamId(), nextEventNumber, 100, (currentSlice) -> {
chunkHandler.handleChunk(currentSlice);
});
}
/**
* Returns a list of all event type names used for this projection.
*
* @return List of event names.
*/
public List<TypeName> getEventTypeNames() {
final List<TypeName> typeNames = new ArrayList<>();
final Set<EventType> eventTypes = dispatcher.getAllTypes();
for (final EventType eventType : eventTypes) {
typeNames.add(new TypeName(eventType.asBaseType()));
}
return typeNames;
}
}

View File

@@ -1,14 +1,9 @@
# Configuration file
#quarkus.datasource.url=jdbc:postgresql://localhost:5432/querydb
#quarkus.datasource.driver=org.postgresql.Driver
#quarkus.datasource.username=postgres
#quarkus.datasource.password=abc
quarkus.datasource.url=jdbc:mariadb://localhost:3306/querydb
quarkus.datasource.driver=org.mariadb.jdbc.Driver
quarkus.datasource.db-kind=mariadb
quarkus.datasource.username=mary
quarkus.datasource.password=abc
quarkus.datasource.jdbc.url=jdbc:mariadb://localhost:3306/querydb
quarkus.hibernate-orm.database.generation=drop-and-create

View File

@@ -12,9 +12,9 @@ import static org.hamcrest.Matchers.not;
import java.util.Arrays;
import java.util.UUID;
import javax.enterprise.context.control.ActivateRequestContext;
import jakarta.enterprise.context.control.ActivateRequestContext;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import org.fuin.cqrs4j.example.quarkus.query.views.personlist.PersonListEntry;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;

View File

@@ -4,36 +4,17 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<parent>
<groupId>org.fuin.cqrs4j.example.quarkus</groupId>
<artifactId>cqrs4j-quarkus-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>cqrs4j-quarkus-example-shared</artifactId>
<version>0.1.0</version>
<name>cqrs4j-quarkus-example-shared</name>
<description>Quarkus CQRS Shared Code for Demo Application</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<esc.version>0.3.1</esc.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-universe-bom</artifactId>
<version>1.0.1.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Compile -->
@@ -41,37 +22,32 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
<version>0.6.9</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
@@ -97,22 +73,11 @@
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
<exclusion>
<artifactId>jaxb-api</artifactId>
<groupId>javax.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
<artifactId>jakarta.json</artifactId>
</dependency>
<dependency>
@@ -130,55 +95,111 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.8.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>2.4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<build>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
<plugins>
</repositories>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>**/*</include>
</includes>
<archive>
<manifestEntries>
<Automatic-Module-Name>org.fuin.cqrs4j.example.shared</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
<versionRange>[3.1.2,)</versionRange>
<goals>
<goal>jdkinternals</goal>
<goal>test-jdkinternals</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -15,7 +15,7 @@ package org.fuin.cqrs4j.example.quarkus.shared;
import java.net.MalformedURLException;
import java.net.URL;
import javax.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;

View File

@@ -12,8 +12,8 @@
*/
package org.fuin.cqrs4j.example.quarkus.shared;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import org.eclipse.microprofile.context.ManagedExecutor;

View File

@@ -16,11 +16,11 @@ import java.nio.charset.Charset;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.context.RequestScoped;
import jakarta.enterprise.inject.Disposes;
import jakarta.enterprise.inject.Produces;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@@ -43,20 +43,22 @@ public class EventStoreFactory {
/**
* Creates an ESJC event store.<br>
* <br>
* CAUTION: The returned event store instance is NOT thread safe.
* CAUTION: The returned event store instance is NOT thread safe.
*
* @param es Native event store API.
* @param registry Serialization registry.
* @param es
* Native event store API.
* @param registry
* Serialization registry.
*
* @return Dependent scope event store.
*/
*/
@Produces
@RequestScoped
public IESJCEventStore createEventStore(final com.github.msemys.esjc.EventStore es,
final SerDeserializerRegistry registry) {
public IESJCEventStore createEventStore(final com.github.msemys.esjc.EventStore es, final SerDeserializerRegistry registry) {
final IESJCEventStore eventstore = new ESJCEventStore.Builder().eventStore(es).serDesRegistry(registry)
.targetContentType(EnhancedMimeType.create("application", "json", Charset.forName("utf-8"))).build();
final IESJCEventStore eventstore = new ESJCEventStore(es, registry, registry,
EnhancedMimeType.create("application", "json", Charset.forName("utf-8")));
eventstore.open();
return eventstore;
@@ -65,7 +67,8 @@ public class EventStoreFactory {
/**
* Closes the ESJC event store when the context is disposed.
*
* @param es Event store to close.
* @param es
* Event store to close.
*/
public void closeEventStore(@Disposes final IESJCEventStore es) {
es.close();
@@ -92,8 +95,10 @@ public class EventStoreFactory {
config.getEventStorePassword());
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
final ThreadFactory threadFactory = Executors.defaultThreadFactory();
final IESHttpEventStore eventStore = new ESHttpEventStore(threadFactory, config.getEventStoreURL(), ESEnvelopeType.JSON, registry,
registry, credentialsProvider);
final IESHttpEventStore eventStore = new ESHttpEventStore.Builder().threadFactory(threadFactory).url(config.getEventStoreURL())
.envelopeType(ESEnvelopeType.JSON).serDesRegistry(registry).credentialsProvider(credentialsProvider).build();
eventStore.open();
return eventStore;
@@ -108,5 +113,5 @@ public class EventStoreFactory {
public void closeEventStore(@Disposes final IESHttpEventStore es) {
es.close();
}
}

View File

@@ -12,11 +12,11 @@
*/
package org.fuin.cqrs4j.example.quarkus.shared;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.eclipse.yasson.FieldAccessStrategy;
import org.fuin.cqrs4j.example.shared.SharedUtils;

View File

@@ -12,8 +12,8 @@
*/
package org.fuin.cqrs4j.example.quarkus.shared;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import org.fuin.cqrs4j.example.shared.SharedUtils;
import org.fuin.esc.spi.JsonbDeSerializer;

View File

@@ -1,166 +1,197 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<name>cqrs4j-example-shared</name>
<description>Shared code for all demo applications and client &amp; server</description>
<parent>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<esc.version>0.3.1</esc.version>
</properties>
<artifactId>cqrs4j-example-shared</artifactId>
<name>cqrs4j-example-shared</name>
<description>Shared code for all demo applications and client &amp; server</description>
<dependencies>
<dependencies>
<!-- Compile -->
<!-- Compile -->
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
<version>0.6.9</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-api</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-api</artifactId>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>jakarta.json.bind</groupId>
<artifactId>jakarta.json.bind-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
</dependency>
<!-- Test -->
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.8.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>2.4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.10.Final</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
<exclusion>
<artifactId>jaxb-api</artifactId>
<groupId>javax.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
<scope>test</scope>
</dependency>
<artifactId>jakarta.json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</dependencies>
<repositories>
<build>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
<plugins>
</repositories>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>**/*</include>
</includes>
<archive>
<manifestEntries>
<Automatic-Module-Name>org.fuin.cqrs4j.example.shared</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jdeps-plugin</artifactId>
<versionRange>[3.1.2,)</versionRange>
<goals>
<goal>jdkinternals</goal>
<goal>test-jdkinternals</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -17,15 +17,15 @@
*/
package org.fuin.cqrs4j.example.shared;
import javax.annotation.concurrent.Immutable;
import javax.json.bind.annotation.JsonbProperty;
import javax.validation.constraints.NotNull;
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.AbstractAggregateCommand;
import org.fuin.ddd4j.ddd.DomainEventExpectedEntityIdPath;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.spi.SerializedDataType;
import org.fuin.objects4j.common.Contract;
import org.fuin.objects4j.common.Immutable;
/**
* A new person should be created in the system.

View File

@@ -17,9 +17,9 @@
*/
package org.fuin.cqrs4j.example.shared;
import javax.annotation.concurrent.Immutable;
import javax.json.bind.annotation.JsonbProperty;
import javax.validation.constraints.NotNull;
import org.fuin.objects4j.common.Immutable;
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.validation.constraints.NotNull;
import org.fuin.ddd4j.ddd.AbstractDomainEvent;
import org.fuin.ddd4j.ddd.EntityIdPath;

View File

@@ -19,9 +19,9 @@ package org.fuin.cqrs4j.example.shared;
import java.util.UUID;
import javax.annotation.concurrent.Immutable;
import javax.json.bind.adapter.JsonbAdapter;
import javax.validation.constraints.NotNull;
import org.fuin.objects4j.common.Immutable;
import jakarta.json.bind.adapter.JsonbAdapter;
import jakarta.validation.constraints.NotNull;
import org.fuin.ddd4j.ddd.AggregateRootUuid;
import org.fuin.ddd4j.ddd.EntityType;

View File

@@ -23,13 +23,13 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.concurrent.Immutable;
import javax.json.bind.adapter.JsonbAdapter;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import javax.validation.constraints.NotNull;
import org.fuin.objects4j.common.Immutable;
import jakarta.json.bind.adapter.JsonbAdapter;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import jakarta.validation.constraints.NotNull;
import org.fuin.objects4j.common.ConstraintViolationException;
import org.fuin.objects4j.ui.Label;

View File

@@ -20,14 +20,14 @@ package org.fuin.cqrs4j.example.shared;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import javax.json.bind.adapter.JsonbAdapter;
import javax.json.bind.config.PropertyVisibilityStrategy;
import java.util.Collection;
import java.util.zip.Adler32;
import org.fuin.ddd4j.ddd.AggregateVersionConverter;
import org.fuin.ddd4j.ddd.EntityIdConverter;
import org.fuin.ddd4j.ddd.EntityIdPathConverter;
import org.fuin.ddd4j.ddd.EventIdConverter;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.spi.Base64Data;
import org.fuin.esc.spi.EscEvent;
import org.fuin.esc.spi.EscEvents;
@@ -40,6 +40,9 @@ import org.fuin.esc.spi.SerializedDataTypeRegistry;
import org.fuin.esc.spi.SimpleSerializedDataTypeRegistry;
import org.fuin.esc.spi.SimpleSerializerDeserializerRegistry;
import jakarta.json.bind.adapter.JsonbAdapter;
import jakarta.json.bind.config.PropertyVisibilityStrategy;
/**
* Utility code shared between command (write) and query (read) module.
*/
@@ -144,9 +147,25 @@ public final class SharedUtils {
.withPropertyVisibilityStrategy(new FieldAccessStrategy()).withEncoding(Charset.forName("utf-8")).build();
}
/**
* Creates an Adler32 checksum based on on event type names.
*
* @param eventTypes
* Types to calculate a checksum for.
*
* @return Checksum based on all names.
*/
public static long calculateChecksum(final Collection<EventType> eventTypes) {
final Adler32 checksum = new Adler32();
for (final EventType eventType : eventTypes) {
checksum.update(eventType.asBaseType().getBytes(Charset.forName("ascii")));
}
return checksum.getValue();
}
private static class FieldAccessStrategy implements PropertyVisibilityStrategy {
@Override
public boolean isVisible(Field field) {
return true;
@@ -156,9 +175,9 @@ public final class SharedUtils {
public boolean isVisible(Method method) {
return false;
}
}
}
/**
* Helper class for type/class combination.
*/

View File

@@ -24,9 +24,9 @@ import java.nio.charset.Charset;
import java.time.ZonedDateTime;
import java.util.UUID;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.apache.commons.io.IOUtils;
import org.eclipse.yasson.FieldAccessStrategy;
@@ -92,7 +92,7 @@ public final class CreatePersonCommandTest {
// VERIFY
assertThat(copy.getEventId().asBaseType()).isEqualTo(UUID.fromString("109a77b2-1de2-46fc-aee1-97fa7740a552"));
assertThat(copy.getTimestamp()).isEqualTo(ZonedDateTime.parse("2019-11-17T10:27:13.183+01:00[Europe/Berlin]"));
assertThat(copy.getEventTimestamp()).isEqualTo(ZonedDateTime.parse("2019-11-17T10:27:13.183+01:00[Europe/Berlin]"));
assertThat(copy.getAggregateRootId().asString()).isEqualTo(PERSON_UUID);
assertThat(copy.getName().asString()).isEqualTo("Peter Parker");

View File

@@ -25,9 +25,9 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.util.UUID;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.apache.commons.io.IOUtils;
import org.eclipse.yasson.FieldAccessStrategy;

View File

@@ -0,0 +1,50 @@
/**
* Copyright (C) 2015 Michael Schnell. All rights reserved.
* http://www.fuin.org/
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see http://www.gnu.org/licenses/.
*/
package org.fuin.cqrs4j.example.shared;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashSet;
import java.util.Set;
import org.fuin.ddd4j.ddd.EventType;
import org.junit.Test;
/**
* Test for the {@link SharedUtils} class.
*/
public final class SharedUtilsTest {
@Test
public void testCalculateChecksum() {
// PREPARE
final Set<EventType> eventTypes = new HashSet<>();
eventTypes.add(new EventType("PersonCreatedEvent"));
eventTypes.add(new EventType("PersonRenamedEvent"));
eventTypes.add(new EventType("PersonDeletedEvent"));
// TEST
final long checksum = SharedUtils.calculateChecksum(eventTypes);
// VERIFY
assertThat(checksum).isEqualTo(1341789591L);
}
}

View File

@@ -2,28 +2,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-command</artifactId>
<version>0.1.0</version>
<name>cqrs4j-spring-example-command</name>
<description>Spring Boot CQRS Command Demo Application</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<esc.version>0.3.1</esc.version>
</properties>
<dependencies>
<!-- compile -->
@@ -31,19 +23,19 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-aggregates</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
@@ -59,19 +51,16 @@
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<!-- runtime -->
@@ -157,12 +146,11 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.31.0</version>
<configuration>
<images>
<image>
<name>eventstore/eventstore:release-4.1.3</name>
<name>eventstore/eventstore:release-${eventstore.version}</name>
<run>
<network>
<mode>bridge</mode>

View File

@@ -15,9 +15,9 @@ package org.fuin.cqrs4j.example.spring.command.controller;
import java.util.Optional;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import org.fuin.cqrs4j.CommandExecutionFailedException;
import org.fuin.cqrs4j.SimpleResult;

View File

@@ -11,7 +11,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import javax.json.bind.Jsonb;
import jakarta.json.bind.Jsonb;
import org.fuin.cqrs4j.ResultType;
import org.fuin.cqrs4j.SimpleResult;

View File

@@ -3,11 +3,161 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-root</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>11</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.parameters>true</maven.compiler.parameters>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<esc.version>0.4.0</esc.version>
<eventstore.version>5.0.9</eventstore.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
<version>0.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-api</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-mem</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.json</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.20.2</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.34.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<modules>
<module>shared</module>
<module>query</module>

View File

@@ -16,6 +16,37 @@ Make sure you installed everything as described [here](../../../../).
## Overview
![Overview](https://raw.github.com/fuinorg/ddd-cqrs-4-java-example/master/spring-boot/query/doc/spring-view.png)
## Running test in IDE
In case you want to run the integration test inside your IDE (Eclipse or other), you need to start the Eventstore and MariaDB before.
1. Start the Eventstore Docker container:
```
docker run -d --name eventstore-node \
-p 2113:2113 \
-p 1113:1113 \
--rm \
eventstore/eventstore:release-5.0.9
```
2. Start the MariaDB Docker container:
```
docker run -d --name mariadb \
-p 3306:3306 \
-e MYSQL_INITDB_SKIP_TZINFO=1 \
-e MYSQL_ROOT_PASSWORD=xyz \
-e MYSQL_DATABASE=querydb \
-e MYSQL_USER=mary \
-e MYSQL_PASSWORD=abc \
--rm \
mariadb:10.4
```
3. Run the test: [PersonControllerIT.java](src/test/java/org/fuin/cqrs4j/example/spring/query/api/PersonControllerIT.java)
4. Run `docker ps` to see the CONTAINER IDs and stop the Eventstore and MariaDB with `docker stop <CONTAINER_ID>`
# TODO ...
**Issues**

View File

@@ -2,28 +2,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-query</artifactId>
<version>0.1.0</version>
<name>cqrs4j-spring-example-query</name>
<description>Spring Boot CQRS Query Demo Application</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<esc.version>0.3.1</esc.version>
</properties>
<dependencies>
<!-- compile -->
@@ -31,13 +23,13 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
@@ -63,25 +55,21 @@
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
</dependency>
<!-- runtime -->
@@ -167,12 +155,11 @@
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.31.0</version>
<configuration>
<images>
<image>
<name>eventstore/eventstore:release-4.1.3</name>
<name>eventstore/eventstore:release-${eventstore.version}</name>
<run>
<network>
<mode>bridge</mode>
@@ -245,21 +232,4 @@
</build>
<repositories>
<repository>
<id>sonatype.oss.snapshots</id>
<name>Sonatype OSS Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<updatePolicy>always</updatePolicy>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@@ -15,7 +15,7 @@ package org.fuin.cqrs4j.example.spring.query.controller;
import java.util.List;
import java.util.UUID;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import org.fuin.cqrs4j.example.shared.PersonId;
import org.fuin.cqrs4j.example.spring.query.views.personlist.PersonListEntry;

View File

@@ -1,10 +1,10 @@
package org.fuin.cqrs4j.example.spring.query.views.common;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import org.fuin.esc.api.SimpleStreamId;
import org.fuin.esc.api.StreamId;

View File

@@ -1,8 +1,8 @@
package org.fuin.cqrs4j.example.spring.query.views.common;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.validation.constraints.NotNull;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.ProjectionService;
import org.fuin.esc.api.StreamId;

View File

@@ -1,6 +1,6 @@
package org.fuin.cqrs4j.example.spring.query.views.personlist;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import org.fuin.cqrs4j.EventHandler;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;

View File

@@ -12,12 +12,12 @@
*/
package org.fuin.cqrs4j.example.spring.query.views.personlist;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.example.shared.PersonId;
import org.fuin.cqrs4j.example.shared.PersonName;

View File

@@ -1,8 +1,12 @@
package org.fuin.cqrs4j.example.spring.query.views.personlist;
import javax.annotation.concurrent.NotThreadSafe;
import java.util.Set;
import org.fuin.objects4j.common.NotThreadSafe;
import org.fuin.cqrs4j.ProjectionService;
import org.fuin.cqrs4j.example.shared.SharedUtils;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.api.ProjectionStreamId;
import org.fuin.esc.api.StreamEventsSlice;
import org.slf4j.Logger;
@@ -30,7 +34,23 @@ public class PersonListEventChunkHandler {
@Autowired
private ProjectionService projectionService;
/**
private ProjectionStreamId streamId;
/**
* Returns the name of the event store projection that is used by this handler.
*
* @return Unique projection stream name.
*/
public ProjectionStreamId getProjectionStreamId() {
if (streamId == null) {
final Set<EventType> eventTypes = dispatcher.getAllTypes();
final String name = "spring-qry-person-" + SharedUtils.calculateChecksum(eventTypes);
streamId = new ProjectionStreamId(name);
}
return streamId;
}
/**
* Returns the next event position to read.
*
* @return Number of the next event to read.

View File

@@ -3,8 +3,8 @@ package org.fuin.cqrs4j.example.spring.query.views.personlist;
import java.util.List;
import java.util.Set;
import javax.annotation.concurrent.NotThreadSafe;
import javax.validation.constraints.NotNull;
import org.fuin.objects4j.common.NotThreadSafe;
import jakarta.validation.constraints.NotNull;
import org.fuin.cqrs4j.EventDispatcher;
import org.fuin.cqrs4j.SimpleEventDispatcher;

View File

@@ -1,7 +1,6 @@
package org.fuin.cqrs4j.example.spring.query.views.personlist;
import static org.fuin.cqrs4j.Cqrs4JUtils.tryLocked;
import static org.fuin.cqrs4j.example.spring.query.views.personlist.PersonListEventChunkHandler.PROJECTION_STREAM_ID;
import java.util.ArrayList;
import java.util.List;
@@ -10,7 +9,7 @@ import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PreDestroy;
import javax.annotation.concurrent.ThreadSafe;
import org.fuin.objects4j.common.ThreadSafe;
import org.fuin.ddd4j.ddd.EventType;
import org.fuin.esc.api.TypeName;
@@ -44,7 +43,7 @@ public class PersonListProjector {
// Above LOCK prevents multithreaded access
@Autowired
private IESHttpEventStore eventStore;
private IESHttpEventStore eventstore;
@Autowired
private PersonListEventChunkHandler chunkHandler;
@@ -85,26 +84,37 @@ public class PersonListProjector {
LOG.info("Application stopped");
}
private void readStreamEvents() {
private void readStreamEvents() {
// TODO Make sure a projection with the correct events exists
// We must update the projection if new events are defined or some are removed!
if (!eventStore.projectionExists(PROJECTION_STREAM_ID)) {
final Set<EventType> eventTypes = dispatcher.getAllTypes();
final List<TypeName> typeNames = new ArrayList<>();
for (final EventType eventType : eventTypes) {
typeNames.add(new TypeName(eventType.asBaseType()));
}
LOG.info("Create projection '{}' with events: {}", PROJECTION_STREAM_ID, typeNames);
eventStore.createProjection(PROJECTION_STREAM_ID, true, typeNames);
}
// Create a projection if it does not exist.
// Multiple projections (even in different microservice versions)
// might share the same projection based on the event name hash.
if (!eventstore.projectionExists(chunkHandler.getProjectionStreamId())) {
final List<TypeName> typeNames = getEventTypeNames();
LOG.info("Create projection '{}' with events: {}", chunkHandler.getProjectionStreamId(), typeNames);
eventstore.createProjection(chunkHandler.getProjectionStreamId(), true, typeNames);
}
// Read and dispatch events
final Long nextEventNumber = chunkHandler.readNextEventNumber();
eventStore.readAllEventsForward(PROJECTION_STREAM_ID, nextEventNumber, 100, (currentSlice) -> {
chunkHandler.handleChunk(currentSlice);
});
// Read and dispatch events
final Long nextEventNumber = chunkHandler.readNextEventNumber();
eventstore.readAllEventsForward(chunkHandler.getProjectionStreamId(), nextEventNumber, 100, (currentSlice) -> {
chunkHandler.handleChunk(currentSlice);
});
}
}
/**
* Returns a list of all event type names used for this projection.
*
* @return List of event names.
*/
public List<TypeName> getEventTypeNames() {
final List<TypeName> typeNames = new ArrayList<>();
final Set<EventType> eventTypes = dispatcher.getAllTypes();
for (final EventType eventType : eventTypes) {
typeNames.add(new TypeName(eventType.asBaseType()));
}
return typeNames;
}
}

View File

@@ -12,7 +12,7 @@ import static org.hamcrest.Matchers.not;
import java.util.Arrays;
import java.util.UUID;
import javax.persistence.EntityManager;
import jakarta.persistence.EntityManager;
import org.fuin.cqrs4j.example.shared.PersonCreatedEvent;
import org.fuin.cqrs4j.example.shared.PersonId;
@@ -91,6 +91,8 @@ public class PersonControllerIT {
// TEST & VERIFY
// given().pathParam("id", personId.asString()).when().get("/persons/{id}").then().log().all(true);
final PersonListEntry person = given().pathParam("id", personId.asString()).when().get("/persons/{id}").then()
.statusCode(200).extract().as(PersonListEntry.class);
assertThat(person.getId(), is(equalTo(personId)));

View File

@@ -5,26 +5,16 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-root</artifactId>
<version>0.2.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.fuin.cqrs4j.example.spring</groupId>
<artifactId>cqrs4j-spring-example-shared</artifactId>
<version>0.1.0</version>
<name>cqrs4j-spring-example-shared</name>
<description>Spring Boot CQRS Shared Code for Demo Application</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<esc.version>0.3.1</esc.version>
</properties>
<dependencies>
<!-- Compile -->
@@ -32,7 +22,7 @@
<dependency>
<groupId>org.fuin.cqrs4j.example</groupId>
<artifactId>cqrs4j-example-shared</artifactId>
<version>0.1.0</version>
<version>0.2.0-SNAPSHOT</version>
</dependency>
<dependency>
@@ -48,37 +38,31 @@
<dependency>
<groupId>org.fuin</groupId>
<artifactId>ddd-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>cqrs-4-java</artifactId>
<version>0.2.1</version>
</dependency>
<dependency>
<groupId>org.fuin</groupId>
<artifactId>objects4j</artifactId>
<version>0.6.9</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-spi</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-esjc</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
<groupId>org.fuin.esc</groupId>
<artifactId>esc-eshttp</artifactId>
<version>${esc.version}</version>
</dependency>
<dependency>
@@ -93,14 +77,12 @@
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
<artifactId>jakarta.json</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
@@ -125,21 +107,18 @@
<dependency>
<groupId>org.fuin</groupId>
<artifactId>units4j</artifactId>
<version>0.8.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>nl.jqno.equalsverifier</groupId>
<artifactId>equalsverifier</artifactId>
<version>2.4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<scope>test</scope>
</dependency>

View File

@@ -5,9 +5,9 @@ import java.net.URL;
import java.nio.charset.Charset;
import java.util.concurrent.Executors;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
@@ -30,77 +30,81 @@ import com.github.msemys.esjc.EventStoreBuilder;
@Component
public class BeanFactory {
/**
* Creates a Jsonb instance.
*
* @return Fully configured instance.
*/
@Bean
public Jsonb createJsonb() {
final JsonbConfig config = new JsonbConfig().withAdapters(SharedUtils.JSONB_ADAPTERS)
.withPropertyVisibilityStrategy(new FieldAccessStrategy());
final Jsonb jsonb = JsonbBuilder.create(config);
return jsonb;
}
/**
* Creates a Jsonb instance.
*
* @return Fully configured instance.
*/
@Bean
public Jsonb createJsonb() {
final JsonbConfig config = new JsonbConfig().withAdapters(SharedUtils.JSONB_ADAPTERS)
.withPropertyVisibilityStrategy(new FieldAccessStrategy());
final Jsonb jsonb = JsonbBuilder.create(config);
return jsonb;
}
/**
* Creates a TCP based event store connection.
*
* @param config Configuration to use.
*
* @return New event store instance.
*/
@Bean(destroyMethod = "shutdown")
public com.github.msemys.esjc.EventStore getEventStore(final Config config) {
return EventStoreBuilder.newBuilder()
.singleNodeAddress(config.getEventStoreHost(), config.getEventStoreTcpPort())
.executor(Executors.newFixedThreadPool(10))
.userCredentials(config.getEventStoreUser(), config.getEventStorePassword()).build();
}
/**
* Creates a TCP based event store connection.
*
* @param config
* Configuration to use.
*
* @return New event store instance.
*/
@Bean(destroyMethod = "shutdown")
public com.github.msemys.esjc.EventStore getEventStore(final Config config) {
return EventStoreBuilder.newBuilder().singleNodeAddress(config.getEventStoreHost(), config.getEventStoreTcpPort())
.executor(Executors.newFixedThreadPool(10)).userCredentials(config.getEventStoreUser(), config.getEventStorePassword())
.build();
}
/**
* Creates an event store connection.
*
* @param config Configuration to use.
*
* @return New event store instance.
*/
@Bean(destroyMethod = "close")
public IESJCEventStore getESJCEventStore(final com.github.msemys.esjc.EventStore es) {
/**
* Creates an event store connection.
*
* @param config
* Configuration to use.
*
* @return New event store instance.
*/
@Bean(destroyMethod = "close")
public IESJCEventStore getESJCEventStore(final com.github.msemys.esjc.EventStore es) {
final SerDeserializerRegistry registry = SharedUtils.createRegistry();
final IESJCEventStore eventstore = new ESJCEventStore(es, registry, registry,
EnhancedMimeType.create("application", "json", Charset.forName("utf-8")));
eventstore.open();
return eventstore;
final SerDeserializerRegistry registry = SharedUtils.createRegistry();
}
final IESJCEventStore eventstore = new ESJCEventStore.Builder().eventStore(es).serDesRegistry(registry)
.targetContentType(EnhancedMimeType.create("application", "json", Charset.forName("utf-8"))).build();
eventstore.open();
return eventstore;
}
/**
* Creates a HTTP based event store connection.
*
* @param config
* Configuration to use.
*
* @return New event store instance.
*/
@Bean(destroyMethod = "close")
public IESHttpEventStore getESHttpEventStore(final Config config) {
final String url = config.getEventStoreProtocol() + "://" + config.getEventStoreHost() + ":" + config.getEventStoreHttpPort();
try {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(config.getEventStoreUser(),
config.getEventStorePassword());
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
final SerDeserializerRegistry registry = SharedUtils.createRegistry();
final ESHttpEventStore es = new ESHttpEventStore.Builder().threadFactory(Executors.defaultThreadFactory()).url(new URL(url))
.envelopeType(ESEnvelopeType.JSON).serDesRegistry(registry).credentialsProvider(credentialsProvider).build();
es.open();
return es;
} catch (final MalformedURLException ex) {
throw new RuntimeException("Failed to create URL: " + url, ex);
}
}
/**
* Creates a HTTP based event store connection.
*
* @param config Configuration to use.
*
* @return New event store instance.
*/
@Bean(destroyMethod = "close")
public IESHttpEventStore getESHttpEventStore(final Config config) {
final String url = config.getEventStoreProtocol() + "://" + config.getEventStoreHost() + ":"
+ config.getEventStoreHttpPort();
try {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(config.getEventStoreUser(),
config.getEventStorePassword());
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
final SerDeserializerRegistry registry = SharedUtils.createRegistry();
final ESHttpEventStore es = new ESHttpEventStore(Executors.defaultThreadFactory(), new URL(url),
ESEnvelopeType.JSON, registry, registry, credentialsProvider);
es.open();
return es;
} catch (final MalformedURLException ex) {
throw new RuntimeException("Failed to create URL: " + url, ex);
}
}
}

View File

@@ -16,9 +16,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.fuin.objects4j.common.Nullable;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import org.fuin.cqrs4j.CommandExecutionFailedException;
import org.fuin.cqrs4j.SimpleResult;