Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

More saga stuff and a small refactoring in the model. Now the orders …

…are related to portfolio instead of users.
  • Loading branch information...
commit aa3a29e4eae15550b9be9197751089202c49dba4 1 parent 15ad3e6
@jettro jettro authored
Showing with 149 additions and 33 deletions.
  1. +1 −2  README
  2. +5 −5 app/src/main/java/org/axonframework/samples/trader/app/api/order/AbstractOrderCommand.java
  3. +5 −5 app/src/main/java/org/axonframework/samples/trader/app/api/order/AbstractOrderPlacedEvent.java
  4. +2 −2 app/src/main/java/org/axonframework/samples/trader/app/api/order/BuyOrderPlacedEvent.java
  5. +2 −2 app/src/main/java/org/axonframework/samples/trader/app/api/order/CreateBuyOrderCommand.java
  6. +2 −2 app/src/main/java/org/axonframework/samples/trader/app/api/order/CreateSellOrderCommand.java
  7. +2 −2 app/src/main/java/org/axonframework/samples/trader/app/api/order/SellOrderPlacedEvent.java
  8. +2 −2 app/src/main/java/org/axonframework/samples/trader/app/command/trading/OrderBook.java
  9. +2 −2 app/src/main/java/org/axonframework/samples/trader/app/command/trading/OrderBookCommandHandler.java
  10. +19 −7 app/src/main/java/org/axonframework/samples/trader/app/command/trading/SellTradeManagerSaga.java
  11. +1 −1  app/src/main/java/org/axonframework/samples/trader/app/query/orderbook/OrderBookListener.java
  12. +14 −1 app/src/test/java/org/axonframework/samples/trader/app/command/trading/SellTradeManagerSagaTest.java
  13. +35 −0 ...st/java/org/axonframework/samples/trader/app/command/trading/matchers/ConfirmTransactionCommandMatcher.java
  14. +57 −0 .../test/java/org/axonframework/samples/trader/app/command/trading/matchers/CreateSellOrderCommandMatcher.java
View
3  README
@@ -6,9 +6,8 @@ Initial setup
- Make sure you have java installed
http://www.java.com/download/
-- Make sure you have maven or gradle installed
+- Make sure you have maven installed
http://maven.apache.org/download.html#Installation
-http://www.gradle.org/installation.html
- Make sure you have mongodb installed
http://www.mongodb.org/display/DOCS/Quickstart
View
10 app/src/main/java/org/axonframework/samples/trader/app/api/order/AbstractOrderCommand.java
@@ -23,22 +23,22 @@
*/
public abstract class AbstractOrderCommand {
- private AggregateIdentifier userId;
+ private AggregateIdentifier portfolioId;
private AggregateIdentifier orderBookId;
private long tradeCount;
private int itemPrice;
private AggregateIdentifier orderId;
- protected AbstractOrderCommand(AggregateIdentifier userId, AggregateIdentifier orderBookId, long tradeCount, int itemPrice) {
- this.userId = userId;
+ protected AbstractOrderCommand(AggregateIdentifier portfolioId, AggregateIdentifier orderBookId, long tradeCount, int itemPrice) {
+ this.portfolioId = portfolioId;
this.orderBookId = orderBookId;
this.tradeCount = tradeCount;
this.itemPrice = itemPrice;
this.orderId = new UUIDAggregateIdentifier();
}
- public AggregateIdentifier getUserId() {
- return userId;
+ public AggregateIdentifier getPortfolioId() {
+ return portfolioId;
}
public AggregateIdentifier getOrderBookId() {
View
10 ...rc/main/java/org/axonframework/samples/trader/app/api/order/AbstractOrderPlacedEvent.java
@@ -26,13 +26,13 @@
private final AggregateIdentifier orderId;
private final long tradeCount;
private final int itemPrice;
- private final AggregateIdentifier userId;
+ private final AggregateIdentifier portfolioId;
- protected AbstractOrderPlacedEvent(AggregateIdentifier orderId, long tradeCount, int itemPrice, AggregateIdentifier userId) {
+ protected AbstractOrderPlacedEvent(AggregateIdentifier orderId, long tradeCount, int itemPrice, AggregateIdentifier portfolioId) {
this.orderId = orderId;
this.tradeCount = tradeCount;
this.itemPrice = itemPrice;
- this.userId = userId;
+ this.portfolioId = portfolioId;
}
public AggregateIdentifier orderBookIdentifier() {
@@ -51,8 +51,8 @@ public int getItemPrice() {
return itemPrice;
}
- public AggregateIdentifier getUserId() {
- return userId;
+ public AggregateIdentifier getPortfolioId() {
+ return portfolioId;
}
}
View
4 app/src/main/java/org/axonframework/samples/trader/app/api/order/BuyOrderPlacedEvent.java
@@ -22,8 +22,8 @@
*/
public class BuyOrderPlacedEvent extends AbstractOrderPlacedEvent {
- public BuyOrderPlacedEvent(AggregateIdentifier orderId, long tradeCount, int itemPrice, AggregateIdentifier userId) {
- super(orderId, tradeCount, itemPrice, userId);
+ public BuyOrderPlacedEvent(AggregateIdentifier orderId, long tradeCount, int itemPrice, AggregateIdentifier portfolioId) {
+ super(orderId, tradeCount, itemPrice, portfolioId);
}
}
View
4 app/src/main/java/org/axonframework/samples/trader/app/api/order/CreateBuyOrderCommand.java
@@ -22,7 +22,7 @@
*/
public class CreateBuyOrderCommand extends AbstractOrderCommand {
- public CreateBuyOrderCommand(AggregateIdentifier userId, AggregateIdentifier orderBookId, long tradeCount, int itemPrice) {
- super(userId, orderBookId, tradeCount, itemPrice);
+ public CreateBuyOrderCommand(AggregateIdentifier portfolioId, AggregateIdentifier orderBookId, long tradeCount, int itemPrice) {
+ super(portfolioId, orderBookId, tradeCount, itemPrice);
}
}
View
4 app/src/main/java/org/axonframework/samples/trader/app/api/order/CreateSellOrderCommand.java
@@ -22,7 +22,7 @@
*/
public class CreateSellOrderCommand extends AbstractOrderCommand {
- public CreateSellOrderCommand(AggregateIdentifier userId, AggregateIdentifier orderBookId, long tradeCount, int itemPrice) {
- super(userId, orderBookId, tradeCount, itemPrice);
+ public CreateSellOrderCommand(AggregateIdentifier portfolioId, AggregateIdentifier orderBookId, long tradeCount, int itemPrice) {
+ super(portfolioId, orderBookId, tradeCount, itemPrice);
}
}
View
4 app/src/main/java/org/axonframework/samples/trader/app/api/order/SellOrderPlacedEvent.java
@@ -22,7 +22,7 @@
*/
public class SellOrderPlacedEvent extends AbstractOrderPlacedEvent {
- public SellOrderPlacedEvent(AggregateIdentifier orderId, long tradeCount, int itemPrice, AggregateIdentifier userId) {
- super(orderId, tradeCount, itemPrice, userId);
+ public SellOrderPlacedEvent(AggregateIdentifier orderId, long tradeCount, int itemPrice, AggregateIdentifier portfolioId) {
+ super(orderId, tradeCount, itemPrice, portfolioId);
}
}
View
4 app/src/main/java/org/axonframework/samples/trader/app/command/trading/OrderBook.java
@@ -76,12 +76,12 @@ private void executeTrades() {
@EventHandler
protected void onBuyPlaced(BuyOrderPlacedEvent event) {
- buyOrders.add(new Order(event.getOrderId(), event.getItemPrice(), event.getTradeCount(), event.getUserId()));
+ buyOrders.add(new Order(event.getOrderId(), event.getItemPrice(), event.getTradeCount(), event.getPortfolioId()));
}
@EventHandler
protected void onSellPlaced(SellOrderPlacedEvent event) {
- sellOrders.add(new Order(event.getOrderId(), event.getItemPrice(), event.getTradeCount(), event.getUserId()));
+ sellOrders.add(new Order(event.getOrderId(), event.getItemPrice(), event.getTradeCount(), event.getPortfolioId()));
}
@EventHandler
View
4 ...in/java/org/axonframework/samples/trader/app/command/trading/OrderBookCommandHandler.java
@@ -41,7 +41,7 @@ public void handleBuyOrder(CreateBuyOrderCommand command) {
orderBook.addBuyOrder(command.getOrderId(),
command.getTradeCount(),
command.getItemPrice(),
- command.getUserId());
+ command.getPortfolioId());
}
@CommandHandler
@@ -51,7 +51,7 @@ public void handleSellOrder(CreateSellOrderCommand command) {
orderBook.addSellOrder(command.getOrderId(),
command.getTradeCount(),
command.getItemPrice(),
- command.getUserId());
+ command.getPortfolioId());
}
@CommandHandler
View
26 .../main/java/org/axonframework/samples/trader/app/command/trading/SellTradeManagerSaga.java
@@ -20,10 +20,12 @@
import org.axonframework.saga.annotation.AbstractAnnotatedSaga;
import org.axonframework.saga.annotation.SagaEventHandler;
import org.axonframework.saga.annotation.StartSaga;
-import org.axonframework.samples.trader.app.api.portfolio.item.ConfirmItemReservationForPortfolioCommand;
+import org.axonframework.samples.trader.app.api.order.CreateSellOrderCommand;
import org.axonframework.samples.trader.app.api.portfolio.item.ItemsReservedEvent;
import org.axonframework.samples.trader.app.api.portfolio.item.NotEnoughItemsAvailableToReserveInPortfolio;
import org.axonframework.samples.trader.app.api.portfolio.item.ReserveItemsCommand;
+import org.axonframework.samples.trader.app.api.transaction.ConfirmTransactionCommand;
+import org.axonframework.samples.trader.app.api.transaction.SellTransactionConfirmedEvent;
import org.axonframework.samples.trader.app.api.transaction.SellTransactionStartedEvent;
import org.springframework.beans.factory.annotation.Autowired;
@@ -34,28 +36,38 @@
private transient CommandBus commandBus;
private int totalItems;
- private long pricePerItem;
+ private int pricePerItem;
+
+ private AggregateIdentifier transactionIdentifier;
+ private AggregateIdentifier orderbookIdentifier;
+ private AggregateIdentifier portfolioIdentifier;
@StartSaga
@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(SellTransactionStartedEvent event) {
- AggregateIdentifier orderbookIdentifier = event.getOrderbookIdentifier();
- AggregateIdentifier portfolioIdentifier = event.getPortfolioIdentifier();
+ transactionIdentifier = event.getTransactionIdentifier();
+ orderbookIdentifier = event.getOrderbookIdentifier();
+ portfolioIdentifier = event.getPortfolioIdentifier();
associateWith("orderbookIdentifier", orderbookIdentifier);
associateWith("portfolioIdentifier", portfolioIdentifier);
ReserveItemsCommand reserveItemsCommand =
new ReserveItemsCommand(portfolioIdentifier, orderbookIdentifier, event.getTotalItems());
- pricePerItem = event.getPricePerItem();
+ pricePerItem = (int) event.getPricePerItem(); // TODO jettro: correct the long and ints
totalItems = event.getTotalItems();
commandBus.dispatch(reserveItemsCommand);
}
@SagaEventHandler(associationProperty = "portfolioIdentifier")
public void handle(ItemsReservedEvent event) {
- ConfirmItemReservationForPortfolioCommand command =
- new ConfirmItemReservationForPortfolioCommand(event.getPortfolioIdentifier(), event.getOrderBookIdentifier(), event.getAmountOfItemsReserved());
+ ConfirmTransactionCommand confirmTransactionCommand = new ConfirmTransactionCommand(transactionIdentifier);
+ commandBus.dispatch(confirmTransactionCommand);
+ }
+
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ public void handle(SellTransactionConfirmedEvent event) {
+ CreateSellOrderCommand command = new CreateSellOrderCommand(portfolioIdentifier, orderbookIdentifier, totalItems, pricePerItem);
commandBus.dispatch(command);
}
View
2  ...src/main/java/org/axonframework/samples/trader/app/query/orderbook/OrderBookListener.java
@@ -109,7 +109,7 @@ private OrderEntry createPlacedOrder(AbstractOrderPlacedEvent event, String type
entry.setIdentifier(event.getOrderId().asString());
entry.setItemsRemaining(event.getTradeCount());
entry.setTradeCount(event.getTradeCount());
- entry.setUserId(event.getUserId().asString());
+ entry.setUserId(event.getPortfolioId().asString());
entry.setType(type);
entry.setItemPrice(event.getItemPrice());
View
15 ...t/java/org/axonframework/samples/trader/app/command/trading/SellTradeManagerSagaTest.java
@@ -19,8 +19,11 @@
import org.axonframework.domain.UUIDAggregateIdentifier;
import org.axonframework.samples.trader.app.api.portfolio.item.ItemsReservedEvent;
import org.axonframework.samples.trader.app.api.portfolio.item.NotEnoughItemsAvailableToReserveInPortfolio;
+import org.axonframework.samples.trader.app.api.transaction.SellTransactionConfirmedEvent;
import org.axonframework.samples.trader.app.api.transaction.SellTransactionStartedEvent;
import org.axonframework.samples.trader.app.command.trading.matchers.ConfirmItemReservationForPortfolioCommandMatcher;
+import org.axonframework.samples.trader.app.command.trading.matchers.ConfirmTransactionCommandMatcher;
+import org.axonframework.samples.trader.app.command.trading.matchers.CreateSellOrderCommandMatcher;
import org.axonframework.samples.trader.app.command.trading.matchers.ReservedItemsCommandMatcher;
import org.axonframework.test.saga.AnnotatedSagaTestFixture;
import org.junit.Before;
@@ -57,10 +60,20 @@ public void testHandle_ItemsReserved() {
fixture.givenAggregate(transactionIdentifier).published(new SellTransactionStartedEvent(orderbookIdentifier, portfolioIdentifier, 100, 10))
.whenAggregate(portfolioIdentifier).publishes(new ItemsReservedEvent(orderbookIdentifier, 100))
.expectActiveSagas(1)
- .expectDispatchedCommandsMatching(new ConfirmItemReservationForPortfolioCommandMatcher(orderbookIdentifier.asString(), portfolioIdentifier.asString(), 100));
+ .expectDispatchedCommandsMatching(new ConfirmTransactionCommandMatcher(transactionIdentifier));
}
@Test
+ public void testHandle_TransactionConfirmed() {
+ fixture.givenAggregate(transactionIdentifier).published(new SellTransactionStartedEvent(orderbookIdentifier, portfolioIdentifier, 100, 10))
+ .andThenAggregate(portfolioIdentifier).published(new ItemsReservedEvent(orderbookIdentifier, 100))
+ .whenAggregate(transactionIdentifier).publishes(new SellTransactionConfirmedEvent())
+ .expectActiveSagas(1)
+ .expectDispatchedCommandsMatching(new CreateSellOrderCommandMatcher(portfolioIdentifier, orderbookIdentifier, 100, 10));
+ }
+
+
+ @Test
@Ignore
public void testHandle_NotEnoughItemsToReserve() {
fixture.givenAggregate(transactionIdentifier).published(new SellTransactionStartedEvent(orderbookIdentifier, portfolioIdentifier, 100, 10))
View
35 ...amework/samples/trader/app/command/trading/matchers/ConfirmTransactionCommandMatcher.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011. Gridshore
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.axonframework.samples.trader.app.command.trading.matchers;
+
+import org.axonframework.domain.AggregateIdentifier;
+import org.axonframework.samples.trader.app.api.transaction.ConfirmTransactionCommand;
+
+/**
+ * @author Jettro Coenradie
+ */
+public class ConfirmTransactionCommandMatcher extends TradeManagerSagaMatcher<ConfirmTransactionCommand> {
+ private AggregateIdentifier transactionIdentifier;
+
+ public ConfirmTransactionCommandMatcher(AggregateIdentifier transactionIdentifier) {
+ this.transactionIdentifier = transactionIdentifier;
+ }
+
+ @Override
+ public boolean doMatch(ConfirmTransactionCommand singleArgument) {
+ return singleArgument.getTransactionIdentifier().asString().equals(transactionIdentifier.asString());
+ }
+}
View
57 ...nframework/samples/trader/app/command/trading/matchers/CreateSellOrderCommandMatcher.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011. Gridshore
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.axonframework.samples.trader.app.command.trading.matchers;
+
+import org.axonframework.domain.AggregateIdentifier;
+import org.axonframework.samples.trader.app.api.order.CreateSellOrderCommand;
+
+/**
+ * @author Jettro Coenradie
+ */
+public class CreateSellOrderCommandMatcher extends TradeManagerSagaMatcher<CreateSellOrderCommand> {
+ private String orderbookIdentifier;
+ private String portfolioIdentifier;
+ private long tradeCount;
+ private int itemPrice;
+
+ public CreateSellOrderCommandMatcher(AggregateIdentifier portfolioIdentifier, AggregateIdentifier orderbookIdentifier, long tradeCount, int itemPrice) {
+ this.portfolioIdentifier = portfolioIdentifier.asString();
+ this.orderbookIdentifier = orderbookIdentifier.asString();
+ this.tradeCount = tradeCount;
+ this.itemPrice = itemPrice;
+ }
+
+ @Override
+ public boolean doMatch(CreateSellOrderCommand command) {
+ if (!command.getOrderBookId().asString().equals(orderbookIdentifier)) {
+ problem = String.format("Orderbook identifier is not as expected, required %s but received %s", orderbookIdentifier, command.getOrderBookId());
+ return false;
+ }
+ if (!command.getPortfolioId().asString().equals(portfolioIdentifier)) {
+ problem = String.format("Portfolio identifier is not as expected, required %s but received %s", portfolioIdentifier, command.getPortfolioId());
+ return false;
+ }
+ if (tradeCount != command.getTradeCount()) {
+ problem = String.format("The amount of items to trade is not as expected, required %d but received %d", tradeCount, command.getTradeCount());
+ return false;
+ }
+ if (itemPrice != command.getItemPrice()) {
+ problem = String.format("The price of items to trade is not as exepcted, required %d but received %d", itemPrice, command.getItemPrice());
+ return false;
+ }
+ return true;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.