package org.jeecqrs.startup;

import javax.annotation.PostConstruct;

/**
 * Orchestrates the initialization of the various infrastructure services.
 * Deploy as @Startup @Singleton EJB.
 * <p>
 * Contrary to the other services, the interface of {@link AbstractApplicationStartup}
 * does not contain the notion of a "bucket", since it is meant as a per-module
 * initialization.
 */
public abstract class AbstractApplicationStartup {

    @PostConstruct
    public void startup() {
        wireUpEventListeners();
        wireUpCommandHandlers();
        wireUpDispatchScheduler();
        wireUpSagaTracker();
        replayEvents();
        startDispatchScheduler();
        startSagaTracker();
    }

    /**
     * Registers event handlers at the {@link EventDispatcher}.
     */
    protected abstract void wireUpEventListeners();

    /**
     * Registers command handlers at the {@link CommandBus}.
     */
    protected abstract void wireUpCommandHandlers();

    /**
     * Sets up the bridge between the {@link EventDispatcher} and the
     * persistence layer, such that newly persisted events are continuously
     * published to the dispatcher.
     * The preferred way is to hook into the event persistence receive
     * notifications about persisted events asynchronously once the events
     * have been persisted to the durable storage. 
     * If this is not supported by the persistence technology, implementations
     * may also use other techniques, such as polling in fixed intervals to
     * query a database for recently published events.
     */
    protected abstract void wireUpDispatchScheduler();

    /**
     * Sets up the {@link SagaTracker} to handle timed events in sagas.
     */
    protected abstract void wireUpSagaTracker();

    /**
     * Replay persisted events on application startup.
     * Implementations should be aware of long transactions and timeouts.
     */
    protected abstract void replayEvents();

    /**
     * Starts the dispatch scheduler, if required (asynchronous
     * implementations may not need this).
     */
    protected abstract void startDispatchScheduler();

    /**
     * Starts the {@link SagaTracker}, if required (asynchronous
     * implementations may not need this).
     */
    protected abstract void startSagaTracker();

}

@@ -38,450 +38,1265 @@
 java
-x.annotation.PostConstruct;%0A%0A/**%0A * Orchestrates the initialization of the various infrastructure services.%0A * Deploy as @Startup @Singleton EJB.%0A * %3Cp%3E%0A * Contrary to the other services, the interface of %7B@link AbstractApplicationStartup%7D%0A * does not contain the notion of a %22bucket%22, since it is meant as a per-module%0A * initialization.%0A */%0Apublic abstract class AbstractApplicationStartup %7B%0A%0A    @PostConstruct%0A    public void startup() %7B%0A
+.util.logging.Level;%0Aimport java.util.logging.Logger;%0Aimport javax.annotation.PostConstruct;%0Aimport javax.annotation.Resource;%0Aimport javax.transaction.HeuristicMixedException;%0Aimport javax.transaction.HeuristicRollbackException;%0Aimport javax.transaction.NotSupportedException;%0Aimport javax.transaction.RollbackException;%0Aimport javax.transaction.SystemException;%0Aimport javax.transaction.UserTransaction;%0A%0A/**%0A * Orchestrates the initialization of the various infrastructure services.%0A * Deploy as @Startup @Singleton EJB.%0A * %3Cp%3E%0A * Contrary to the other services, the interface of %7B@link AbstractApplicationStartup%7D%0A * does not contain the notion of a %22bucket%22, since it is meant as a per-module%0A * initialization.%0A */%0Apublic abstract class AbstractApplicationStartup %7B%0A%0A    @Resource(name=%22transactionTimeout%22)%0A    private int transactionTimeout = 84000;%0A%0A    @Resource%0A    private UserTransaction userTransaction;%0A%0A    @PostConstruct%0A    public void startup() %7B%0A        try %7B%0A            userTransaction.setTransactionTimeout(transactionTimeout);%0A        %7D catch (SystemException ex) %7B%0A            Logger.getLogger(AbstractApplicationStartup.class.getName()).log(Level.SEVERE, null, ex);%0A        %7D%0A        try %7B%0A            userTransaction.begin();%0A    
     
@@ -1319,24 +1319,28 @@
 isteners();%0A
+    
         wire
@@ -1364,24 +1364,28 @@
 ();%0A        
+   
+ 
 wireUpDispat
@@ -1391,32 +1391,36 @@
 tchScheduler();%0A
+    
         wireUpSa
@@ -1440,16 +1440,20 @@
         
+    
 replayEv
@@ -1464,24 +1464,28 @@
 ();%0A        
+ 
+   
 startDispatc
@@ -1502,24 +1502,28 @@
 ();%0A        
+    
 startSagaTra
@@ -1526,24 +1526,407 @@
 aTracker();%0A
+            userTransaction.commit();%0A        %7D catch (NotSupportedException %7C SystemException %7C HeuristicMixedException %7C%0A                HeuristicRollbackException %7C IllegalStateException %7C RollbackException %7C%0A                SecurityException ex) %7B%0A            // all of these are hard errors that prevent application startup%0A            throw new RuntimeException(ex);%0A        %7D%0A
     %7D%0A%0A    /

use user transaction sin AbstractApplicationStartup and increase transaction timeout