Transaction aggregate refactoring related to status

This commit is contained in:
Michal Zeman
2019-09-22 11:17:29 +02:00
parent cdff13c395
commit b3fc8b6e45
6 changed files with 87 additions and 20 deletions

View File

@@ -11,13 +11,6 @@ import java.math.BigDecimal;
public class TransactionAggregate {
enum State {
INITIALIZED,
CREATED,
FINISHED,
FAILED
}
private Id aggregateId;
private Id fromAccount;
@@ -26,15 +19,15 @@ public class TransactionAggregate {
private BigDecimal amount;
private State state;
private TransactionStatus status;
public TransactionAggregate(String aggregateId) {
this.aggregateId = new Id(aggregateId);
state = State.INITIALIZED;
status = TransactionStatus.INITIALIZED;
}
public TransactionCreated validateCreateTransaction(CreateTransaction command) {
if (state == State.INITIALIZED) {
if (status == TransactionStatus.INITIALIZED) {
Id.validate(command.fromAccountId(), command.toAccountId());
if (command.amount().compareTo(BigDecimal.ZERO) <= 0) {
throw new RuntimeException(String.format("Amount can't be %s", command.amount()));
@@ -48,13 +41,13 @@ public class TransactionAggregate {
.toAccountId(command.toAccountId())
.build();
} else {
throw new RuntimeException(String.format("Can't be applied command %s, aggregate is in state %s",
command, this.state));
throw new RuntimeException(String.format("Can't be applied command %s, aggregate is in TransactionStatus %s",
command, this.status));
}
}
public TransactionFinished validateFinishTransaction(FinishTransaction command) {
if (state == State.CREATED) {
if (status == TransactionStatus.CREATED) {
return TransactionFinished.builder()
.aggregateId(aggregateId.getValue())
.correlationId(command.correlationId())
@@ -62,7 +55,7 @@ public class TransactionAggregate {
.toAccountId(toAccount.getValue())
.build();
} else {
throw new RuntimeException(String.format("Transaction in the state: %s can't be finished!", state));
throw new RuntimeException(String.format("Transaction in the state: %s can't be finished!", status));
}
}
@@ -70,26 +63,27 @@ public class TransactionAggregate {
this.fromAccount = new Id(created.fromAccountId());
this.toAccount = new Id(created.toAccountId());
this.amount = created.amount();
this.state = State.CREATED;
this.status = TransactionStatus.CREATED;
return this;
}
public TransactionAggregate applyTransactionFinished(TransactionFinished event) {
this.state = State.FINISHED;
this.status = TransactionStatus.FINISHED;
return this;
}
public TransactionAggregate applyTransactionFailed(TransactionFailed event) {
this.state = State.FAILED;
this.status = TransactionStatus.FAILED;
return this;
}
public TransactionState getState() {
public TransactionState getStatus() {
return TransactionState.builder()
.amount(amount)
.fromAccountId(fromAccount.getValue())
.toAccountId(toAccount.getValue())
.aggregateId(aggregateId.getValue())
.status(this.status)
.build();
}
}

View File

@@ -15,6 +15,8 @@ public interface TransactionState {
BigDecimal amount();
TransactionStatus status();
static ImmutableTransactionState.Builder builder() {
return ImmutableTransactionState.builder();
}

View File

@@ -0,0 +1,8 @@
package com.mz.reactor.ddd.reactorddd.transaction.domain;
public enum TransactionStatus {
INITIALIZED,
CREATED,
FINISHED,
FAILED
}

View File

@@ -58,6 +58,9 @@ public class TransactionCommandHandler implements CommandHandler<TransactionAggr
public CommandResult execute(TransactionAggregate aggregate, TransactionCommand command) {
if (command instanceof CreateTransaction) {
return doCreateTransaction(aggregate, (CreateTransaction) command);
}
if (command instanceof FinishTransaction) {
return doFinishTransaction(aggregate, (FinishTransaction) command);
}else {
return CommandResult.badCommand();
}

View File

@@ -2,6 +2,9 @@ package com.mz.reactor.ddd.reactorddd.transaction.domain.event;
import org.immutables.value.Value;
/**
* this event is fired only when someone is trying to finish transaction which is not in proper status
*/
@Value.Immutable
public interface FinishTransactionFailed extends TransactionEvent {

View File

@@ -3,6 +3,7 @@ package com.mz.reactor.ddd.reactorddd.transaction.domain;
import com.mz.reactor.ddd.reactorddd.transaction.domain.command.CreateTransaction;
import com.mz.reactor.ddd.reactorddd.transaction.domain.command.FinishTransaction;
import com.mz.reactor.ddd.reactorddd.transaction.domain.event.TransactionCreated;
import com.mz.reactor.ddd.reactorddd.transaction.domain.event.TransactionFailed;
import com.mz.reactor.ddd.reactorddd.transaction.domain.event.TransactionFinished;
import org.junit.jupiter.api.Test;
@@ -68,7 +69,7 @@ class TransactionAggregateTest {
.build();
var aggregate = new TransactionAggregate(aggregateId);
var state = aggregate.applyTransactionCreated(event).getState();
var state = aggregate.applyTransactionCreated(event).getStatus();
assertEquals(state.aggregateId(), aggregateId);
assertEquals(state.toAccountId(), toAccountId);
@@ -125,9 +126,65 @@ class TransactionAggregateTest {
@Test
void applyTransactionFinished() {
//given
var aggregateId = UUID.randomUUID().toString();
var correlationId = UUID.randomUUID().toString();
var toAccountId = UUID.randomUUID().toString();
var fromAccountId = UUID.randomUUID().toString();
var event = TransactionCreated.builder()
.aggregateId(aggregateId)
.correlationId(correlationId)
.amount(BigDecimal.TEN)
.fromAccountId(fromAccountId)
.toAccountId(toAccountId)
.build();
var aggregate = new TransactionAggregate(aggregateId);
aggregate.applyTransactionCreated(event);
//when
var transactionFinished = TransactionFinished.builder()
.toAccountId(toAccountId)
.fromAccountId(fromAccountId)
.aggregateId(aggregateId)
.build();
var state = aggregate.applyTransactionFinished(transactionFinished).getStatus();
//then
assertEquals(state.status(), TransactionStatus.FINISHED);
}
@Test
void applyTransactionFailed() {
//given
var aggregateId = UUID.randomUUID().toString();
var correlationId = UUID.randomUUID().toString();
var toAccountId = UUID.randomUUID().toString();
var fromAccountId = UUID.randomUUID().toString();
var event = TransactionCreated.builder()
.aggregateId(aggregateId)
.correlationId(correlationId)
.amount(BigDecimal.TEN)
.fromAccountId(fromAccountId)
.toAccountId(toAccountId)
.build();
var aggregate = new TransactionAggregate(aggregateId);
aggregate.applyTransactionCreated(event);
//when
var transactionFailed = TransactionFailed.builder()
.toAccountId(toAccountId)
.fromAccountId(fromAccountId)
.aggregateId(aggregateId)
.amount(BigDecimal.TEN)
.build();
var state = aggregate.applyTransactionFailed(transactionFailed).getStatus();
//then
assertEquals(state.status(), TransactionStatus.FAILED);
assertEquals(state.amount(), BigDecimal.TEN);
}
}