diff --git a/java-es-cqrs/.gitignore b/java-es-cqrs/.gitignore
new file mode 100644
index 0000000000..153c9335eb
--- /dev/null
+++ b/java-es-cqrs/.gitignore
@@ -0,0 +1,29 @@
+HELP.md
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+
+### VS Code ###
+.vscode/
diff --git a/java-es-cqrs/pom.xml b/java-es-cqrs/pom.xml
new file mode 100644
index 0000000000..4160c62b0c
--- /dev/null
+++ b/java-es-cqrs/pom.xml
@@ -0,0 +1,20 @@
+
+ 4.0.0
+ com.sapient.learning
+ java-events
+ 0.0.1-SNAPSHOT
+ java-es-cqrs
+
+ 1.8
+ 1.8
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.12
+
+
+
\ No newline at end of file
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/Main.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/Main.java
new file mode 100644
index 0000000000..4e9c872cf1
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/Main.java
@@ -0,0 +1,57 @@
+package com.baeldung.patterns.cqrs;
+
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.baeldung.patterns.cqrs.aggregates.UserAggregate;
+import com.baeldung.patterns.cqrs.commands.CreateUserCommand;
+import com.baeldung.patterns.cqrs.commands.UpdateUserCommand;
+import com.baeldung.patterns.cqrs.projections.UserProjection;
+import com.baeldung.patterns.cqrs.projectors.UserProjector;
+import com.baeldung.patterns.cqrs.queries.AddressByRegionQuery;
+import com.baeldung.patterns.cqrs.queries.ContactByTypeQuery;
+import com.baeldung.patterns.cqrs.repository.UserReadRepository;
+import com.baeldung.patterns.cqrs.repository.UserWriteRepository;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.User;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+ UserWriteRepository writeRepository = new UserWriteRepository();
+ UserReadRepository readRepository = new UserReadRepository();
+ UserProjector projector = new UserProjector(readRepository);
+ UserAggregate userAggregate = new UserAggregate(writeRepository);
+ UserProjection userProjection = new UserProjection(readRepository);
+
+ String userId = UUID.randomUUID()
+ .toString();
+ User user = null;
+ CreateUserCommand createUserCommand = new CreateUserCommand(userId, "Tom", "Sawyer");
+ user = userAggregate.handleCreateUserCommand(createUserCommand);
+ projector.project(user);
+
+ UpdateUserCommand updateUserCommand = new UpdateUserCommand(user.getUserid(), Stream.of(new Address("New York", "NY", "10001"), new Address("Los Angeles", "CA", "90001"))
+ .collect(Collectors.toSet()),
+ Stream.of(new Contact("EMAIL", "tom.sawyer@gmail.com"), new Contact("EMAIL", "tom.sawyer@rediff.com"))
+ .collect(Collectors.toSet()));
+ user = userAggregate.handleUpdateUserCommand(updateUserCommand);
+ projector.project(user);
+
+ updateUserCommand = new UpdateUserCommand(userId, Stream.of(new Address("New York", "NY", "10001"), new Address("Housten", "TX", "77001"))
+ .collect(Collectors.toSet()),
+ Stream.of(new Contact("EMAIL", "tom.sawyer@gmail.com"), new Contact("PHONE", "700-000-0001"))
+ .collect(Collectors.toSet()));
+ user = userAggregate.handleUpdateUserCommand(updateUserCommand);
+ projector.project(user);
+
+ AddressByRegionQuery addressByRegionQuery = new AddressByRegionQuery(user.getUserid(), "NY");
+ System.out.println(userProjection.handle(addressByRegionQuery));
+
+ ContactByTypeQuery contactByTypeQuery = new ContactByTypeQuery(user.getUserid(), "EMAIL");
+ System.out.println(userProjection.handle(contactByTypeQuery));
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/aggregates/UserAggregate.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/aggregates/UserAggregate.java
new file mode 100644
index 0000000000..b5e16cff0e
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/aggregates/UserAggregate.java
@@ -0,0 +1,30 @@
+package com.baeldung.patterns.cqrs.aggregates;
+
+import com.baeldung.patterns.cqrs.commands.CreateUserCommand;
+import com.baeldung.patterns.cqrs.commands.UpdateUserCommand;
+import com.baeldung.patterns.cqrs.repository.UserWriteRepository;
+import com.baeldung.patterns.domain.User;
+
+public class UserAggregate {
+
+ private UserWriteRepository writeRepository;
+
+ public UserAggregate(UserWriteRepository repository) {
+ this.writeRepository = repository;
+ }
+
+ public User handleCreateUserCommand(CreateUserCommand command) {
+ User user = new User(command.getUserId(), command.getFiratName(), command.getLastName());
+ writeRepository.addUser(user.getUserid(), user);
+ return user;
+ }
+
+ public User handleUpdateUserCommand(UpdateUserCommand command) {
+ User user = writeRepository.getUser(command.getUserId());
+ user.setAddresses(command.getAddresses());
+ user.setContacts(command.getContacts());
+ writeRepository.addUser(user.getUserid(), user);
+ return user;
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/commands/CreateUserCommand.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/commands/CreateUserCommand.java
new file mode 100644
index 0000000000..4ab939dbab
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/commands/CreateUserCommand.java
@@ -0,0 +1,14 @@
+package com.baeldung.patterns.cqrs.commands;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class CreateUserCommand {
+
+ private String userId;
+ private String firatName;
+ private String lastName;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/commands/UpdateUserCommand.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/commands/UpdateUserCommand.java
new file mode 100644
index 0000000000..58a4889458
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/commands/UpdateUserCommand.java
@@ -0,0 +1,20 @@
+package com.baeldung.patterns.cqrs.commands;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class UpdateUserCommand {
+
+ private String userId;
+ private Set
addresses = new HashSet<>();
+ private Set contacts = new HashSet<>();
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/projections/UserProjection.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/projections/UserProjection.java
new file mode 100644
index 0000000000..40a56e727f
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/projections/UserProjection.java
@@ -0,0 +1,37 @@
+package com.baeldung.patterns.cqrs.projections;
+
+import java.util.Set;
+
+import com.baeldung.patterns.cqrs.queries.AddressByRegionQuery;
+import com.baeldung.patterns.cqrs.queries.ContactByTypeQuery;
+import com.baeldung.patterns.cqrs.repository.UserReadRepository;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.UserAddress;
+import com.baeldung.patterns.domain.UserContact;
+
+public class UserProjection {
+
+ private UserReadRepository repository;
+
+ public UserProjection(UserReadRepository repository) {
+ this.repository = repository;
+ }
+
+ public Set handle(ContactByTypeQuery query) throws Exception {
+ UserContact userContact = repository.getUserContact(query.getUserId());
+ if (userContact == null)
+ throw new Exception("User does not exist.");
+ return userContact.getContactByType()
+ .get(query.getContactType());
+ }
+
+ public Set handle(AddressByRegionQuery query) throws Exception {
+ UserAddress userAddress = repository.getUserAddress(query.getUserId());
+ if (userAddress == null)
+ throw new Exception("User does not exist.");
+ return userAddress.getAddressByRegion()
+ .get(query.getState());
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/projectors/UserProjector.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/projectors/UserProjector.java
new file mode 100644
index 0000000000..25c10094c1
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/projectors/UserProjector.java
@@ -0,0 +1,56 @@
+package com.baeldung.patterns.cqrs.projectors;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import com.baeldung.patterns.cqrs.repository.UserReadRepository;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.User;
+import com.baeldung.patterns.domain.UserAddress;
+import com.baeldung.patterns.domain.UserContact;
+
+public class UserProjector {
+
+ UserReadRepository readRepository = new UserReadRepository();
+
+ public UserProjector(UserReadRepository readRepository) {
+ this.readRepository = readRepository;
+ }
+
+ public void project(User user) {
+ UserContact userContact = readRepository.getUserContact(user.getUserid());
+ if (userContact == null)
+ userContact = new UserContact();
+ userContact.setContacts(user.getContacts());
+ Map> contactByType = new HashMap<>();
+ for (Contact contact : user.getContacts()) {
+ Set contacts = contactByType.get(contact.getType());
+ if (contacts == null)
+ contacts = new HashSet<>();
+ contacts.add(contact);
+ contactByType.put(contact.getType(), contacts);
+ }
+ userContact.setContactByType(contactByType);
+ readRepository.addUserContact(user.getUserid(), userContact);
+
+ UserAddress userAddress = readRepository.getUserAddress(user.getUserid());
+ if (userAddress == null)
+ userAddress = new UserAddress();
+ userAddress.setAddresses(user.getAddresses());
+ Map> addressByRegion = new HashMap<>();
+ for (Address address : user.getAddresses()) {
+ Set addresses = addressByRegion.get(address.getState());
+ if (addresses == null)
+ addresses = new HashSet<>();
+ addresses.add(address);
+ addressByRegion.put(address.getState(), addresses);
+ }
+ userAddress.setAddressByRegion(addressByRegion);
+ readRepository.addUserAddress(user.getUserid(), userAddress);
+
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/queries/AddressByRegionQuery.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/queries/AddressByRegionQuery.java
new file mode 100644
index 0000000000..4a0f0769f2
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/queries/AddressByRegionQuery.java
@@ -0,0 +1,12 @@
+package com.baeldung.patterns.cqrs.queries;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class AddressByRegionQuery {
+
+ private String userId;
+ private String state;
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/queries/ContactByTypeQuery.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/queries/ContactByTypeQuery.java
new file mode 100644
index 0000000000..b6c271b472
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/queries/ContactByTypeQuery.java
@@ -0,0 +1,12 @@
+package com.baeldung.patterns.cqrs.queries;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class ContactByTypeQuery {
+
+ private String userId;
+ private String contactType;
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/repository/UserReadRepository.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/repository/UserReadRepository.java
new file mode 100644
index 0000000000..a7ef2f6f96
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/repository/UserReadRepository.java
@@ -0,0 +1,31 @@
+package com.baeldung.patterns.cqrs.repository;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.baeldung.patterns.domain.UserAddress;
+import com.baeldung.patterns.domain.UserContact;
+
+public class UserReadRepository {
+
+ private Map userAddress = new HashMap<>();
+
+ private Map userContact = new HashMap<>();
+
+ public void addUserAddress(String id, UserAddress user) {
+ userAddress.put(id, user);
+ }
+
+ public UserAddress getUserAddress(String id) {
+ return userAddress.get(id);
+ }
+
+ public void addUserContact(String id, UserContact user) {
+ userContact.put(id, user);
+ }
+
+ public UserContact getUserContact(String id) {
+ return userContact.get(id);
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/repository/UserWriteRepository.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/repository/UserWriteRepository.java
new file mode 100644
index 0000000000..8636e36225
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/cqrs/repository/UserWriteRepository.java
@@ -0,0 +1,20 @@
+package com.baeldung.patterns.cqrs.repository;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.baeldung.patterns.domain.User;
+
+public class UserWriteRepository {
+
+ private Map store = new HashMap<>();
+
+ public void addUser(String id, User user) {
+ store.put(id, user);
+ }
+
+ public User getUser(String id) {
+ return store.get(id);
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/Main.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/Main.java
new file mode 100644
index 0000000000..1f20e0be38
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/Main.java
@@ -0,0 +1,48 @@
+package com.baeldung.patterns.crud;
+
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.baeldung.patterns.crud.repository.UserRepository;
+import com.baeldung.patterns.crud.service.UserService;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+
+ UserRepository repository = new UserRepository();
+ UserService service = new UserService(repository);
+ String userId = UUID.randomUUID()
+ .toString();
+
+ service.createUser(userId, "Tom", "Sawyer");
+ service.updateUser(userId,
+ Stream.of(
+ new Contact("EMAIL", "tom.sawyer@gmail.com"),
+ new Contact("EMAIL", "tom.sawyer@rediff.com"),
+ new Contact("PHONE", "700-000-0001"))
+ .collect(Collectors.toSet()),
+ Stream.of(
+ new Address("New York", "NY", "10001"),
+ new Address("Los Angeles", "CA", "90001"),
+ new Address("Housten", "TX", "77001"))
+ .collect(Collectors.toSet()));
+ service.updateUser(userId,
+ Stream.of(
+ new Contact("EMAIL", "tom.sawyer@gmail.com"),
+ new Contact("PHONE", "700-000-0001"))
+ .collect(Collectors.toSet()),
+ Stream.of(
+ new Address("New York", "NY", "10001"),
+ new Address("Housten", "TX", "77001"))
+ .collect(Collectors.toSet()));
+
+ System.out.println(service.getContactByType(userId, "EMAIL"));
+ System.out.println(service.getAddressByRegion(userId, "NY"));
+
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/repository/UserRepository.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/repository/UserRepository.java
new file mode 100644
index 0000000000..b22d40e6e0
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/repository/UserRepository.java
@@ -0,0 +1,20 @@
+package com.baeldung.patterns.crud.repository;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.baeldung.patterns.domain.User;
+
+public class UserRepository {
+
+ private Map store = new HashMap<>();
+
+ public void addUser(String id, User user) {
+ store.put(id, user);
+ }
+
+ public User getUser(String id) {
+ return store.get(id);
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/service/UserService.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/service/UserService.java
new file mode 100644
index 0000000000..d21a796304
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/crud/service/UserService.java
@@ -0,0 +1,55 @@
+package com.baeldung.patterns.crud.service;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.baeldung.patterns.crud.repository.UserRepository;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.User;
+
+public class UserService {
+
+ private UserRepository repository;
+
+ public UserService(UserRepository repository) {
+ this.repository = repository;
+ }
+
+ public void createUser(String userId, String firstName, String lastName) {
+ User user = new User(userId, firstName, lastName);
+ repository.addUser(userId, user);
+ }
+
+ public void updateUser(String userId, Set contacts, Set addresses) throws Exception {
+ User user = repository.getUser(userId);
+ if (user == null)
+ throw new Exception("User does not exist.");
+ user.setContacts(contacts);
+ user.setAddresses(addresses);
+ repository.addUser(userId, user);
+ }
+
+ public Set getContactByType(String userId, String contactType) throws Exception {
+ User user = repository.getUser(userId);
+ if (user == null)
+ throw new Exception("User does not exit.");
+ Set contacts = user.getContacts();
+ return contacts.stream()
+ .filter(c -> c.getType()
+ .equals(contactType))
+ .collect(Collectors.toSet());
+ }
+
+ public Set getAddressByRegion(String userId, String state) throws Exception {
+ User user = repository.getUser(userId);
+ if (user == null)
+ throw new Exception("User does not exist.");
+ Set addresses = user.getAddresses();
+ return addresses.stream()
+ .filter(a -> a.getState()
+ .equals(state))
+ .collect(Collectors.toSet());
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/Address.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/Address.java
new file mode 100644
index 0000000000..dfaa724434
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/Address.java
@@ -0,0 +1,14 @@
+package com.baeldung.patterns.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class Address {
+
+ private String city;
+ private String state;
+ private String postcode;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/Contact.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/Contact.java
new file mode 100644
index 0000000000..a151cdb4ff
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/Contact.java
@@ -0,0 +1,13 @@
+package com.baeldung.patterns.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class Contact {
+
+ private String type;
+ private String detail;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/User.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/User.java
new file mode 100644
index 0000000000..8f59723894
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/User.java
@@ -0,0 +1,22 @@
+package com.baeldung.patterns.domain;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import lombok.Data;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+@Data
+@RequiredArgsConstructor
+public class User {
+ @NonNull
+ private String userid;
+ @NonNull
+ private String firstname;
+ @NonNull
+ private String lastname;
+ private Set contacts = new HashSet<>();
+ private Set addresses = new HashSet<>();
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/UserAddress.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/UserAddress.java
new file mode 100644
index 0000000000..33f9bdf28f
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/UserAddress.java
@@ -0,0 +1,16 @@
+package com.baeldung.patterns.domain;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import lombok.Data;
+
+@Data
+public class UserAddress {
+
+ private Set addresses = new HashSet<>();
+ private Map> addressByRegion = new HashMap<>();
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/UserContact.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/UserContact.java
new file mode 100644
index 0000000000..4f2ba812a4
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/domain/UserContact.java
@@ -0,0 +1,16 @@
+package com.baeldung.patterns.domain;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import lombok.Data;
+
+@Data
+public class UserContact {
+
+ private Set contacts = new HashSet<>();
+ private Map> contactByType = new HashMap<>();
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/Main.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/Main.java
new file mode 100644
index 0000000000..77649088e9
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/Main.java
@@ -0,0 +1,48 @@
+package com.baeldung.patterns.es;
+
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.es.repository.EventStore;
+import com.baeldung.patterns.es.service.UserService;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+
+ EventStore repository = new EventStore();
+ UserService service = new UserService(repository);
+ String userId = UUID.randomUUID()
+ .toString();
+
+ service.createUser(userId, "Tom", "Sawyer");
+ service.updateUser(userId,
+ Stream.of(
+ new Contact("EMAIL", "tom.sawyer@gmail.com"),
+ new Contact("EMAIL", "tom.sawyer@rediff.com"),
+ new Contact("PHONE", "700-000-0001"))
+ .collect(Collectors.toSet()),
+ Stream.of(
+ new Address("New York", "NY", "10001"),
+ new Address("Los Angeles", "CA", "90001"),
+ new Address("Housten", "TX", "77001"))
+ .collect(Collectors.toSet()));
+ service.updateUser(userId,
+ Stream.of(
+ new Contact("EMAIL", "tom.sawyer@gmail.com"),
+ new Contact("PHONE", "700-000-0001"))
+ .collect(Collectors.toSet()),
+ Stream.of(
+ new Address("New York", "NY", "10001"),
+ new Address("Housten", "TX", "77001"))
+ .collect(Collectors.toSet()));
+
+ System.out.println(service.getContactByType(userId, "EMAIL"));
+ System.out.println(service.getAddressByRegion(userId, "NY"));
+
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/Event.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/Event.java
new file mode 100644
index 0000000000..4718450cac
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/Event.java
@@ -0,0 +1,15 @@
+package com.baeldung.patterns.es.events;
+
+import java.util.Date;
+import java.util.UUID;
+
+import lombok.ToString;
+
+@ToString
+public abstract class Event {
+
+ public final UUID id = UUID.randomUUID();
+
+ public final Date created = new Date();
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserAddressAddedEvent.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserAddressAddedEvent.java
new file mode 100644
index 0000000000..caa640798b
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserAddressAddedEvent.java
@@ -0,0 +1,16 @@
+package com.baeldung.patterns.es.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class UserAddressAddedEvent extends Event {
+
+ private String city;
+ private String state;
+ private String postCode;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserAddressRemovedEvent.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserAddressRemovedEvent.java
new file mode 100644
index 0000000000..f0702d8810
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserAddressRemovedEvent.java
@@ -0,0 +1,16 @@
+package com.baeldung.patterns.es.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class UserAddressRemovedEvent extends Event {
+
+ private String city;
+ private String state;
+ private String postCode;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserContactAddedEvent.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserContactAddedEvent.java
new file mode 100644
index 0000000000..0bce2f997e
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserContactAddedEvent.java
@@ -0,0 +1,15 @@
+package com.baeldung.patterns.es.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class UserContactAddedEvent extends Event {
+
+ private String contactType;
+ private String contactDetails;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserContactRemovedEvent.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserContactRemovedEvent.java
new file mode 100644
index 0000000000..9c043971e7
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserContactRemovedEvent.java
@@ -0,0 +1,15 @@
+package com.baeldung.patterns.es.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class UserContactRemovedEvent extends Event {
+
+ private String contactType;
+ private String contactDetails;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserCreatedEvent.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserCreatedEvent.java
new file mode 100644
index 0000000000..8e725cd667
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserCreatedEvent.java
@@ -0,0 +1,16 @@
+package com.baeldung.patterns.es.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class UserCreatedEvent extends Event {
+
+ private String userId;
+ private String firstName;
+ private String lastName;
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserRemovedEvent.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserRemovedEvent.java
new file mode 100644
index 0000000000..b609cb1daf
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/events/UserRemovedEvent.java
@@ -0,0 +1,12 @@
+package com.baeldung.patterns.es.events;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class UserRemovedEvent extends Event {
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/repository/EventStore.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/repository/EventStore.java
new file mode 100644
index 0000000000..87914d8c12
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/repository/EventStore.java
@@ -0,0 +1,29 @@
+package com.baeldung.patterns.es.repository;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.baeldung.patterns.es.events.Event;
+
+public class EventStore {
+
+ private Map> store = new HashMap<>();
+
+ public void addEvent(String id, Event event) {
+ List events = store.get(id);
+ if (events == null) {
+ events = new ArrayList();
+ events.add(event);
+ store.put(id, events);
+ } else {
+ events.add(event);
+ }
+ }
+
+ public List getEvents(String id) {
+ return store.get(id);
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/service/UserService.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/service/UserService.java
new file mode 100644
index 0000000000..0233453d68
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/service/UserService.java
@@ -0,0 +1,94 @@
+package com.baeldung.patterns.es.service;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.User;
+import com.baeldung.patterns.es.events.UserAddressAddedEvent;
+import com.baeldung.patterns.es.events.UserAddressRemovedEvent;
+import com.baeldung.patterns.es.events.UserContactAddedEvent;
+import com.baeldung.patterns.es.events.UserContactRemovedEvent;
+import com.baeldung.patterns.es.events.UserCreatedEvent;
+import com.baeldung.patterns.es.repository.EventStore;
+
+public class UserService {
+
+ private EventStore repository;
+
+ public UserService(EventStore repository) {
+ this.repository = repository;
+ }
+
+ public void createUser(String userId, String firstName, String lastName) {
+ UserCreatedEvent event = new UserCreatedEvent(userId, firstName, lastName);
+ repository.addEvent(userId, event);
+ }
+
+ public void updateUser(String userId, Set contacts, Set addresses) throws Exception {
+ User user = UserUtility.recreateUserState(repository, userId);
+ if (user == null)
+ throw new Exception("User does not exist.");
+
+ List contactsToRemove = user.getContacts()
+ .stream()
+ .filter(c -> !contacts.contains(c))
+ .collect(Collectors.toList());
+ for (Contact contact : contactsToRemove) {
+ UserContactRemovedEvent contactRemovedEvent = new UserContactRemovedEvent(contact.getType(), contact.getDetail());
+ repository.addEvent(userId, contactRemovedEvent);
+ }
+
+ List contactsToAdd = contacts.stream()
+ .filter(c -> !user.getContacts()
+ .contains(c))
+ .collect(Collectors.toList());
+ for (Contact contact : contactsToAdd) {
+ UserContactAddedEvent contactAddedEvent = new UserContactAddedEvent(contact.getType(), contact.getDetail());
+ repository.addEvent(userId, contactAddedEvent);
+ }
+
+ List addressesToRemove = user.getAddresses()
+ .stream()
+ .filter(a -> !addresses.contains(a))
+ .collect(Collectors.toList());
+ for (Address address : addressesToRemove) {
+ UserAddressRemovedEvent addressRemovedEvent = new UserAddressRemovedEvent(address.getCity(), address.getState(), address.getPostcode());
+ repository.addEvent(userId, addressRemovedEvent);
+ }
+
+ List addressesToAdd = addresses.stream()
+ .filter(a -> !user.getAddresses()
+ .contains(a))
+ .collect(Collectors.toList());
+ for (Address address : addressesToAdd) {
+ UserAddressAddedEvent addressAddedEvent = new UserAddressAddedEvent(address.getCity(), address.getState(), address.getPostcode());
+ repository.addEvent(userId, addressAddedEvent);
+ }
+ }
+
+ public Set getContactByType(String userId, String contactType) throws Exception {
+ User user = UserUtility.recreateUserState(repository, userId);
+ if (user == null)
+ throw new Exception("User does not exist.");
+ Set contacts = user.getContacts();
+ return contacts.stream()
+ .filter(c -> c.getType()
+ .equals(contactType))
+ .collect(Collectors.toSet());
+ }
+
+ public Set getAddressByRegion(String userId, String state) throws Exception {
+ User user = UserUtility.recreateUserState(repository, userId);
+ if (user == null)
+ throw new Exception("User does not exist.");
+ Set addresses = user.getAddresses();
+ return addresses.stream()
+ .filter(a -> a.getState()
+ .equals(state))
+ .collect(Collectors.toSet());
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/es/service/UserUtility.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/service/UserUtility.java
new file mode 100644
index 0000000000..b7ed9208b2
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/es/service/UserUtility.java
@@ -0,0 +1,66 @@
+package com.baeldung.patterns.es.service;
+
+import java.util.List;
+import java.util.UUID;
+
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.User;
+import com.baeldung.patterns.es.events.Event;
+import com.baeldung.patterns.es.events.UserAddressAddedEvent;
+import com.baeldung.patterns.es.events.UserAddressRemovedEvent;
+import com.baeldung.patterns.es.events.UserContactAddedEvent;
+import com.baeldung.patterns.es.events.UserContactRemovedEvent;
+import com.baeldung.patterns.es.events.UserCreatedEvent;
+import com.baeldung.patterns.es.events.UserRemovedEvent;
+import com.baeldung.patterns.es.repository.EventStore;
+
+public class UserUtility {
+
+ public static User recreateUserState(EventStore store, String userId) {
+ User user = null;
+
+ List events = store.getEvents(userId);
+ for (Event event : events) {
+ if (event instanceof UserCreatedEvent) {
+ UserCreatedEvent e = (UserCreatedEvent) event;
+ user = new User(UUID.randomUUID()
+ .toString(), e.getFirstName(), e.getLastName());
+ }
+ if (event instanceof UserRemovedEvent) {
+ user = null;
+ }
+ if (event instanceof UserAddressAddedEvent) {
+ UserAddressAddedEvent e = (UserAddressAddedEvent) event;
+ Address address = new Address(e.getCity(), e.getState(), e.getPostCode());
+ if (user != null)
+ user.getAddresses()
+ .add(address);
+ }
+ if (event instanceof UserAddressRemovedEvent) {
+ UserAddressRemovedEvent e = (UserAddressRemovedEvent) event;
+ Address address = new Address(e.getCity(), e.getState(), e.getPostCode());
+ if (user != null)
+ user.getAddresses()
+ .remove(address);
+ }
+ if (event instanceof UserContactAddedEvent) {
+ UserContactAddedEvent e = (UserContactAddedEvent) event;
+ Contact contact = new Contact(e.getContactType(), e.getContactDetails());
+ if (user != null)
+ user.getContacts()
+ .add(contact);
+ }
+ if (event instanceof UserContactRemovedEvent) {
+ UserContactRemovedEvent e = (UserContactRemovedEvent) event;
+ Contact contact = new Contact(e.getContactType(), e.getContactDetails());
+ if (user != null)
+ user.getContacts()
+ .remove(contact);
+ }
+ }
+
+ return user;
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/Main.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/Main.java
new file mode 100644
index 0000000000..44395a75a7
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/Main.java
@@ -0,0 +1,61 @@
+package com.baeldung.patterns.escqrs;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.baeldung.patterns.cqrs.commands.CreateUserCommand;
+import com.baeldung.patterns.cqrs.commands.UpdateUserCommand;
+import com.baeldung.patterns.cqrs.projections.UserProjection;
+import com.baeldung.patterns.cqrs.queries.AddressByRegionQuery;
+import com.baeldung.patterns.cqrs.queries.ContactByTypeQuery;
+import com.baeldung.patterns.cqrs.repository.UserReadRepository;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.es.events.Event;
+import com.baeldung.patterns.es.repository.EventStore;
+import com.baeldung.patterns.escqrs.aggregates.UserAggregate;
+import com.baeldung.patterns.escqrs.projectors.UserProjector;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+
+ EventStore writeRepository = new EventStore();
+ UserReadRepository readRepository = new UserReadRepository();
+ UserProjector projector = new UserProjector(readRepository);
+ UserAggregate userAggregate = new UserAggregate(writeRepository);
+ UserProjection userProjection = new UserProjection(readRepository);
+
+ String userId = UUID.randomUUID()
+ .toString();
+ List events = null;
+ CreateUserCommand createUserCommand = new CreateUserCommand(userId, "Kumar", "Chandrakant");
+ events = userAggregate.handleCreateUserCommand(createUserCommand);
+
+ projector.project(userId, events);
+
+ UpdateUserCommand updateUserCommand = new UpdateUserCommand(userId, Stream.of(new Address("New York", "NY", "10001"), new Address("Los Angeles", "CA", "90001"))
+ .collect(Collectors.toSet()),
+ Stream.of(new Contact("EMAIL", "tom.sawyer@gmail.com"), new Contact("EMAIL", "tom.sawyer@rediff.com"))
+ .collect(Collectors.toSet()));
+ events = userAggregate.handleUpdateUserCommand(updateUserCommand);
+ projector.project(userId, events);
+
+ updateUserCommand = new UpdateUserCommand(userId, Stream.of(new Address("New York", "NY", "10001"), new Address("Housten", "TX", "77001"))
+ .collect(Collectors.toSet()),
+ Stream.of(new Contact("EMAIL", "tom.sawyer@gmail.com"), new Contact("PHONE", "700-000-0001"))
+ .collect(Collectors.toSet()));
+ events = userAggregate.handleUpdateUserCommand(updateUserCommand);
+ projector.project(userId, events);
+
+ AddressByRegionQuery addressByRegionQuery = new AddressByRegionQuery(userId, "NY");
+ System.out.println(userProjection.handle(addressByRegionQuery));
+
+ ContactByTypeQuery contactByTypeQuery = new ContactByTypeQuery(userId, "EMAIL");
+ System.out.println(userProjection.handle(contactByTypeQuery));
+
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/aggregates/UserAggregate.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/aggregates/UserAggregate.java
new file mode 100644
index 0000000000..7d32aeb2a2
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/aggregates/UserAggregate.java
@@ -0,0 +1,87 @@
+package com.baeldung.patterns.escqrs.aggregates;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.baeldung.patterns.cqrs.commands.CreateUserCommand;
+import com.baeldung.patterns.cqrs.commands.UpdateUserCommand;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.User;
+import com.baeldung.patterns.es.events.Event;
+import com.baeldung.patterns.es.events.UserAddressAddedEvent;
+import com.baeldung.patterns.es.events.UserAddressRemovedEvent;
+import com.baeldung.patterns.es.events.UserContactAddedEvent;
+import com.baeldung.patterns.es.events.UserContactRemovedEvent;
+import com.baeldung.patterns.es.events.UserCreatedEvent;
+import com.baeldung.patterns.es.repository.EventStore;
+import com.baeldung.patterns.es.service.UserUtility;
+
+public class UserAggregate {
+
+ private EventStore writeRepository;
+
+ public UserAggregate(EventStore repository) {
+ this.writeRepository = repository;
+ }
+
+ public List handleCreateUserCommand(CreateUserCommand command) {
+ UserCreatedEvent event = new UserCreatedEvent(command.getUserId(), command.getFiratName(), command.getLastName());
+ writeRepository.addEvent(command.getUserId(), event);
+ return Arrays.asList(event);
+ }
+
+ public List handleUpdateUserCommand(UpdateUserCommand command) {
+ User user = UserUtility.recreateUserState(writeRepository, command.getUserId());
+ List events = new ArrayList<>();
+
+ List contactsToRemove = user.getContacts()
+ .stream()
+ .filter(c -> !command.getContacts()
+ .contains(c))
+ .collect(Collectors.toList());
+ for (Contact contact : contactsToRemove) {
+ UserContactRemovedEvent contactRemovedEvent = new UserContactRemovedEvent(contact.getType(), contact.getDetail());
+ events.add(contactRemovedEvent);
+ writeRepository.addEvent(command.getUserId(), contactRemovedEvent);
+ }
+
+ List contactsToAdd = command.getContacts()
+ .stream()
+ .filter(c -> !user.getContacts()
+ .contains(c))
+ .collect(Collectors.toList());
+ for (Contact contact : contactsToAdd) {
+ UserContactAddedEvent contactAddedEvent = new UserContactAddedEvent(contact.getType(), contact.getDetail());
+ events.add(contactAddedEvent);
+ writeRepository.addEvent(command.getUserId(), contactAddedEvent);
+ }
+
+ List addressesToRemove = user.getAddresses()
+ .stream()
+ .filter(a -> !command.getAddresses()
+ .contains(a))
+ .collect(Collectors.toList());
+ for (Address address : addressesToRemove) {
+ UserAddressRemovedEvent addressRemovedEvent = new UserAddressRemovedEvent(address.getCity(), address.getState(), address.getPostcode());
+ events.add(addressRemovedEvent);
+ writeRepository.addEvent(command.getUserId(), addressRemovedEvent);
+ }
+
+ List addressesToAdd = command.getAddresses()
+ .stream()
+ .filter(a -> !user.getAddresses()
+ .contains(a))
+ .collect(Collectors.toList());
+ for (Address address : addressesToAdd) {
+ UserAddressAddedEvent addressAddedEvent = new UserAddressAddedEvent(address.getCity(), address.getState(), address.getPostcode());
+ events.add(addressAddedEvent);
+ writeRepository.addEvent(command.getUserId(), addressAddedEvent);
+ }
+
+ return events;
+ }
+
+}
diff --git a/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/projectors/UserProjector.java b/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/projectors/UserProjector.java
new file mode 100644
index 0000000000..036b6e8396
--- /dev/null
+++ b/java-es-cqrs/src/main/java/com/baeldung/patterns/escqrs/projectors/UserProjector.java
@@ -0,0 +1,123 @@
+package com.baeldung.patterns.escqrs.projectors;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.baeldung.patterns.cqrs.repository.UserReadRepository;
+import com.baeldung.patterns.domain.Address;
+import com.baeldung.patterns.domain.Contact;
+import com.baeldung.patterns.domain.UserAddress;
+import com.baeldung.patterns.domain.UserContact;
+import com.baeldung.patterns.es.events.Event;
+import com.baeldung.patterns.es.events.UserAddressAddedEvent;
+import com.baeldung.patterns.es.events.UserAddressRemovedEvent;
+import com.baeldung.patterns.es.events.UserContactAddedEvent;
+import com.baeldung.patterns.es.events.UserContactRemovedEvent;
+import com.baeldung.patterns.es.events.UserCreatedEvent;
+import com.baeldung.patterns.es.events.UserRemovedEvent;
+
+public class UserProjector {
+
+ UserReadRepository readRepository = new UserReadRepository();
+
+ public UserProjector(UserReadRepository readRepository) {
+ this.readRepository = readRepository;
+ }
+
+ public void project(String userId, List events) {
+
+ for (Event event : events) {
+ if (event instanceof UserCreatedEvent)
+ apply(userId, (UserCreatedEvent) event);
+ if (event instanceof UserRemovedEvent)
+ apply(userId, (UserRemovedEvent) event);
+ if (event instanceof UserAddressAddedEvent)
+ apply(userId, (UserAddressAddedEvent) event);
+ if (event instanceof UserAddressRemovedEvent)
+ apply(userId, (UserAddressRemovedEvent) event);
+ if (event instanceof UserContactAddedEvent)
+ apply(userId, (UserContactAddedEvent) event);
+ if (event instanceof UserContactRemovedEvent)
+ apply(userId, (UserContactRemovedEvent) event);
+ }
+
+ }
+
+ public void apply(String userId, UserCreatedEvent event) {
+
+ }
+
+ public void apply(String userId, UserRemovedEvent event) {
+
+ }
+
+ public void apply(String userId, UserAddressAddedEvent event) {
+ Address address = new Address(event.getCity(), event.getState(), event.getPostCode());
+ UserAddress userAddress = readRepository.getUserAddress(userId);
+ if (userAddress == null)
+ userAddress = new UserAddress();
+ userAddress.getAddresses()
+ .add(address);
+ Set addresses = userAddress.getAddressByRegion()
+ .get(address.getState());
+ if (addresses == null)
+ addresses = new HashSet<>();
+ addresses.add(address);
+ userAddress.getAddressByRegion()
+ .put(address.getState(), addresses);
+ readRepository.addUserAddress(userId, userAddress);
+ }
+
+ public void apply(String userId, UserAddressRemovedEvent event) {
+ Address address = new Address(event.getCity(), event.getState(), event.getPostCode());
+ UserAddress userAddress = readRepository.getUserAddress(userId);
+ if (userAddress != null) {
+ userAddress.getAddresses()
+ .remove(address);
+ Set addresses = userAddress.getAddressByRegion()
+ .get(address.getState());
+ if (addresses != null) {
+ addresses.remove(address);
+ userAddress.getAddressByRegion()
+ .put(address.getState(), addresses);
+ }
+ readRepository.addUserAddress(userId, userAddress);
+ }
+ }
+
+ public void apply(String userId, UserContactAddedEvent event) {
+ Contact contact = new Contact(event.getContactType(), event.getContactDetails());
+ UserContact userContact = readRepository.getUserContact(userId);
+ if (userContact == null)
+ userContact = new UserContact();
+ userContact.getContacts()
+ .add(contact);
+ Set contacts = userContact.getContactByType()
+ .get(contact.getType());
+ if (contacts == null)
+ contacts = new HashSet<>();
+ contacts.add(contact);
+ userContact.getContactByType()
+ .put(contact.getType(), contacts);
+ readRepository.addUserContact(userId, userContact);
+ }
+
+ public void apply(String userId, UserContactRemovedEvent event) {
+ Contact contact = new Contact(event.getContactType(), event.getContactDetails());
+ UserContact userContact = readRepository.getUserContact(userId);
+ if (userContact != null) {
+ userContact.getContacts()
+ .remove(contact);
+ Set contacts = userContact.getContactByType()
+ .get(contact.getType());
+ if (contacts != null) {
+ contacts.remove(contact);
+ userContact.getContactByType()
+ .put(contact.getType(), contacts);
+ }
+ readRepository.addUserContact(userId, userContact);
+ }
+ }
+
+}