Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Stardust/Knowledge Base/Java API/Dynamic Event Binding

Requirements

A process, let say, Main Process has to trigger a sub-process called Escalation Process, but it doesn't know when to trigger it (not known during design). It only knows that when certain data or indicator will be available at proces execution it would like to trigger the sub-process.

Approach

We will be modelling the Main Process by defining an Process level Event Handling, Timer, and will not bind it Automatically. We will use a process data that will be set somewhere during process execution and this data will be used to indicate the time when we would like the Timer event to get fired and trigger the Escalation Process.

TimerEventDefinition1.JPG


TimerEventDefinition2.JPG


Complete Process

BindActionTestModel MainProcess Default.jpg

We will use IPP WorkflowService's API bindProcessEventHandler to bind the event after a value is available to the data to which Timer is bound.

Code:

package com.sungard.cm.invo.ipp.training;
 
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
 
import org.eclipse.stardust.common.config.Parameters;
import org.eclipse.stardust.engine.api.query.ActivityInstanceQuery;
import org.eclipse.stardust.engine.api.query.ActivityInstances;
import org.eclipse.stardust.engine.api.query.ActivityStateFilter;
import org.eclipse.stardust.engine.api.runtime.ActivityInstance;
import org.eclipse.stardust.engine.api.runtime.ActivityInstanceState;
import org.eclipse.stardust.engine.api.runtime.AdministrationService;
import org.eclipse.stardust.engine.api.runtime.DocumentManagementService;
import org.eclipse.stardust.engine.api.runtime.QueryService;
import org.eclipse.stardust.engine.api.runtime.ServiceFactory;
import org.eclipse.stardust.engine.api.runtime.ServiceFactoryLocator;
import org.eclipse.stardust.engine.api.runtime.UserService;
import org.eclipse.stardust.engine.api.runtime.WorkflowService;
import org.eclipse.stardust.engine.core.runtime.beans.removethis.SecurityProperties;
 
public class PrioritySettler {
	private static ServiceFactory serviceFactory;
	private static QueryService queryService;
	private static WorkflowService workflowService;
	private static UserService userService;
	private static AdministrationService adminService;
	private static DocumentManagementService documentService;
 
	public PrioritySettler() {
 
	}
 
	@SuppressWarnings("deprecation")
	public void evaluateAndUpdatePriority(long pOID) {
 
		System.out.println("Process OID to change the priority: "+ pOID);
		try{
			init("motu", "motu");
 
			workflowService.bindProcessEventHandler(pOID, "SLA");
 
 
		}catch(Exception e){
			//Default thresholdMins to 10 minutes
			e.printStackTrace();
			thresholdValue = 1;
		}
		finally {
			uninit();
		}
			}
 
	static void init(String backdoorAccount, String backdoorKey) throws IOException {
 
		// Get the factory and provide login credentials
		Map <String, String> prop = new HashMap();
 
		serviceFactory = ServiceFactoryLocator
				.get("motu", "motu");
		// Get the service instances
		queryService = serviceFactory.getQueryService();
		workflowService = serviceFactory.getWorkflowService();
		userService = serviceFactory.getUserService();
		documentService = serviceFactory.getDocumentManagementService();
		adminService = serviceFactory.getAdministrationService();
 
 
	}
 
	static void uninit() {
		//System.out.println("In Uninit#############");
		if (serviceFactory != null) {
			// Release all resources
			serviceFactory.close();
		}
	}
}


Another approach can be taken to define the class and instead of hard coding motu/motu, we can declare a bean referring to this class and can inject the required service objects as properties, like:

<bean id="prioritySettler" class="com.sungard.cm.invo.ipp.training.PrioritySettler">
		<property name="userService" ref="carnotUserService" />
		<property name="queryService" ref="carnotQueryService" />
                <property name="adminService" ref="carnotAdministrationService" />
		<property name="workflowService" ref="carnotWorkflowService" />
                <property name="documentService" ref="carnotDocumentManagementService" />
</bean>


public class PrioritySettler {
 
	private static QueryService queryService;
        private static WorkflowService workflowService;
	private static UserService userService;
	private static AdministrationService adminService;
	private static DocumentManagementService documentService;
 
	public static QueryService getQueryService() {
		return queryService;
	}
 
	public static void setQueryService(QueryService queryService) {
		PrioritySettler.queryService = queryService;
	}
 
	public static WorkflowService getWorkflowService() {
		return workflowService;
	}
 
	public static void setWorkflowService(WorkflowService workflowService) {
		PrioritySettler.workflowService = workflowService;
	}
 
	public static UserService getUserService() {
		return userService;
	}
 
	public static void setUserService(UserService userService) {
		PrioritySettler.userService = userService;
	}
 
	public static AdministrationService getAdminService() {
		return adminService;
	}
 
	public static void setAdminService(AdministrationService adminService) {
		PrioritySettler.adminService = adminService;
	}
 
	public static DocumentManagementService getDocumentService() {
		return documentService;
	}
 
	public static void setDocumentService(DocumentManagementService documentService) {
		PrioritySettler.documentService = documentService;
	}
 
 
 
 
 
	public PrioritySettler() {
 
	}
 
	@SuppressWarnings("deprecation")
	public void evaluateAndUpdatePriority(long pOID) {
 
		System.out.println("Process OID to change the priority: "+ pOID);
		try{
 
			workflowService.bindProcessEventHandler(pOID, "SLA");
 
 
		}catch(Exception e){
			//Default thresholdMins to 10 minutes
			e.printStackTrace();
			thresholdValue = 1;
		}
		finally {
 
		}
	}
}


With this approach please ensure to edit the model so that activity Bind Timer is now uses Spring Bean application instead of POJO and uses the bean 'prioritySettler'.

Results


In this example case, when Main Process is started:

  1. User will input data (time in milliseconds since Jan 1, 1970) on first activity UI.
  2. User will see the entered time value on next screen, after completing this activity.
  3. The application activity "Bind Timer", will call the POJO method and bind the Timer Event named "SLA" and the process Escalation Process witll be triggered at the time the user entered on first activity.


For example, you started Main Process at 16:45 hours and input the value (in milliseconds since Jan1, 1970) of 16:50, the Escalation Process will be triggered at 16:50.

Artifacts

Please get the required artifacts from here

Back to the top