WE have a requirement to kick off the workflow and control programmatically after replication. I am able to trigger the workflow after replication, however I cannot get any workitem from this workflow. I can see this workflow on the page, however workflow api is not giving me the workitems.
List<WorkItem> workItems = wf.getWorkItems(); //line 144
I can see workitem nodes in crx /etc/workflow/instances/server0/2017-09-14/publish_example_60/workItems as well, it has items and workflow data
I am using AEM 6.3, AEM recommends using com.adobe.granite.workflow. as mentioned in
Interacting with Workflows Programmatically
I have even tried with old cq workflow api, issue is same.
I have userservice migration (line 43) it has full permissions to /content/we-retail and /etc/workflow. Permission is not an issue here.
I have used out of box /etc/workflow/models/publish_example/jcr:content/model and we-retail site for demo purpose.
We have different workflow and content path, path and workflow can be changed to any values depending on requirement
package com.replication.workflow.handler;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Session;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.event.jobs.JobManager;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.event.WorkflowEvent;
import com.adobe.granite.workflow.exec.WorkItem;
import com.adobe.granite.workflow.exec.Workflow;
import com.adobe.granite.workflow.exec.WorkflowData;
import com.adobe.granite.workflow.model.WorkflowModel;
import com.day.cq.replication.ReplicationAction;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageEvent;
/**
* The <code>WorkflowEventCatcher</code> class listens to workflow events.
*/
@Component(immediate = true, service = { EventHandler.class }, property = {
"event.topics=com/day/cq/replication" })
public class ReplicationEventWorkflowStarter implements EventHandler {
static final String EVENT_TOPICS = "event.topics";
public static final String SERVICE_USER_NAME = "migration";
private static final Logger logger = LoggerFactory.getLogger(ReplicationEventWorkflowStarter.class);
@Reference
private JobManager jobManager;
private static final String WORKFLOW_MODEL = "/etc/workflow/models/publish_example/jcr:content/model";
@Reference
private ResourceResolverFactory resolverFactory;
private Session session;
@Override
public void handleEvent(Event event) {
// process(event);
logger.debug("Checking event.");
PageEvent pageEvent = PageEvent.fromEvent(event);
if (pageEvent != null) {
logger.debug("Event is a page event.");
}
String n[] = event.getPropertyNames();
logger.debug("Event occurred: {}", event.getProperty(WorkflowEvent.EVENT_TYPE));
logger.debug("Event properties: ");
for (String s : n) {
logger.debug(s + " = " + event.getProperty(s));
}
ReplicationAction action = ReplicationAction.fromEvent(event);
if (action != null) {
logger.debug("Replication action {} occured on {} ", action.getType().getName(), action.getPath());
}
logger.debug("");
boolean abc = process(event, action);
}
public boolean process(Event event, ReplicationAction action) {
logger.info("Received event of topic: " + event.getTopic());
String topic = event.getTopic();
ResourceResolver resourceResolver = null;
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, SERVICE_USER_NAME);
// Session session = resourceResolver.adaptTo(Session.class);
logger.debug("eventTopic {} ", topic);
String path = action.getPath();
logger.debug("### path: " + path);
if (path.startsWith("/content/we-retail")) {
try {
resourceResolver = resolverFactory.getServiceResourceResolver(param);
logger.debug("### event topic: " + event.getTopic());
logger.debug("### path: " + path);
Resource resPage = resourceResolver.getResource(path);
logger.debug(" resPage {}", resPage);
Page page = resPage.adaptTo(Page.class);
String title =page.getProperties().get("jcr:title",String.class);
logger.debug("title {}", title);
session = resourceResolver.adaptTo(Session.class);
logger.debug(" session {}" , session);
if (title.equals("Experience")) {
// Create a workflow session
//WorkflowSession wfSession = workflowService.getWorkflowSession(session);
WorkflowSession wfSession = resourceResolver.adaptTo(WorkflowSession.class);
// Get the workflow model
WorkflowModel wfModel = wfSession.getModel(WORKFLOW_MODEL);
// Get the workflow data
// The first param in the newWorkflowData metresohod is the payloadType. Just a
// fancy name to let it know what type of workflow it is working with.
WorkflowData wfData = wfSession.newWorkflowData("JCR_PATH", path);
logger.debug("### starting workflow again: {}" , wfData);
logger.debug("### workflow model: {}" , wfModel);
logger.debug("### workflow session: {}" , wfSession);
// Run the Workflow.
Workflow wf = wfSession.startWorkflow(wfModel, wfData);
// querying work items
//WorkItem[] workItems = wfSession.getActiveWorkItems();
List<WorkItem> workItems = wf.getWorkItems();
logger.debug(" workflow data {} " , wf.getWorkflowData());
logger.debug(" state {} , is active {} metadata {} id {}", wf.getState(), wf.isActive(), wf.getMetaDataMap(), wf.getId() );
logger.debug(" active work items {}" , workItems);
int i=0;
String activeId = "";
for(WorkItem item:workItems) {
String id = item.getId();
logger.debug("workflow item {}" , item);
logger.debug("workflow id {}" , id);
}
/* WorkItem workItem = wfSession.getWorkItem(activeId);
// getting routes
List<Route> routes = wfSession.getRoutes(workItem);
// completing or advancing to the next step
wfSession.complete(workItem, routes.get(0));*/
}
} catch (Exception e) {
logger.error("### error: {}", e);
}
}
return true;
}
}