Writing a Time-based Workflow

There are often scenarios where you need to execute some business logic on a scheduled basis. For example, perhaps you want to compute fulfillment rates hourly, or maybe you want to make a request to a web service every Tuesday night to get new fuel rates.

The One Network Platform handles scheduled jobs using a concept known as Time-based Workflows. A Time-based Workflow is simply a piece of java code which is executed on a scheduled basis.

As an example, let's say we have a requirement to send a list of all Books in our database published by "One Network Publishing Inc." to an external web service every Tuesday at 2:00 AM. We can implement this using a Time-based Workflow.

To begin our example, let's open the Bookstore MPT. We need to choose some Model under which we can put our Workflow. Since we're going to be sending out Book data, let's create it under Book. (This is done only for organizational reasons; there is no hard constraint that the workflow code fetches Books - it is at liberty to do anything.) We'll call our new workflow "SendBooksTimeBasedWorkflow":

images/download/attachments/144836686/addTBW-version-1-modificationdate-1655930996000-api-v2.jpg

After adding the workflow, we need to change it from Action-based to Time-based. (These two workflow types have a different interface; Action-based accept Models as input, whereas Time-based have no input.) Since this is a new workflow, we click OK to ignore the Studio warning about losing changes.

images/download/attachments/144836686/changeToTBW-version-1-modificationdate-1655931011000-api-v2.jpg

Now we can choose our schedule. Let's choose Complex Recurring, click Add and choose Every Month Tuesday at 2:00AM.

images/download/attachments/144836686/addSchedule-version-1-modificationdate-1655931026000-api-v2.jpg

It's time to write our workflow code. Click the "Code" tab, then click the "Edit" link. This will open up an editor so that you can begin writing workflow code.

images/download/attachments/144836686/editCode-version-1-modificationdate-1655931042000-api-v2.jpg

We will put all our logic in the execute method. The only piece of context we have available is the TimeBasedWorkflowContext, which has a PlatformUserContext to represent the user executing the time-based workflow. (For time-based workflows, this is always a privileged VALUE_CHAIN_ADMIN.) Let's write a little code to fetch Books published by "One Network Publishing Inc.". We won't worry about calling the external web service for now.

package com.mybooks.mpt.ZBKS_Book.wf;
import java.util.List;
import com.mybooks.model.Book;
import com.onenetwork.platform.data.model.ModelDataService;
import com.onenetwork.platform.data.model.ModelQuery;
import com.onenetwork.platform.data.sql.SqlParams;
import com.onenetwork.platform.env.servicelocator.Services;
import com.onenetwork.platform.tools.log.PlatformLogger;
import com.onenetwork.platform.workflow.AbstractTimeBasedWorkflowActivity;
import com.onenetwork.platform.workflow.TimeBasedWorkflowContext;
public class SendBooksTimeBasedWorkflow extends AbstractTimeBasedWorkflowActivity {
private static PlatformLogger LOG = PlatformLogger.get(SendBooksTimeBasedWorkflow.class);
@Override
public void execute(TimeBasedWorkflowContext context) {
// Time-based workflows do not have any "input". Any writes should be initiated
// via ModelDataService.write() rather than through WorkflowService.
ModelDataService mds = Services.get(ModelDataService.class);
SqlParams params = new SqlParams().setStringValue("PUBLISHER", "One Network Publishing Inc.");
List<Book> books = mds.read(
Book.class,
context.getPlatformUserContext(),
params,
ModelQuery.sqlFilter("PUBLISHER = $PUBLISHER$"));
LOG.info("Fetched books: " + books);
}
}


After making these changes, build the Bookstore module and restart the server.

This code looks good - but how do we test it? We certainly don't want to wait until Every Month Tuesday at 2AM. Fortunately, we can use the JMX console. The JMX console uses the Java Management Extensions to provide administrative features. Navigate to http://localhost/jmx-console to view your JMX console:

images/download/attachments/144836686/gridScheduler-version-1-modificationdate-1655931058000-api-v2.jpg

Within the JMX console, you should see a link to the "Grid Scheduler=Grid Scheduler" MBean. Follow this link to see a list of all currently deployed time-based workflows. Within this list you should see an entry for our new workflow: ZBKS.Book~ZBKS.SendBooksTimeBasedWorkflow

images/download/attachments/144836686/runTBW-version-1-modificationdate-1655931075000-api-v2.jpg

Click the "run" link next to that workflow to kick it off now. You should then be able to review the server log to see the LOG.info we generated from the workflow

images/download/attachments/144836686/tbwLog-version-1-modificationdate-1655931094000-api-v2.jpg