Custom Triggers and Actions

NOTE: Creating custom triggers and actions requires experience coding with Java. This documentation assumes that you are comfortable writing and working with Java code.

Once the trigger or action has been created, however, you can easily use it within a flow chart with no knowledge of Java code. Once the action has been created and deployed, you can use it in the Flux Designer or Web-based Designer exactly as you would use any other action. Custom triggers and actions can also be used when creating flow charts using Java code.

Flux provides a backbone for creating suites of custom triggers and actions that can be easily integrated into your flow charts. The following sections describe how you can create custom triggers and actions, use them in your flow charts, and view and edit them in the standalone and Web-based Designers.

Custom Triggers

You can create a custom trigger by following these steps:

  1. Create an interface that is used to initialize your trigger. This interface must extend flux.Trigger and should contain getter and setter methods for each of your trigger's properties.
  2. You may want your custom trigger to contain persistent variables, which Flux automatically persists to the database. For each persistent variable that your class will use, create a variable class that implements java.io.Serializable. Persistent variables must follow the rules for persistence described in Persistence .
  3. Create an implementation class that extends fluximpl.TriggerImpl and implements your interface.
  4. In the implementation class, implement each getter and setter method from your interface.
    If your custom trigger contains persistent variables, your getter and setter methods should manipulate them using the get() and put() methods of the variable manager, available by calling getVariableManager().

In addition to your own getter and setter methods, you must implement the following:

  • One constructor that calls super(FlowChartImpl, String), and another that calls super(FlowChartImpl, "<My Trigger Name>"), where <My Trigger Name> is the default name for this trigger.
  • getHiddenVariables() – Return a java.util.Set that contains the names of each of your persistent variables.
  • verify() - Determine whether your custom trigger is ready to be added to the engine - for example, check to ensure that vital job data is not null or empty. If the trigger is not ready to be added, throw an EngineException.
  • execute()- This is the method that Flux will call to determine whether the flow chart is ready to fire. The execute() method should check to see whether a certain event has occurred. If the event has not occurred, throw a flux.dev.NotTriggeredException. You can also return a variable or throw your own exception from the execute() method. As with other triggers and actions, returned variables can be accessed from the flow context.
  • getNextPollingDate()­- Return a java.util.Date that specifies the next time the engine should poll your trigger. Your trigger's execute() method is called each time the trigger is polled. For optimal performance, your trigger should wait as long as your needs allowing between pollings.

For a complete, working example of a custom trigger, refer to the examples/software_developers/custom_synchronous_trigger directory under your Flux installation directory.

Custom Actions

You can create a custom action as follows:

  1. Create an interface that is used to initialize your action. This interface must extend flux.Action and should contain getter and setter methods for each of your action's properties.
  2. You may want your custom action to contain persistent variables, which Flux automatically persists to the database. For each persistent variable that your class will use, create a variable class that implements java.io.Serializable. Persistent variables must follow the rules for persistence described in Persistence .
  3. Create an implementation class that extends fluximpl.ActionImpl and implements your interface.
  4. In the implementation class, implement each getter and setter method from your interface.
    If your custom action contains persistent variables, your getter and setter methods should manipulate them using the get() and put() methods of the variable manager, available by calling getVariableManager().

In addition to your own getter and setter methods, you must implement the following:

  • One constructor that calls super(FlowChartImpl, String), and another that calls super(FlowChartImpl, "<My Action Name>"), where <My Action Name> is the default name for this action.
  • getHiddenVariables() – Return a java.util.Set that contains the names of each of your persistent variables.
  • verify() - Determine whether your custom trigger is ready to be added to the engine - for example, check to ensure that vital job data is not null or empty. If the trigger is not ready to be added, throw an EngineException.
  • execute()- Perform your custom action. The code in execute() runs whenever the flow of execution in your flow chart reaches this action. You can return a variable or throw an exception from the execute() method. As with other triggers and actions, returned variables can be accessed from the flow context.

The code below demonstrates a simple Hello World implementation.

import flux.EngineException;
import flux.FlowContext;
import flux.file.FileActionException;
import fluximpl.ActionImpl;
import fluximpl.FlowChartImpl;
import java.util.Set;
 
public interface CustomAction extends flux.Action {
//  Normally, getter() and setter() methods would go here, but
//  this action has no properties to get or set.
}
 
public class CustomActionImpl extends ActionImpl implements CustomInterface {
 
//    This constructor creates the action with a default name.
  public FileActionImpl() {
    super(new  FlowChartImpl(), "Custom Action");
  }
 
//    This constructor is required too.
  public FileActionImpl(FlowChartImpl fc, String name) {
    super(fc, name);
  }
 
//    No persistent variables, so nothing to return.
  public Set getHiddenVariableNames() {
    return null;
  }
 
//    This action has no data that needs verified.
  public void verify() throws EngineException, FileActionException {
  }
 
//    Code that will be executed when this action runs.
  public Object execute(FlowContext flowContext) throws Exception {
    System.out.println("Hello World!");
//      Always return for the the result. Represented as the
//      flow context variable RESULT in the flow chart.
    return new Boolean(true);
  }
}

For a complete working example of a custom action, refer to the examples/software_developers/custom_action directory under your Flux installation directory.

Adapter Factories

When you create custom triggers and actions, you must make them available for inclusion in your jobs by creating adapter factories. An adapter factory is a factory that makes new instances of your custom triggers and actions.

To create an adapter factory, first create a class that implements flux.dev.AdapterFactory. Your custom factory must implement the init(FlowChartImpl) method of AdapterFactory, as in the following code:

import flux.dev.AdapterFactory;
import fluximpl.FlowChartImpl;
 
public class MyCustomFactory implements AdapterFactory {
  private FlowChartImpl flowChart;
  public void init(FlowChartImpl flowChart) {
    this.flowChart = flowChart;
  }
}

Make sure that the variable flowChart is saved in a field. This variable is used to attach your custom triggers or actions to a specific flow chart when they are created.

You will also need to create additional methods that make new instances of your custom triggers and actions. These methods must take a String argument that specifies the name of the trigger or action instance, and call the appropriate constructor on your custom class. For example:

public MyCustomAction makeCustomAction (String name) {
  return new MyCustomActionImpl(flowChart, name);
}

By passing in a reference to the flow chart, you bind the custom trigger or action to that flow chart.

Once you have created your adapter factory, you will need to make it available to the engine. to do so, create a file called factories.properties. In this file, give your adapter factory a short name that links it to your custom factory class, like so:

MyFactoryShortName=examples.custom_action.FileFactory

You can give your factory any short name you like, as long as it does not conflict with any of the built-in factory names. These include "file", "gui", "jee", "jmx", "messaging", "transform", "web_services", or "xml".

The custom trigger and custom action examples mentioned above each contain a working example of a custom adapter factory. You can also view all of the built-in adapter factories by calling flux.EngineHelper.getActionCatalog() method. This method returns a CatalogNode object representing the root node of the tree of actions. Any node in this tree that has at least one child represents an action factory.

Transient Variables

Your custom trigger or action may return a variable from the execute() method. Any variables returned are assumed to be persistable, and therefore are assumed to follow the persistence rules described in Persistence .

If you need to return a non-persistent variable instead, simply call flux.FlowContext.returnTransient() immediately before returning the variable from execute(). As long as you call returnTransient() before returning, your variable will not be stored to the database, and will be cleared from the flow context at the next transaction break.

Using Custom Triggers and Actions

To use your custom triggers and actions in Java code, you must include the following on your engine's class path:

  • All of your custom classes, including interfaces, implementation classes, variable classes, and adapter factories.
  • The factories.properties files for your custom adapter factories.

You can access your custom adapter factory in code by calling FlowChart.makeFactory(), like so:

Factory factory = Factory.makeInstance();
EngineHelper helper = factory.makeEngineHelper();
FlowChart flowChart = helper.makeFlowChart();
MyCustomFactory myCustomFactory = flowChart.makeFactory("MyFactoryShortName");

This method returns an instance of your adapter factory, which you can then use to make your custom triggers and actions.

In the Flux standalone or Web-based Designer

Using the Flux standalone or Web-based Designer, you can easily view and edit your custom triggers and actions, allowing you to interacting with them visually using the intuitive Flux drag and drop interface.

To use your custom triggers and actions in the standalone Flux Designer, place your factories.properties file in the Flux installation directory and run the flux-designer script.

For a concrete example that shows how to display and use a custom action in the Flux Designer, see the examples/software_developers/custom_action example under your Flux installation directory. Follow the steps outlined in the file flux-designer-custom-action.txt.

You can also use your custom triggers and actions in the Flux Web-based Designer. To do so, simply make sure your custom classes are available to the engine as described in Using Custom Trigggers and Actions above. Because dependencies only need to be available to the engine to use them in the Web-based Designer, a single Operations Console instance can monitor multiple engines without dependency issues.

Customizing your Trigger or Action with BeanInfo Classes

A JavaBean BeanInfo class can be created for custom actions by following the standard JavaBean conventions and extending SimpleBeanInfo.

SimpleBeanInfo Javadoc:

http://download.oracle.com/javase/1.5.0/docs/api/java/beans/SimpleBeanInfo.html

In the getPropertyDescriptors() method of your BeanInfo class, call super.getPropertyDescriptors() to retrieve the base property descriptors. Return them, along with your custom action’s property descriptors, from your getPropertyDescriptors() method.

The Designer uses these property descriptors to display and edit your custom action’s properties. The Designer also uses your BeanInfo to display other information, such as your custom action’s icons.

Any property that contains an attribute named "transient" with its value set to Boolean.TRUE is not saved to XML. The name of the "transient" property is considered case-insensitive.

Custom Property Editors

NOTE: Custom property editors are only available in the standalone Designer. You will not be able to use your custom editors in the Web-based Designer.

You can create a custom editor for any property on your custom trigger or action. These custom editors override the default property editors built into the Designer, and are displayed in the Designer when you edit your custom properties.

The class name of your custom editor must be patterned after the custom property's class name. For example, if your custom property is called com.somecompany.MyCustomProperty, then the name of your property editor will be com.somecompany.MyCustomPropertyEditor.

Your editor class must implement the java.beans.PropertyEditor interface.

In addition to creating custom property editors, you can completely customize the look and feel of a custom action’s entire property editor panel by using a customizer. A customizer allows you to display a complete property editor, entirely of your own design, within the Flux Designer.

The class name of your customizer is retrieved from the java.beans.BeanInfo.getBeanDescriptor().getCustomizerClass() method. Your customizer class must extend the javax.swing.JPanel class and implement the java.beans.PropertyEditor interface.

Custom property editor and customizer classes may need to implement the flux.gui.StopEditingListener interface to ensure that the classes are provided notification when the user is finished editing a property, which can happen when a custom property editor or customizer loses focus.

 
 
Was this article helpful?
0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.