diff --git a/build.gradle b/build.gradle index 74f6e53..bb9f775 100644 --- a/build.gradle +++ b/build.gradle @@ -28,13 +28,16 @@ dependencies { implementation 'com.google.cloud:spring-cloud-gcp-starter-pubsub' implementation 'org.springframework.integration:spring-integration-core' implementation 'com.google.cloud:google-cloud-pubsub:1.113.7' + implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' } tasks.named('test') { useJUnitPlatform() } - +tasks.withType(JavaCompile).configureEach { + options.compilerArgs << '-parameters' +} bootBuildImage { imageName = "${System.getenv("DOCKER_NAMESPACE")}/autoinvestor-${rootProject.name}:${System.getenv("DOCKER_IMAGE_VERSION")}" docker { diff --git a/src/main/java/io/autoinvestor/infrastructure/CreateUserEventMapperDocument.java b/src/main/java/io/autoinvestor/infrastructure/CreateUserEventMapperDocument.java new file mode 100644 index 0000000..2ab1568 --- /dev/null +++ b/src/main/java/io/autoinvestor/infrastructure/CreateUserEventMapperDocument.java @@ -0,0 +1,24 @@ +package io.autoinvestor.infrastructure; + +import io.autoinvestor.domain.Event; +import io.autoinvestor.domain.users.UserWasRegisteredEvent; +import io.autoinvestor.domain.users.UserWasRegisteredEventPayload; +import org.springframework.stereotype.Component; + +@Component +public class CreateUserEventMapperDocument { + UserCreatedEventDocument toDocument(Event userCreatedEvent){ + UserWasRegisteredEventPayload payload = (UserWasRegisteredEventPayload) userCreatedEvent.getPayload(); + return new UserCreatedEventDocument( + userCreatedEvent.getId().value(), + userCreatedEvent.getAggregateId().value(), + payload.firstName().value(), + payload.lastName().value(), + payload.email().value(), + payload.riskLevel().value(), + userCreatedEvent.getOccurredAt().toInstant(), + userCreatedEvent.getVersion() + + ); + } +} diff --git a/src/main/java/io/autoinvestor/infrastructure/MongoUserRepository.java b/src/main/java/io/autoinvestor/infrastructure/MongoUserRepository.java new file mode 100644 index 0000000..9b3d469 --- /dev/null +++ b/src/main/java/io/autoinvestor/infrastructure/MongoUserRepository.java @@ -0,0 +1,34 @@ +package io.autoinvestor.infrastructure; + +import io.autoinvestor.domain.Event; +import io.autoinvestor.domain.UserRepository; +import io.grpc.alts.internal.Identity; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Primary; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.stream.Collectors; + + +@Repository +@Primary +public class MongoUserRepository implements UserRepository { + + private final MongoTemplate template; + private final CreateUserEventMapperDocument mapper; + + public MongoUserRepository(MongoTemplate template, CreateUserEventMapperDocument mapper) { + this.template = template; + this.mapper = mapper; + } + + @Override + public void save(List> userEvents) { + List documents = userEvents.stream() + .map(mapper::toDocument) + .collect(Collectors.toList()); + template.insertAll(documents); + } +} diff --git a/src/main/java/io/autoinvestor/infrastructure/UserCreatedEventDocument.java b/src/main/java/io/autoinvestor/infrastructure/UserCreatedEventDocument.java new file mode 100644 index 0000000..e53f945 --- /dev/null +++ b/src/main/java/io/autoinvestor/infrastructure/UserCreatedEventDocument.java @@ -0,0 +1,20 @@ +package io.autoinvestor.infrastructure; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.mapping.Field; + +import java.time.Instant; + +@Document(collection = "userCreated") +public record UserCreatedEventDocument( + @Id String id, + String aggregateId, + String firstName, + String lastName, + String email, + Integer riskLevel, + @Field("occurredAt") Instant occurredAt, + Integer version + +) {} diff --git a/src/main/java/io/autoinvestor/infrastructure/UserReadModelDocument.java b/src/main/java/io/autoinvestor/infrastructure/UserReadModelDocument.java index 7577dc0..9cb10dc 100644 --- a/src/main/java/io/autoinvestor/infrastructure/UserReadModelDocument.java +++ b/src/main/java/io/autoinvestor/infrastructure/UserReadModelDocument.java @@ -1,7 +1,11 @@ package io.autoinvestor.infrastructure; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document(collection = "usersReadModel") public record UserReadModelDocument( - String userId, + @Id String userId, String email, String firstName, String lastName, diff --git a/src/main/java/io/autoinvestor/infrastructure/UserReadModelMongo.java b/src/main/java/io/autoinvestor/infrastructure/UserReadModelMongo.java new file mode 100644 index 0000000..6acb6e4 --- /dev/null +++ b/src/main/java/io/autoinvestor/infrastructure/UserReadModelMongo.java @@ -0,0 +1,35 @@ +package io.autoinvestor.infrastructure; + +import io.autoinvestor.application.UsersReadModel; +import io.autoinvestor.ui.user.UserResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; + +@Repository +@Primary +public class UserReadModelMongo implements UsersReadModel { + + @Autowired + private MongoTemplate mongoTemplate; + + public void add(UserReadModelDocument document) { + mongoTemplate.save(document); + } + + @Override + public UserResponse get(String email) { + Query query = new Query(Criteria.where("email").is(email)); + UserReadModelDocument document = mongoTemplate.findOne(query, UserReadModelDocument.class); + if (document == null) { + return null; + } + return UserResponseDocumentMapper.map(document); + } +} diff --git a/src/main/java/io/autoinvestor/infrastructure/UsersProjection.java b/src/main/java/io/autoinvestor/infrastructure/UsersProjection.java index 79ca90c..4545da8 100644 --- a/src/main/java/io/autoinvestor/infrastructure/UsersProjection.java +++ b/src/main/java/io/autoinvestor/infrastructure/UsersProjection.java @@ -1,16 +1,20 @@ package io.autoinvestor.infrastructure; import io.autoinvestor.domain.users.UserWasRegisteredEvent; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; +import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.stereotype.Component; @Component public class UsersProjection { private final UserReadModelInMemory userReadModelInMemory; + private final UserReadModelMongo userReadModelMongo; - public UsersProjection(UserReadModelInMemory userReadModelInMemory) { + public UsersProjection(UserReadModelInMemory userReadModelInMemory, UserReadModelMongo userReadModelMongo) { this.userReadModelInMemory = userReadModelInMemory; + this.userReadModelMongo = userReadModelMongo; } @EventListener @@ -22,6 +26,7 @@ public void onUserRegistered(UserWasRegisteredEvent userWasRegisteredEvent) { Integer riskLevel = userWasRegisteredEvent.getPayload().riskLevel().value(); UserReadModelDocument userReadModelDocument = new UserReadModelDocument(userId, email, firstName, lastName, riskLevel); - this.userReadModelInMemory.add(userReadModelDocument); + //this.userReadModelInMemory.add(userReadModelDocument); + this.userReadModelMongo.add(userReadModelDocument); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4730e72..282edf2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,2 +1,4 @@ spring.application.name=users -spring.cloud.gcp.pubsub.project-id=autoinvestor-tfm \ No newline at end of file +spring.cloud.gcp.pubsub.project-id=autoinvestor-tfm +spring.data.mongodb.uri=${MONGODB_URI} +spring.data.mongodb.database=${MONGODB_DB} \ No newline at end of file