add source

This commit is contained in:
Daniel Kang
2018-04-20 16:55:07 +09:00
parent fc0e658154
commit db4bcdceae
69 changed files with 3523 additions and 14 deletions

1
lesson-1/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/.metadata/

11
lesson-1/README.md Normal file
View File

@@ -0,0 +1,11 @@
Lesson-1
---
A very basic sample of Axon framework.
In this Sample, you will learn the basic concept of Axon and CQRS & EventSourcing.
- Command
- Event
- CommandGateway
- Command Handler
- Event Handler

16
lesson-1/pom.xml Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sbs-axon</artifactId>
<groupId>com.edi.learn</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>lesson-1</artifactId>
<version>1</version>
</project>

View File

@@ -0,0 +1,34 @@
package com.edi.learn.axon;
import com.edi.learn.axon.command.aggregates.BankAccount;
import com.edi.learn.axon.command.commands.CreateAccountCommand;
import com.edi.learn.axon.command.commands.WithdrawMoneyCommand;
import com.edi.learn.axon.common.domain.AccountId;
import org.axonframework.config.Configuration;
import org.axonframework.config.DefaultConfigurer;
import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
public class Application {
private static final Logger LOGGER = getLogger(Application.class);
public static void main(String args[]){
Configuration config = DefaultConfigurer.defaultConfiguration()
.configureAggregate(BankAccount.class)
.configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine())
.buildConfiguration();
config.start();
AccountId id = new AccountId();
config.commandGateway().send(new CreateAccountCommand(id, "MyAccount",1000));
config.commandGateway().send(new WithdrawMoneyCommand(id, 500));
config.commandGateway().send(new WithdrawMoneyCommand(id, 500));
/*config.commandBus().dispatch(asCommandMessage(new CreateAccountCommand(id, "MyAccount", 1000)));
config.commandBus().dispatch(asCommandMessage(new WithdrawMoneyCommand(id, 500)));*/
}
}

View File

@@ -0,0 +1,60 @@
package com.edi.learn.axon.command.aggregates;
import com.edi.learn.axon.command.commands.CreateAccountCommand;
import com.edi.learn.axon.command.commands.WithdrawMoneyCommand;
import com.edi.learn.axon.common.domain.AccountId;
import com.edi.learn.axon.common.events.AccountCreatedEvent;
import com.edi.learn.axon.common.events.MoneyWithdrawnEvent;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.commandhandling.model.AggregateIdentifier;
import org.axonframework.eventhandling.EventHandler;
import org.slf4j.Logger;
import java.math.BigDecimal;
import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;
import static org.slf4j.LoggerFactory.getLogger;
public class BankAccount {
private static final Logger LOGGER = getLogger(BankAccount.class);
@AggregateIdentifier
private AccountId accountId;
private String accountName;
private BigDecimal balance;
public BankAccount() {
}
@CommandHandler
public BankAccount(CreateAccountCommand command){
LOGGER.debug("Construct a new BankAccount");
apply(new AccountCreatedEvent(command.getAccountId(), command.getAccountName(), command.getAmount()));
}
@CommandHandler
public void handle(WithdrawMoneyCommand command){
apply(new MoneyWithdrawnEvent(command.getAccountId(), command.getAmount()));
}
@EventHandler
public void on(AccountCreatedEvent event){
this.accountId = event.getAccountId();
this.accountName = event.getAccountName();
this.balance = new BigDecimal(event.getAmount());
LOGGER.info("Account {} is created with balance {}", accountId, this.balance);
}
@EventHandler
public void on(MoneyWithdrawnEvent event){
BigDecimal result = this.balance.subtract(new BigDecimal(event.getAmount()));
if(result.compareTo(BigDecimal.ZERO)<0)
LOGGER.error("Cannot withdraw more money than the balance!");
else {
this.balance = result;
LOGGER.info("Withdraw {} from account {}, balance result: {}", event.getAmount(), accountId, balance);
}
}
}

View File

@@ -0,0 +1,29 @@
package com.edi.learn.axon.command.commands;
import com.edi.learn.axon.common.domain.AccountId;
public class CreateAccountCommand {
private AccountId accountId;
private String accountName;
private long amount;
public CreateAccountCommand(AccountId accountId, String accountName, long amount) {
this.accountId = accountId;
this.accountName = accountName;
this.amount = amount;
}
public AccountId getAccountId() {
return accountId;
}
public String getAccountName() {
return accountName;
}
public long getAmount() {
return amount;
}
}

View File

@@ -0,0 +1,26 @@
package com.edi.learn.axon.command.commands;
import com.edi.learn.axon.common.domain.AccountId;
import org.axonframework.commandhandling.TargetAggregateIdentifier;
public class WithdrawMoneyCommand {
@TargetAggregateIdentifier
private AccountId accountId;
private long amount;
public WithdrawMoneyCommand(AccountId accountId, long amount) {
this.accountId = accountId;
this.amount = amount;
}
public AccountId getAccountId() {
return accountId;
}
public long getAmount() {
return amount;
}
}

View File

@@ -0,0 +1,48 @@
package com.edi.learn.axon.common.domain;
import org.axonframework.common.Assert;
import org.axonframework.common.IdentifierFactory;
import java.io.Serializable;
public class AccountId implements Serializable {
private static final long serialVersionUID = 7119961474083133148L;
private final String identifier;
private final int hashCode;
public AccountId() {
this.identifier = IdentifierFactory.getInstance().generateIdentifier();
this.hashCode = identifier.hashCode();
}
public AccountId(String identifier) {
Assert.notNull(identifier, ()->"Identifier may not be null");
this.identifier = identifier;
this.hashCode = identifier.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AccountId accountId = (AccountId) o;
return identifier.equals(accountId.identifier);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public String toString() {
return identifier;
}
}

View File

@@ -0,0 +1,28 @@
package com.edi.learn.axon.common.events;
import com.edi.learn.axon.common.domain.AccountId;
public class AccountCreatedEvent {
private AccountId accountId;
private String accountName;
private long amount;
public AccountCreatedEvent(AccountId accountId, String accountName, long amount) {
this.accountId = accountId;
this.accountName = accountName;
this.amount = amount;
}
public AccountId getAccountId() {
return accountId;
}
public String getAccountName() {
return accountName;
}
public long getAmount() {
return amount;
}
}

View File

@@ -0,0 +1,22 @@
package com.edi.learn.axon.common.events;
import com.edi.learn.axon.common.domain.AccountId;
public class MoneyWithdrawnEvent {
private AccountId accountId;
private long amount;
public MoneyWithdrawnEvent(AccountId accountId, long amount) {
this.accountId = accountId;
this.amount = amount;
}
public AccountId getAccountId() {
return accountId;
}
public long getAmount() {
return amount;
}
}

View File

@@ -0,0 +1,14 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>