Unexpected behaviour when using com.adobe.granite.workflow.exec.Route API
Greetings,
I would like to create conditional loop behavior in my AEM workflow. I have found two possible implementations in the documentation, but am having trouble getting either to work.
The first method would be to use the built in 'GoTo' step. However, I want the loop to execute conditionally based upon the value of a variable that must be calculated on the server. My idea was to generate this value in a custom workflow process immediately before the 'GoTo' step and then pass the value to the 'GoTo'. However, I have been unable to find a way to successfully pass the variable such that it will be visible in the 'GoTo' step's ECMA script. Please let me know if there is a way to do this.
The second method is to use the com.adobe.granite.workflow.exec.Route API. When attempting to use this however, the workflow steps do no execute in the order I expected.
Consider the following workflow diagram:

Under my test case I expect the order of execution to be:
1. Flow Start
2. Publishing Gatekeeper
3. References Exist
4. Or Split
5. Broken Links Email to Unpublish Initiator
6.Continue to Unpublish? (Participant Step: await user action)
7. Or Split
8. Reassign to Publish (initiate loop: goto 'Continue to Unpublish')
6. Continue to Unpublish?
7. Or Split
8. Reassign to Publish (now break out of loop and continue normally)
9. Email Authors About Broken Links
10. Or Split
11. Deactivate Page
The Routes API is used in the custom workflow process 'Reassign to Publish' to send the workflow back to the step 'Continue to Unpublish?' (which is a Participant Step). In the logs I can see that the Routes API does trigger the 'Continue to Unpublish?' workflow to execute again. However, what is odd is that the 'Email Authors About Broken Links' also executes as if the reroute never occurred. I would have expected it to wait until 'Reassign to Publish' executed for the second time (and breaks out of the loop). I have been sure to disable 'Handler Advance' on the 'Reassign to Publish' step.

Here is the source code for the 'Reassign to Publish' step. Please let me know if you have any thoughts. Thank you.
@8220494(
service=WorkflowProcess.class,
immediate = true,
property= {
"service.description=Reassign to publishers and return to 'Continue to Unpublish?' step",
"service.vendor=TNC",
"process.label=Reassign to Publishers and Retry"
})
public class ReassignToPublishers implements WorkflowProcess {
private static final Logger LOG = LoggerFactory.getLogger(ReassignToPublishers.class);
@3214626
private TNCUtilities tncUtilities;
@9944223
public void execute(WorkItem workItem, WorkflowSession wfSession, MetaDataMap metaDataMap)
throws WorkflowException {
String contentPath = workItem.getWorkflowData().getPayload().toString();
try (ResourceResolver resolver = tncUtilities.getWriteResourceResolver()) {
String initiator = workItem.getWorkflow().getInitiator();
String publisher = workItem.getWorkflow().getMetaDataMap().get("publisher", String.class);
LOG.info("Immediately before initiatorCanPublish call.");
LOG.info("PUBLISHER: {}, INITIATOR: {}", publisher, initiator);
if (publisher == null
/*&& !WorkflowHelper.initiatorCanPublish(initiator, contentPath, resolver)*/) {
LOG.info("Inside initiatorCanPublish()");
//UserManager userManager = resolver.adaptTo(UserManager.class);
publisher = "admin";
// WorkflowHelper.getPublisher(session, userManager, contentPath);
LOG.info("Desginate publisher {} as next assignee", publisher);
workItem.getWorkflow().getMetaDataMap().put("publisher", publisher);
LOG.info("GoTo 'Continue To Unpublish?' step.");
List<Route> routes = wfSession.getBackRoutes(workItem, false);
Route specificRoute = null;
for (Route route : routes) {
LOG.info("ROUTE NAME: {}", route.getName());
if (route.getName().equals("Continue to Unpublish?")) {
specificRoute = route;
break;
}
}
if (specificRoute != null) {
LOG.info("Warping to: {}", specificRoute.getName());
wfSession.complete(workItem, specificRoute);
}
} else {
String assignee = publisher != null ? publisher : initiator;
LOG.info("Assignee: {} has publish rights for content path: {}. No reassignment needed.",
assignee, contentPath);
}
} catch (Exception re) {
LOG.error("An error occurred while reassigning to publisher: {}", contentPath, re);
}
LOG.info("Exiting ReassignToPublishers workflow step.");
}
}