├── .gitignore
├── .mvn
└── wrapper
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── README.md
├── companies
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── company
│ │ └── command
│ │ ├── Company.java
│ │ └── CompanyOrderBookListener.java
│ └── test
│ ├── java
│ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── company
│ │ └── command
│ │ └── CompanyTest.java
│ └── resources
│ └── log4j.properties
├── core-api
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── axonframework
│ └── samples
│ └── trader
│ └── api
│ ├── company
│ ├── commands.kt
│ ├── events.kt
│ └── valueObjects.kt
│ ├── orders
│ ├── trades
│ │ ├── commands.kt
│ │ └── events.kt
│ ├── transaction
│ │ ├── commands.kt
│ │ ├── events.kt
│ │ └── valueObjects.kt
│ └── valueObjects.kt
│ ├── portfolio
│ ├── cash
│ │ ├── commands.kt
│ │ └── events.kt
│ ├── commands.kt
│ ├── events.kt
│ ├── stock
│ │ ├── commands.kt
│ │ └── events.kt
│ └── valueObjects.kt
│ └── users
│ ├── UserAccount.java
│ ├── commands.kt
│ ├── events.kt
│ └── valueObjects.kt
├── external-listeners
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── listener
│ │ ├── BroadcastingTextWebSocketHandler.java
│ │ ├── ExecutedTradesBroadcaster.java
│ │ ├── WebSocketConfig.java
│ │ └── config
│ │ └── ExternalListenersConfig.java
│ └── resources
│ ├── META-INF
│ └── spring
│ │ └── external-context.xml
│ └── external-config.properties
├── infrastructure
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── infra
│ │ └── config
│ │ ├── CQRSInfrastructureConfig.java
│ │ ├── CQRSInfrastructureHSQLDBConfig.java
│ │ └── PersistenceInfrastructureConfig.java
│ └── resources
│ ├── META-INF
│ └── spring
│ │ └── configuration-context.xml
│ ├── ehcache.xml
│ └── trader.properties
├── mvnw
├── mvnw.cmd
├── orders
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── orders
│ │ ├── command
│ │ ├── BuyTradeManagerSaga.java
│ │ ├── Portfolio.java
│ │ ├── PortfolioManagementUserListener.java
│ │ ├── SellTradeManagerSaga.java
│ │ ├── TradeManagerSaga.java
│ │ └── Transaction.java
│ │ └── config
│ │ └── OrderConfig.java
│ └── test
│ ├── java
│ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── orders
│ │ └── command
│ │ ├── BuyTradeManagerSagaTest.java
│ │ ├── PortfolioManagementUserListenerTest.java
│ │ ├── PortfolioTest.java
│ │ ├── SellTradeManagerSagaTest.java
│ │ ├── TransactionCommandHandlingTest.java
│ │ └── matchers
│ │ ├── AddItemsToPortfolioCommandMatcher.java
│ │ ├── BaseCommandMatcher.java
│ │ ├── CancelItemReservationForPortfolioCommandMatcher.java
│ │ ├── CancelMoneyReservationFromPortfolioCommandMatcher.java
│ │ ├── CancelTransactionCommandMatcher.java
│ │ ├── ConfirmItemReservationForPortfolioCommandMatcher.java
│ │ ├── ConfirmMoneyReservationFromPortfolionCommandMatcher.java
│ │ ├── ConfirmTransactionCommandMatcher.java
│ │ ├── CreateBuyOrderCommandMatcher.java
│ │ ├── CreateSellOrderCommandMatcher.java
│ │ ├── DepositMoneyToPortfolioCommandMatcher.java
│ │ ├── ExecutedTransactionCommandMatcher.java
│ │ ├── ReserveMoneyFromPortfolioCommandMatcher.java
│ │ └── ReservedItemsCommandMatcher.java
│ └── resources
│ └── log4j.properties
├── pom.xml
├── query
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── axonframework
│ │ │ └── samples
│ │ │ └── trader
│ │ │ └── query
│ │ │ ├── company
│ │ │ ├── CompanyEventHandler.java
│ │ │ ├── CompanyView.java
│ │ │ └── CompanyViewRepository.java
│ │ │ ├── config
│ │ │ └── HsqlDbConfiguration.java
│ │ │ ├── orderbook
│ │ │ ├── OrderBookEventHandler.java
│ │ │ ├── OrderBookView.java
│ │ │ ├── OrderBookViewRepository.java
│ │ │ └── OrderView.java
│ │ │ ├── portfolio
│ │ │ ├── ItemEntry.java
│ │ │ ├── PortfolioItemEventHandler.java
│ │ │ ├── PortfolioMoneyEventHandler.java
│ │ │ ├── PortfolioView.java
│ │ │ └── PortfolioViewRepository.java
│ │ │ ├── tradeexecuted
│ │ │ ├── TradeExecutedQueryRepository.java
│ │ │ └── TradeExecutedView.java
│ │ │ └── transaction
│ │ │ ├── TransactionEventHandler.java
│ │ │ ├── TransactionState.java
│ │ │ ├── TransactionView.java
│ │ │ └── TransactionViewRepository.java
│ └── resources
│ │ └── META-INF
│ │ └── persistence.xml
│ └── test
│ └── java
│ └── org
│ └── axonframework
│ └── samples
│ └── trader
│ └── query
│ ├── company
│ └── CompanyEventHandlerTest.java
│ ├── portfolio
│ ├── PortfolioEntryMatcher.java
│ ├── PortfolioItemEventHandlerTest.java
│ └── PortfolioViewTest.java
│ └── transaction
│ ├── TransactionEntryMatcher.java
│ └── TransactionEventHandlerTest.java
├── trade-engine
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── tradeengine
│ │ └── command
│ │ ├── Order.java
│ │ └── OrderBook.java
│ └── test
│ └── java
│ └── org
│ └── axonframework
│ └── samples
│ └── trader
│ └── tradeengine
│ └── command
│ └── OrderBookTest.java
├── users-query
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── query
│ │ └── users
│ │ ├── UserEventHandler.java
│ │ ├── UserView.java
│ │ └── UserViewRepository.java
│ └── test
│ └── java
│ └── org
│ └── axonframework
│ └── samples
│ └── trader
│ └── query
│ └── users
│ └── UserEventHandlerTest.java
├── users
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── axonframework
│ │ └── samples
│ │ └── trader
│ │ └── users
│ │ ├── command
│ │ └── User.java
│ │ └── util
│ │ └── DigestUtils.java
│ └── test
│ └── java
│ └── org
│ └── axonframework
│ └── samples
│ └── trader
│ └── app
│ └── command
│ └── user
│ └── UserTest.java
└── web-ui
├── pom.xml
└── src
└── main
├── java
└── org
│ └── axonframework
│ └── samples
│ └── trader
│ └── webui
│ ├── admin
│ └── AdminController.java
│ ├── companies
│ └── CompanyController.java
│ ├── config
│ └── AppConfig.java
│ ├── dashboard
│ └── DashboardController.java
│ ├── init
│ ├── BaseDBInit.java
│ ├── DBInit.java
│ ├── DBInitException.java
│ ├── DataController.java
│ ├── DataResults.java
│ ├── HsqlDBInit.java
│ └── RunDBInitializerWhenNeeded.java
│ ├── order
│ ├── AbstractOrder.java
│ ├── BuyOrder.java
│ ├── CreateOrder.java
│ ├── OrderBookController.java
│ └── SellOrder.java
│ ├── rest
│ └── RestController.java
│ ├── security
│ ├── TraderAuthenticationProvider.java
│ └── UserController.java
│ └── util
│ └── SecurityUtil.java
├── resources
├── META-INF
│ └── spring
│ │ └── security-context.xml
├── log4j.properties
└── messages.properties
└── webapp
├── WEB-INF
├── decorators.xml
├── decorators
│ └── master.jsp
├── dispatcher-servlet.xml
├── jsp
│ ├── admin
│ │ └── portfolio
│ │ │ ├── detail.jsp
│ │ │ └── list.jsp
│ ├── company
│ │ ├── buy.jsp
│ │ ├── details.jsp
│ │ ├── form-include.jsp
│ │ ├── list.jsp
│ │ └── sell.jsp
│ ├── dashboard
│ │ └── index.jsp
│ ├── data
│ │ ├── collection.jsp
│ │ ├── collections.jsp
│ │ └── info.jsp
│ ├── include.jsp
│ ├── index.jsp
│ ├── orderbook
│ │ ├── list.jsp
│ │ ├── orders.jsp
│ │ └── socket.jsp
│ └── user
│ │ ├── detail.jsp
│ │ └── list.jsp
├── messages
│ ├── fields.properties
│ └── validation.properties
└── web.xml
├── favicon.ico
├── index.html
├── js
├── jquery-1.6.4.min.js
├── jquery.tablesorter.min.js
└── sockjs-0.2.1.min.js
├── login.jsp
└── style
├── bootstrap-1.3.0.min.css
├── bootstrap-1.4.0.min.css
└── main.css
/.gitignore:
--------------------------------------------------------------------------------
1 | # used to ignore certain files by git
2 | # mac osx files
3 | .DS_Store
4 | #gradle build files
5 | .gradle
6 | build
7 | # intellij files
8 | .idea/
9 | **/.idea/*
10 | **/gradle.properties
11 | *.ipr
12 | *.iws
13 | *.iml
14 | target/
15 | out/*
16 | rebel.xml
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AxonFramework/Axon-trader/149c80498aef30baa45000fa241362e2fc0e2001/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Archived project
2 |
3 | This project has been discontinued and is not being updated to latest standards anymore. There are several sample applications around that show the usage of Axon Framework that are kept up-to-date continuously.
4 |
5 | A few examples (at the time of writing):
6 | - https://github.com/AxonIQ/hotel-demo
7 | - https://github.com/fraktalio/restaurant-demo
8 | - https://github.com/abuijze/bike-rental-demo
9 | - https://github.com/abuijze/bike-rental-extended
10 |
11 | ---
12 |
13 | This is a sample application to demonstrate the possibilities of the Axon framework in a high load environment. We have chosen to create a Trader application. All you need to run it is java and maven.
14 |
15 |
16 | Initial setup
17 | -------------
18 | - Make sure you have java installed
19 | http://www.java.com/download/
20 |
21 | Running the sample
22 | ------------------
23 | - First you need to download the source code, if you are reading this file on your local machine you already have downloaded the source code. If you are on the main page of the Github project, you can easily find a url to clone the repository or to download a zip with all the sources.
24 |
25 | * Maven
26 | - Step into the main folder of the project
27 | > ./mvnw tomcat7:run
28 | - Browse to http://localhost:8080 and you should see the user accounts that you can use to login.
29 | (You can always refresh the data by calling /data/init on the application)
30 |
31 | More documentation
32 | ----------------------
33 | We are documenting the sample on the wiki of the github project.
34 | https://github.com/AxonFramework/Axon-trader/wiki
35 |
--------------------------------------------------------------------------------
/companies/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
21 | 4.0.0
22 |
23 |
24 | org.axonframework.samples
25 | axon-trader
26 | 2.0-SNAPSHOT
27 |
28 |
29 | axon-trader-companies
30 |
31 |
32 |
33 |
34 | ${project.groupId}
35 | axon-trader-core-api
36 | ${project.version}
37 |
38 |
39 |
40 |
41 | org.springframework
42 | spring-beans
43 |
44 |
45 |
46 | org.springframework
47 | spring-context
48 |
49 |
50 |
51 | org.axonframework
52 | axon-core
53 | ${axon.version}
54 |
55 |
56 |
57 |
58 | org.axonframework
59 | axon-test
60 | ${axon.version}
61 | test
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/companies/src/main/java/org/axonframework/samples/trader/company/command/Company.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2012. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.company.command;
18 |
19 | import org.axonframework.commandhandling.CommandHandler;
20 | import org.axonframework.commandhandling.model.AggregateIdentifier;
21 | import org.axonframework.eventsourcing.EventSourcingHandler;
22 | import org.axonframework.samples.trader.api.company.*;
23 | import org.axonframework.spring.stereotype.Aggregate;
24 |
25 | import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;
26 |
27 | @Aggregate
28 | public class Company {
29 |
30 | @AggregateIdentifier
31 | private CompanyId companyId;
32 |
33 | @SuppressWarnings("UnusedDeclaration")
34 | public Company() {
35 | // Required by Axon Framework
36 | }
37 |
38 | @CommandHandler
39 | public Company(CreateCompanyCommand cmd) {
40 | apply(new CompanyCreatedEvent(
41 | cmd.getCompanyId(), cmd.getCompanyName(), cmd.getCompanyValue(), cmd.getAmountOfShares()
42 | ));
43 | }
44 |
45 | @CommandHandler
46 | public void handle(AddOrderBookToCompanyCommand cmd) {
47 | apply(new OrderBookAddedToCompanyEvent(companyId, cmd.getOrderBookId()));
48 | }
49 |
50 |
51 | @EventSourcingHandler
52 | public void on(CompanyCreatedEvent event) {
53 | companyId = event.getCompanyId();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/companies/src/main/java/org/axonframework/samples/trader/company/command/CompanyOrderBookListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.company.command;
18 |
19 | import org.axonframework.commandhandling.gateway.CommandGateway;
20 | import org.axonframework.config.ProcessingGroup;
21 | import org.axonframework.eventhandling.EventHandler;
22 | import org.axonframework.samples.trader.api.company.AddOrderBookToCompanyCommand;
23 | import org.axonframework.samples.trader.api.company.CompanyCreatedEvent;
24 | import org.axonframework.samples.trader.api.orders.OrderBookId;
25 | import org.axonframework.samples.trader.api.orders.trades.CreateOrderBookCommand;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.springframework.beans.factory.annotation.Autowired;
29 | import org.springframework.stereotype.Service;
30 |
31 | /**
32 | * This listener is used to create order book instances when we have created a new company
33 | * TODO #28 the OrderBook aggregate should be instantiated from the Company aggregate, as is possible since axon 3.3
34 | **/
35 | @Service
36 | @ProcessingGroup("commandPublishingEventHandlers")
37 | public class CompanyOrderBookListener {
38 |
39 | private static final Logger logger = LoggerFactory.getLogger(CompanyOrderBookListener.class);
40 |
41 | private final CommandGateway commandGateway;
42 |
43 | @Autowired
44 | public CompanyOrderBookListener(CommandGateway commandGateway) {
45 | this.commandGateway = commandGateway;
46 | }
47 |
48 | @EventHandler
49 | public void on(CompanyCreatedEvent event) {
50 | logger.debug("About to dispatch a new command to create an OrderBook for the company {}", event.getCompanyId());
51 |
52 | OrderBookId orderBookId = new OrderBookId();
53 | commandGateway.send(new CreateOrderBookCommand(orderBookId));
54 | commandGateway.send(new AddOrderBookToCompanyCommand(event.getCompanyId(), orderBookId));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/companies/src/test/java/org/axonframework/samples/trader/company/command/CompanyTest.java:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.company.command;
2 |
3 | import org.axonframework.samples.trader.api.company.*;
4 | import org.axonframework.samples.trader.api.orders.OrderBookId;
5 | import org.axonframework.samples.trader.api.users.UserId;
6 | import org.axonframework.test.aggregate.AggregateTestFixture;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 |
10 | public class CompanyTest {
11 |
12 | private AggregateTestFixture fixture;
13 |
14 | private CompanyId companyId = new CompanyId();
15 | private OrderBookId orderBookId = new OrderBookId();
16 |
17 | private CompanyCreatedEvent companyCreatedEvent;
18 |
19 | @Before
20 | public void setUp() {
21 | fixture = new AggregateTestFixture<>(Company.class);
22 |
23 | companyCreatedEvent = new CompanyCreatedEvent(companyId, "TestItem", 1000L, 10000L);
24 | }
25 |
26 | @Test
27 | public void testCreateCompany() {
28 | fixture.givenNoPriorActivity()
29 | .when(new CreateCompanyCommand(companyId, new UserId(), "TestItem", 1000L, 10000L))
30 | .expectEvents(companyCreatedEvent);
31 | }
32 |
33 | @Test
34 | public void testAddOrderBookToCompany() {
35 | fixture.given(companyCreatedEvent)
36 | .when(new AddOrderBookToCompanyCommand(companyId, orderBookId))
37 | .expectEvents(new OrderBookAddedToCompanyEvent(companyId, orderBookId));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/companies/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2012. Axon Framework
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | log4j.rootLogger=WARN,Stdout
18 |
19 | log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
20 | log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
21 | log4j.appender.Stdout.layout.conversionPattern=%d [%t] %-5p %-30.30c{1} %x - %m%n
22 |
23 | log4j.logger.org.springframework=WARN
24 | log4j.logger.org.axonframework=DEBUG
25 | log4j.logger.org.axonframework.samples.trader=WARN
26 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/company/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.company
2 |
3 | import org.axonframework.commandhandling.TargetAggregateIdentifier
4 | import org.axonframework.samples.trader.api.orders.OrderBookId
5 | import org.axonframework.samples.trader.api.users.UserId
6 |
7 | abstract class CompanyCommand(@TargetAggregateIdentifier open val companyId: CompanyId)
8 |
9 | data class CreateCompanyCommand(
10 | override val companyId: CompanyId,
11 | val userId: UserId,
12 | val companyName: String,
13 | val companyValue: Long,
14 | val amountOfShares: Long
15 | ) : CompanyCommand(companyId)
16 |
17 | data class AddOrderBookToCompanyCommand(
18 | override val companyId: CompanyId,
19 | val orderBookId: OrderBookId
20 | ) : CompanyCommand(companyId)
21 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/company/events.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.company
2 |
3 | import org.axonframework.samples.trader.api.orders.OrderBookId
4 |
5 | abstract class CompanyEvent(open val companyId: CompanyId)
6 |
7 | data class CompanyCreatedEvent(
8 | override val companyId: CompanyId,
9 | val companyName: String,
10 | val companyValue: Long,
11 | val amountOfShares: Long
12 | ) : CompanyEvent(companyId)
13 |
14 | data class OrderBookAddedToCompanyEvent(
15 | override val companyId: CompanyId,
16 | val orderBookId: OrderBookId
17 | ) : CompanyEvent(companyId)
18 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/company/valueObjects.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.company
2 |
3 | import org.axonframework.common.IdentifierFactory
4 | import java.io.Serializable
5 |
6 | data class CompanyId(val identifier: String = IdentifierFactory.getInstance().generateIdentifier()) : Serializable {
7 |
8 | companion object {
9 | private const val serialVersionUID = -2521069615900157076L
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/orders/trades/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.orders.trades
2 |
3 | import org.axonframework.commandhandling.TargetAggregateIdentifier
4 | import org.axonframework.samples.trader.api.orders.OrderBookId
5 | import org.axonframework.samples.trader.api.orders.OrderId
6 | import org.axonframework.samples.trader.api.orders.transaction.TransactionId
7 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
8 | import javax.validation.constraints.Min
9 |
10 | abstract class AbstractOrderCommand(
11 | open val orderId: OrderId,
12 | open val portfolioId: PortfolioId,
13 | @TargetAggregateIdentifier open val orderBookId: OrderBookId,
14 | open val transactionId: TransactionId,
15 | @Min(0) open val tradeCount: Long,
16 | @Min(0) open val itemPrice: Long
17 | )
18 |
19 | data class CreateBuyOrderCommand(
20 | override val orderId: OrderId,
21 | override val portfolioId: PortfolioId,
22 | override val orderBookId: OrderBookId,
23 | override val transactionId: TransactionId,
24 | override val tradeCount: Long,
25 | override val itemPrice: Long
26 | ) : AbstractOrderCommand(orderId, portfolioId, orderBookId, transactionId, tradeCount, itemPrice)
27 |
28 | data class CreateSellOrderCommand(
29 | override val orderId: OrderId,
30 | override val portfolioId: PortfolioId,
31 | override val orderBookId: OrderBookId,
32 | override val transactionId: TransactionId,
33 | override val tradeCount: Long,
34 | override val itemPrice: Long
35 | ) : AbstractOrderCommand(orderId, portfolioId, orderBookId, transactionId, tradeCount, itemPrice)
36 |
37 | abstract class OrderBookCommand(@TargetAggregateIdentifier open val orderBookId: OrderBookId)
38 |
39 | data class CreateOrderBookCommand(override val orderBookId: OrderBookId) : OrderBookCommand(orderBookId)
40 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/orders/trades/events.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.orders.trades
2 |
3 | import org.axonframework.samples.trader.api.orders.OrderBookId
4 | import org.axonframework.samples.trader.api.orders.OrderId
5 | import org.axonframework.samples.trader.api.orders.transaction.TransactionId
6 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
7 | import java.io.Serializable
8 |
9 | abstract class AbstractOrderPlacedEvent(
10 | open val orderBookId: OrderBookId,
11 | open val orderId: OrderId,
12 | open val transactionId: TransactionId,
13 | open val tradeCount: Long,
14 | open val itemPrice: Long,
15 | open val portfolioId: PortfolioId
16 | )
17 |
18 | data class BuyOrderPlacedEvent(
19 | override val orderBookId: OrderBookId,
20 | override val orderId: OrderId,
21 | override val transactionId: TransactionId,
22 | override val tradeCount: Long,
23 | override val itemPrice: Long,
24 | override val portfolioId: PortfolioId
25 | ) : AbstractOrderPlacedEvent(orderBookId, orderId, transactionId, tradeCount, itemPrice, portfolioId)
26 |
27 | data class SellOrderPlacedEvent(
28 | override val orderBookId: OrderBookId,
29 | override val orderId: OrderId,
30 | override val transactionId: TransactionId,
31 | override val tradeCount: Long,
32 | override val itemPrice: Long,
33 | override val portfolioId: PortfolioId
34 | ) : AbstractOrderPlacedEvent(orderBookId, orderId, transactionId, tradeCount, itemPrice, portfolioId)
35 |
36 | abstract class OrderBookEvent(open val orderBookId: OrderBookId)
37 |
38 | data class OrderBookCreatedEvent(override val orderBookId: OrderBookId) : OrderBookEvent(orderBookId)
39 |
40 | data class TradeExecutedEvent(
41 | val orderBookId: OrderBookId,
42 | val tradeCount: Long,
43 | val tradePrice: Long,
44 | val buyOrderId: OrderId,
45 | val sellOrderId: OrderId,
46 | val buyTransactionId: TransactionId,
47 | val sellTransactionId: TransactionId
48 | ) : Serializable {
49 | companion object {
50 | private const val serialVersionUID = 6292249351659536792L
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/orders/transaction/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.orders.transaction
2 |
3 | import org.axonframework.commandhandling.TargetAggregateIdentifier
4 | import org.axonframework.samples.trader.api.orders.OrderBookId
5 | import org.axonframework.samples.trader.api.orders.TransactionType
6 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
7 |
8 | abstract class TransactionCommand(@TargetAggregateIdentifier open val transactionId: TransactionId)
9 |
10 | abstract class AbstractStartTransactionCommand(
11 | override val transactionId: TransactionId,
12 | open val orderBookId: OrderBookId,
13 | open val portfolioId: PortfolioId,
14 | open val tradeCount: Long,
15 | open val pricePerItem: Long
16 | ) : TransactionCommand(transactionId) {
17 | abstract val transactionType: TransactionType
18 | }
19 |
20 | data class StartBuyTransactionCommand(
21 | override val transactionId: TransactionId,
22 | override val orderBookId: OrderBookId,
23 | override val portfolioId: PortfolioId,
24 | override val tradeCount: Long,
25 | override val pricePerItem: Long
26 | ) : AbstractStartTransactionCommand(transactionId, orderBookId, portfolioId, tradeCount, pricePerItem) {
27 | override val transactionType: TransactionType = TransactionType.BUY
28 | }
29 |
30 | data class StartSellTransactionCommand(
31 | override val transactionId: TransactionId,
32 | override val orderBookId: OrderBookId,
33 | override val portfolioId: PortfolioId,
34 | override val tradeCount: Long,
35 | override val pricePerItem: Long
36 | ) : AbstractStartTransactionCommand(transactionId, orderBookId, portfolioId, tradeCount, pricePerItem) {
37 | override val transactionType: TransactionType = TransactionType.SELL
38 | }
39 |
40 | data class CancelTransactionCommand(override val transactionId: TransactionId) : TransactionCommand(transactionId)
41 |
42 | data class ConfirmTransactionCommand(override val transactionId: TransactionId) : TransactionCommand(transactionId)
43 |
44 | data class ExecutedTransactionCommand(
45 | override val transactionId: TransactionId,
46 | val amountOfItems: Long,
47 | val itemPrice: Long
48 | ) : TransactionCommand(transactionId)
49 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/orders/transaction/valueObjects.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.orders.transaction
2 |
3 | import org.axonframework.common.IdentifierFactory
4 | import java.io.Serializable
5 |
6 | data class TransactionId(val identifier: String = IdentifierFactory.getInstance().generateIdentifier()) : Serializable {
7 |
8 | companion object {
9 | private const val serialVersionUID = -5267104328616955617L
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/orders/valueObjects.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.orders
2 |
3 | import org.axonframework.common.IdentifierFactory
4 | import java.io.Serializable
5 |
6 | enum class TransactionType {
7 | SELL, BUY
8 | }
9 |
10 | data class OrderBookId(val identifier: String = IdentifierFactory.getInstance().generateIdentifier()) : Serializable {
11 |
12 | companion object {
13 | private const val serialVersionUID = -7842002574176005113L
14 | }
15 |
16 | }
17 |
18 | data class OrderId(val identifier: String = IdentifierFactory.getInstance().generateIdentifier()) : Serializable {
19 |
20 | companion object {
21 | private const val serialVersionUID = 4034328048230397374L
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/cash/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio.cash
2 |
3 | import org.axonframework.samples.trader.api.orders.transaction.TransactionId
4 | import org.axonframework.samples.trader.api.portfolio.PortfolioCommand
5 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
6 | import javax.validation.constraints.Min
7 |
8 | data class CancelCashReservationCommand(
9 | override val portfolioId: PortfolioId,
10 | val transactionId: TransactionId,
11 | val amountOfMoneyToCancel: Long
12 | ) : PortfolioCommand(portfolioId)
13 |
14 | data class ConfirmCashReservationCommand(
15 | override val portfolioId: PortfolioId,
16 | val transactionId: TransactionId,
17 | val amountOfMoneyToConfirmInCents: Long
18 | ) : PortfolioCommand(portfolioId)
19 |
20 | data class DepositCashCommand(
21 | override val portfolioId: PortfolioId,
22 | @Min(0) val moneyToAddInCents: Long
23 | ) : PortfolioCommand(portfolioId)
24 |
25 | data class ReserveCashCommand(
26 | override val portfolioId: PortfolioId,
27 | val transactionId: TransactionId,
28 | @Min(0) val amountOfMoneyToReserve: Long
29 | ) : PortfolioCommand(portfolioId)
30 |
31 | data class WithdrawCashCommand(
32 | override val portfolioId: PortfolioId,
33 | @Min(0) val amountToPayInCents: Long
34 | ) : PortfolioCommand(portfolioId)
35 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/cash/events.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio.cash
2 |
3 | import org.axonframework.samples.trader.api.orders.transaction.TransactionId
4 | import org.axonframework.samples.trader.api.portfolio.PortfolioEvent
5 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
6 |
7 | data class CashDepositedEvent(
8 | override val portfolioId: PortfolioId,
9 | val moneyAddedInCents: Long
10 | ) : PortfolioEvent(portfolioId)
11 |
12 | data class CashReservationCancelledEvent(
13 | override val portfolioId: PortfolioId,
14 | val transactionId: TransactionId,
15 | val amountOfMoneyToCancel: Long
16 | ) : PortfolioEvent(portfolioId)
17 |
18 | data class CashReservationConfirmedEvent(
19 | override val portfolioId: PortfolioId,
20 | val transactionId: TransactionId,
21 | val amountOfMoneyConfirmedInCents: Long
22 | ) : PortfolioEvent(portfolioId)
23 |
24 | data class CashReservationRejectedEvent(
25 | override val portfolioId: PortfolioId,
26 | val transactionId: TransactionId,
27 | val amountToPayInCents: Long
28 | ) : PortfolioEvent(portfolioId)
29 |
30 | data class CashReservedEvent(
31 | override val portfolioId: PortfolioId,
32 | val transactionId: TransactionId,
33 | val amountToReserve: Long
34 | ) : PortfolioEvent(portfolioId)
35 |
36 | data class CashWithdrawnEvent(
37 | override val portfolioId: PortfolioId,
38 | val amountPaidInCents: Long
39 | ) : PortfolioEvent(portfolioId)
40 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio
2 |
3 | import org.axonframework.commandhandling.TargetAggregateIdentifier
4 | import org.axonframework.samples.trader.api.users.UserId
5 |
6 | abstract class PortfolioCommand(@TargetAggregateIdentifier open val portfolioId: PortfolioId)
7 |
8 | data class CreatePortfolioCommand(
9 | override val portfolioId: PortfolioId,
10 | val userId: UserId
11 | ) : PortfolioCommand(portfolioId)
12 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/events.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio
2 |
3 | import org.axonframework.samples.trader.api.users.UserId
4 |
5 | abstract class PortfolioEvent(open val portfolioId: PortfolioId)
6 |
7 | class PortfolioCreatedEvent(
8 | override val portfolioId: PortfolioId,
9 | val userId: UserId
10 | ) : PortfolioEvent(portfolioId)
11 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/stock/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio.stock
2 |
3 | import org.axonframework.samples.trader.api.orders.OrderBookId
4 | import org.axonframework.samples.trader.api.orders.transaction.TransactionId
5 | import org.axonframework.samples.trader.api.portfolio.PortfolioCommand
6 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
7 | import javax.validation.constraints.Min
8 |
9 | data class AddItemsToPortfolioCommand(
10 | override val portfolioId: PortfolioId,
11 | val orderBookId: OrderBookId,
12 | @Min(0) val amountOfItemsToAdd: Long
13 | ) : PortfolioCommand(portfolioId)
14 |
15 | data class CancelItemReservationForPortfolioCommand(
16 | override val portfolioId: PortfolioId,
17 | val orderBookId: OrderBookId,
18 | val transactionId: TransactionId,
19 | val amountOfItemsToCancel: Long
20 | ) : PortfolioCommand(portfolioId)
21 |
22 | data class ConfirmItemReservationForPortfolioCommand(
23 | override val portfolioId: PortfolioId,
24 | val orderBookId: OrderBookId,
25 | val transactionId: TransactionId,
26 | val amountOfItemsToConfirm: Long
27 | ) : PortfolioCommand(portfolioId)
28 |
29 | data class ReserveItemsCommand(
30 | override val portfolioId: PortfolioId,
31 | val orderBookId: OrderBookId,
32 | val transactionId: TransactionId,
33 | val amountOfItemsToReserve: Long
34 | ) : PortfolioCommand(portfolioId)
35 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/stock/events.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio.stock
2 |
3 | import org.axonframework.samples.trader.api.orders.OrderBookId
4 | import org.axonframework.samples.trader.api.orders.transaction.TransactionId
5 | import org.axonframework.samples.trader.api.portfolio.PortfolioEvent
6 | import org.axonframework.samples.trader.api.portfolio.PortfolioId
7 |
8 | data class ItemReservationCancelledForPortfolioEvent(
9 | override val portfolioId: PortfolioId,
10 | val orderBookId: OrderBookId,
11 | val transactionId: TransactionId,
12 | val amountOfCancelledItems: Long
13 | ) : PortfolioEvent(portfolioId)
14 |
15 | data class ItemReservationConfirmedForPortfolioEvent(
16 | override val portfolioId: PortfolioId,
17 | val orderBookId: OrderBookId,
18 | val transactionId: TransactionId,
19 | val amountOfConfirmedItems: Long
20 | ) : PortfolioEvent(portfolioId)
21 |
22 | data class ItemsAddedToPortfolioEvent(
23 | override val portfolioId: PortfolioId,
24 | val orderBookId: OrderBookId,
25 | val amountOfItemsAdded: Long
26 | ) : PortfolioEvent(portfolioId)
27 |
28 | data class ItemsReservedEvent(
29 | override val portfolioId: PortfolioId,
30 | val orderBookId: OrderBookId,
31 | val transactionId: TransactionId,
32 | val amountOfItemsReserved: Long
33 | ) : PortfolioEvent(portfolioId)
34 |
35 | data class ItemToReserveNotAvailableInPortfolioEvent(
36 | override val portfolioId: PortfolioId,
37 | val orderBookId: OrderBookId,
38 | val transactionId: TransactionId
39 | ) : PortfolioEvent(portfolioId)
40 |
41 | data class NotEnoughItemsAvailableToReserveInPortfolioEvent(
42 | override val portfolioId: PortfolioId,
43 | val orderBookId: OrderBookId,
44 | val transactionId: TransactionId,
45 | val availableAmountOfItems: Long,
46 | val amountOfItemsToReserve: Long
47 | ) : PortfolioEvent(portfolioId)
48 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/portfolio/valueObjects.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.portfolio
2 |
3 | import org.axonframework.common.IdentifierFactory
4 | import java.io.Serializable
5 |
6 | data class PortfolioId(val identifier: String = IdentifierFactory.getInstance().generateIdentifier()) : Serializable {
7 |
8 | companion object {
9 | private const val serialVersionUID = 6784433385287437985L
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/users/UserAccount.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2012. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.api.users;
18 |
19 | /**
20 | * Object used to obtain information about an available UserAccount
21 | *
22 | * @author Jettro Coenradie
23 | */
24 | public interface UserAccount {
25 |
26 | String getUserId();
27 |
28 | String getUserName();
29 |
30 | String getFullName();
31 | }
32 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/users/commands.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.users
2 |
3 | import org.axonframework.commandhandling.TargetAggregateIdentifier
4 | import java.util.*
5 | import javax.validation.constraints.NotNull
6 | import javax.validation.constraints.Size
7 |
8 | abstract class UserCommand(@TargetAggregateIdentifier open val userId: UserId)
9 |
10 | class CreateUserCommand(
11 | override val userId: UserId,
12 | val name: String, @NotNull @Size(min = 3)
13 | val username: String, @NotNull @Size(min = 3)
14 | val password: String
15 | ) : UserCommand(userId)
16 |
17 | data class AuthenticateUserCommand(
18 | override val userId: UserId,
19 | val userName: String,
20 | @NotNull @Size(min = 3) val password: CharArray
21 | ) : UserCommand(userId) {
22 |
23 | override fun equals(other: Any?): Boolean {
24 | if (this === other) return true
25 | if (other !is AuthenticateUserCommand) return false
26 |
27 | if (userId != other.userId) return false
28 | if (userName != other.userName) return false
29 | if (!Arrays.equals(password, other.password)) return false
30 |
31 | return true
32 | }
33 |
34 | override fun hashCode(): Int {
35 | var result = userId.hashCode()
36 | result = 31 * result + userName.hashCode()
37 | result = 31 * result + Arrays.hashCode(password)
38 | return result
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/users/events.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.users
2 |
3 | abstract class UserEvent(open val userId: UserId)
4 |
5 | data class UserCreatedEvent(
6 | override val userId: UserId,
7 | val name: String,
8 | val username: String,
9 | val password: String
10 | ) : UserEvent(userId)
11 |
12 | data class UserAuthenticatedEvent(override val userId: UserId) : UserEvent(userId)
13 |
--------------------------------------------------------------------------------
/core-api/src/main/java/org/axonframework/samples/trader/api/users/valueObjects.kt:
--------------------------------------------------------------------------------
1 | package org.axonframework.samples.trader.api.users
2 |
3 | import org.axonframework.common.IdentifierFactory
4 | import java.io.Serializable
5 |
6 | data class UserId(val identifier: String = IdentifierFactory.getInstance().generateIdentifier()) : Serializable {
7 |
8 | companion object {
9 | private const val serialVersionUID = -4860092244272266543L
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/external-listeners/src/main/java/org/axonframework/samples/trader/listener/BroadcastingTextWebSocketHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2016. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.listener;
18 |
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 | import org.springframework.web.socket.CloseStatus;
22 | import org.springframework.web.socket.TextMessage;
23 | import org.springframework.web.socket.WebSocketSession;
24 | import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator;
25 | import org.springframework.web.socket.handler.TextWebSocketHandler;
26 |
27 | import java.io.IOException;
28 | import java.util.Map;
29 | import java.util.concurrent.ConcurrentHashMap;
30 | import java.util.concurrent.TimeUnit;
31 |
32 | class BroadcastingTextWebSocketHandler extends TextWebSocketHandler {
33 |
34 | private static final Logger logger = LoggerFactory.getLogger(BroadcastingTextWebSocketHandler.class);
35 | private Map sessions = new ConcurrentHashMap<>();
36 |
37 | @Override
38 | public void afterConnectionEstablished(WebSocketSession session) throws Exception {
39 | super.afterConnectionEstablished(session);
40 |
41 | sessions.put(session.getId(),
42 | new ConcurrentWebSocketSessionDecorator(session, (int) TimeUnit.SECONDS.toMillis(10), 5 * 1024));
43 | }
44 |
45 | @Override
46 | public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
47 | super.afterConnectionClosed(session, status);
48 |
49 | sessions.remove(session.getId());
50 | }
51 |
52 | protected void broadcast(String data) {
53 | final TextMessage message = new TextMessage(data);
54 | sessions.forEach((key, session) -> {
55 | try {
56 | session.sendMessage(message);
57 | } catch (IOException e) {
58 | logger.warn("An error occurred while trying to send a message to a WebSocket", e);
59 | }
60 | });
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/external-listeners/src/main/java/org/axonframework/samples/trader/listener/ExecutedTradesBroadcaster.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.listener;
18 |
19 | import org.axonframework.eventhandling.EventHandler;
20 | import org.axonframework.samples.trader.api.orders.trades.TradeExecutedEvent;
21 | import org.codehaus.jackson.JsonFactory;
22 | import org.codehaus.jackson.JsonGenerator;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 | import org.springframework.stereotype.Component;
26 |
27 | import java.io.IOException;
28 | import java.io.StringWriter;
29 | import java.io.Writer;
30 |
31 | /**
32 | * Creates a JSON object and broadcasts it to every connected WebSocket session. The structure of the json object is:
33 | *
34 | * {
35 | * tradeExecuted :
36 | * {
37 | * orderbookId: ... ,
38 | * count: ... ,
39 | * price: ...
40 | * }
41 | * }
42 | *
43 | * The url to send the request to can be configured.
44 | *
45 | * @author Jettro Coenradie
46 | */
47 | @Component
48 | public class ExecutedTradesBroadcaster extends BroadcastingTextWebSocketHandler {
49 | private static final Logger logger = LoggerFactory.getLogger(ExecutedTradesBroadcaster.class);
50 |
51 | private JsonFactory jsonFactory = new JsonFactory();
52 |
53 | @EventHandler
54 | public void handle(TradeExecutedEvent event) {
55 | try {
56 | doHandle(event);
57 | } catch (IOException e) {
58 | logger.warn("Problem while sending TradeExecutedEvent to external system");
59 | }
60 | }
61 |
62 | private void doHandle(TradeExecutedEvent event) throws IOException {
63 | String jsonObjectAsString = createJsonInString(event);
64 |
65 | this.broadcast(jsonObjectAsString);
66 | }
67 |
68 | private String createJsonInString(TradeExecutedEvent event) throws IOException {
69 | Writer writer = new StringWriter();
70 | JsonGenerator g = jsonFactory.createJsonGenerator(writer);
71 | g.writeStartObject();
72 | g.writeObjectFieldStart("tradeExecuted");
73 | g.writeStringField("orderbookId", event.getOrderBookId().toString());
74 | g.writeStringField("count", String.valueOf(event.getTradeCount()));
75 | g.writeStringField("price", String.valueOf(event.getTradePrice()));
76 | g.writeEndObject(); // for trade-executed
77 | g.close();
78 | return writer.toString();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/external-listeners/src/main/java/org/axonframework/samples/trader/listener/WebSocketConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2016. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.listener;
18 |
19 | import org.springframework.beans.factory.annotation.Autowired;
20 | import org.springframework.context.annotation.Configuration;
21 | import org.springframework.web.socket.config.annotation.EnableWebSocket;
22 | import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
23 | import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
24 |
25 | @Configuration
26 | @EnableWebSocket
27 | public class WebSocketConfig implements WebSocketConfigurer {
28 |
29 | @Autowired
30 | private ExecutedTradesBroadcaster executedTradesBroadcaster;
31 |
32 | @Override
33 | public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
34 | registry.addHandler(executedTradesBroadcaster, "/eventbus")
35 | .withSockJS();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/external-listeners/src/main/java/org/axonframework/samples/trader/listener/config/ExternalListenersConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2016. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.listener.config;
18 |
19 | import org.axonframework.eventhandling.EventProcessor;
20 | import org.axonframework.eventhandling.SimpleEventHandlerInvoker;
21 | import org.axonframework.eventhandling.SubscribingEventProcessor;
22 | import org.axonframework.eventsourcing.eventstore.EventStore;
23 | import org.axonframework.samples.trader.listener.ExecutedTradesBroadcaster;
24 | import org.springframework.beans.factory.annotation.Autowired;
25 | import org.springframework.context.annotation.Bean;
26 | import org.springframework.context.annotation.ComponentScan;
27 | import org.springframework.context.annotation.Configuration;
28 | import org.springframework.context.annotation.PropertySource;
29 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
30 |
31 | @Configuration
32 | @ComponentScan("org.axonframework.samples.trader.listener")
33 | @PropertySource("classpath:external-config.properties")
34 | public class ExternalListenersConfig {
35 |
36 | @Autowired
37 | private EventStore eventStore;
38 |
39 | @Autowired
40 | private ExecutedTradesBroadcaster executedTradesBroadcaster;
41 |
42 | @Bean
43 | public EventProcessor externalListenersEventProcessor() {
44 | SubscribingEventProcessor eventProcessor = new SubscribingEventProcessor("externalListenersEventProcessor",
45 | new SimpleEventHandlerInvoker(executedTradesBroadcaster),
46 | eventStore);
47 |
48 | eventProcessor.start();
49 |
50 | return eventProcessor;
51 | }
52 |
53 | @Bean
54 | public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
55 | PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
56 | return configurer;
57 | }
58 | }
--------------------------------------------------------------------------------
/external-listeners/src/main/resources/META-INF/spring/external-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/external-listeners/src/main/resources/external-config.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2012. Axon Framework
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 | serverUrlEventBus=http://localhost:8080/eventbus
17 |
--------------------------------------------------------------------------------
/infrastructure/src/main/java/org/axonframework/samples/trader/infra/config/CQRSInfrastructureHSQLDBConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2010-2016. Axon Framework
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.axonframework.samples.trader.infra.config;
18 |
19 | import org.axonframework.common.jdbc.ConnectionProvider;
20 | import org.axonframework.common.transaction.NoTransactionManager;
21 | import org.axonframework.eventhandling.saga.repository.SagaStore;
22 | import org.axonframework.eventhandling.saga.repository.jdbc.HsqlSagaSqlSchema;
23 | import org.axonframework.eventhandling.saga.repository.jdbc.JdbcSagaStore;
24 | import org.axonframework.eventhandling.saga.repository.jdbc.SagaSqlSchema;
25 | import org.axonframework.eventsourcing.eventstore.EmbeddedEventStore;
26 | import org.axonframework.eventsourcing.eventstore.EventStore;
27 | import org.axonframework.eventsourcing.eventstore.jdbc.EventSchema;
28 | import org.axonframework.eventsourcing.eventstore.jdbc.EventTableFactory;
29 | import org.axonframework.eventsourcing.eventstore.jdbc.HsqlEventTableFactory;
30 | import org.axonframework.eventsourcing.eventstore.jdbc.JdbcEventStorageEngine;
31 | import org.axonframework.spring.jdbc.SpringDataSourceConnectionProvider;
32 | import org.springframework.context.annotation.Bean;
33 | import org.springframework.context.annotation.Configuration;
34 | import org.springframework.context.annotation.Profile;
35 |
36 | import javax.sql.DataSource;
37 |
38 | @Configuration
39 | @Profile("hsqldb")
40 | public class CQRSInfrastructureHSQLDBConfig {
41 |
42 | @Bean
43 | public SpringDataSourceConnectionProvider springDataSourceConnectionProvider(DataSource dataSource) {
44 | return new SpringDataSourceConnectionProvider(dataSource);
45 | }
46 |
47 | @Bean
48 | public JdbcEventStorageEngine eventStorageEngine(ConnectionProvider connectionProvider) {
49 | return new JdbcEventStorageEngine(connectionProvider, NoTransactionManager.INSTANCE);
50 | }
51 |
52 | @Bean
53 | public EventStore eventStore(ConnectionProvider connectionProvider) {
54 | return new EmbeddedEventStore(eventStorageEngine(connectionProvider));
55 | }
56 |
57 | @Bean
58 | public EventTableFactory eventSchemaFactory() {
59 | return HsqlEventTableFactory.INSTANCE;
60 | }
61 |
62 | @Bean
63 | public EventSchema eventSchema() {
64 | return new EventSchema();
65 | }
66 |
67 | @Bean
68 | public SagaSqlSchema sagaSqlSchema() {
69 | return new HsqlSagaSqlSchema();
70 | }
71 |
72 | @Bean
73 | public SagaStore