How to make an extremely simple cron job on JBoss ESB

8k views Asked by At

I'm looking for the simplest thing that could possibly work to schedule a simple job - a job which doesn't interact with any other ESB component. [Go easy on me as this my first hour in ESB-land.]

I get the bit about having a cron-scheduler producer. It appears to be deliciously simple if you're familiar with cron:

<providers>
  <schedule-provider name="schedule">
    <cron-schedule scheduleid="cron-trigger" cronExpression="0/1 * * * * ?" />
  </schedule-provider>
</providers>

Next there is a listener (referencing the producer) to handle the scheduled events

<services>
    <service category="ServiceCat" name="ServiceName" description="Test Service">
        <listeners>
            <scheduled-listener name="cron-schedule-listener" 
                                scheduleidref="cron-trigger"
                                event-processor="org.example.MyListener" />
        </listeners>
    </service>
</services> 

Given that my job action isn't going to send any messages, or need to notify anything regarding success or failure. could I simply extend ScheduleListener and override the onSchedule() method and implement my job execution there without creating an action?

Even if this were possible, would there be any benefit for using an action for this simple pattern?

I'm using JBoss ESB 4.9.

2

There are 2 answers

0
Welsh On BEST ANSWER

Another way of doing this is to implement the org.jboss.soa.esb.schedule.ScheduledEventListener class.

As such your jboss-esb.xml would look like so:

<?xml version="1.0"?>
<jbossesb parameterReloadSecs="5" xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd">
 <providers>
  <schedule-provider name="myDaemonProvider">
   <cron-schedule cronExpression="0 */1 * * * ?" scheduleid="my-daemon-trigger"/>
  </schedule-provider>
 </providers>
 <services>
  <service category="Cron" description="My Cron Daemon" name="MyDaemon">
   <listeners>
    <scheduled-listener event-processor="com.myCompany.esb.myDaemon.main.MyDaemonScheduledEventListener" name="my-daemon-listener"  scheduleidref="my-daemon-trigger"/>
   </listeners>
  </service>
 </services>
</jbossesb>

And then your com.myCompany.esb.myDaemon.main.MyDaemonScheduledEventListener would look like:

package com.myCompany.esb.myDaemon.main;

import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.schedule.ScheduledEventListener;
import org.jboss.soa.esb.schedule.SchedulingException;

public class MyDaemonScheduledEventListener implements ScheduledEventListener {

    public void initialize(ConfigTree arg0) throws ConfigurationException {
        System.out.println("Initializing the Cron Daemon...");
    }

    public void uninitialize() {
        System.out.println("Uninitializing the Cron Daemon...");
    }

    public void onSchedule() throws SchedulingException {
        System.out.println("Scheduled Execution!");
    }
}

So when you deploy this, it will cause the onSchedule() to run every minute.

0
David J. Liszewski On

I punted and added my own nearly empty ScheduledEventMessageComposer and had my job extend AbstractActionLifecycle

jboss-esb.xml:

<?xml version="1.0"?>
<jbossesb parameterReloadSecs="300"
 xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd">
 <providers>
  <schedule-provider name="schedule">
  <!-- fire every hour -->
   <cron-schedule cronExpression="0 1 * * * ?" scheduleid="cron-trigger"/>
  </schedule-provider>
 </providers>
 <services>
  <service category="dummy" description="create dummy message" name="dummy-message">
   <listeners>
    <scheduled-listener event-processor="org.example.ActionMsgComposer"
     name="cron-schedule-listener" scheduleidref="cron-trigger"/>
   </listeners>
   <actions mep="OneWay">
    <action class="org.example.CronAction" name="action" process="execute"/>
   </actions>
  </service>
 </services>
</jbossesb> 

org.example.ActionMsgComposer:

package org.example;

import org.jboss.soa.esb.ConfigurationException;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.listeners.ScheduledEventMessageComposer;
import org.jboss.soa.esb.message.Message;
import org.jboss.soa.esb.message.format.MessageFactory;
import org.jboss.soa.esb.message.format.MessageType;
import org.jboss.soa.esb.schedule.SchedulingException;

public class ActionMsgComposer implements ScheduledEventMessageComposer {

    public void initialize(ConfigTree config) throws ConfigurationException {
    }

    public void uninitialize() {
    }

    public Message composeMessage() throws SchedulingException {
        Message myMessage = MessageFactory.getInstance().getMessage(MessageType.JBOSS_XML);
        myMessage.getBody().add("dummy");
        return myMessage;
    }

    public Message onProcessingComplete(Message message)
            throws SchedulingException {
        return message;
    }

}

org.example.CronAction:

package org.example;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;

import org.jboss.soa.esb.actions.AbstractActionLifecycle;
import org.jboss.soa.esb.actions.ActionLifecycleException;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.message.Message;

public class CronAction extends AbstractActionLifecycle {

    private ConfigTree configTree;
    private boolean initialized = false;
    private final Lock initLock = new ReentrantLock(true);
    private final Condition initCondition = initLock.newCondition();

    public CronAction(ConfigTree config) {
        configTree = config;
    }

    public ConfigTree getConfigTree() {
        return configTree;
    }

    @Override
    public void initialise() throws ActionLifecycleException {
        try {
            initLock.lock();
            super.initialise();
            // ** do any one-time initialization for cron job here **
            initialized = true;
            initCondition.signalAll();
        } finally {
            initLock.unlock();
        }
    }

    public Message exec(Message message) {
        waitUntilInitialized();
        // ** do cron job here ** 
        return message;
    }

    @Override
    public void destroy() throws ActionLifecycleException {
        super.destroy();
        // ** do any clean-up for cron job here **
    }

    private void waitUntilInitialized() {
        if (!initialized) {
            try {
                initLock.lock();
                while (!initialized) {
                    initCondition.await();
                }
            } catch (InterruptedException e) {
                // ignore
            } finally {
                initLock.unlock();
            }
        }
    }

}