Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/pull-request-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ jobs:
java-version: 21

- name: Build & Test
run: ./gradlew clean build
run: ./gradlew clean build

- name: Spotless Check
run: ./gradlew spotlessCheck
1 change: 0 additions & 1 deletion HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ For further reference, please consider the following sections:
These additional references should also help you:

* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)

74 changes: 47 additions & 27 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,51 +1,71 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'io.freefair.lombok' version '8.13.1'
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'io.freefair.lombok' version '8.13.1'
id 'com.diffplug.spotless' version '7.0.4'
}

group = 'io.autoinvestor'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

repositories {
mavenCentral()
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

implementation 'com.google.cloud:google-cloud-pubsub:1.123.0'
implementation "com.google.cloud:spring-cloud-gcp-starter-pubsub:6.1.1"
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.springframework.integration:spring-integration-core'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'com.google.cloud:google-cloud-pubsub:1.123.0'
implementation "com.google.cloud:spring-cloud-gcp-starter-pubsub:6.1.1"
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.springframework.integration:spring-integration-core'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'

testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:gcloud'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:gcloud'

compileOnly 'org.projectlombok:lombok:1.18.38'
annotationProcessor 'org.projectlombok:lombok:1.18.38'
compileOnly 'org.projectlombok:lombok:1.18.38'
annotationProcessor 'org.projectlombok:lombok:1.18.38'

testCompileOnly 'org.projectlombok:lombok:1.18.38'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.38'
testCompileOnly 'org.projectlombok:lombok:1.18.38'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.38'
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}
tasks.withType(JavaCompile).configureEach {
options.compilerArgs << '-parameters'
options.compilerArgs << '-parameters'
}
bootBuildImage {
publish = false
publish = false
}

spotless {
java {
googleJavaFormat('1.22.0').aosp()
removeUnusedImports()
trimTrailingWhitespace()
leadingTabsToSpaces()
endWithNewline()
importOrder '', 'java', 'javax', 'org', 'com'
target 'src/**/*.java'
}

format 'misc', {
target '*.gradle', '*.md', '.gitignore'
leadingTabsToSpaces()
trimTrailingWhitespace()
endWithNewline()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,4 @@
import jakarta.annotation.Nullable;

public record RegisterUserCommand(
@Nullable String firstName,
@Nullable String lastName,
String email,
Integer riskLevel
) {
}
@Nullable String firstName, @Nullable String lastName, String email, Integer riskLevel) {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import io.autoinvestor.application.UserDTO;
import io.autoinvestor.application.UsersReadModel;
import io.autoinvestor.domain.EventStore;
import io.autoinvestor.domain.events.Event;
import io.autoinvestor.domain.events.EventPublisher;
import io.autoinvestor.domain.EventStore;
import io.autoinvestor.domain.model.User;
import io.autoinvestor.exceptions.BadRequestException;
import lombok.RequiredArgsConstructor;

import java.util.List;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -29,19 +30,24 @@ public void handle(RegisterUserCommand command) {
throw UserRegisteredAlreadyExists.with(command.email());
}

User user = User.create(command.firstName(), command.lastName(), command.email(), command.riskLevel());
User user =
User.create(
command.firstName(),
command.lastName(),
command.email(),
command.riskLevel());

List<Event<?>> events = user.getUncommittedEvents();

this.eventStore.save(user);

UserDTO dto = new UserDTO(
user.getState().userId().value(),
command.email(),
command.firstName(),
command.lastName(),
command.riskLevel()
);
UserDTO dto =
new UserDTO(
user.getState().userId().value(),
command.email(),
command.firstName(),
command.lastName(),
command.riskLevel());
this.readModel.save(dto);

this.eventPublisher.publish(events);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
package io.autoinvestor.application.RequestUserById;

public record GetUserByIdQuery(String userId) {
}
public record GetUserByIdQuery(String userId) {}
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
package io.autoinvestor.application.RequestUserById;

import io.autoinvestor.application.UserNotFound;
import io.autoinvestor.application.UserDTO;
import io.autoinvestor.application.UserNotFound;
import io.autoinvestor.application.UsersReadModel;
import io.autoinvestor.ui.UserResponse;
import lombok.RequiredArgsConstructor;

import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class GetUserByIdQueryHandler {
private final UsersReadModel readModel;

public UserResponse handle (GetUserByIdQuery query) {
UserDTO dto = this.readModel.getById(query.userId())
.orElseThrow(() -> UserNotFound.with(query.userId()));
public UserResponse handle(GetUserByIdQuery query) {
UserDTO dto =
this.readModel
.getById(query.userId())
.orElseThrow(() -> UserNotFound.with(query.userId()));

return new UserResponse(
dto.userId(),
dto.firstName(),
dto.lastName(),
dto.email(),
dto.riskLevel()
);
dto.userId(), dto.firstName(), dto.lastName(), dto.email(), dto.riskLevel());
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
package io.autoinvestor.application.RequestUserUseCase;

public record GetUserQuery(String email) {
}
public record GetUserQuery(String email) {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.autoinvestor.application.UsersReadModel;
import io.autoinvestor.ui.UserResponse;
import lombok.RequiredArgsConstructor;

import org.springframework.stereotype.Service;

@Service
Expand All @@ -14,15 +15,12 @@ public class GetUserQueryHandler {
private final UsersReadModel usersReadModel;

public UserResponse handle(GetUserQuery query) {
UserDTO dto = this.usersReadModel.get(query.email())
.orElseThrow(() -> UserNotFound.with(query.email()));
UserDTO dto =
this.usersReadModel
.get(query.email())
.orElseThrow(() -> UserNotFound.with(query.email()));

return new UserResponse(
dto.userId(),
dto.firstName(),
dto.lastName(),
dto.email(),
dto.riskLevel()
);
dto.userId(), dto.firstName(), dto.lastName(), dto.email(), dto.riskLevel());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
package io.autoinvestor.application.UpdateUserUseCase;

public record UpdateUserCommand(
String userId,
int riskLevel
) {
}
public record UpdateUserCommand(String userId, int riskLevel) {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import io.autoinvestor.domain.model.User;
import io.autoinvestor.domain.model.UserId;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
Expand All @@ -22,31 +22,32 @@ public class UpdateUserCommandHandler {
private final EventPublisher eventPublisher;
private final UsersReadModel readModel;

public void handle(UpdateUserCommand command) {

public void handle (UpdateUserCommand command) {

String userIdToUpdate = String.valueOf(readModel.getById(command.userId())
.map(UserDTO::userId)
.orElseThrow(() -> UserNotFound.with(command.userId())));
String userIdToUpdate =
String.valueOf(
readModel
.getById(command.userId())
.map(UserDTO::userId)
.orElseThrow(() -> UserNotFound.with(command.userId())));
User user = this.eventStore.get(UserId.from(userIdToUpdate));
user.update(userIdToUpdate, command.riskLevel());

List<Event<?>> events = user.getUncommittedEvents();

this.eventStore.save(user);

UserDTO dto = new UserDTO(
user.getState().userId().value(),
user.getState().userEmail().value(),
user.getState().firstName().value(),
user.getState().lastName().value(),
command.riskLevel()
);
UserDTO dto =
new UserDTO(
user.getState().userId().value(),
user.getState().userEmail().value(),
user.getState().firstName().value(),
user.getState().lastName().value(),
command.riskLevel());
this.readModel.update(dto);

this.eventPublisher.publish(events);

user.markEventsAsCommitted();

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ private UserDoesntExist(String message) {
}

public static UserDoesntExist with(String userId) {
String message = "User with id " + userId + "doesn't exist";
String message = "User with id " + userId + "doesn't exist";
return new UserDoesntExist(message);
}

}
8 changes: 2 additions & 6 deletions src/main/java/io/autoinvestor/application/UserDTO.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
package io.autoinvestor.application;

public record UserDTO(String userId,
String email,
String firstName,
String lastName,
int riskLevel) {
}
public record UserDTO(
String userId, String email, String firstName, String lastName, int riskLevel) {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.autoinvestor.application;


import java.util.Optional;

public interface UsersReadModel {
void save(UserDTO user);

Optional<UserDTO> get(String email);

Optional<UserDTO> getById(String userId);

void update(UserDTO dto);
}
2 changes: 1 addition & 1 deletion src/main/java/io/autoinvestor/domain/EventStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import io.autoinvestor.domain.model.User;
import io.autoinvestor.domain.model.UserId;


public interface EventStore {
void save(User user);

User get(UserId userId);
}
6 changes: 2 additions & 4 deletions src/main/java/io/autoinvestor/domain/Id.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ protected static String generateId() {

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Id that))
return false;
if (this == o) return true;
if (!(o instanceof Id that)) return false;
return Objects.equals(id, that.id);
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/io/autoinvestor/domain/events/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ protected Event(Id aggregateId, String type, P payload, int version) {
this.version = version;
}

protected Event(EventId id, Id aggregateId, String type, P payload, Date occurredAt, int version) {
protected Event(
EventId id, Id aggregateId, String type, P payload, Date occurredAt, int version) {
this.id = id;
this.aggregateId = aggregateId;
this.type = type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,3 @@ public void markEventsAsCommitted() {
appliedEvents.clear();
}
}

Loading