Expand my Community achievements bar.

SOLVED

Moving assets to PIM system - HTTP API the correct choice

Avatar

Level 2

I am creating an integration between the AEM system and our PIM system.  What I want to accomplish is I want to be able to "monitor" a particular folder structure and if an asset is moved to this folder or any subfolders I want to download it and upload it into our PIM system.  I need basically two capabilities:

1. A way to do a quick query to say are there any assets (other than folders) in a given folder

2. Download any of those assets

 

I have been through the documentation and it seems the HTTP Asset API seems like the most logical choice but I don't see an easy way to achieve #1 without manually iterating the folder structure I want to monitor and do a list contents call checking for assets.  This does not seem like a good choice.  Is there an easier way to do such a query?  Is the Http Assets API not the way to do it?

 

I should add that this is AEM 6.5 on premise not the cloud service.

 

Thanks.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi, 

There are multiple ways to achieve what you are trying to do. I would suggest discarding the query approach and instead using a Workflow Launcher that triggers a Workflow upon a new asset being added or created. This will initiate a custom workflow that provides you with the asset path, allowing for various possibilities. You could directly POST from the workflow to your PIM, or you could implement an external process responsible for posting to the PIM, which the workflow could invoke.

 

You can read more about WF Launchers here: https://experienceleague.adobe.com/en/docs/experience-manager-65/content/sites/administering/operati...

https://medium.com/@toimrank/aem-launcher-3358aef72d8c

And here about custom step workflows: https://medium.com/@toimrank/aem-custom-workflow-process-step-56e176f8f067 

https://experienceleague.adobe.com/en/docs/experience-manager-learn/forms/adaptive-forms/custom-proc...

 

Hope this helps.



Esteban Bustamante

View solution in original post

11 Replies

Avatar

Correct answer by
Community Advisor

Hi, 

There are multiple ways to achieve what you are trying to do. I would suggest discarding the query approach and instead using a Workflow Launcher that triggers a Workflow upon a new asset being added or created. This will initiate a custom workflow that provides you with the asset path, allowing for various possibilities. You could directly POST from the workflow to your PIM, or you could implement an external process responsible for posting to the PIM, which the workflow could invoke.

 

You can read more about WF Launchers here: https://experienceleague.adobe.com/en/docs/experience-manager-65/content/sites/administering/operati...

https://medium.com/@toimrank/aem-launcher-3358aef72d8c

And here about custom step workflows: https://medium.com/@toimrank/aem-custom-workflow-process-step-56e176f8f067 

https://experienceleague.adobe.com/en/docs/experience-manager-learn/forms/adaptive-forms/custom-proc...

 

Hope this helps.



Esteban Bustamante

Thank you for your suggestions!  I will look into these approaches and see if this will work for us.

Ok, I have been knee deep in this and I think this is going to work for us but I am struggling with one thing.  The API requires authentication via OAuth2 using the password credential/client secret flow.  I'm trying to figure out the best way to do this in the workflow process and I came across this:

 

https://experienceleague.adobe.com/en/docs/experience-platform/destinations/destination-sdk/function...

 

Is this functionality that can be used from a custom step?

Avatar

Community Advisor

Do you mean the PIM API requires authentication? If so, that’s not a problem. You just need to add the "authentication" header with the access token you obtain from your PIM system when making your REST call from Java (custom workflow step). The documentation you shared isn’t useful for this case.

 

It would help if you looked at something like this:

https://forum.jmix.io/t/how-to-authenticate-in-rest-from-java-code/1525 

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/unable-to-generate-access-... 



Esteban Bustamante

Thanks Esteban!  I am not a java expert so I wasn't sure what libraries we are allowed to use in the custom workflow step.  So one of the examples used spring so I'm assuming this is ok to use to make the http calls.

Avatar

Community Advisor

Hey, no worries. The example with Spring might not be ideal. Let me give you a more detailed answer, in a custom workflow step, you are working in a Java environment, so any Java code can be used. You can refer to these resources, which outline the preferred way to make a REST call within AEM. Ideally, you should create an OSGi service to perform the REST call and use that service from your custom workflow step. The only thing you would add is the authorization header in your REST call

 

Check these examples:

https://sourcedcode.com/blog/aem/handling-http-requests-httpclient-in-aem 

https://www.theaemmaven.com/post/testing-java-http-clients-in-aem 



Esteban Bustamante

Avatar

Level 2

Right.  So I would create a service that get's the access token.  I would call that service from the workflow step and then use that token and set it as the bearer token when making any calls to the API.

I am 99% out of the woods here and I tried to resist asking this question but I'm having a hard time finding the correct answer anywhere.

 

I have everything working but when I receive the payload I cannot get the image/document from the payload node.  It just says that nothing exists.  Here is the current way I am trying to get it:

String assetPath = workItem.getWorkflowData().getPayload().toString();
			ResourceResolver resourceResolver = wfSession.adaptTo(ResourceResolver.class);
			Resource payloadResource = resourceResolver.getResource(assetPath);
			Node payloadNode = payloadResource.adaptTo(Node.class);
...
builder.addBinaryBody("file", payload.getProperty("jcr:data").getBinary().getStream());

The error I get is that jcr:data doesn't exist.

Here is the asset

ChristopherHo5_0-1724444606264.png

Any idea what could be the problem?

Avatar

Level 2

I also just tried this and it doesn't work either:

if (payload != null && payload.hasNode("jcr:content")) {
                Node contentNode = payload.getNode("jcr:content");
                if (contentNode.hasProperty("jcr:data")) {
                    dataStream = contentNode.getProperty("jcr:data").getBinary().getStream();
                }
            }

Avatar

Level 2

This doesn't work either but I can see it on the payload node:

 

InputStream dataStream = null;
            log.info("Payload: " + payload.toString());
            if (payload != null && payload.hasProperty("jcr:content")) {
                Property contentproperty = payload.getProperty("jcr:content");
                /*if (contentNode.hasProperty("jcr:data")) {
                    dataStrseam = contenstNode.getProperty("jcr:data").getBinary().getStream();
                }*/
                dataStream = contentproperty.getBinary().getStream();
            }

 

Yet you can see it in the log:

Payload: Node[NodeDelegate{tree=/content/dam/pim/60057/confused.jpg: { jcr:primaryType = dam:Asset, jcr:mixinTypes = [mix:referenceable], jcr:createdBy = admin, jcr:created = 2024-08-22T17:25:27.256-06:00, jcr:uuid = 5562b3f9-6133-488c-b2d6-d5806be6063e, jcr:content = { ... }}}]

I'm kind of at a loss for ideas at this point. 

Avatar

Level 2

This seems to have worked for anyone else struggling with this:

String assetPath = workItem.getWorkflowData().getPayload().toString();
			ResourceResolver resourceResolver = wfSession.adaptTo(ResourceResolver.class);
			Resource payloadResource = resourceResolver.getResource(assetPath);
			Asset payload = payloadResource.adaptTo(Asset.class);
if (payload != null) {
            	log.info("Payload exists as an asset");
                dataStream = payload.getOriginal().getStream();
            }