So I have facility in my AEM code to import an comma-delimited file and turn that into pages (cq:page type) within AEM.
The flow goes like this: browser => AJAX call => SlingServlet => Workflow => SlingServer => browser
I want to pass a string from the Workflow back to my SlingServlet.
@SlingServlet(paths = "/services/courses/start-import", methods = "POST", metatype = true, label = "my-label-here")
public class myImportServlet extends SlingAllMethodsServlet {
This is the main body of the servlet
protected String startWorkflow(SlingHttpServletRequest request, WorkflowDescr workflowDescr) throws WorkflowException, ParseException {
ResourceResolver resourceResolver = request.getResourceResolver();
Session session = resourceResolver.adaptTo(Session.class);
String message = "my message here";
WorkflowSession wfSession = workflowService.getWorkflowSession(session);
WorkflowModel model = wfSession.getModel(workflowDescr.getModel());
WorkflowData data = wfSession.newWorkflowData("JCR_PATH", request.getRequestPathInfo().getResourcePath());
data.getMetaDataMap().put(AbsoluteTimeoutHandler.ABS_TIME, new Date().getTime());
Workflow test = wfSession.startWorkflow(model, data);
return message;
}
I searched the net but didn't see anything useful. Thank you.
Solved! Go to Solution.
Hi,
let's have a look at the details. You mention that the interaction should look like this:
browser => AJAX call => SlingServlet => Workflow => SlingServlet => browser
(I corrected the second mention of "SlingServlet". "SlingServer" does not make any sense here.)
This is an synchronous process, so all parts should be well-suited to work in a synchronous fashion. But the workflow engine triggers workflows asynchronously, and the workflows are processed asynchronous. You cannot include an async process in a full synchronous interaction pattern, unless you are willing to wait until the async eventually finishes. In your case I don't think that you are willing to wait minutes, if not hours (depending on various factors).
You need to make all the functionality async. That means, that you should extract the logic from the workflow steps and make it usable as standalone services. And then a workflow step can call this functionality as well.
HTH,
Jörg
Are you using workflow to create the page?
I skeptical if you can return the response from workflow to browser via sling servlet
Views
Replies
Total Likes
Hi,
You should be able to perform these in your current format. But, this does feels rather long route to a short and straight forward task.
To respond back simply tell response to print the string e.g.
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
response.getOutputStream().print(startWorkflow(request, new WorkflowDescr(yourInitVarsHere)));
You might require to either change your architecture or re-think how to solve this, to follow standard AEM patterns for this task.
Regards,
Peter
Views
Replies
Total Likes
Hi,
You should be able to perform these in your current format. But, this does feels rather long route to a short and straight forward task.
To respond back simply tell response to print the string e.g.
/**
* Launch workflow to create new page and print workflow ID back
*/
@SlingServlet(paths = "/services/courses/start-import", methods = "POST", metatype = true, label = "my-label-here")
public class myImportServlet extends SlingAllMethodsServlet {
@Reference
private WorkflowService workflowService;
@Reference
private ResourceResolverFactory resolverFactory;
private static final Logger LOG = LoggerFactory.getLogger(myImportServlet.class);
public String startWorkflow(String workflowName, String workflowContent) {
try
{
//Invoke the adaptTo method to create a Session
ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
Session session = resourceResolver.adaptTo(Session.class);
//Create a workflow session
WorkflowSession wfSession = workflowService.getWorkflowSession(session);
// Get the workflow model
WorkflowModel wfModel = wfSession.getModel(workflowName);
// Get the workflow data
// The first param in the newWorkflowData method 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", workflowContent);
// Run the Workflow.
Workflow workflow = wfSession.startWorkflow(wfModel, wfData);
return workflow.getId();
}
catch(Exception e)
{
LOG.error("Unable to start workflow due to:", e);
}
return null;
}
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
// Print the data form workflow back to the page
response.getOutputStream().print(startWorkflow("createNewPage", "pagename"));
response.getOutputStream().flush();
response.setStatus(200);
response.setContentType(String.valueOf(TEXT_PLAIN));
}
}
You might require to either change your architecture or re-think how to solve this, to follow standard AEM patterns for this task.
P.S. naming your classes with lower case is unusual in Java.
Regards,
Peter
Views
Replies
Total Likes
hello. I've looked at the sample code and It doesn't really tell me how to return a string from my workflow back to the servlet.
for reference, this is my entry point in my workflow. (can't edit original post)
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaDataMap) throws WorkflowException {
try {
String string1 = "temp message";
log.info("Start Course Import Service");
} catch (Exception e) {
log.error("Error in Course Import Service", e);
}
}
I just want to return the contents of the variable string1. Thanks
Views
Replies
Total Likes
I am not sure you can call into a custom Workflow step like you can a Service. I would look at Saving the String value in a JCR node by performing a JCR write operation from the workflow step and then reading it from the Sling Servlet.
Views
Replies
Total Likes
Hi,
let's have a look at the details. You mention that the interaction should look like this:
browser => AJAX call => SlingServlet => Workflow => SlingServlet => browser
(I corrected the second mention of "SlingServlet". "SlingServer" does not make any sense here.)
This is an synchronous process, so all parts should be well-suited to work in a synchronous fashion. But the workflow engine triggers workflows asynchronously, and the workflows are processed asynchronous. You cannot include an async process in a full synchronous interaction pattern, unless you are willing to wait until the async eventually finishes. In your case I don't think that you are willing to wait minutes, if not hours (depending on various factors).
You need to make all the functionality async. That means, that you should extract the logic from the workflow steps and make it usable as standalone services. And then a workflow step can call this functionality as well.
HTH,
Jörg
Views
Likes
Replies
Views
Likes
Replies