Expand my Community achievements bar.

How to retry a workflow step in aem 6.5?

Avatar

Level 3

Hi,

 

Here is my use case :

I want to retry one of my workflow step that got failed with some reason. I am not able to find anything around this.

20 Replies

Avatar

Level 3

Hi,

 

WorkflowRetryService is not there when I am using this service in aem 6.5. Could you please tell the dependency around that? or what is the import for this service?

 

 

Avatar

Employee Advisor

@KirtiKhatri94 ,

 

Here WorkflowRetryService is a custom interface like our project specific interface let's say DebalWorkflowRetryService and it is responsible to perform retry operation.

 

Hope this will help.

Avatar

Level 3

ok ok,,But everytime I get workitem null from the workflow session. Could you please tell how you get the workitem from the session?

Avatar

Employee Advisor

how are you trying to get workflow session object ? Are you doing using servlet? 

Please share.

Avatar

Level 3

Yes using servlet and session I am getting from service user : 

workflowSession = getResolver.getWorkflowServiceResolver().adaptTo(WorkflowSession.class);

Avatar

Employee Advisor

Could you please check below point -

Go to configurations in felix http://servername:port/system/console/configMgr

Search for "user mapper service " or your service user name

you will see an entry like mentioned below

 

DEBAL_DAS_0-1649298579415.png

 

 

if it is not there then add one.

Please search for your service user name in http://aemhost:port/security/users.html like mentioned below and check permission -

 

DEBAL_DAS_1-1649298579641.png

 

What is difference between getResolver and getWorkflowServiceResolver in your code? Are they returning ResourceResolver object? Please confirm.

 

Avatar

Level 3

Hi,

 

getResolver is the custom interface object and getWorkflowServiceResolver is the method

@Override
public ResourceResolver getWorkflowServiceResolver() throws LoginException {
return getResourceResolver("fmcc-workflow");
}

private ResourceResolver getResourceResolver(final String subServiceName) throws LoginException {
HashMap<String, Object> param = new HashMap<>();
param.put(ResourceResolverFactory.SUBSERVICE, subServiceName);
return resolverFactory.getServiceResourceResolver(param);
}

 Yes, Permissions are there.

WorkItem, I get null everytime.

Avatar

Employee Advisor

Have you injected that custom interface like this -

 

@reference
CustomInterface getResolver;

 

could you please share the details below method -

getResourceResolver("fmcc-workflow");

 It will help to troubleshoot -

Avatar

Level 3

yes : 

@Reference
private GetResolver getResolver;

Please find below method :  

private ResourceResolver getResourceResolver(final String subServiceName) throws LoginException {
HashMap<String, Object> param = new HashMap<>();
param.put(ResourceResolverFactory.SUBSERVICE, subServiceName);
return resolverFactory.getServiceResourceResolver(param);
}

Avatar

Level 3

Actually what is happening,, When everything is going smooth like every step is going in success then I am getting node under workItem in crx, but if any of the process step fails due to service down or something then in that case I am not getting any node under workItem in crx.

Avatar

Employee Advisor

In below sample servlet I have used this query to identify failed workflow items as nodes and I am considering individual node's path as workflowItemPath as shown below -

package com.aem.demo.core.servlets;

import java.io.IOException;
import java.util.Objects;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.servlet.Servlet;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import com.adobe.granite.workflow.WorkflowException;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import com.aem.demo.core.services.GetResolver;

@Component(service = Servlet.class, property = { "sling.servlet.paths=" + "/bin/workflowfailed",
		"sling.servlet.methods=" + HttpConstants.METHOD_GET })
public class FailedWorkflowdetails extends SlingAllMethodsServlet {

	@Reference
	private GetResolver getResolver;

	protected void doGet(SlingHttpServletRequest slingHttpServletRequest,
			SlingHttpServletResponse slingHttpServletResponse) {

		try {

			Session session = getResolver.getWorkflowServiceResolver().adaptTo(Session.class);
			WorkflowSession workflowSession = getResolver.getWorkflowServiceResolver().adaptTo(WorkflowSession.class);
			String failedWorkItemQuery = "SELECT * FROM [cq:WorkItem] AS s WHERE ISDESCENDANTNODE([/var/workflow/instances/server0]) and subType='FailureItem' and status = 'ACTIVE'";
			if (Objects.nonNull(session)) {
				QueryManager queryManager = session.getWorkspace().getQueryManager();
				Query query = queryManager.createQuery(failedWorkItemQuery, Query.JCR_SQL2);
				QueryResult queryResult = query.execute();
				NodeIterator nodeIterator = queryResult.getNodes();
				while (nodeIterator.hasNext()) {
					Node nextNode = nodeIterator.nextNode();
					WorkItem workItem = workflowSession.getWorkItem(nextNode.getPath());
					slingHttpServletResponse.getWriter().write(
							workItem.getItemSubType().concat("****************").concat(workItem.getNode().getTitle()));
				}

			}

		} catch (LoginException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RepositoryException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (WorkflowException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

I have created similar Interface and Implementation class like you -

package com.aem.demo.core.services;

import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;

public interface GetResolver {

	public ResourceResolver getWorkflowServiceResolver() throws LoginException;
}
package com.aem.demo.core.services.impl;

import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import java.util.HashMap;

import org.apache.sling.api.resource.LoginException;

import com.aem.demo.core.services.GetResolver;


@Component(service = GetResolver.class, immediate = true)
public class GetResolverImpl implements GetResolver {
	
	@Reference
	ResourceResolverFactory resourceResolverFactory;


	@Override
	public ResourceResolver getWorkflowServiceResolver() throws LoginException {
		return getResourceResolver("fmcc-workflow");
	}
	
	private ResourceResolver getResourceResolver(final String subServiceName) throws LoginException {
	    HashMap<String, Object> param = new HashMap<>();
	    param.put(ResourceResolverFactory.SUBSERVICE, subServiceName);
	    return resourceResolverFactory.getServiceResourceResolver(param);
	}

}

Servlet response -

DEBAL_DAS_0-1649472610346.png

Failed item in inbox -

DEBAL_DAS_1-1649472778881.png

 

Service user mapper service amendment -

DEBAL_DAS_2-1649472880415.png

 

Now  we can call  retryworkflow method as suggested by @arunpatidar. Please review.

Avatar

Level 3

Thank u for your support Debal.

One query : 

 If I have checked handler advance for one of my process step that is failing,,then it is going in archive with the failed comment. And If I don't check handler advance,,then it is there in instances till one step back of failed step . My failed step is not in inbox. It is either in archive or in instances.

Avatar

Employee Advisor

Is it happening with you only or your teammates are also facing the similar issue?

Please check whether admin can see that failed step in inbox or not.

Avatar

Level 3

It is happening with teammates also. 

Okay I ll check inbox once again. Thank you

Avatar

Level 3

I have unchecked handler advance of one of my process step. I started my flow and my process step got failed due to third party api that I am using is down. Since I unchecked the handler advance so workflow didn't proceed further and it is in instances only. Now I have to retry this particular step that got failed. That I am not getting idea how to do that. Because it is not in inbox. It is in instances only.

Avatar

Employee Advisor

Could you please check with your admin whether they are able to see that failed step in inbox or not.

 

Please execute below JCR SQL2 query to see failed workflow items in CRXDE -

SELECT * FROM [cq:WorkItem] AS s WHERE ISDESCENDANTNODE([/var/workflow/instances/server0]) and subType='FailureItem' and status = 'ACTIVE'

 

You will be getting response like below -

 

DEBAL_DAS_0-1650303859001.png

 

Avatar

Level 3

Hi Debal,

 

Above query gave results to me but not those results which recently got failed for me. and those are still in instances only. because, I have unchecked the handler advance from my process step. I am completing that particular step from the code if my api is successful otherwise I am not completing. And If I check handler advance in process step, when the api will fail inside of that process step, It ll proceed further and ll execute further steps because handler advance was checked.

Avatar

Level 3

Hi Debal,

 

How can I move my workflow to libs/cq/workflow/admin/console/content/failures.html

when one of my process step fails?

Avatar

Employee Advisor

Yes, here you could see I had some issue with sample workflow step and workflow execution got failed and now the failed workflow instance is available in Failure now -

 

DEBAL_DAS_0-1652282691516.png

JCR_SQL2 query to get workflow instance with ABORTED status -

SELECT * FROM [cq:Workflow] AS s WHERE ISDESCENDANTNODE([/var/workflow/instances/server0]) and status = 'ABORTED'