What is a Workflow?
A series of tasks to produce a desired outcome, usually involving multiple participants and several stages in an organization. Workflow describes the sequential steps that comprise a work process in the business environment. In its most comprehensive form, workflow includes the procedures, people and tools involved in each step of a business process. Workflow may either be sequential, with each step contingent upon completion of the previous one, or parallel, with multiple steps occurring simultaneously.
Custom Workflow Steps
While working on CQ5 workflows , you might have undergone two variations where you need to write your custom implementations of a workflow process :
- Custom ParticipantStepChooser : The ParticipantStepChooser allows assigning a user or a group to execute a specific branch of the workflow model and also allows to use a user’s session to perform a certain task like activating pages or assets. This might be useful when you need to write some business logic while allocating a particular Workflow Step to a predefined set of users/groups based on some condition- kind of Dynamic Participant Chooser.
- Custom Process Step: The WorkflowProcess interface is intented to implement an item of job where you are writing some Business logic based on your requirement on the workflow payload.
Workflow Process | Implements Interface | Method |
ParticipantStepChooser | ParticipantStepChooser | String: getParticipant(Workitem, WorkflowSession, MetadataMap) |
Process Step | WorkflowProcess | void: execute(Workitem, WorkflowSession, MetadataMap) |
Sample Workflow Process Step
Workflow process steps can be customized in ample number of ways , I have mentioned below the basic version to give you a kick-start for writing a workflow. Just go ahead , pick this template and write your business logic.
@Component( label = "CQ Workflow Process", description = "Sample Workflow Process implementation", metatype = false, immediate = false ) @Properties({ @Property( name = "service.description", value = "CQ Workflow Process implementation.", propertyPrivate = true ), @Property( label = "Workflow Label", name = "process.label", value = "CQ Workflow Process", description = "CQ Workflow Process description" ) }) @Service public class SampleProcessWorkflow implements WorkflowProcess { @Reference ResourceResolverFactory resourceResolverFactory; private static final Logger log = LoggerFactory.getLogger(SampleProcessWorkflow.class); @Override public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException { final WorkflowData workflowData = workItem.getWorkflowData(); final String type = workflowData.getPayloadType(); if (!StringUtils.equals(type, "JCR_PATH")) { return; } Session session = workflowSession.getSession(); final String path = workflowData.getPayload().toString(); try { Node node = session.getNode(path); /* Write your custom code here. */ } catch (Exception ex) { /* Use this block for Exception Handling. */ } throw new UnsupportedOperationException("Not supported yet."); } }
Sometimes you need to have persisted data within your workflow steps. There is a good implementation for working that out. Please use the code from Apache V2 implementation.
Sample Participant Chooser Step
@Component @Service @Properties({ @Property(name = "service.description", value = "A sample implementation of a dynamic participant chooser."), @Property(name = "service.vendor", value = "SampleVendor"), @Property(name = ParticipantStepChooser.SERVICE_PROPERTY_LABEL, value = "Sample Participant Chooser")}) public class MyDynamicParticipant implements ParticipantStepChooser { private static final String TYPE_JCR_PATH = "JCR_PATH"; public String getParticipant(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException { WorkflowData workflowData = workItem.getWorkflowData(); if (workflowData.getPayloadType().equals(TYPE_JCR_PATH)) { // Write your custom code here. String path = workflowData.getPayload().toString(); String pathFromArgument = args.get("PROCESS_ARGS", String.class); if (pathFromArgument != null && path.startsWith(pathFromArgument)) { return "admin"; } } return "administrators"; } }
Sample ECMA Script
Besides the Java implementation of a Process Step, you can also proceed by writing some ECMA script. This is a quicker way to do so, if you are accustomed to the syntax of ECMA. I would list a few examples below:
var workflowData = workItem.getWorkflowData(); if (workflowData.getPayloadType() == "JCR_PATH") { // Write your custom code here. var path = workflowData.getPayload().toString(); var node = workflowSession.getSession().getItem(path); node.setProperty("approved", args[0] == "true" ? true : false); node.save(); }
There might be limitless possibilities in Workflow Designs and Custom Processes, I hope the above templates help you to start. If are you are stuck somewhere or encounter something challenging in workflows , please let me know via commenting below, I might be helpful.
Happy coding. !!
Hi Hashim,
Is there a way to start executing a workflow from a particular process step from a service.
LikeLike
Yes you can trigger a workflow programmatically . Check these links- http://stackoverflow.com/questions/15233798/cq5-programmatically-run-a-workflow
http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__dcfz-hi_team_i_havew.html
LikeLike
Hi Hashim,
Is it possible to get the id’s of workflow instances that are in the Granite workflow queue? My use case is that I have a workflow launcher attached on a node creation event. I want to show the status “Waiting” until the control comes to the execute method of the workflow. Any ideas on how to do it?
LikeLike
Hi Anisha,
I think this should be available from Workflow Session (getWorkflows(String[] states) ) .getId()
https://docs.adobe.com/content/docs/en/cq/5-6-1/javadoc/com/day/cq/workflow/WorkflowSession.html
https://docs.adobe.com/content/docs/en/cq/5-6-1/javadoc/com/day/cq/workflow/exec/Workflow.html
You can also use Workflow.getState() to retrieve state of the workflow.
https://stackoverflow.com/questions/43149392/how-to-find-the-workflow-running-instances-by-java-in-aem
This might help you too https://github.com/Adobe-Consulting-Services/acs-aem-commons/pull/897/files
LikeLike
Hi Hashim
One user trying to create a node and childnodes through page by entering the values from front end
from ajax call and servlet we can create node and child nodes on specific node in content folder
here before creating nodes admin can accept that then nodes will be created. but here the problem is how to pass multiple values from servlet to workflow
we can call workflow in servlet only one value we can send we can not send multiple values.
Any ideas?
Thanks,
Srikanth
LikeLike