Permalink
Browse files

Finished the sagas for transactions

  • Loading branch information...
1 parent 759fce0 commit cd949215bed1da77672b1e026a44d5a5b0821583 @jettro jettro committed Jan 16, 2012
Showing with 1,052 additions and 165 deletions.
  1. +9 −0 ...main/java/org/axonframework/samples/trader/app/api/portfolio/item/AddItemsToPortfolioCommand.java
  2. +8 −0 ...ramework/samples/trader/app/api/portfolio/money/ConfirmMoneyReservationFromPortfolionCommand.java
  3. +98 −0 app/src/main/java/org/axonframework/samples/trader/app/command/trading/BuyTradeManagerSaga.java
  4. +54 −41 app/src/main/java/org/axonframework/samples/trader/app/command/trading/SellTradeManagerSaga.java
  5. +94 −0 app/src/main/java/org/axonframework/samples/trader/app/command/trading/TradeManagerSaga.java
  6. +134 −0 app/src/test/java/org/axonframework/samples/trader/app/command/trading/BuyTradeManagerSagaTest.java
  7. +60 −13 app/src/test/java/org/axonframework/samples/trader/app/command/trading/SellTradeManagerSagaTest.java
  8. +59 −0 .../axonframework/samples/trader/app/command/trading/matchers/AddItemsToPortfolioCommandMatcher.java
  9. +58 −0 .../samples/trader/app/command/trading/matchers/CancelItemReservationForPortfolioCommandMatcher.java
  10. +55 −0 ...amples/trader/app/command/trading/matchers/CancelMoneyReservationFromPortfolioCommandMatcher.java
  11. +48 −0 ...rg/axonframework/samples/trader/app/command/trading/matchers/CancelTransactionCommandMatcher.java
  12. +26 −17 ...samples/trader/app/command/trading/matchers/ConfirmItemReservationForPortfolioCommandMatcher.java
  13. +54 −0 ...ples/trader/app/command/trading/matchers/ConfirmMoneyReservationFromPortfolionCommandMatcher.java
  14. +16 −3 ...g/axonframework/samples/trader/app/command/trading/matchers/ConfirmTransactionCommandMatcher.java
  15. +65 −0 ...a/org/axonframework/samples/trader/app/command/trading/matchers/CreateBuyOrderCommandMatcher.java
  16. +24 −17 .../org/axonframework/samples/trader/app/command/trading/matchers/CreateSellOrderCommandMatcher.java
  17. +55 −0 ...nframework/samples/trader/app/command/trading/matchers/DepositMoneyToPortfolioCommandMatcher.java
  18. +58 −0 .../axonframework/samples/trader/app/command/trading/matchers/ExecutedTransactionCommandMatcher.java
  19. +54 −0 ...ramework/samples/trader/app/command/trading/matchers/ReserveMoneyFromPortfolioCommandMatcher.java
  20. +23 −16 ...va/org/axonframework/samples/trader/app/command/trading/matchers/ReservedItemsCommandMatcher.java
  21. +0 −58 ...t/java/org/axonframework/samples/trader/app/command/trading/matchers/TradeManagerSagaMatcher.java
@@ -51,4 +51,13 @@ public AggregateIdentifier getOrderBookIdentifier() {
public AggregateIdentifier getPortfolioIdentifier() {
return portfolioIdentifier;
}
+
+ @Override
+ public String toString() {
+ return "AddItemsToPortfolioCommand{" +
+ "amountOfItemsToAdd=" + amountOfItemsToAdd +
+ ", portfolioIdentifier=" + portfolioIdentifier +
+ ", orderBookIdentifier=" + orderBookIdentifier +
+ '}';
+ }
}
@@ -37,4 +37,12 @@ public long getAmountOfMoneyToConfirmInCents() {
public AggregateIdentifier getPortfolioIdentifier() {
return portfolioIdentifier;
}
+
+ @Override
+ public String toString() {
+ return "ConfirmMoneyReservationFromPortfolionCommand{" +
+ "amountOfMoneyToConfirmInCents=" + amountOfMoneyToConfirmInCents +
+ ", portfolioIdentifier=" + portfolioIdentifier +
+ '}';
+ }
}
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012. 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;
+
+import org.axonframework.saga.annotation.EndSaga;
+import org.axonframework.saga.annotation.SagaEventHandler;
+import org.axonframework.saga.annotation.StartSaga;
+import org.axonframework.samples.trader.app.api.order.CreateBuyOrderCommand;
+import org.axonframework.samples.trader.app.api.portfolio.item.AddItemsToPortfolioCommand;
+import org.axonframework.samples.trader.app.api.portfolio.money.*;
+import org.axonframework.samples.trader.app.api.transaction.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Jettro Coenradie
+ */
+public class BuyTradeManagerSaga extends TradeManagerSaga {
+ private final static Logger logger = LoggerFactory.getLogger(BuyTradeManagerSaga.class);
+
+ @StartSaga
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ public void handle(BuyTransactionStartedEvent event) {
+ setTransactionIdentifier(event.getTransactionIdentifier());
+ setOrderbookIdentifier(event.getOrderbookIdentifier());
+ setPortfolioIdentifier(event.getPortfolioIdentifier());
+
+ associateWith("orderBookIdentifier", getOrderbookIdentifier());
+ associateWith("portfolioIdentifier", getPortfolioIdentifier());
+
+ setPricePerItem(event.getPricePerItem());
+ setTotalItems(event.getTotalItems());
+
+ ReserveMoneyFromPortfolioCommand command = new ReserveMoneyFromPortfolioCommand(getPortfolioIdentifier(), getTotalItems() * getPricePerItem());
+ getCommandBus().dispatch(command);
+ }
+
+ @SagaEventHandler(associationProperty = "portfolioIdentifier")
+ public void handle(MoneyReservedFromPortfolioEvent event) {
+ ConfirmTransactionCommand command = new ConfirmTransactionCommand(getTransactionIdentifier());
+ getCommandBus().dispatch(command);
+ }
+
+ @SagaEventHandler(associationProperty = "portfolioIdentifier")
+ @EndSaga
+ public void handle(NotEnoughMoneyInPortfolioToMakeReservationEvent event) {
+ // Nothing to do, no reservations were made and the transaction is finished
+ }
+
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ public void handle(BuyTransactionConfirmedEvent event) {
+ CreateBuyOrderCommand command = new CreateBuyOrderCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), getTotalItems(), getPricePerItem());
+ getCommandBus().dispatch(command);
+ }
+
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ public void handle(BuyTransactionCancelledEvent event) {
+ long amountToCancel = (event.getTotalAmountOfItems() - event.getAmountOfExecutedItems()) * getPricePerItem();
+ CancelMoneyReservationFromPortfolioCommand command = new CancelMoneyReservationFromPortfolioCommand(getPortfolioIdentifier(), amountToCancel);
+ getCommandBus().dispatch(command);
+ }
+
+
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ @EndSaga
+ public void handle(BuyTransactionExecutedEvent event) {
+ ConfirmMoneyReservationFromPortfolionCommand confirmCommand =
+ new ConfirmMoneyReservationFromPortfolionCommand(getPortfolioIdentifier(), event.getAmountOfItems() * event.getItemPrice());
+ getCommandBus().dispatch(confirmCommand);
+ AddItemsToPortfolioCommand addItemsCommand =
+ new AddItemsToPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getAmountOfItems());
+ getCommandBus().dispatch(addItemsCommand);
+ }
+
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ public void handle(BuyTransactionPartiallyExecutedEvent event) {
+ ConfirmMoneyReservationFromPortfolionCommand confirmCommand =
+ new ConfirmMoneyReservationFromPortfolionCommand(getPortfolioIdentifier(), event.getAmountOfExecutedItems() * event.getItemPrice());
+ getCommandBus().dispatch(confirmCommand);
+ AddItemsToPortfolioCommand addItemsCommand =
+ new AddItemsToPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getAmountOfExecutedItems());
+ getCommandBus().dispatch(addItemsCommand);
+ }
+
+}
@@ -15,72 +15,85 @@
package org.axonframework.samples.trader.app.command.trading;
-import org.axonframework.commandhandling.CommandBus;
-import org.axonframework.domain.AggregateIdentifier;
-import org.axonframework.saga.annotation.AbstractAnnotatedSaga;
+import org.axonframework.saga.annotation.EndSaga;
import org.axonframework.saga.annotation.SagaEventHandler;
import org.axonframework.saga.annotation.StartSaga;
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;
+import org.axonframework.samples.trader.app.api.portfolio.item.*;
+import org.axonframework.samples.trader.app.api.portfolio.money.DepositMoneyToPortfolioCommand;
+import org.axonframework.samples.trader.app.api.transaction.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* @author Jettro Coenradie
*/
-public class SellTradeManagerSaga extends AbstractAnnotatedSaga {
-
- private transient CommandBus commandBus;
- private long totalItems;
- private long pricePerItem;
-
- private AggregateIdentifier transactionIdentifier;
- private AggregateIdentifier orderbookIdentifier;
- private AggregateIdentifier portfolioIdentifier;
+public class SellTradeManagerSaga extends TradeManagerSaga {
+ private final static Logger logger = LoggerFactory.getLogger(SellTradeManagerSaga.class);
@StartSaga
@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(SellTransactionStartedEvent event) {
- transactionIdentifier = event.getTransactionIdentifier();
- orderbookIdentifier = event.getOrderbookIdentifier();
- portfolioIdentifier = event.getPortfolioIdentifier();
+ setTransactionIdentifier(event.getTransactionIdentifier());
+ setOrderbookIdentifier(event.getOrderbookIdentifier());
+ setPortfolioIdentifier(event.getPortfolioIdentifier());
+ setPricePerItem(event.getPricePerItem());
+ setTotalItems(event.getTotalItems());
- associateWith("orderbookIdentifier", orderbookIdentifier);
- associateWith("portfolioIdentifier", portfolioIdentifier);
+ associateWith("orderBookIdentifier", getOrderbookIdentifier());
+ associateWith("portfolioIdentifier", getPortfolioIdentifier());
ReserveItemsCommand reserveItemsCommand =
- new ReserveItemsCommand(portfolioIdentifier, orderbookIdentifier, event.getTotalItems());
- pricePerItem = event.getPricePerItem(); // TODO jettro: correct the long and ints
- totalItems = event.getTotalItems();
- commandBus.dispatch(reserveItemsCommand);
+ new ReserveItemsCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getTotalItems());
+ getCommandBus().dispatch(reserveItemsCommand);
}
@SagaEventHandler(associationProperty = "portfolioIdentifier")
public void handle(ItemsReservedEvent event) {
- ConfirmTransactionCommand confirmTransactionCommand = new ConfirmTransactionCommand(transactionIdentifier);
- commandBus.dispatch(confirmTransactionCommand);
+ ConfirmTransactionCommand confirmTransactionCommand = new ConfirmTransactionCommand(getTransactionIdentifier());
+ getCommandBus().dispatch(confirmTransactionCommand);
+ }
+
+ @SagaEventHandler(associationProperty = "portfolioIdentifier")
+ @EndSaga
+ public void handle(NotEnoughItemsAvailableToReserveInPortfolio event) {
+ logger.debug("Cannot continue with transaction with id {} since the items needed cannot be reserved", getTotalItems());
}
@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(SellTransactionConfirmedEvent event) {
- CreateSellOrderCommand command = new CreateSellOrderCommand(portfolioIdentifier, orderbookIdentifier, totalItems, pricePerItem);
- commandBus.dispatch(command);
+ CreateSellOrderCommand command = new CreateSellOrderCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), getTotalItems(), getPricePerItem());
+ getCommandBus().dispatch(command);
}
- @SagaEventHandler(associationProperty = "portfolioIdentifier")
- public void handle(NotEnoughItemsAvailableToReserveInPortfolio event) {
- // TODO jettro: not sure if I need to do something here, maybe inactivate this saga ?
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ @EndSaga
+ public void handle(SellTransactionCancelledEvent event) {
+ logger.debug("Saga for Sell Transaction with id {} is cancelled", event.getTransactionIdentifier());
+ CancelItemReservationForPortfolioCommand command =
+ new CancelItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getTotalAmountOfItems() - event.getAmountOfExecutedItems());
+ getCommandBus().dispatch(command);
}
- /*-------------------------------------------------------------------------------------------*/
- /* Getters and setters */
- /*-------------------------------------------------------------------------------------------*/
- @Autowired
- public void setCommandBus(CommandBus commandBus) {
- this.commandBus = commandBus;
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ @EndSaga
+ public void handle(SellTransactionExecutedEvent event) {
+ ConfirmItemReservationForPortfolioCommand confirmCommand =
+ new ConfirmItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getAmountOfItems());
+ getCommandBus().dispatch(confirmCommand);
+ DepositMoneyToPortfolioCommand depositCommand =
+ new DepositMoneyToPortfolioCommand(getPortfolioIdentifier(), event.getItemPrice() * event.getAmountOfItems());
+ getCommandBus().dispatch(depositCommand);
}
+
+ @SagaEventHandler(associationProperty = "transactionIdentifier")
+ public void handle(SellTransactionPartiallyExecutedEvent event) {
+ ConfirmItemReservationForPortfolioCommand confirmCommand =
+ new ConfirmItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getAmountOfExecutedItems());
+ getCommandBus().dispatch(confirmCommand);
+ DepositMoneyToPortfolioCommand depositCommand =
+ new DepositMoneyToPortfolioCommand(getPortfolioIdentifier(), event.getItemPrice() * event.getAmountOfExecutedItems());
+ getCommandBus().dispatch(depositCommand);
+ }
+
}
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012. 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;
+
+import org.axonframework.commandhandling.CommandBus;
+import org.axonframework.domain.AggregateIdentifier;
+import org.axonframework.saga.annotation.AbstractAnnotatedSaga;
+import org.axonframework.saga.annotation.SagaEventHandler;
+import org.axonframework.samples.trader.app.api.order.TradeExecutedEvent;
+import org.axonframework.samples.trader.app.api.transaction.ExecutedTransactionCommand;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Jettro Coenradie
+ */
+public abstract class TradeManagerSaga extends AbstractAnnotatedSaga {
+ private transient CommandBus commandBus;
+ private long totalItems;
+ private long pricePerItem;
+ private AggregateIdentifier transactionIdentifier;
+ private AggregateIdentifier orderbookIdentifier;
+ private AggregateIdentifier portfolioIdentifier;
+
+ @SagaEventHandler(associationProperty = "orderBookIdentifier")
+ public void handle(TradeExecutedEvent event) {
+ ExecutedTransactionCommand command = new ExecutedTransactionCommand(transactionIdentifier, event.getTradeCount(), event.getTradePrice());
+ commandBus.dispatch(command);
+ }
+
+ /*-------------------------------------------------------------------------------------------*/
+ /* Getters and setters */
+ /*-------------------------------------------------------------------------------------------*/
+ @Autowired
+ public void setCommandBus(CommandBus commandBus) {
+ this.commandBus = commandBus;
+ }
+
+ protected CommandBus getCommandBus() {
+ return commandBus;
+ }
+
+ protected AggregateIdentifier getOrderbookIdentifier() {
+ return orderbookIdentifier;
+ }
+
+ protected void setOrderbookIdentifier(AggregateIdentifier orderbookIdentifier) {
+ this.orderbookIdentifier = orderbookIdentifier;
+ }
+
+ protected AggregateIdentifier getPortfolioIdentifier() {
+ return portfolioIdentifier;
+ }
+
+ protected void setPortfolioIdentifier(AggregateIdentifier portfolioIdentifier) {
+ this.portfolioIdentifier = portfolioIdentifier;
+ }
+
+ protected long getPricePerItem() {
+ return pricePerItem;
+ }
+
+ protected void setPricePerItem(long pricePerItem) {
+ this.pricePerItem = pricePerItem;
+ }
+
+ protected long getTotalItems() {
+ return totalItems;
+ }
+
+ protected void setTotalItems(long totalItems) {
+ this.totalItems = totalItems;
+ }
+
+ protected AggregateIdentifier getTransactionIdentifier() {
+ return transactionIdentifier;
+ }
+
+ protected void setTransactionIdentifier(AggregateIdentifier transactionIdentifier) {
+ this.transactionIdentifier = transactionIdentifier;
+ }
+}
Oops, something went wrong.

0 comments on commit cd94921

Please sign in to comment.