Publish External Event from the Aggregate

80 views
Skip to first unread message

Gerard Quinn

unread,
Jan 2, 2018, 1:13:52 PM1/2/18
to Axon Framework Users
After the aggregate is updated, I want to publish out the latest value of the aggregate as an event without having an additional action on the command handler. I don't want this logic run when building the aggreagate from the database though!

The bad line in my eyes below is 'publisher.publish(stockItem.invoke(x -> x.getSupply()))' below. This is called after addAdjustment updates the aggregate and saves the event to the backing store. 

The line is in the commandhandler but I think it's better design to raise something inside 'addAdjustment' method?

Option 1 - use commandbus, inside andThen or andThenApply
Option 2 - use sometype of non-domain aggregate event
Option 3- as I have done

It would be nice to have it outside the UoW too!

I'm using EmbeddedEventStore and a Cassandra Backend.

  @CommandHandler
    public void handle(StockItemFCStockSupplyCommand command) throws Exception {
        LOGGER.info("Handling StockItemFCStockSupplyCommand ...");
        Aggregate<StockItem> stockItem = null;
        String sku = command.getSku();

        try {
            stockItem = repository.load(sku);
        }
        catch (AggregateNotFoundException e) {
            stockItem = repository.newInstance(()-> new StockItem(sku));
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage());
            throw e;
        }

        stockItem.execute(aggregateRoot -> aggregateRoot.addAdjustment(command.getQuantity()));

        //Publish the Latest Supply Record to NOSQL Implementation
        publisher.publish(stockItem.invoke(x -> x.getSupply()));
    }


@AggregateRoot
@Revision("1.0")
public class StockItem {
    private static final Logger LOGGER = LoggerFactory.getLogger(StockItem.class);
    @AggregateIdentifier
    private String aggregateIdentifier;
    private int supply;

    public StockItem() { }

    public StockItem(String aggregateIdentifier) {
        LOGGER.info("Creating a new Aggregate " + aggregateIdentifier);
        apply(new StockItemCreatedEvent(aggregateIdentifier, 0));
    }

    public void addAdjustment(Integer quantity) {
        LOGGER.trace("addAdjustment - Raising StockItemSupplyEvent");
        apply(new StockItemAdjustmentEvent(this.aggregateIdentifier, quantity));
        //Add something here or use andThen or andThenApply?
    }

    @EventSourcingHandler
    private void on(StockItemCreatedEvent event) {
        LOGGER.info("StockItemCreatedEvent ..." + event.getAggregateIdentifier());
        this.aggregateIdentifier = event.getAggregateIdentifier();
        this.supply = event.getQuantity();
    }

    @EventSourcingHandler
    private void on(StockItemAdjustmentEvent event) {
        LOGGER.trace(String.format("StockItemAdjustmentEvent {%s},{%s}", event.getAggregateIdentifier(), event.getQuantity()));
        this.supply += event.getQuantity();
    }

    public int getSupply() {
        return this.supply;
    }
}

Allard Buijze

unread,
Jan 3, 2018, 3:03:11 AM1/3/18
to axonfr...@googlegroups.com
Hi Gerard,

I'm not sure I really understand what you're trying to achieve. Sending out the state of an aggregate as an event is a very awkward thing to do, and I feel this is an attempt to solve some issue that probably has a better way to be fixed.

You say "I don't want this logic run when building the aggregate from the database though!" Logic in command handlers is *never* executed when an aggregate is loaded. It is always executed on a loaded aggregate. So you can just "apply" the event you want published, even an apply(this), if you are really, really, sure (and then think again) that you want to publish the aggregate state.

In your example, it looks like you just want to publish the current level of stock for a specific item. That's information that could very well have its place in the StockItemAdjustmentEvent. It could say: item x reduced by 10, now have 20 in stock.

Hope this helps.
Cheers,

Allard

Op di 2 jan. 2018 om 19:13 schreef Gerard Quinn <gerard...@gmail.com>:
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Reply all
Reply to author
Forward
0 new messages