Skip to content
This repository has been archived by the owner on Dec 14, 2021. It is now read-only.

Commit

Permalink
trying to start selling items through the mongo saga repository
Browse files Browse the repository at this point in the history
  • Loading branch information
jettro committed Jan 19, 2012
1 parent cd94921 commit 7b60d52
Show file tree
Hide file tree
Showing 29 changed files with 3,095 additions and 12 deletions.
9 changes: 8 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,11 @@ Running the sample

Advanced configuration
----------------------
To write when done :-)
To write when done :-)


Note to myself
----------------------
Should the ID of the transaction be the same are the ID of the order? Is that possible? There should most probably
be a relation between the two. Think about this, since that would cross aggregate boundaries, which is not allowed.
Think more about the domain concepts around this.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import org.axonframework.domain.DomainEvent;

/**
* <p>A new company is created with a certain value and an amount of shares. Those two values can be used to calculate
* the starting point for the value of a share.</p>
*
* @author Jettro Coenradie
*/
public class CompanyCreatedEvent extends DomainEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import org.axonframework.domain.AggregateIdentifier;

/**
* <p>Create a new company by proving the name, the estiamted value of the company and the amount of shares that are
* available for the company. You also must provide the id of the user that wants to create the company.</p>
*
* @author Jettro Coenradie
*/
public class CreateCompanyCommand {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.axonframework.domain.UUIDAggregateIdentifier;

/**
* <p>Abstract parent class for all commands that are order related.</p>
*
* @author Allard Buijze
*/
public abstract class AbstractOrderCommand {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.axonframework.domain.DomainEvent;

/**
* <p>Abstract parent class for all buy and sell order placed events.</p>
*
* @author Allard Buijze
*/
public abstract class AbstractOrderPlacedEvent extends DomainEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.axonframework.domain.AggregateIdentifier;

/**
* <p>A new Buy Order is placed.</p>
*
* @author Allard Buijze
*/
public class BuyOrderPlacedEvent extends AbstractOrderPlacedEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.axonframework.domain.AggregateIdentifier;

/**
* <p>Create a new Buy Order.</p>
*
* @author Allard Buijze
*/
public class CreateBuyOrderCommand extends AbstractOrderCommand {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.axonframework.domain.AggregateIdentifier;

/**
* <p>Create a new OrderBook for the Company represented by the provided companyIdentifier.</p>
*
* @author Jettro Coenradie
*/
public class CreateOrderBookCommand {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.axonframework.domain.AggregateIdentifier;

/**
* <p>Create a new Sell Order using the amount of items to sell for the provided price.</p>
*
* @author Allard Buijze
*/
public class CreateSellOrderCommand extends AbstractOrderCommand {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.axonframework.domain.DomainEvent;

/**
* <p>A new OrderBook is created for the company with the provided identifier.</p>
*
* @author Jettro Coenradie
*/
public class OrderBookCreatedEvent extends DomainEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.axonframework.domain.AggregateIdentifier;

/**
* <p>A new Sell Order is placed for the current OrderBook. </p>
*
* @author Allard Buijze
*/
public class SellOrderPlacedEvent extends AbstractOrderPlacedEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import org.axonframework.domain.DomainEvent;

/**
* <p>A new trade has been executed. The event contains the amount of items that are traded and the price for the items
* that are traded. The event also contains the identifiers for the Buy Order and the Sell order.</p>
*
* @author Allard Buijze
*/
public class TradeExecutedEvent extends DomainEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ public class BuyTradeManagerSaga extends TradeManagerSaga {
@StartSaga
@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(BuyTransactionStartedEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("A new buy transaction is started with identifier {}, for portfolio with identifier {} and orderbook with identifier {}",
new Object[]{event.getTransactionIdentifier(), event.getPortfolioIdentifier(), event.getOrderbookIdentifier()});
logger.debug("The new buy transaction with identifier {} is for buying {} items for the price of {}",
new Object[]{event.getTransactionIdentifier(), event.getTotalItems(), event.getPricePerItem()});
}
setTransactionIdentifier(event.getTransactionIdentifier());
setOrderbookIdentifier(event.getOrderbookIdentifier());
setPortfolioIdentifier(event.getPortfolioIdentifier());
Expand All @@ -48,27 +54,36 @@ public void handle(BuyTransactionStartedEvent event) {
getCommandBus().dispatch(command);
}

/**
* TODO jettro: Moet er hier niet nog iets specifieks inkomen voor deze specifieke transactie? Anders kun je toch niet meerdere transacties per portfolio tegelijk uitvoeren?
*
* @param event
*/
@SagaEventHandler(associationProperty = "portfolioIdentifier")
public void handle(MoneyReservedFromPortfolioEvent event) {
logger.debug("Money for transaction with identifier {} is reserved", getTransactionIdentifier());
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
logger.debug("Not enough money was available to make reservation in transaction {} for portfolio {}. Required: {}",
new Object[]{getTransactionIdentifier(), event.getPortfolioIdentifier(), event.getAmountToPayInCents()});
}

@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(BuyTransactionConfirmedEvent event) {
logger.debug("Buy Transaction {} is approved to make the buy order", event.getTransactionIdentifier());
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();
logger.debug("Buy Transaction {} is cancelled, amount of money reserved to cancel is {}", event.getTransactionIdentifier(), amountToCancel);
CancelMoneyReservationFromPortfolioCommand command = new CancelMoneyReservationFromPortfolioCommand(getPortfolioIdentifier(), amountToCancel);
getCommandBus().dispatch(command);
}
Expand All @@ -77,6 +92,8 @@ public void handle(BuyTransactionCancelledEvent event) {
@SagaEventHandler(associationProperty = "transactionIdentifier")
@EndSaga
public void handle(BuyTransactionExecutedEvent event) {
logger.debug("Buy Transaction {} is executed, last amount of executed items is {} for a price of {}",
new Object[]{event.getTransactionIdentifier(), event.getAmountOfItems(), event.getItemPrice()});
ConfirmMoneyReservationFromPortfolionCommand confirmCommand =
new ConfirmMoneyReservationFromPortfolionCommand(getPortfolioIdentifier(), event.getAmountOfItems() * event.getItemPrice());
getCommandBus().dispatch(confirmCommand);
Expand All @@ -87,6 +104,8 @@ public void handle(BuyTransactionExecutedEvent event) {

@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(BuyTransactionPartiallyExecutedEvent event) {
logger.debug("Buy Transaction {} is partially executed, amount of executed items is {} for a price of {}",
new Object[]{event.getTransactionIdentifier(), event.getAmountOfExecutedItems(), event.getItemPrice()});
ConfirmMoneyReservationFromPortfolionCommand confirmCommand =
new ConfirmMoneyReservationFromPortfolionCommand(getPortfolioIdentifier(), event.getAmountOfExecutedItems() * event.getItemPrice());
getCommandBus().dispatch(confirmCommand);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ public class SellTradeManagerSaga extends TradeManagerSaga {
@StartSaga
@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(SellTransactionStartedEvent event) {
if (logger.isDebugEnabled()) {
logger.debug("A new sell transaction is started with identifier {}, for portfolio with identifier {} and orderbook with identifier {}",
new Object[]{event.getTransactionIdentifier(), event.getPortfolioIdentifier(), event.getOrderbookIdentifier()});
logger.debug("The sell transaction with identifier {} is for selling {} items for the price of {}",
new Object[]{event.getTransactionIdentifier(), event.getTotalItems(), event.getPricePerItem()});
}

setTransactionIdentifier(event.getTransactionIdentifier());
setOrderbookIdentifier(event.getOrderbookIdentifier());
setPortfolioIdentifier(event.getPortfolioIdentifier());
Expand All @@ -50,6 +57,7 @@ public void handle(SellTransactionStartedEvent event) {

@SagaEventHandler(associationProperty = "portfolioIdentifier")
public void handle(ItemsReservedEvent event) {
logger.debug("Items for transaction {} are reserved", getTransactionIdentifier());
ConfirmTransactionCommand confirmTransactionCommand = new ConfirmTransactionCommand(getTransactionIdentifier());
getCommandBus().dispatch(confirmTransactionCommand);
}
Expand All @@ -62,22 +70,28 @@ public void handle(NotEnoughItemsAvailableToReserveInPortfolio event) {

@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(SellTransactionConfirmedEvent event) {
logger.debug("Sell Transaction {} is approved to make the buy order", event.getTransactionIdentifier());

CreateSellOrderCommand command = new CreateSellOrderCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), getTotalItems(), getPricePerItem());
getCommandBus().dispatch(command);
}

@SagaEventHandler(associationProperty = "transactionIdentifier")
@EndSaga
public void handle(SellTransactionCancelledEvent event) {
logger.debug("Saga for Sell Transaction with id {} is cancelled", event.getTransactionIdentifier());
long amountOfCancelledItems = event.getTotalAmountOfItems() - event.getAmountOfExecutedItems();
logger.debug("Sell Transaction {} is cancelled, amount of money reserved to cancel is {}", event.getTransactionIdentifier(), amountOfCancelledItems);
CancelItemReservationForPortfolioCommand command =
new CancelItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getTotalAmountOfItems() - event.getAmountOfExecutedItems());
new CancelItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), amountOfCancelledItems);
getCommandBus().dispatch(command);
}

@SagaEventHandler(associationProperty = "transactionIdentifier")
@EndSaga
public void handle(SellTransactionExecutedEvent event) {
logger.debug("Sell Transaction {} is executed, last amount of executed items is {} for a price of {}",
new Object[]{event.getTransactionIdentifier(), event.getAmountOfItems(), event.getItemPrice()});

ConfirmItemReservationForPortfolioCommand confirmCommand =
new ConfirmItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getAmountOfItems());
getCommandBus().dispatch(confirmCommand);
Expand All @@ -88,6 +102,9 @@ public void handle(SellTransactionExecutedEvent event) {

@SagaEventHandler(associationProperty = "transactionIdentifier")
public void handle(SellTransactionPartiallyExecutedEvent event) {
logger.debug("Sell Transaction {} is partially executed, amount of executed items is {} for a price of {}",
new Object[]{event.getTransactionIdentifier(), event.getAmountOfExecutedItems(), event.getItemPrice()});

ConfirmItemReservationForPortfolioCommand confirmCommand =
new ConfirmItemReservationForPortfolioCommand(getPortfolioIdentifier(), getOrderbookIdentifier(), event.getAmountOfExecutedItems());
getCommandBus().dispatch(confirmCommand);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.mongo;

import com.mongodb.DB;
import com.mongodb.DBCollection;
import org.axonframework.saga.repository.mongo.MongoTemplate;
import org.springframework.data.mongodb.MongoDbFactory;

/**
* @author Jettro Coenradie
*/
public class CFSagaMongoTemplate implements MongoTemplate {
static final String SAGA_ASSOCIATIONS = "sagaassociations";
static final String SAGA_COLLECTION = "sagacollection";
private MongoDbFactory mongoDbFactory;

public CFSagaMongoTemplate(MongoDbFactory mongoDbFactory) {
this.mongoDbFactory = mongoDbFactory;
}

@Override
public DBCollection sagaCollection() {
return database().getCollection(SAGA_COLLECTION);
}

@Override
public DBCollection associationsCollection() {
return database().getCollection(SAGA_ASSOCIATIONS);
}

@Override
public DB database() {
return mongoDbFactory.getDb();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class PortfolioEntry {
@Id
private String identifier;
private String userIdentifier;
private String userName;
private long amountOfMoney;
private long reservedAmountOfMoney;

Expand Down Expand Up @@ -111,6 +112,14 @@ public void setItemsReserved(Map<String, ItemEntry> itemsReserved) {
this.itemsReserved = itemsReserved;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

/*-------------------------------------------------------------------------------------------*/
/* Private helper methods */
/*-------------------------------------------------------------------------------------------*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.axonframework.samples.trader.app.api.portfolio.PortfolioCreatedEvent;
import org.axonframework.samples.trader.app.api.portfolio.money.*;
import org.axonframework.samples.trader.app.query.portfolio.repositories.PortfolioQueryRepository;
import org.axonframework.samples.trader.app.query.user.repositories.UserQueryRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -32,6 +33,7 @@ public class PortfolioMoneyEventListener {
private final static Logger logger = LoggerFactory.getLogger(PortfolioMoneyEventListener.class);

private PortfolioQueryRepository portfolioRepository;
private UserQueryRepository userQueryRepository;

@EventHandler
public void handleEvent(PortfolioCreatedEvent event) {
Expand All @@ -41,6 +43,7 @@ public void handleEvent(PortfolioCreatedEvent event) {
PortfolioEntry portfolioEntry = new PortfolioEntry();
portfolioEntry.setIdentifier(event.getPortfolioIdentifier().asString());
portfolioEntry.setUserIdentifier(event.getUserIdentifier().asString());
portfolioEntry.setUserName(userQueryRepository.findByIdentifier(event.getUserIdentifier().asString()).getFullName());
portfolioEntry.setAmountOfMoney(0);
portfolioEntry.setReservedAmountOfMoney(0);

Expand Down Expand Up @@ -95,4 +98,10 @@ public void handleEvent(MoneyReservationConfirmedFromPortfolioEvent event) {
public void setPortfolioRepository(PortfolioQueryRepository portfolioRepository) {
this.portfolioRepository = portfolioRepository;
}

@SuppressWarnings("SpringJavaAutowiringInspection")
@Autowired
public void setUserQueryRepository(UserQueryRepository userQueryRepository) {
this.userQueryRepository = userQueryRepository;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@
*/
public interface UserQueryRepository extends PagingAndSortingRepository<UserEntry, String> {
UserEntry findByUsername(String username);

UserEntry findByIdentifier(String identifier);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,17 @@
<bean id="eventStore" class="org.axonframework.eventstore.mongo.MongoEventStore">
<constructor-arg ref="mongoTemplate"/>
</bean>

<bean id="sagaRepository" class="org.axonframework.saga.repository.mongo.MongoSagaRepository">
<constructor-arg ref="mongoSagaTemplate"/>
</bean>

<axon:saga-manager id="sagaManager" saga-repository="sagaRepository" event-bus="eventBus">
<axon:types>
org.axonframework.samples.trader.app.command.trading.SellTradeManagerSaga,
org.axonframework.samples.trader.app.command.trading.BuyTradeManagerSaga
</axon:types>
</axon:saga-manager>

<bean id="resourceInjector" class="org.axonframework.saga.spring.SpringResourceInjector"/>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<constructor-arg ref="mongoDbFactory"/>
</bean>

<bean id="mongoSagaTemplate" class="org.axonframework.samples.trader.app.mongo.CFSagaMongoTemplate">
<constructor-arg ref="mongoDbFactory"/>
</bean>

<beans profile="default">
<mongo:db-factory id="mongoDbFactory" dbname="axontrader" host="127.0.0.1" port="27017"/>
</beans>
Expand Down
Loading

0 comments on commit 7b60d52

Please sign in to comment.