package org.myeslib.example.jdbi.routes; import static com.google.common.base.Preconditions.checkNotNull; import static org.myeslib.util.ValidationHelper.ensureSameVersion; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.myeslib.core.Command; import org.myeslib.core.Event; import org.myeslib.core.data.Snapshot; import org.myeslib.core.data.UnitOfWork; import org.myeslib.core.storage.SnapshotReader; import org.myeslib.example.SampleDomain.CreateCommandHandler; import org.myeslib.example.SampleDomain.CreateInventoryItem; import org.myeslib.example.SampleDomain.DecreaseCommandHandler; import org.myeslib.example.SampleDomain.DecreaseInventory; import org.myeslib.example.SampleDomain.IncreaseCommandHandler; import org.myeslib.example.SampleDomain.IncreaseInventory; import org.myeslib.example.SampleDomain.InventoryItemAggregateRoot; import org.myeslib.example.SampleDomain.ItemDescriptionGeneratorService; import org.myeslib.example.jdbi.modules.InventoryItemModule.AggregateRootHistoryWriterDaoFactory; import org.myeslib.jdbi.storage.JdbiUnitOfWorkJournal; import org.myeslib.util.UUIDGenerator; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.TransactionIsolationLevel; import com.google.inject.Inject; @Slf4j @RequiredArgsConstructor(onConstructor=@__(@Inject)) public class InventoryItemCmdProcessor implements Processor { final static String ID = "id"; final SnapshotReader<UUID, InventoryItemAggregateRoot> snapshotReader; final DBI dbi; final AggregateRootHistoryWriterDaoFactory aggregateRootHistoryWriterDaoFactory; final ItemDescriptionGeneratorService domainService; final UUIDGenerator uuidGenerator; @Override public void process(Exchange e) throws Exception { final Handle handle = dbi.open(); try { handle.getConnection().setAutoCommit(false); handle.begin(); handle.setTransactionIsolation(TransactionIsolationLevel.READ_COMMITTED); final UUID id = e.getIn().getHeader(ID, UUID.class); final Command command = e.getIn().getBody(Command.class); final Snapshot<InventoryItemAggregateRoot> snapshot = snapshotReader.get(id); checkNotNull(id); checkNotNull(command); checkNotNull(command.getTargetVersion()); final List<? extends Event> events; final InventoryItemAggregateRoot instance = snapshot.getAggregateInstance(); if (command instanceof CreateInventoryItem) { CreateCommandHandler commandHandler = new CreateCommandHandler(instance, domainService); events = commandHandler.handle(((CreateInventoryItem) command)); } else if (command instanceof IncreaseInventory) { ensureSameVersion(id.toString(), command.getTargetVersion(), snapshot.getVersion()); IncreaseCommandHandler commandHandler = new IncreaseCommandHandler(instance); events = commandHandler.handle(((IncreaseInventory) command)); } else if (command instanceof DecreaseInventory) { ensureSameVersion(id.toString(), command.getTargetVersion(), snapshot.getVersion()); DecreaseCommandHandler commandHandler = new DecreaseCommandHandler(instance); events = commandHandler.handle(((DecreaseInventory) command)); } else { throw new IllegalArgumentException("Unknown command"); } final JdbiUnitOfWorkJournal<UUID> uowJournal = new JdbiUnitOfWorkJournal<>(aggregateRootHistoryWriterDaoFactory.create(handle)); final UnitOfWork uow = UnitOfWork.create(uuidGenerator.generate(), command, events); uowJournal.append(id, uow); handle.commit(); e.getOut().setHeader(ID, id); e.getOut().setBody(uow); log.debug("commited transaction {} {}", id, Thread.currentThread()); } catch (Throwable ex) { handle.rollback(); log.error("*** Error - rolback tx"); ex.printStackTrace(); throw new RuntimeException(ex); } finally { handle.close(); } } }