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
6 changes: 3 additions & 3 deletions Oracle_CQRS/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<version>3.4.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>Oracle_CQRS</artifactId>
Expand All @@ -14,8 +14,8 @@
<java.version>21</java.version>
<lombok.version>1.18.38</lombok.version>
<springdoc-openapi.version>2.8.6</springdoc-openapi.version>
<oracle-spring-boot-starter-ucp.version>25.1.0</oracle-spring-boot-starter-ucp.version>
<oracle-spring-boot-starter-aqjms.version>25.1.0</oracle-spring-boot-starter-aqjms.version>
<oracle-spring-boot-starter-ucp.version>25.2.0</oracle-spring-boot-starter-ucp.version>
<oracle-spring-boot-starter-aqjms.version>25.2.0</oracle-spring-boot-starter-aqjms.version>
</properties>

<dependencies>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.example.oracle.cqrs.command.aggregates;

import jakarta.transaction.Transactional;
import lombok.*;

import lombok.Getter;
import org.example.oracle.cqrs.command.commands.*;
import org.example.oracle.cqrs.common.events.*;
import org.example.oracle.cqrs.command.producers.EventProducer;
Expand Down Expand Up @@ -37,45 +37,8 @@ public AccountAggregate(EventProducer eventProducer, EventStoreRepository eventS

@JmsListener(destination = "${txeventq.queue.commands.name}", id = "sampleCommand")
void handleCommand(BaseCommand command) {

BaseEvent event;

switch (command) {
case CreateAccountCommand createAccountCommand -> {
System.out.println("Handling create: " + command);
if (createAccountCommand.getInitialBalance() < 0)
throw new IllegalArgumentException("Initial balance is negative");

event = new AccountCreatedEvent(UUID.randomUUID().toString(), createAccountCommand.getInitialBalance(), createAccountCommand.getCurrency(), AccountStatus.CREATED, createAccountCommand.getAccountId());

}
case DebitAccountCommand debitAccountCommand -> {
System.out.println("Handling debit: " + command);
if (debitAccountCommand.getAmount() < 0) throw new IllegalArgumentException("Amount is negative");

event = new AccountDebitedEvent(UUID.randomUUID().toString(), debitAccountCommand.getAccountId(), debitAccountCommand.getCurrency(), debitAccountCommand.getAmount());


}
case CreditAccountCommand creditAccountCommand -> {
System.out.println("Handling debit: " + command);
if (creditAccountCommand.getAmount() < 0) throw new IllegalArgumentException("Amount is negative");

event = new AccountCreditedEvent(UUID.randomUUID().toString(), creditAccountCommand.getCurrency(), creditAccountCommand.getAmount(), creditAccountCommand.getAccountId());


}
case UpdateAccountStatusCommand updateAccountStatusCommand -> {
System.out.println("Handling debit: " + command);
event = new AccountStatusUpdatedEvent(UUID.randomUUID().toString(), updateAccountStatusCommand.getAccountStatus(), updateAccountStatusCommand.getAccountId());

}

default -> throw new IllegalStateException("Unexpected value: " + command);
}

BaseEvent event = command.createEvent();
eventProducer.enqueue(event);
eventStoreRepository.save(event);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.oracle.cqrs.common.events.BaseEvent;


@AllArgsConstructor @NoArgsConstructor
public class BaseCommand<T>{
public abstract class BaseCommand<T>{
@Getter
private T id;
public abstract BaseEvent createEvent();

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package org.example.oracle.cqrs.command.commands;

import lombok.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.oracle.cqrs.common.enums.AccountStatus;
import org.example.oracle.cqrs.common.events.AccountCreatedEvent;
import org.example.oracle.cqrs.common.events.BaseEvent;

@Getter @NoArgsConstructor
import java.util.UUID;

@Getter
@NoArgsConstructor
public class CreateAccountCommand extends BaseCommand<String> {
private double initialBalance;
private String currency;
Expand All @@ -14,4 +21,13 @@ public CreateAccountCommand(String id, double initialBalance, String currency, S
this.currency = currency;
this.accountId = accountId;
}

@Override
public BaseEvent createEvent() {
System.out.println("Handling create: " + this);
if (this.getInitialBalance() < 0)
throw new IllegalArgumentException("Initial balance is negative");

return new AccountCreatedEvent(UUID.randomUUID().toString(), initialBalance, currency, AccountStatus.CREATED, accountId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.oracle.cqrs.common.events.AccountCreditedEvent;
import org.example.oracle.cqrs.common.events.BaseEvent;

import java.util.UUID;

@Getter
@NoArgsConstructor
Expand All @@ -17,4 +21,13 @@ public CreditAccountCommand(String id, String accountId, double amount, String c
this.amount = amount;
this.currency = currency;
}

@Override
public BaseEvent createEvent() {
System.out.println("Handling debit: " + this);
if (amount < 0) throw new IllegalArgumentException("Amount is negative");

return new AccountCreditedEvent(UUID.randomUUID().toString(), currency, amount, accountId);

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package org.example.oracle.cqrs.command.commands;

import lombok.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.oracle.cqrs.common.events.AccountDebitedEvent;
import org.example.oracle.cqrs.common.events.BaseEvent;

import java.util.UUID;

@Getter
@NoArgsConstructor
Expand All @@ -16,4 +21,11 @@ public DebitAccountCommand(String id, String accountId, double amount, String cu
this.currency = currency;
}

@Override
public BaseEvent createEvent() {
System.out.println("Handling debit: " + this);
if (amount < 0) throw new IllegalArgumentException("Amount is negative");
return new AccountDebitedEvent(UUID.randomUUID().toString(), accountId, currency, amount);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.oracle.cqrs.common.enums.AccountStatus;
import org.example.oracle.cqrs.common.events.AccountStatusUpdatedEvent;
import org.example.oracle.cqrs.common.events.BaseEvent;

import java.util.UUID;

@Getter
@NoArgsConstructor
Expand All @@ -15,4 +19,10 @@ public UpdateAccountStatusCommand(String id, String accountId, AccountStatus acc
this.accountId = accountId;
this.accountStatus = accountStatus;
}

@Override
public BaseEvent createEvent() {
System.out.println("Handling update account : " + this);
return new AccountStatusUpdatedEvent(UUID.randomUUID().toString(), accountStatus, accountId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,19 @@
import org.example.oracle.cqrs.common.Dtos.DebitAccountDTO;
import org.example.oracle.cqrs.common.Dtos.UpdateAccountStatusDTO;
import org.example.oracle.cqrs.common.events.BaseEvent;
import org.springframework.http.HttpStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.util.UriComponentsBuilder;


import java.net.URI;
import java.util.List;
import java.util.UUID;

Expand All @@ -26,38 +35,41 @@ public class AccountCommandRest {

private CommandsProducer commandsProducer;
private EventStoreRepository eventStoreRepository;
private String queryBsedUrl ;

AccountCommandRest(CommandsProducer commandsProducer, EventStoreRepository eventStoreRepository) {
AccountCommandRest(CommandsProducer commandsProducer, EventStoreRepository eventStoreRepository, @Value("${query.base.url}") String queryBsedUrl) {
this.commandsProducer = commandsProducer;
this.eventStoreRepository = eventStoreRepository;
this.queryBsedUrl = queryBsedUrl;
}

@PostMapping("/create")
public ResponseEntity createAccount(@Valid @RequestBody CreateAccountDTO request) {
String accountId = UUID.randomUUID().toString();
commandsProducer.enqueue(new CreateAccountCommand(UUID.randomUUID().toString(), request.getInitialBalance(), request.getCurrency(), accountId));

return ResponseEntity.status(HttpStatus.ACCEPTED).header("Location", "/api/queries/status/" + accountId).build();
URI location = getGetQueryUri(accountId);
return ResponseEntity.created(location).build();
}

@PostMapping("/debit")
public ResponseEntity debitAccount(@Valid @RequestBody DebitAccountDTO request) {
commandsProducer.enqueue(new DebitAccountCommand(UUID.randomUUID().toString(), request.getAccountId(), request.getAmount(), request.getCurrency()));

return ResponseEntity.status(HttpStatus.ACCEPTED).header("Location", "/api/queries/" + request.getAccountId()).build();
URI location = getGetQueryUri(request.getAccountId());
return ResponseEntity.created(location).build();
}

@PostMapping("/credit")
public ResponseEntity creditAccount(@Valid @RequestBody CreditAccountDTO request) {
commandsProducer.enqueue(new CreditAccountCommand(UUID.randomUUID().toString(), request.getAccountId(), request.getAmount(), request.getCurrency()));

return ResponseEntity.status(HttpStatus.ACCEPTED).header("Location", "/api/queries/" + request.getAccountId()).build();
URI location = getGetQueryUri(request.getAccountId());
return ResponseEntity.created(location).build();
}

@PutMapping("/updateStatus")
public ResponseEntity updateStatus(@Valid @RequestBody UpdateAccountStatusDTO request) {
commandsProducer.enqueue(new UpdateAccountStatusCommand(UUID.randomUUID().toString(), request.getAccountId(), request.getAccountStatus()));
return ResponseEntity.status(HttpStatus.ACCEPTED).header("Location", "/api/queries/status/" + request.getAccountId()).build();
URI location = getGetQueryUri(request.getAccountId());
return ResponseEntity.created(location).build();
}


Expand All @@ -71,5 +83,13 @@ public String exceptionHandler(Exception exception) {
return exception.getMessage();
}

private URI getGetQueryUri(String accountId) {
URI location = UriComponentsBuilder.fromHttpUrl(queryBsedUrl)
.path("/" + accountId)
.build()
.toUri();
return location;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package org.example.oracle.cqrs.common.Dtos;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -11,6 +12,6 @@
public class UpdateAccountStatusDTO {
@NotBlank
private String accountId ;
@NotBlank
@NotNull
private AccountStatus accountStatus ;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import org.example.oracle.cqrs.query.entities.Account;
import org.example.oracle.cqrs.query.repositories.AccountRepository;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.example.oracle.cqrs.common.enums.AccountStatus;

import java.util.Date;
Expand Down
3 changes: 2 additions & 1 deletion Oracle_CQRS/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
txeventq.queue.commands.name=${txeventq:commandsqueue}
txeventq.queue.events.name=${txeventq:eventsqueue}
txeventq.queue.events.name=${txeventq:eventsqueue}
query.base.url=http://localhost:8081/api/queries