Tuesday Mar 24, 2009

Worth a hill of beans!

In this blog, we'll show how to get Scheduler BC to trigger a Stateless Session Bean (SLSB) deployed in a Java EE Service Engine.  I'm using GlassFish ESB v2.1 Milestone 1 Installer from here so YMMV if using a different version:

  1. Start a new EJB Module project:

  2. Enter Name and Location of EJB Module:

  3. Select the GlassFish Server and press Finish:

  4. Under the Source Packages node of the project, create a Scheduler WSDL Binding:

  5. Choose the SCHEDULER Binding Type and press Next:

  6. Add a new Simple trigger:

  7. Define the Simple Trigger:

  8. Ensure the appropriate Date Format is selected before pressing Finish:

  9. Under the Source Packages node, create a Web Service from WSDL:

  10. Specify the Name and Location step and browse for the Scheduler Binding WSDL created earlier:

  11. Remember to enter a Package name before pressing Finish:

  12. In the Java editor that appears, implement the method accordingly:

  13. Almost done, save everything and create a Composite Application project:

  14. Key in Project Name and press Finish:

  15. Drag the EJB Module project onto the CASA canvas and do a Build Project and afterwards, should look like this:

  16. Save everything, Deploy the Composite Application project, and you should get similar results:

Tuesday Mar 10, 2009

Cup of poJO anyone?

NOTE, the instructions here have been updated a little for GlassFish ESB v2.1 since its release.

A lot of the demos until this point have illustrated Scheduler BC consuming a BPEL SE, so how 'bout consuming a 'cup of Jo' instead?  POJO that is. 

We'll now show how to have Scheduler BC trigger a POJO SE to execute a Windows (2000, XP, Vista) command that pops up a dialog with some greeting.  Of course, you can adapt this to do more useful things like 'downloading a file from some remote site so that File BC can pick it up and send it to BPEL SE for processing'...but then that'll be work and fun is good!

Prerequisites: Scheduler BC now comes pre-installed with GF ESB v2.1, but you'll need to install POJO SE (installer here).

  1. Create a Java (SE) Application project, keeping the default Main class, although it won't be used here (but it's needed due to a POJO SE project idiosyncrasy):

  2. Right-click the schedpojodemo package and add a New | Other | ESB | POJO for Binding:

  3. Specify that the POJO SE is to work with Scheduler BC by:

  4. Select Next and Add a Simple Trigger:

    The Windows command chosen here in the trigger Message is long so you can copy it from here:

  5. Select Next and Choose Node for the Input Argument Type in the POJO method that will be doing the providing:

  6. Select Finish and in the SchedPojoBinding.java Java editor that shows up, fix the package import warning for Node (answer: org.w3c.dom.Node):

  7. Copy the imports below into the same class, pasting it before the first import statement that's already there:
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.logging.Level;
  8. Copy the code below into the same class, pasting it just above the line that declares "private static final Logger logger":
        private void FireTriggerOperation(String input) {
            List args = new ArrayList();
            if (System.getProperty("os.name").toLowerCase()                 //NOI18N
                    .startsWith("windows")) {                               //NOI18N
                args.add("cmd.exe");                                        //NOI18N
                args.add("/c");                                             //NOI18N
            ProcessBuilder procBuilder = new ProcessBuilder(args);
            try {
                Process proc = procBuilder.start();
                StreamEater stdOutEater =
                        new StreamEater(proc.getInputStream(), "StdOut");   //NOI18N
                StreamEater stdErrEater =
                        new StreamEater(proc.getErrorStream(), "StdErr");   //NOI18N
                int rc = proc.waitFor();
                logger.info("Command \\"" + input + "\\" exit code: " + rc);  //NOI18N
            } catch (IOException ex) {
                logger.log(Level.SEVERE, "Unknown command? " + input, ex);  //NOI18N
            } catch (InterruptedException ie) {
                logger.log(Level.WARNING, "Command aborted!");              //NOI18N
        private class StreamEater extends Thread {
            private BufferedReader rdr;
            private String name;
            public StreamEater(InputStream is, String name) {
                super(name + "-Eater");                                     //NOI18N
                rdr = new BufferedReader(new InputStreamReader(is));
                this.name = name;
            public void run() {
                String line = null;
                try {
                    while ((line = rdr.readLine()) != null) {
                        logger.info(name + "> " + line);                    //NOI18N
                } catch (IOException ex) {
                    logger.log(Level.SEVERE, "Problem reading " + name, ex);//NOI18N
                try {
                } catch (IOException ex) {
                    // ignore
                rdr = null;
        public static void main(String[] args) throws Throwable {
            SchedPojoBinding spb = new SchedPojoBinding();
            spb.FireTriggerOperation("echo MsgBox \\"Howdy, all's well!\\", " //NOI18N
                    + "0, \\"Scheduler POJO Demo\\" > C:\\\\temp\\\\howdy.vbs & " //NOI18N
                    + "wscript.exe C:\\\\temp\\\\howdy.vbs");                   //NOI18N
  9. In the FireTriggerOperation(Node inupt) method, add this call:

  10. From here on, it's pretty much mundane...Save this project and create a new Composite Application project
  11. Drag the SchedPojoDemo project into the Service Assembly canvas and do a Build Project
  12. Deploy the CASA project and voila, you got your popup!

Tuesday Feb 24, 2009

Scheduler is going Hybrid!

Hybrid trigger that is!  In addition to Simple and Cron, there is now Hybrid which is essentially a Cron trigger beginning a Simple trigger that ends after a specified duration.  This allows scheduling tasks like download a sales receipts file by FTP from a store franchise, Monday through Friday from 9AM to 5PM on the hour trying repeatedly at 2 minute intervals for 10 minutes (just in case a particular store is a bit off schedule in having a data file available precisely at 9:00AM for example).

  • From the Scheduler Control and Triggers panel, pick Hybrid from the Add combo box:

  • Define the Cron Expression that will determine when the Simple trigger will begin, the Duration, number of Repeat's, and Interval between repeats:

  • For demo purpose, it's impractical to use the aforementioned schedule so let's just abbreviate it to trigger on the five of every hour that is at :00, :05, :10, etc and for a 2 minute duration with a 30 seconds interval:

  • After defining the File BC binding and customary BPEL Process and deploying the respective Service Assembly, we get results like this:

  • If you wish to try of this new Hybrid trigger, use a Scheduler component build on or after 25 February 2009 using JNLP launch or JAR download.

Friday Jan 23, 2009

Scheduler Monitoring Available

Self-explanatory Component Provided Statistics for the Scheduler BC are now available, such as shown by the Admin Console for the GlassFish server:

Wednesday Jan 07, 2009

Trigger metadata moved to NM properties to facilitate BC to BC in Fuji

Previously, metadata (such as the trigger Name, Group and Date) and the actual triggering message were both encapsulated in the XML message sent to the provider endpoint.  However, this necessitates extra intermediary processing in Fuji IFL if the metadata were not desired when connecting the Scheduler binding directly to another such as File.  Thus, SchedulerBC now transmits metadata via Normalized Message Properties (NM Properties) and the triggering message solely represents the message part sent to the provider.  If however trigger metadata is still required in say a BPEL business logic, then they can be accessed via the BPEL Mapper Properties node under the respective BPEL variable as illustrated below:

Monday Dec 22, 2008

Fuji Scheduler Quickstart Instructions

This section used to be called Adding Scheduler To Existing Fuji Environment and intended for the Fuji acquainted, but since M4 is the next Milestone, it has become too unwieldy to do patching.  Everything is now pre-bundled into a pre-release fujifelix-1.0-M4-SNAPSHOT.jar so there aren't copious bundles to download anymore, so here are the few steps required:

  1. Extract fujifelix-1.0-M4-SNAPSHOT.jar
  2. Install scheduler-archetype-1.0-M4-SNAPSHOT.jar into pertinent Maven repository:

  3. Delete the .index directory in the Maven repository to ensure the newer Scheduler Archetype is used when the repository is next indexed
  4. Install Fuji IFL Support NB Plugin
  5. Install Fuji Server NB Plugin

Friday Dec 05, 2008

Systemic Qualities Enhancements

To make it even more useful, some essential Systemic Qualities have been added to Scheduler BC

  • Application Configuration

    You may have noticed a small icon (looks like an Application icon with a gear cog in it) affixed to the left of some labels in Scheduler trigger definition panel:

    As the tool tip indicates, these parameters are part of the available Application Configuration for the Scheduler Binding Component, and can be optionally configured at deployment time.  This is essential for Administrators in order to deploy a project, after Development and Quality Assurance have finished their tasks in the project lifecycle, since the run-time environment(s) that may be quite different in terms of locale.

    • To start, you need to associate a Configuration Extension profile with the respective Scheduler endpoint by clicking on the consumer icon of the Scheduler port in the CASA editor and selecting Properties:

    • Now, enter the desired name of the profile, such as the name given to the Scheduler WSDL (binding):

    • Next under the Services tab, make sure the GlassFish V2 Server and Scheduler Binding Component (sun-scheduler-binding) have been started, then right-click sun-scheduler-binding and select Properties:

    • Then, click Add button to add a new row representing all the Application configurable parameters for the Scheduler BC, using the same name for the Application Configuration Name as given in the CASA editor.

      Pay particular attention to values given for the startDate and endDate; they need to either be the string literals now and never respectively or, dates conforming to the format specified in Date Format of the GUI editor when the Scheduler WSDL (binding) was first created or subsequently edited.

    Now when the Composite Application is deployed, the Scheduler BC will use those Application Configuration that have been defined for the respective endpoint.

    Besides using NetBeans IDE to specify Application Configuration, you can also use:

  • Application Variables

    The message sent when a trigger is fired can now reference Application Variables that are set at deployment time and will be evaluated each and everytime prior to the message being sent; this allows the variables to be changed dynamically.  This feature is useful if the message sent contains confidential information such as passwords that firstly, you don't want to reveal statically in the message while it's being configured in either the Simple or Cron trigger editor.  Secondly, passwords used in enterprises often require periodic maintenance for security reasons and thus the runtime administrators need access to these, without touching the business logic specified during design time and verified during quality assurance.  To utilize Application Variables:

    • Reference them in the Message field of the trigger editor, using the dollar sign curly braces format (highlighted in following figure):

      Note, any Application Variable defined is available to all JBI applications deployed in a GlassFish server and thus care needs to be taken to qualify these for different deployments, typically by prefixing their names with a unique key such as the name of the WSDL binding ("cronBinding." as shown here.

    • Next, prior to deployment time, set the referenced Application Variables by right-clicking the GlassFish V2|JBI|Binding Components|sun-scheduler-binding node in the Services tab, select Properties and click on the ellipsis ("...") button for the Application Variables property in the Configuration section. Press the Add button and choose the type of variable desired, such as a Password type:

    • For each Application Variable, enter the Name exactly as referenced in the Message field, of course omitting the dollar sign and curly braces, and the corresponding value (note, Password fields are masked out for confidentiality); the latter cannot reference another Application Variable.

      Press OK when done and the Application Variables are ready for use by the deployment:

    • Like Application Configuration, Application Variables can also be configured using the Sun Java System Application Server (GlassFish) Admin Console:

    • Similarly, there are asadmin CLI commands to create (create-jbi-application-variable), update (update-jbi-application-variable, and delete (delete-jbi-application-variable) Application Variables.

    Here's the output using the configured Application Variables:

  • Logging

    Scheduler BC now emits more detailed and controllable logging.  Each log entry starts with an ID SCHEDBC-Xyyy where X is a digit that represent 7 different logging levels: 1 (FINEST), 2 (FINER), 3 (FINE), 4 (CONFIG), 5 (INFO), 6 (WARNING), and 7 (SEVERE) that are explained here.  Note, levels 1 through 3 inclusive are not internationalized as they represent debugging levels.

    Here's a sample output:

Tuesday Nov 11, 2008

Cron Trigger Now Available

Took some time but hopefully it was worth waiting for, Cron triggering capability is finally available for the Scheduler BC!  Cron triggers enable your business logic to do something at particular moments in time, as opposed to Simple triggers that perform a task at a periodic interval of time.  An assumption here is you are already familiar with the current Scheduler BC (if not please read some of the previous blog entries first) and using BC's and SE's in general.

  • Create a Scheduler Binding (WSDL) as before by right-clicking over the Process Files folder and choosing New | Other | ESB | Binding and choose SCHEDULER Binding:

  • Click Next and select Cron from the Add combo box (or if already so, just press the plus (+) sign button) to begin adding a new Cron trigger:

  • We'll start off with a very simple Cron trigger to fire the top of every minute.  Appropriately fill in Name, Description and Message fields and then select the Second (1) tab if not already done.  Select the Just on Second choice if not already so and the associated spinner to set the second-of-the-minute will be automatically enabled, then set it to zero (0).  (Note, the respective controls in the other choices are only enabled if that choice is selected.)  This is the only condition that needs to be defined because all the others are already defaulted appropriately (verifiable in the Cron Expression text field; see CronExpression JavaDoc here) and so you can simply press Add Cron Trigger button:

  • I deliberately didn't choose a more complicated Cron Expression because if run, they'll generally span a longer period than a demo affords.  However, just for illustration, let's define one that reminds Americans to vote in the General Election once every four years and this is typically the first Tuesday in November and let's say poll opens at 8:00:00 AM.  Start by selecting the Second (1) tab and Just on Second choice, and setting the second spinner to zero (0):

  • Set the Just on Minute spinner to 0, Just on Hour spinner to 8, of the Minute (2) and Hour (3) tabs respectively:

  • Select the Day-of-Week (6) tab and select choice On the and drop down settings First and TUE:

  • Having done so, the Day (4) tab is automatically set to No specific Day of the month because the Quartz Scheduler API requires it to be mutually exclusive with Day-of-Week:

  • Select the Month (5) tab and choose Just on Month and month 11 (November):

  • Finally, we need to specify the optional Year (7) tab by checking on the option box and then select the Starting on Year choice, setting year to 2008 and the repeating every to 4:

  • Not that we can practically test out this exact expression, but you can try something similar otherwise.  Anyways, as a contrast, let's define also a Simple trigger that repeats every minute by choosing Simple from the Add combo box and filling in the respective fields:

  • Since we're testing at the Second granularity, the default Date Format setting is insufficient so let's change it to W3C XML date and time format:

  • We're done and can now press Finish and here's the resulting WSDL:

  • Next, we'll define a FILE binding (process not shown here) that appends to a file and a BPEL Process (please refer to previous blogs if uncertain how to create FILE binding or BPEL Process) to map the Message payload from the trigger to the file output part1:

  • Create the customary Composite Application project and drag the BPEL project into it and Build:

  • Deploy the Composite Application project and you'll get results similar to:

  • Since this feaature has just been checked in on November 11, 2008, the officially built binaries won't be available yet for you to try out the Cron trigger, so here are the home-baked cookies:

Friday Oct 17, 2008

Scheduler Redux

The surgery was successful and the patient has become a BC!  Anyhow, Scheduler BC works pretty much the same as any other, such as File BC.  However, with the recent WSDL Binding Wizard changes across the board for all BC's,  it's worth mentioning how to create a deployment for a Scheduler BC triggering a BPEL to write to a File BC.

Create a Scheduler WSDL Document

  • Launch the WSDL Binding Wizard by right-clicking over the Process Files folder of a BPEL project and select New | WSDL Document

    • Or equivalently, select New | Other | ESB (Category) | Binding (File Type) from the Process Files context menu

  • Enter an appropriate File Name for the WSDL, choose Concrete WSDL Document for the WSDL Type, select SCHEDULER from the Binding drop-down box and press Next
  • Press the Add button to add a new Trigger, key in appropriate data and press Add Trigger button when done

  • Optionally, define a custom date and time format to be used with the scheduler; this format is used both to interpret date and time values persisted in the Scheduler's WSDL as well as displaying the date and time in the message sent to the endpoint being triggered

  • Compose the Format by selecting from the various date/time component Pattern drop-down boxes, as well as typing other literals; all the while a Sample text field illustrates what the date and time will look like

  • Press Finish and the new Scheduler WSDL editor appears

Create a File WSDL Document

  • Similarly, right click over the Process Files folder again, select New | WSDL Document and this time create a FILE Binding Concrete WSDL Document, of Type Write and press Next

  • Specify the respective fields and click Finish

Create a BPEL and Connect the Components
  • Create a new BPEL in the same Process Files folder and drag and drop the Scheduler WSDL to approximately the middle of the Ports column left of the BPEL canvas

  • OK the ensuing dialog confirming creation of Partner Link to represent the Scheduler BC consuming endpoint

  • Similarly, drag and drop the File WSDL to the right column

  • In the ensuing dialog, click the Swap Roles button since this time the BPEL is the consumer of the service the File BC provides

  • Create Receive, Assign, and Invoke activities in the BPEL and Edit the Receive activity to select the Partner Link representing the Scheduler BC

  • Press the Create button to create an Input Variable for the Scheduler operation by accepting all the default values in the pop-up dialog (not shown) and hit OK here

  • Similarly edit the Invoke activity and also create an Input Variable for the File BC operation

  • Double click on the Assign activity and map from the payload of the Scheduler input variable to part1 of the File input variable, and Save All your work

Deploy a Composite Application for Scheduler BC » BPEL » File BC

  • Create a new Composite Application project and drag and drop the BPEL project onto the CASA Editor canvas

  • Hit the Build (hammer) button twice (second time to get rid of progress label...known issue)

  • Right click over the CASA project and select Deploy (you must have a running Glass Fish server with Scheduler Binding Component installed already of course) and you should be getting results in C:\\temp\\output.xml like this:

Installation Binaries

  • You'll need to run the latest OpenESB or GlassFish ESB Installer for the desired platform from here (as of 24 October 2008) and it will have both design-time and run-time Scheduler BC components pre-installed.
  • Otherwise, a-la-carte binaries are available for:
    • Scheduler WSDL Binding Extension NetBeans plug-in (you may need to rename it back to a .nbm extension after downloading)
    • Scheduler BC GF plug-in

Wednesday Sep 17, 2008

Date/Time configuration enhancements added

Since my last blog about the  OJC Scheduler editor, the date/time specifications for the Simple Trigger's Active Period have been improved.  Also, there's now a SimpleDateFormat chooser GUI to specify formats.  Here's what the Simple Trigger panel looks like now:

The Now/Never checkboxes are mutually exclusive with their adjacent spinner (JSpinner) fields.  To enter a specific date, make sure the respective checkbox is unchecked and place the cursor in date/time component field that you wish to vary (for example, the 2-digit month in the screenshot below) and press either the up or down arrow in the spinner.

If you wish to change the date/time format, press the Format button and a SimpleDateFormat Chooser pops up:

Build the format by selecting a pattern from one or more of the Patterns drop-down boxes and the corresponding SimpleDateFormat pattern will be inserted at the current caret position in the Format field.  As you build, the Sample textfield reflects what the date/time will look like.  Similarly, you can now also easily configure the format of the Job Date Format field by choosing <define custom...> in the drop-down list and the same SimpleDateFormat Chooser will appear:

Incidentally, management has decided the Scheduler component should now be a Binding Component instead of a Service Engine, so this enhancement will be the last as for as the Scheduler in SE form is concerned.  It will take a little while before a BC version will be available.

Tuesday Sep 09, 2008

Announcing Scheduler Service Engine

Ever wanted to kick off your BPEL to do something like send a loan approval status to a customer every so often?  Now you can easily do so in OpenESB with the advent of the Scheduler (powered by OpenSymphony Quartz) Service Engine (SE)!  With a few simple steps, you can create schedule files that will trigger your BPEL provider endpoint with a message and begin a new Business Process instance that subsequently performs some task like sending status to loan applicants.  The following instructions assume you have some familiarity with how to use components in OpenESB, but if not please click here to get more acquainted.

  1. Create a new Scheduler project in NetBeans by going to File | New Project and choosing SOA category and Scheduler Module project type and then selecting Next:
  2. Enter an apropos name for the Scheduler project and select Finish:
  3. Create a schedule file that can contain one or more triggers by right-clicking in the Process Files folder of the newly created Scheduler project and selecting New | Schedule File menu item:
  4. Enter a meaningful name for the schedule file (the project and schedule file names form the prefix to the name of the Scheduler SE consumer endpoint—in this example, it will be schedLoansRUs-sendLoanStatusPort—that will be sending a message to your BPEL provider endpoint) and press Finish:
  5. A Table view editor for the schedule file appears and now simply click on the Simple Trigger toolbar button (just a clock) to create a new trigger (currently only Quartz SimpleTrigger has been implemented; CronTrigger will follow soon).  You can double-click in the Name cell to give the trigger a more meaningful name, as well as provide a Description:
  6. or if you're a diehard  XML fan, there's the XML Source view:

  7. With the respective trigger table row highlighted (note, the Selected checkbox is used for indicating selected triggers for deletion), you can specify the various parameters for that trigger.  Changes to a field are registered when either focus is lost or an Enter key is pressed (except for the Message text area since it will accept newlines as part of the data):
    • The Starting and Ending Date & Time entries delineate when this trigger will be active.  Until a date/time chooser is implemented (very soon; or please donate if you have a good free open-source one), you'll need to enter one manually in the default locale format (Java SimpleDateFormat is used); the first item in the Job Date Format exemplifies the default locale format.  Alternatively, if you want the trigger to be active immediately after the Composite Application has been deployed, choose Now and similarly select Never if the active period has no end.
    • A simple trigger basically repeats after a certain time interval so specify the Repeat Count or Indefinite and the various time units that comprise the overall time interval.
    • Finally, the Job section pertains to the Message that will be sent when the trigger fires and will contain a metadata part that details the appointed date and time the trigger was configured to fire (note, this may precede the actual time the message is received due to network latency) in the specified Date Format.  Moreover, the metadata will also contain the trigger's name and group to which it belongs.
  8. Save your work and right-click over the Scheduler project and select Build Project to generate the corresponding abstract WSDL file for the schedule:
  9. The abstract WSDL can be used to define a BPEL service to receive the trigger message and so we'll now go to File | New Project and select the SOA category, BPEL Module project type and press Next:
  10. Key in an apropos name for the BPEL project and press Finish:
  11. We need to copy and paste the abstract WSDL generated for the schedule from the Scheduler project into the BPEL project's Process Files folder (XML catalog referencing will be supported soon):
  12. To simulate sending a loan application status to a customer, we're just going to write to a file on disk.  Thus, we need to create a concrete WSDL for the File Binding Component (BC) and start by right-clicking the BPEL project's Process Files and selecting New | WSDL Document:
  13. Supply a meaningful name for the WSDL file and press Next (don't press Finish yet):
  14. Choose a One-Way Operation for the Operation Type and press Next:
  15. Then choose FILE Binding Type and now at last, press Finish:
  16. We're almost there and now have to define the BPEL process that is to be triggered by the schedule.  Right-click the BPEL project's Process Files folder and select New | BPEL Process:
  17. In the ensuing BPEL editor, drag and drop the Scheduler's abstract WSDL from the BPEL's Process Files folder to somewhere approximately the middle of the left gray column until you select a hotspot target dot:
  18. Now do analogously for the File concrete WSDL but to the right gray column:
  19. Next, drag and drop these activities from the BPEL Palette onto the canvas area at appropriate hotspot locations: a Receive, an Assign, and an Invoke:
  20. Select the edit icon (one with a pencil) of the Receive activity and specify the appropriate fields as illustrated below, remembering to create an Input Variable:
  21. Similarly, edit the Invoke activity and specify the fields as illustrated below, again remembering to create an Input Variable:
  22. Now double-click on the Assign activity to configure the Mapper for it, to do something similar to the following (note the use of the message metadata):
  23. "Are we there yet, are we there yet?"  Yup, almost.  We just need to dump both projects into a Composite Application project, build and deploy.  Thus, go to File | New Project and select SOA category, Composite Application project type and press Next:
  24. As always, enter a meaningful name for the Composite App and press Finish:
  25. Drag and drop both Scheduler and BPEL projects onto the Comp App editor canvas and press the Build (hammer) toolbar button (might need to press the Build button again to dismiss the Reloading progress meter):
  26. Connect the Scheduler consumer endpoint chevron to the BPEL provider endpoint (this will be enhanced soon to be automatically done); when there are multiple schedules defined and hence multiple scheduler consumer endpoints, it's prudent to choose meaningful names for the Scheduler project and schedule file because together, they help form the endpoint names as seen here:
  27. Save all your work and we're almost ready for deployment.  But first we must verify that the GlassFish Application Server and Scheduler SE are up and running by going to the Services window (tab):
  28. Alas, go back to the Projects tab and right-click the Composite App project and select Deploy:
  29. The Comp App project will start running and you should see a test.xml file in your OS temp directory (ex. C:\\temp on Windows) with content something like this (hint, you'll need to configure the File BC to use append mode):

  30. Voilà, you're done!  Happy trails!
  31. P.S. If you want to take a test drive, click here for the OpenESB installer and here for this Scheduler demo projects.


Edward Wong


« July 2016