Implementing a task
A task can be added on the fly during runtime. You implement a task class and put that class under Swordfish_installed_directory/custom directory. Then it will be automatically loaded when you open flow designer.
To implement a task, a task class must implement TaskHandler and define an TaskDefinition java annotation.
TaskHandler interface
package com.ism.was.flow.entity;
import java.util.Map;
import java.util.Properties;
public interface TaskHandler {
public boolean initializeTask(Properties props);
public boolean execute(String flowId, String taskId, String transactionId, FlowTask [] tasks, Map requestData);
public TaskResult getResult();
public String getName();
public boolean finalizeTask();
}
Signature
public boolean initializeTask(Properties props);
Description
Used when extra additional initialization is required for a task
Parameters
props - input attributes defined in flow.
Return
boolean value.
True - initialization succeeded
False - initialization failed
Signature
public boolean execute(String flowId, String taskId, String transactionId, FlowTask [] tasks, Map requestData);
Description
Main method of a task
Parameters
flowId - flow id
taskId - task id
transactionId - transaction id
tasks - tasks executed previously
requestData - collection of output data from previous tasks
Return
boolean value.
True - succeeded
False - failed
Signature
public TaskResult getResult();
Description
Returns the result of task execution. This result contains the input and output data of the task execution
Parameters
Return
TaskResult may contain error information, if it failed.
Signature
public boolean finalizeTask();
Description
Used when an additional finalization is required of a task
Parameters
Return
boolean value.
True - succeeded
False - failed
TaskDefinition annotation
package com.ism.was.flow.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface TaskDefinition {
public String name();
public String description();
public int arguments();
public String html() default "";
public String type() default "java";
public String icon() default "";
public FieldDefinition [] fields() default {};
public FieldDefinition [] outs() default {};
public boolean test() default false;
public String testLink() default "";
public boolean custom() default false;
public String customPage() default "";
}
Attributes
name
Task name displayed in flow designer
description
Task description
arguments
Number of input attribute. For display purpose only.
html
custom html page for input/output attributes
type
task type. For display purpose only
icon
path of task icon. ex) images/task.png
fields
input attribute list
outs
output attribute list
test
whether test page is provided
testLink
custom html page for testing
custom
True if custom html page is provided for input attibutes
customPage
The class path of the html page
ex) com/ism/was/flow/handler/html/ftptransfer-task.html
FieldDefinition
package com.ism.was.flow.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldDefinition {
public String name();
public String label() default "";
public String help() default "";
public int width() default 0;
public String type() default "text";
public int height() default 0;
public int rows() default 3;
public int cols() default 80;
public String selectFrom() default "";
public String [] options() default {};
public String [] labels() default {};
}
Attributes
name
Attribute name displayed in property editor
label
Label of attribute
help
Help message
width
Not used. For display purpose only. HTML text box
height
Not used. For display purpose only. HTML text box
rows
For display purpose only. HTML textarea
cols
For display purpose only. HTML textarea
selectFrom
Used only when option list of HTML select is from a class invocation
options
Available values of the attribute. HTML select
labels
For display purpose only. HTML select
Example implementation - Wait Task
package com.ism.was.flow.handler;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import com.ism.common.Common;
import com.ism.common.logger.DefaultLogger;
import com.ism.was.flow.annotation.FieldDefinition;
import com.ism.was.flow.annotation.TaskDefinition;
import com.ism.was.flow.config.FlowConstants;
import com.ism.was.flow.entity.FlowTask;
import com.ism.was.flow.entity.SubFlowExecution;
import com.ism.was.flow.entity.TaskHandler;
import com.ism.was.flow.entity.TaskResult;
import com.ism.was.flow.log.SubFlowExecutionLog;
import com.ism.was.flow.log.SubflowLogManager;
import com.ism.was.flow.util.FlowUtil;
@TaskDefinition(
name="Wait", description="Wait sub flow completion", arguments=-1,
custom=false,type="function",
icon="images/wait.png",
fields = {
@FieldDefinition(name="SubFlowId", width=100, height=30, rows=10, cols=80, type="select", selectFrom="com.ism.projects.jpa.web.flow.FlowProcessor" ),
@FieldDefinition(name="ExecutionCount", width=100, height=30, rows=10, cols=80, type="text" ),
@FieldDefinition(name="Timeout", width=100, height=30, rows=10, cols=80, type="text" ),
},
outs = {
}
)
public class WaitSubTask implements TaskHandler {
protected Properties props;
protected TaskResult result;
protected Properties outprops;
private String resultValueName = null;
public boolean initializeTask(Properties props) {
// TODO Auto-generated method stub
this.props = props;
return true;
}
public boolean execute(String flowId, String taskId, String gidSeq, FlowTask[] tasks, Map imap) {
// TODO Auto-generated method stub
result = new TaskResult(gidSeq);
result.setStartTime();
Vector imaps = new Vector();
HashMap omap = new HashMap();
omap.putAll(imap);
result.setSuccess(true);
String iid = (String)props.get("interface-id");
String from = (String)props.get("input-from");
String gid = (String)imap.get("GID");
String subFlowId = (String)props.get("SubFlowId");
String executionCount = (String)props.get("ExecutionCount");
String timeout = (String)props.get("Timeout");
resultValueName = (String)props.get("out-ResultValue");
if ( resultValueName == null || resultValueName.trim().length() < 1 ) {
resultValueName = "ResultValue";
}
Object rtn = null;
int completedCount = 0;
try {
executionCount = (String)FlowUtil.getValue(imap, props, executionCount);
if ( executionCount == null ) {
throw new Exception("ExecutionCount cannot be null or empty");
}
int executionCountInt = -1;
try {
executionCountInt = Integer.parseInt(executionCount.trim());
}catch( Exception e ) {
throw new Exception("ExecutionCount value is invalid[" + executionCount + "]");
}
long start = System.currentTimeMillis();
long timeoutLong = Long.parseLong(timeout) * 1000; //30 sec
boolean succeeded = false;
int interval = 0;
while ( true ) {
String fkey = String.format("%s-%s-%s", flowId, subFlowId, gid);
int count = SubflowLogManager.countComplete(fkey);
if ( ++interval % 10 == 0 ) {
DefaultLogger.logN("Expected count = {}, logged count = {}, {}, {}, {} ", executionCountInt, count, flowId, subFlowId, gid);
}else {
DefaultLogger.logV("Expected count = {}, logged count = {}, {}, {}, {} ", executionCountInt, count, flowId, subFlowId, gid);
}
if ( count != executionCountInt ) {
Thread.sleep(2000);
}else {
succeeded = true;
SubflowLogManager.removeSubflows(fkey);
break;
}
if ( Common.shutdown ) {
break;
}
long now = System.currentTimeMillis();
if ( now > (start + timeoutLong) ) {
break;
}
}
omap.put(resultValueName, rtn);
result.setSuccess(succeeded);
}catch( Exception e ) {
DefaultLogger.logE(e, "Failed to executing function");
result.setErrorMessage(e.getMessage());
result.setException(e);
result.setSuccess(false);
}
result.setData(omap);
result.setEndTime();
return result.isSuccess();
}
public TaskResult getResult() {
// TODO Auto-generated method stub
return result;
}
public String getName() {
// TODO Auto-generated method stub
return null;
}
public boolean finalizeTask() {
// TODO Auto-generated method stub
return false;
}
}
Last updated