Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

how to create workflow model programmatically in aem

Avatar

Level 2

I would like to create an aem workflow model programmatically due to the business requirement, and i used below code to implement it, but it throws an exception,this problem has been torturing me for a week. Could you please give some hints? Thanks in advance.

The jave code is below.

<code> package com.sample.mms.workflow; import java.util.Iterator; import java.util.List; import javax.jcr.RepositoryException; import org.apache.commons.lang.StringUtils; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceResolverFactory; import org.osgi.framework.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sample.mms.service.ConfigurationService; import com.sample.mms.service.TopicOwnerBizService; import com.sample.mms.util.WorkflowUtil; import com.day.cq.workflow.WorkflowException; import com.day.cq.workflow.WorkflowService; import com.day.cq.workflow.WorkflowSession; import com.day.cq.workflow.exec.WorkItem; import com.day.cq.workflow.exec.WorkflowData; import com.day.cq.workflow.exec.WorkflowProcess; import com.day.cq.workflow.metadata.MetaDataMap; import com.day.cq.workflow.model.WorkflowModel; import com.day.cq.workflow.model.WorkflowNode; import com.day.cq.workflow.model.WorkflowTransition; @Component @Service @Properties({ @Property(name = Constants.SERVICE_DESCRIPTION, value = "general topic owner mark and approval each topic page step"), @Property(name = Constants.SERVICE_VENDOR, value = "Someone"), @Property(name = "process.label", value = "SAMPLE MMS NL - General Topic Owner Approval Process Step") }) public class TopicOwnerHandleProcessStep implements WorkflowProcess { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Reference ResourceResolverFactory resourceResolverFactory; @Reference private ConfigurationService configurationService; @Reference private TopicOwnerBizService topicOwnerBizService; @Reference private WorkflowService workflowService; @Override public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException { final WorkflowData workflowData = workItem.getWorkflowData(); final String payLoadType = workflowData.getPayloadType(); if(!StringUtils.equals(payLoadType, "JCR_PATH")){ return; } final String payLoad = workflowData.getPayload().toString(); String topicOwnerGroup = configurationService.getTopic_owner_participant_group(); ResourceResolver resourceResolver = null; UserManager userManager = null; try { resourceResolver = WorkflowUtil.getResourceResolver(resourceResolverFactory); userManager = resourceResolver.adaptTo(UserManager.class); List<User> list = WorkflowUtil.getUsersByGroup(userManager, topicOwnerGroup); User user = null; WorkflowModel wm = workflowSession.createNewModel("sample mms topic owner review each topic page_" + System.currentTimeMillis()); WorkflowData wd = workflowSession.newWorkflowData("JCR_PATH", payLoad); WorkflowNode startNode = wm.getRootNode(); WorkflowNode endNode = wm.getEndNode(); WorkflowNode andSplitNode = wm.createNode("and split",WorkflowNode.TYPE_AND_SPLIT,null); WorkflowNode andJoinNode = wm.createNode("and join",WorkflowNode.TYPE_AND_JOIN,""); wm.validate(); //this is the place where the exception throwed.wm.createTransition(startNode,andSplitNode,null);wm.createTransition(andJoinNode,endNode,null); for(int i=0;i<list.size();i++){ user = list.get(i); Iterator<Resource> resources = topicOwnerBizService.getResourceByTopicOwner(resourceResolver, payLoad, user.getID()); if(resources.hasNext()){ WorkflowNode topicOwnerParticipantNode = wm.createNode("topic owner participant",WorkflowNode.TYPE_PARTICIPANT,""); topicOwnerParticipantNode.getMetaDataMap().put("timeoutMillis", 0L); topicOwnerParticipantNode.getMetaDataMap().put("timeoutHandler", "com.sample.mms.workflow.TopicOwnerTimeoutHandler"); topicOwnerParticipantNode.getMetaDataMap().put("PARTICIPANT", user.getID()); WorkflowNode orSplitNode = wm.createNode("or split",WorkflowNode.TYPE_OR_SPLIT,""); WorkflowNode orJoinNode = wm.createNode("or join",WorkflowNode.TYPE_OR_JOIN,""); WorkflowNode topicOwnerApprovalNode = wm.createNode("topic owner approval",WorkflowNode.TYPE_PROCESS,""); topicOwnerApprovalNode.getMetaDataMap().put("PROCESS_AUTO_ADVANCE", true); topicOwnerApprovalNode.getMetaDataMap().put("PROCESS", "com.sample.mms.workflow.TopicOwnerApprovalProcessStep"); topicOwnerApprovalNode.getMetaDataMap().put("PROCESS_ARGS", "approval"); WorkflowNode topicOwnerRejectNode = wm.createNode("topic owner reject",WorkflowNode.TYPE_PROCESS,""); topicOwnerRejectNode.getMetaDataMap().put("PROCESS_AUTO_ADVANCE", true); topicOwnerRejectNode.getMetaDataMap().put("PROCESS", "com.sample.mms.workflow.TopicOwnerApprovalProcessStep"); topicOwnerRejectNode.getMetaDataMap().put("PROCESS_ARGS", "reject"); WorkflowNode timeoutNode = wm.createNode("time out join",WorkflowNode.TYPE_PROCESS,""); wm.createTransition(orSplitNode,topicOwnerApprovalNode,null); wm.createTransition(orSplitNode,topicOwnerRejectNode,null); WorkflowTransition orSplitAndTimeOutTransition = wm.createTransition(orSplitNode,timeoutNode,null); orSplitAndTimeOutTransition.setRule("function check(){return false;}"); wm.createTransition(topicOwnerApprovalNode,orJoinNode,null); wm.createTransition(topicOwnerRejectNode,orJoinNode,null); wm.createTransition(timeoutNode,orJoinNode,null); wm.createTransition(andSplitNode,orSplitNode,null); wm.createTransition(orJoinNode,andJoinNode,null); } } workflowSession.startWorkflow(wm, wd); } catch (LoginException e) { e.printStackTrace(); } catch (RepositoryException e) { e.printStackTrace(); } } } </code>

The error log is below.

<code> 20.04.2016 17:35:24.054 *INFO* [JobHandler: /etc/workflow/instances/2016-04-20/model_27918689599044:/content/samplemms/2016/02/index] com.adobe.granite.workflow.core.WorkflowSessionImpl Workflow model deployed: /etc/workflow/models/sample_mms_topic_owner_175(Version: 1.0) 20.04.2016 17:35:36.015 *ERROR* [JobHandler: /etc/workflow/instances/2016-04-20/model_27918689599044:/content/samplemms/2016/02/index] com.day.cq.workflow.compatibility.CQWorkflowProcessRunner Process execution resulted in an error: null java.lang.NullPointerException: null at com.adobe.granite.workflow.core.model.WorkflowModelImpl.createTransition(WorkflowModelImpl.java:155) at com.adobe.granite.workflow.core.model.WorkflowModelImpl.createTransition(WorkflowModelImpl.java:149) at com.day.cq.workflow.impl.model.CQWorkflowModelWrapper.createTransition(CQWorkflowModelWrapper.java:145) at com.sample.mms.workflow.TopicOwnerHandleProcessStep.execute(TopicOwnerHandleProcessStep.java:105) at com.day.cq.workflow.compatibility.CQWorkflowProcessRunner.execute(CQWorkflowProcessRunner.java:93) at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:215) at com.adobe.granite.workflow.core.job.JobHandler.process(JobHandler.java:140) at org.apache.sling.event.jobs.JobUtil$1.run(JobUtil.java:365) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) 20.04.2016 17:35:36.015 *ERROR* [JobHandler: /etc/workflow/instances/2016-04-20/model_27918689599044:/content/samplemms/2016/02/index] com.adobe.granite.workflow.core.job.JobHandler Process execution resulted in an error com.adobe.granite.workflow.WorkflowException: Process execution resulted in an error at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:225) at com.adobe.granite.workflow.core.job.JobHandler.process(JobHandler.java:140) at org.apache.sling.event.jobs.JobUtil$1.run(JobUtil.java:365) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: com.adobe.granite.workflow.WorkflowException: Failed to execute process at com.day.cq.workflow.compatibility.CQWorkflowProcessRunner.execute(CQWorkflowProcessRunner.java:108) at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(HandlerBase.java:215) ... 5 common frames omitted Caused by: java.lang.NullPointerException: null at com.adobe.granite.workflow.core.model.WorkflowModelImpl.createTransition(WorkflowModelImpl.java:155) at com.adobe.granite.workflow.core.model.WorkflowModelImpl.createTransition(WorkflowModelImpl.java:149) at com.day.cq.workflow.impl.model.CQWorkflowModelWrapper.createTransition(CQWorkflowModelWrapper.java:145) at com.sample.mms.workflow.TopicOwnerHandleProcessStep.execute(TopicOwnerHandleProcessStep.java:105) at com.day.cq.workflow.compatibility.CQWorkflowProcessRunner.execute(CQWorkflowProcessRunner.java:93) ... 6 common frames omitted </code>
5 Replies

Avatar

Level 3

Are u able to create the workflow model without adding any steps to it.

Avatar

Level 2

I would like to add step programmatically, not drag in some step component. because i want to get an AND SPLIT with dynamic branches. Do you have any ideas?

Avatar

Level 10

Can you provide a brief of your use case, what are you trying to implement?

Is it not possible to configure workflow in starting and only passing parameter to it at runtime?

Avatar

Level 2

edubey wrote...

Can you provide a brief of your use case, what are you trying to implement?

Is it not possible to configure workflow in starting and only passing parameter to it at runtime?

 


Hi Edubey,

I'm trying to implement an AND SPLIT with dynymic branches programmatically.

It thorws exception before passing parameter, It throws exception when create the transition at line [wm.createTransition(startNode,andSplitNode,null);], so i don't think this is the root cause. I'm not pretty sure where I new the workflow model is properly. 

Could you please help give any hints?

Really appreciate for your any help!

 

Best Regards,

Hunter

Avatar

Level 2

Finally I found another workaround from business aspect