Skip to content

Commit cc4beae

Browse files
authored
fix: update endpoints to correctly store events and persiste them in MongoDB (#44)
1 parent 0972e44 commit cc4beae

65 files changed

Lines changed: 877 additions & 646 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,23 @@ dependencies {
2121
implementation 'org.springframework.boot:spring-boot-starter-web'
2222
testImplementation 'org.springframework.boot:spring-boot-starter-test'
2323
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
24-
implementation 'org.springframework.security:spring-security-core:'
25-
implementation 'io.jsonwebtoken:jjwt:0.12.6'
26-
implementation 'io.github.cdimascio:java-dotenv:5.2.2'
27-
implementation platform("com.google.cloud:spring-cloud-gcp-dependencies:6.1.1")
28-
implementation 'com.google.cloud:spring-cloud-gcp-starter-pubsub'
24+
25+
implementation 'com.google.cloud:google-cloud-pubsub:1.123.0'
26+
implementation "com.google.cloud:spring-cloud-gcp-starter-pubsub:6.1.1"
27+
implementation 'com.fasterxml.jackson.core:jackson-databind'
2928
implementation 'org.springframework.integration:spring-integration-core'
30-
implementation 'com.google.cloud:google-cloud-pubsub:1.113.7'
3129
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
3230

31+
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
32+
testImplementation 'org.testcontainers:testcontainers'
33+
testImplementation 'org.testcontainers:junit-jupiter'
34+
testImplementation 'org.testcontainers:gcloud'
35+
36+
compileOnly 'org.projectlombok:lombok:1.18.38'
37+
annotationProcessor 'org.projectlombok:lombok:1.18.38'
38+
39+
testCompileOnly 'org.projectlombok:lombok:1.18.38'
40+
testAnnotationProcessor 'org.projectlombok:lombok:1.18.38'
3341
}
3442

3543
tasks.named('test') {

src/main/java/io/autoinvestor/application/PasswordService.java

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package io.autoinvestor.application.RegisterUserUseCase;
22

3+
import io.autoinvestor.application.UserDTO;
34
import io.autoinvestor.application.UsersReadModel;
4-
import io.autoinvestor.domain.Event;
5-
import io.autoinvestor.domain.EventPublisher;
6-
import io.autoinvestor.domain.UserRepository;
7-
import io.autoinvestor.domain.users.User;
5+
import io.autoinvestor.domain.events.Event;
6+
import io.autoinvestor.domain.events.EventPublisher;
7+
import io.autoinvestor.domain.EventStore;
8+
import io.autoinvestor.domain.model.User;
89
import io.autoinvestor.exceptions.BadRequestException;
9-
import io.autoinvestor.infrastructure.UserCreatedEventMessageMapper;
10-
import io.autoinvestor.infrastructure.UserCreatedMessage;
11-
import io.autoinvestor.infrastructure.UsersEventPublisher;
1210
import java.util.List;
1311

1412
import lombok.RequiredArgsConstructor;
@@ -18,25 +16,36 @@
1816
@RequiredArgsConstructor
1917
public class RegisterUserCommandHandler {
2018

21-
private final UserRepository repository;
19+
private final EventStore eventStore;
2220
private final EventPublisher eventPublisher;
23-
private final UsersEventPublisher usersEventPublisher;
24-
private final UserCreatedEventMessageMapper userCreatedEventMessageMapper;
25-
private final UsersReadModel usersReadModel;
21+
private final UsersReadModel readModel;
2622

2723
public void handle(RegisterUserCommand command) {
2824
if (command.email() == null || command.email().isBlank()) {
2925
throw new BadRequestException("Email cannot be null or empty");
3026
}
31-
if (usersReadModel.get(command.email()) != null) {
27+
28+
if (this.readModel.get(command.email()).isPresent()) {
3229
throw UserRegisteredAlreadyExists.with(command.email());
3330
}
3431

3532
User user = User.create(command.firstName(), command.lastName(), command.email(), command.riskLevel());
36-
List<Event<?>> uncommittedEvents = user.releaseEvents();
37-
this.repository.save(uncommittedEvents);
38-
this.eventPublisher.publish(uncommittedEvents);
39-
List<UserCreatedMessage> userCreatedMessages = this.userCreatedEventMessageMapper.map(uncommittedEvents);
40-
this.usersEventPublisher.publishUserCreated(userCreatedMessages);
33+
34+
List<Event<?>> events = user.getUncommittedEvents();
35+
36+
this.eventStore.save(user);
37+
38+
UserDTO dto = new UserDTO(
39+
user.getState().userId().value(),
40+
command.email(),
41+
command.firstName(),
42+
command.lastName(),
43+
command.riskLevel()
44+
);
45+
this.readModel.save(dto);
46+
47+
this.eventPublisher.publish(events);
48+
49+
user.markEventsAsCommitted();
4150
}
4251
}

src/main/java/io/autoinvestor/application/RequestUserById/GetUserByIdCommandHandler.java

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.autoinvestor.application.RequestUserById;
2+
3+
import io.autoinvestor.application.UserNotFound;
4+
import io.autoinvestor.application.UserDTO;
5+
import io.autoinvestor.application.UsersReadModel;
6+
import io.autoinvestor.ui.UserResponse;
7+
import lombok.RequiredArgsConstructor;
8+
import org.springframework.stereotype.Service;
9+
10+
@Service
11+
@RequiredArgsConstructor
12+
public class GetUserByIdQueryHandler {
13+
private final UsersReadModel readModel;
14+
15+
public UserResponse handle (GetUserByIdQuery query) {
16+
UserDTO dto = this.readModel.getById(query.userId())
17+
.orElseThrow(() -> UserNotFound.with(query.userId()));
18+
19+
return new UserResponse(
20+
dto.userId(),
21+
dto.firstName(),
22+
dto.lastName(),
23+
dto.email(),
24+
dto.riskLevel()
25+
);
26+
}
27+
}
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package io.autoinvestor.application.RequestUserUseCase;
22

3+
import io.autoinvestor.application.UserDTO;
4+
import io.autoinvestor.application.UserNotFound;
35
import io.autoinvestor.application.UsersReadModel;
4-
import io.autoinvestor.ui.user.UserResponse;
6+
import io.autoinvestor.ui.UserResponse;
57
import lombok.RequiredArgsConstructor;
68
import org.springframework.stereotype.Service;
79

@@ -11,10 +13,16 @@ public class GetUserQueryHandler {
1113

1214
private final UsersReadModel usersReadModel;
1315

14-
public UserResponse handle(GetUserQuery getUserQuery) {
15-
if (usersReadModel.get(getUserQuery.email()) == null) {
16-
throw UserNotFound.with(getUserQuery.email());
17-
}
18-
return usersReadModel.get(getUserQuery.email());
16+
public UserResponse handle(GetUserQuery query) {
17+
UserDTO dto = this.usersReadModel.get(query.email())
18+
.orElseThrow(() -> UserNotFound.with(query.email()));
19+
20+
return new UserResponse(
21+
dto.userId(),
22+
dto.firstName(),
23+
dto.lastName(),
24+
dto.email(),
25+
dto.riskLevel()
26+
);
1927
}
2028
}

src/main/java/io/autoinvestor/application/RequestUserUseCase/UserNotFound.java

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.autoinvestor.application;
2+
3+
public record UserDTO(String userId,
4+
String email,
5+
String firstName,
6+
String lastName,
7+
int riskLevel) {
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.autoinvestor.application;
2+
3+
public class UserNotFound extends RuntimeException {
4+
private UserNotFound(String message) {
5+
super(message);
6+
}
7+
8+
public static UserNotFound with(String name) {
9+
String message = "User with id/email " + name + " doesn't exist.";
10+
return new UserNotFound(message);
11+
}
12+
}
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package io.autoinvestor.application;
22

3-
import io.autoinvestor.infrastructure.UserReadModelDocument;
4-
import io.autoinvestor.ui.user.UserResponse;
53

6-
public interface UsersReadModel {
7-
8-
void add(UserReadModelDocument document);
4+
import java.util.Optional;
95

10-
UserResponse get(String email);
11-
UserResponse getById(String userId);
6+
public interface UsersReadModel {
7+
void save(UserDTO user);
8+
Optional<UserDTO> get(String email);
9+
Optional<UserDTO> getById(String userId);
1210
}

0 commit comments

Comments
 (0)