Expand my Community achievements bar.

SOLVED

Is it Possible to Change the Payload of Workflow

Avatar

Level 4

Hello.

I created a Workflow that launches in response to an Asset upload. This workflow renames the uploaded asset. However, this changes the payload (I.e. the original asset/path no longer exists). Thus I am running into issues when adding this step to the OOB "DAM Update Asset". Specifically, the Steps in that Workflow still try to use the "old" JCR path rather than the renamed one. This understandably generates an error.

 

I assume I would be able to call the OOB DAM Update Asset workflow from mine; however, Adobe advises against this and instead recommends updating the payload. However, I see no details on how one updates the payload. That is,I do not see how to update the Payload using any of the objects accessible from the ECMA script.

 

How can this be achieved?

For reference, here is my custom script:

var workflowData = workItem.getWorkflowData();
var pType = workflowData.getPayloadType();
if (workflowData.getPayloadType() == "JCR_PATH") {
    var path = workflowData.getPayload().toString();
    var parentPath = path.replace('/jcr:content/renditions/original', '');
    if (workflowSession.getSession().itemExists(parentPath)) { 
        var replaceChars = new RegExp(" ", "g");
        var node =  workflowSession.getSession().getItem(path+"/jcr:content");
        var pNode = workflowSession.getSession().getItem(parentPath);
        var name = pNode.getPath();
        var newName = name.replace(replaceChars, "_");
        if(name != newName) {
         workflowSession.getSession().move(name, newName);
        pNode.save();
        }
    } else {
        log.warn("Item does not exist: " + path);
    }
}
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

I am afraid that what you would like to achieve is not possible using Workflow Launcher, or could work not deterministic (you can try to use launcher for dam:Asset node created, but most likely this will not mean DAM Update Asset workflow is completed). In terms of event handler you do not have to run workflow via event handler, if rename is the only operation, you can write simple event handler and job consumer to do that. You will get path to asset from event, and the code could be very simple.

@component(
        immediate = true,
        service = EventHandler.class,
        property = EventConstants.EVENT_TOPIC + "=" + DamEvent.EVENT_TOPIC)
public class DAMEventHandler implements EventHandler {

    private static final Logger LOG = LoggerFactory.getLogger(DAMEventHandler.class);

    @Override
    public void handleEvent(Event event) {
        DamEvent damEvent = DamEvent.fromEvent(event);
        if (DamEvent.Type.DAM_UPDATE_ASSET_WORKFLOW_COMPLETED.equals(damEvent.getType())) {
            LOG.info("Processed asset path: " + damEvent.getAssetPath());

            // place for your code
        }
    }
}

and more complex example: https://github.com/wcm-io/io.wcm.handler.media/blob/1.5.2/src/main/java/io/wcm/handler/mediasource/d...

If you still want to use workflow for rename, you can alternatively use Container step to run your custom workflow from DAM Update Asset. Of course you will have to add this step to DAM Update Asset but then you will need to create your own copy of DAM Update Asset to set modification. In that case simpler will be to do the rename as the last step, and delegating this activity to separate workflow will not bring any benefit.

View solution in original post

3 Replies

Avatar

Community Advisor

Hi @KMarchewa,

Changing payload is possible but it is not recommended to be done. The main reason is a fact that many mechanisms using it and some of them can cache original payload path value.

Here is a sample ECMA script - for education purposes.

 

var workflow = workItem.getWorkflow();
if (workflow != null) {
	var path = workflow.getId();
    if (path != null) {
		log.info("Changing payload...");
        var jcrsession = workflowSession.getSession();
        if (jcrsession != null && jcrsession.nodeExists(path + "/data/payload")) {
			var payloadNode = jcrsession.getNode(path + "/data/payload");
            // 8 = javax.jcr.PropertyType.PATH
			payloadNode.setProperty("path", "/content/new/payload/path", 8);
            jcrsession.save();
        }
    }
}

 

In general payload information is stored under /data/payload of each workflow instance. I do not think there is dedicated api to change payload value, so in above code JCR api is used.

In your case I would try something different: OOTB DAM Update Asset workflow sent following event DamEvent.Type.DAM_UPDATE_ASSET_WORKFLOW_COMPLETED. You can listen on that event and trigger rename action base on it. This will guarantee that DAM Update Asset is completed, and payload modification is not needed.

Avatar

Level 4

@lukasz-m  Thanks much for the response. Listening for the event indeed sounds like a much better approach.

However, my question is: is there a way to listener for this Event using a Workflow Launchers or similar? For example, does it create a particular Node type or property I can watch for using a Launcher?

 

I see how to do this programmatically based on the following: https://experienceleague.adobe.com/docs/experience-manager-64/developing/extending-aem/extending-wor...s

but would like to avoid adding such to our code base if possible?

Thanks so much!

Avatar

Correct answer by
Community Advisor

I am afraid that what you would like to achieve is not possible using Workflow Launcher, or could work not deterministic (you can try to use launcher for dam:Asset node created, but most likely this will not mean DAM Update Asset workflow is completed). In terms of event handler you do not have to run workflow via event handler, if rename is the only operation, you can write simple event handler and job consumer to do that. You will get path to asset from event, and the code could be very simple.

@component(
        immediate = true,
        service = EventHandler.class,
        property = EventConstants.EVENT_TOPIC + "=" + DamEvent.EVENT_TOPIC)
public class DAMEventHandler implements EventHandler {

    private static final Logger LOG = LoggerFactory.getLogger(DAMEventHandler.class);

    @Override
    public void handleEvent(Event event) {
        DamEvent damEvent = DamEvent.fromEvent(event);
        if (DamEvent.Type.DAM_UPDATE_ASSET_WORKFLOW_COMPLETED.equals(damEvent.getType())) {
            LOG.info("Processed asset path: " + damEvent.getAssetPath());

            // place for your code
        }
    }
}

and more complex example: https://github.com/wcm-io/io.wcm.handler.media/blob/1.5.2/src/main/java/io/wcm/handler/mediasource/d...

If you still want to use workflow for rename, you can alternatively use Container step to run your custom workflow from DAM Update Asset. Of course you will have to add this step to DAM Update Asset but then you will need to create your own copy of DAM Update Asset to set modification. In that case simpler will be to do the rename as the last step, and delegating this activity to separate workflow will not bring any benefit.