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
22 changes: 13 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,24 @@ 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.security:spring-security-core:'
implementation 'io.jsonwebtoken:jjwt:0.12.6'
implementation 'io.github.cdimascio:java-dotenv:5.2.2'
implementation platform("com.google.cloud:spring-cloud-gcp-dependencies:6.1.1")
implementation 'com.google.cloud:spring-cloud-gcp-starter-pubsub'

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 'com.google.cloud:google-cloud-pubsub:1.113.7'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation("jakarta.validation:jakarta.validation-api:3.0.2")
implementation("org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.2.5.RELEASE")
implementation("org.springframework.integration:spring-integration-core")
implementation 'com.google.cloud:spring-cloud-gcp-starter-pubsub'

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'

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

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.autoinvestor.application;

import java.util.List;

public interface HoldingsReadModel {
void add(HoldingsReadModelDTO dto);
void update(HoldingsReadModelDTO dto);
List<HoldingsReadModelDTO> getHoldings(String userId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.autoinvestor.application;

public record ComplexReadModelDTO(
public record HoldingsReadModelDTO(
String userId,
String assetId,
Integer amount,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.autoinvestor.application.NewHoldingUseCase;

import io.autoinvestor.application.ComplexReadModelDTO;
import io.autoinvestor.application.ReadModel;
import io.autoinvestor.domain.*;
import io.autoinvestor.application.HoldingsReadModel;
import io.autoinvestor.application.HoldingsReadModelDTO;
import io.autoinvestor.application.UsersWalletReadModel;
import io.autoinvestor.domain.events.Event;
import io.autoinvestor.domain.events.EventPublisher;
import io.autoinvestor.domain.events.WalletEventStoreRepository;
import io.autoinvestor.domain.model.AssetId;
import io.autoinvestor.domain.model.Wallet;
import io.autoinvestor.domain.model.WalletId;
import io.autoinvestor.exceptions.UserWithoutPortfolio;
import io.autoinvestor.infrastructure.EventMessageMapper;
import io.autoinvestor.infrastructure.EventPublisherQueue;
import io.autoinvestor.infrastructure.HoldingAddedOrUpdatedMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -16,29 +19,37 @@
@RequiredArgsConstructor
public class NewHoldingCommandHandler {

private final WalletRepository eventRepository;
private final ReadModel readModel;
private final EventMessageMapper messageMapper;
private final EventPublisherQueue eventPublisher;
private final WalletEventStoreRepository eventStore;
private final UsersWalletReadModel usersWalletReadModel;
private final HoldingsReadModel holdingsReadModel;
private final EventPublisher eventPublisher;

public void handle (NewHoldingCommand command) {
String walletId = readModel.getWalletId(command.userId());
public void handle(NewHoldingCommand command) {
String walletId = this.usersWalletReadModel.getWalletId(command.userId());
if (walletId == null) {
throw UserWithoutPortfolio.with(command.userId());
}
Wallet wallet = eventRepository.get(walletId);
wallet.newHolding(command.userId(), command.assetId(), command.amount(), command.boughtPrice());
List<Event<?>> uncommittedEvents = wallet.releaseEvents();
this.eventRepository.save(uncommittedEvents);
ComplexReadModelDTO dto = new ComplexReadModelDTO(
wallet.getState().userId().value(),

Wallet wallet = this.eventStore.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));

wallet.createHolding(command.userId(), command.assetId(), command.amount(), command.boughtPrice());

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

this.eventStore.save(wallet);

HoldingsReadModelDTO dto = new HoldingsReadModelDTO(
wallet.getState().getUserId().value(),
command.assetId(),
wallet.getState().holdings().get(AssetId.of(command.assetId())).amount().value(),
wallet.getState().holdings().get(AssetId.of(command.assetId())).boughtPrice().value()
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).amount().value(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).boughtPrice().value()

);
readModel.add(dto);
List<HoldingAddedOrUpdatedMessage> holdingAddedMessages = this.messageMapper.mapToHoldingAddedMessage(uncommittedEvents);
this.eventPublisher.publishHoldingAddedOrUpdated(holdingAddedMessages);
this.holdingsReadModel.add(dto);

this.eventPublisher.publish(events);

wallet.markEventsAsCommitted();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.autoinvestor.application.QueryHoldingsUseCase;

import io.autoinvestor.application.ComplexReadModelDTO;
import io.autoinvestor.application.ReadModel;
import io.autoinvestor.application.HoldingsReadModel;
import io.autoinvestor.application.HoldingsReadModelDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -11,9 +11,9 @@
@RequiredArgsConstructor
public class GetHoldingsQueryHandler {

private final ReadModel readModel;
private final HoldingsReadModel readModel;

public List<ComplexReadModelDTO> handle (GetHoldingsQuery query) {
return readModel.getHoldings(query.userId());
public List<HoldingsReadModelDTO> handle (GetHoldingsQuery query) {
return this.readModel.getHoldings(query.userId());
}
}
15 changes: 0 additions & 15 deletions src/main/java/io/autoinvestor/application/ReadModel.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.autoinvestor.application.UptdateHoldingUseCase;

import io.autoinvestor.application.ComplexReadModelDTO;
import io.autoinvestor.application.ReadModel;
import io.autoinvestor.domain.AssetId;
import io.autoinvestor.domain.Event;
import io.autoinvestor.domain.Wallet;
import io.autoinvestor.domain.WalletRepository;
import io.autoinvestor.application.HoldingsReadModel;
import io.autoinvestor.application.HoldingsReadModelDTO;
import io.autoinvestor.application.UsersWalletReadModel;
import io.autoinvestor.domain.events.EventPublisher;
import io.autoinvestor.domain.model.AssetId;
import io.autoinvestor.domain.events.Event;
import io.autoinvestor.domain.model.Wallet;
import io.autoinvestor.domain.events.WalletEventStoreRepository;
import io.autoinvestor.domain.model.WalletId;
import io.autoinvestor.exceptions.UserWithoutPortfolio;
import io.autoinvestor.infrastructure.EventMessageMapper;
import io.autoinvestor.infrastructure.EventPublisherQueue;
import io.autoinvestor.infrastructure.HoldingAddedOrUpdatedMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -19,29 +19,36 @@
@RequiredArgsConstructor
public class UpdateHoldingCommandHandler {

private final ReadModel readModel;
private final WalletRepository eventRepository;
private final EventMessageMapper messageMapper;
private final EventPublisherQueue eventPublisher;
private final UsersWalletReadModel usersWalletReadModel;
private final HoldingsReadModel holdingsReadModel;
private final WalletEventStoreRepository eventStore;
private final EventPublisher eventPublisher;

public void handle (UpdateHoldingCommand command) {
String walletId = readModel.getWalletId(command.userId());
String walletId = this.usersWalletReadModel.getWalletId(command.userId());
if (walletId == null) {
throw UserWithoutPortfolio.with(command.userId());
}
Wallet wallet = eventRepository.get(walletId);

Wallet wallet = this.eventStore.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));

wallet.updateHolding(command.userId(), command.assetId(), command.amount(), command.boughtPrice());
List<Event<?>> uncommittedEvents = wallet.releaseEvents();
this.eventRepository.save(uncommittedEvents);
ComplexReadModelDTO dto = new ComplexReadModelDTO(
wallet.getState().userId().value(),
command.assetId(),
wallet.getState().holdings().get(AssetId.of(command.assetId())).amount().value(),
wallet.getState().holdings().get(AssetId.of(command.assetId())).boughtPrice().value()

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

this.eventStore.save(wallet);

HoldingsReadModelDTO dto = new HoldingsReadModelDTO(
wallet.getState().getUserId().value(),
command.assetId(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).amount().value(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).boughtPrice().value()
);
this.readModel.update(dto);
List<HoldingAddedOrUpdatedMessage> holdingUpdatedMessages = this.messageMapper.mapToHoldingUpdatedMessage(uncommittedEvents);
this.eventPublisher.publishHoldingAddedOrUpdated(holdingUpdatedMessages);
this.holdingsReadModel.update(dto);

this.eventPublisher.publish(events);

wallet.markEventsAsCommitted();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.autoinvestor.application;

public interface UsersWalletReadModel {
void add(UsersWalletReadModelDTO dto);
String getWalletId(String userId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.autoinvestor.application;

public record SimpleReadModelDTO(
public record UsersWalletReadModelDTO(
String walletId,
String userId
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.autoinvestor.application.WalletCreatedUseCase;
import io.autoinvestor.application.SimpleReadModelDTO;
import io.autoinvestor.application.ReadModel;
import io.autoinvestor.domain.Event;
import io.autoinvestor.domain.WalletRepository;
import io.autoinvestor.domain.Wallet;
import io.autoinvestor.application.UsersWalletReadModel;
import io.autoinvestor.application.UsersWalletReadModelDTO;
import io.autoinvestor.domain.events.Event;
import io.autoinvestor.domain.events.WalletEventStoreRepository;
import io.autoinvestor.domain.events.EventPublisher;
import io.autoinvestor.domain.model.Wallet;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

Expand All @@ -13,21 +14,26 @@
@RequiredArgsConstructor
public class WalletCreatedHandler {

private final WalletRepository eventRepository;
private final ReadModel readModel;
private final WalletEventStoreRepository eventStore;
private final EventPublisher eventPublisher;
private final UsersWalletReadModel readModel;

public void handle(WalletCreateCommand command) {
System.out.println("Mensaje recibido en WalletCreatedHandler: " + command.userId());
Wallet wallet = Wallet.create(command.userId());
List<Event<?>> uncomittedEvents = wallet.releaseEvents();
this.eventRepository.save(uncomittedEvents);
SimpleReadModelDTO dto = new SimpleReadModelDTO(
wallet.getState().walletId().value(),
wallet.getState().userId().value()

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

this.eventStore.save(wallet);

UsersWalletReadModelDTO dto = new UsersWalletReadModelDTO(
wallet.getState().getWalletId().value(),
wallet.getState().getUserId().value()
);
readModel.add(dto);
this.readModel.add(dto);

this.eventPublisher.publish(events);

wallet.markEventsAsCommitted();
}
}

39 changes: 0 additions & 39 deletions src/main/java/io/autoinvestor/domain/AggregateRoot.java

This file was deleted.

Loading