Version 8

    Schduling of Services

     

    Background

    In the current implementation, different types of listeners can be configured to poll, like File pollers , sql table poller, etc. These poller are all configured by specifiying a pollLatancyInterval that is an attribute common to all listeners. But the logic for polling is duplicated in the different gateway listener implementations.

     

    The configuration that exist allows one to specify a pollLatenyInterval like this:

    <property name="pollLatencySeconds" value="5"></property>
    

    This will start polling immediately every 5 seconds and poll indefinetly.

     

    Goal

    The goal is to reduce the duplication of code and have all listeners use the same code base for polling. Another goal is to have the ability to have more control over polling intervals, as well as to be able to specify start and end dates for pollers.

     

    The implementation should not require major refactoring of the current code base.

     

    Implementation

    This is a suggestion of how Quartz could be used to implement the scheduling for the ESB. The scheduling could be "inserted" into the inheritence chain as described here:

     

     

     

     

    The main thing to note is that the work that the listener in question is to perform is now located in the performWork() method and not in doRun(). This method will be called by when the job is executed.

     

     

     

    To be an un-instrusive as possible the Job created is a Quartz NoOpJob, and a JobListenerAdapter is registered like this in AbstractScheduler's doInitialize method:

    @Override
    protected void doInitialise() throws ManagedLifecycleException
    {
        ...
        final JobDetail jbd = new JobDetail( jobName, jobGroupName, NoOpJob.class );
        final JobListener listener = new JobListenerAdapter( this );
        scheduler.addJobListener( listener );
        ...
    

    And this is what the JobAdapter looks like:

    public class JobListenerAdapter implements JobListener
    {
         private Logger log = Logger.getLogger( JobListenerAdapter.class );
         
         private AbstractScheduler gateway;
         
         public JobListenerAdapter( final AbstractScheduler gateway )
         {
              if ( gateway == null)
                   throw new IllegalArgumentException( "gateway must not be null" );
              this.gateway = gateway;
         }
         
         public void jobWasExecuted( final JobExecutionContext jobContext, final JobExecutionException exception )
         {
              log.info( "jobWasExceuted.." );
              if ( gateway != null )
                   gateway.performWork();
              else
                   log.warn( "gateway was null, when job fired!!");
         }
         
         public String getName()
         {
              return "listener-job";
         }
    
         public void jobExecutionVetoed( JobExecutionContext jobContext )  {  }
         public void jobToBeExecuted( JobExecutionContext jobContext )  {  }
    
    }
    

     

    Alterative implementation

    This suggestion was given in this forum thread by Tom Fennelly.

     

    What I was thinking re scheduling was to have a "ScheduledEventProvider" (e.g.  that generates scheduled events):

    <sevent-provider name="EveryMinEvent">
        <sevent-bus>
            <property name="cronExpression" value="0/20 * * * * ?"></property>
            <property name="startDate" value="07-07-15 19:17:00"></property>
            <property name="endDate" value="07-07-15 19:19:00"></property>
        </sevent-bus>
    </sevent-provider>
    

     

    The <sevent-listener> could be configured with a MessageComposer in the same way all (or at least some) of the other listeners can be configured with a composer (org.jboss.soa.esb.listeners.message.MessageComposer impl) that does whatever is needed:

    <sevent-listener
        is-gateway="true"
        name="WSListener" 
        busidref="EveryMinEvent" 
        maxThreads="1">
        <property name="gatewayClass" value="org.jboss.soa.esb.listeners.gateway.WSGateway"></property>
        <property name="composer-class" value="example.SOAPPacker"></property>
        <property name="composer-process" value="packageSOAPMessage"></property>
    </sevent-listener>
    

     

    So, taking the WSListener as an example, it would actually be implemented as a MessageComposer that sits on a <sevent-listener> and when triggered (asked to "compose"), it goes off and makes the SOAP invocation and uses the result to compose the org.jboss.soa.esb.message.Message payload to be processed by the service pipeline (or whatever).

     

     

     

    Configuration

    The scheduling can be configured by either a cron expression or with a pollLatencyInterval as can be done today.

     

     

     

    Example of cron expression configuration:

    <property name="cronExpression" value="0/20 * * * * ?"></property>
    <property name="startDate" value="07-07-15 19:17:00"></property>
    <property name="endDate" value="07-07-15 19:19:00"></property>
    

     

    Example of pollLatency configuration:

    <property name="pollLatencySeconds" value="10"></property>
    <property name="repeatCount" value="10"></property>
    <property name="startDate" value="07-07-15 19:17:00"></property>
    <property name="endDate" value="07-07-15 19:19:00"></property>
    

    Note that startDate and endDate are optional.

     

    If a startDate is not specified then the polling will start immedietly.

     

    If endDate is not specified the it will run indefinetly.

     

     

     

    More information about the cronExpression can be found by looking at the javadoc for CronExpression

     

    Additional requirements

    • Calendar support

    • Configurable date format for startDate and endDate

    • Configuratble Locale support

    • ...

     

    References