How to keep track of old and new path after asset is moved | Community
Skip to main content
Ankan_Ghosh
Level 3
August 20, 2024
Solved

How to keep track of old and new path after asset is moved

  • August 20, 2024
  • 1 reply
  • 1258 views

Hello, community!!

My current project has used 3rd party search provider to index the pages and documents. A scheduler runs and indexes the published documents to the 3rd party source. If a document is unpublished and is present in the 3rd party source it is deleted from the source. For all these indexing there is a scheduler that runs every midnight. 

The problem arises when someone moves a document in aem, the scheduler runs and indexes the document in the 3rd party source once again as a new entry. As the document in the old path was never unpublished, we cannot even delete it from the source. 

 

I need a solution so that whenever I move a document (asset under a certain path), I can keep track of the old and new paths. On completion of the move operation, I want to remove the old path from the source (3rd party) and index the new path. Is there a way to keep track of the paths? Can we do this with the help of the event listener or handler? 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by lukasz-m

Hi @ankan_ghosh,

You can use EventHandler together with DAM EVENT_TOPIC, which provides DAM/Asset specific events. Next you can use below properties form event to get old and new path:

  • srcAbsPath - contains information about old/original path
  • assetPath - contains information about new/destination path

Here is a code example.

package com.sample.events; import com.day.cq.dam.api.DamEvent; import org.osgi.service.component.annotations.Component; import org.osgi.service.event.Event; import org.osgi.service.event.EventConstants; import org.osgi.service.event.EventHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @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.ASSET_MOVED.equals(damEvent.getType())) { if (event.containsProperty("assetPath") && event.containsProperty("srcAbsPath")) { String oldPath = event.getProperty("srcAbsPath").toString(); String newPath = event.getProperty("assetPath").toString(); LOG.info("Old path: " + oldPath); LOG.info("New path: " + newPath); // place for some other code } } } }

Please make sure you do not put any heavy logic inside EventHandler, rather use Sling Jobs to delegate this. Heavy logic can cause an issue that EventHandler will be blacklisted an will not be run anymore.

1 reply

lukasz-m
Community Advisor
lukasz-mCommunity AdvisorAccepted solution
Community Advisor
August 20, 2024

Hi @ankan_ghosh,

You can use EventHandler together with DAM EVENT_TOPIC, which provides DAM/Asset specific events. Next you can use below properties form event to get old and new path:

  • srcAbsPath - contains information about old/original path
  • assetPath - contains information about new/destination path

Here is a code example.

package com.sample.events; import com.day.cq.dam.api.DamEvent; import org.osgi.service.component.annotations.Component; import org.osgi.service.event.Event; import org.osgi.service.event.EventConstants; import org.osgi.service.event.EventHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @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.ASSET_MOVED.equals(damEvent.getType())) { if (event.containsProperty("assetPath") && event.containsProperty("srcAbsPath")) { String oldPath = event.getProperty("srcAbsPath").toString(); String newPath = event.getProperty("assetPath").toString(); LOG.info("Old path: " + oldPath); LOG.info("New path: " + newPath); // place for some other code } } } }

Please make sure you do not put any heavy logic inside EventHandler, rather use Sling Jobs to delegate this. Heavy logic can cause an issue that EventHandler will be blacklisted an will not be run anymore.

pulkitvashisth
Community Advisor
Community Advisor
August 20, 2024

Hi @ankan_ghosh 
Above solve by @lukasz-m is apt for finding new and old paths of a moved asset/resource.

But considering your use case , as the scheduler runs every midnight :  what if the asset is moved multiple times during the day. 
Considering above solution , in which every time an asset is move -> we send a server push to 3rd party to unpublish the previous path.
1. Sending unpublished asset push in real time using EventListener will be quite an overhead. 

2. Also I think if you are reindexing at the end of the day but publishing content on every Asset Move Listener might create data discrepancy at third party.

So in addition to above logic what you can do is for each move operation you can store oldpath and newpath at a node under var
Like for eg. at /var/movedAssets
you can store such mapping
{
"movedAssets": [
{"oldPath": "/content/dam/old/path1.jpg", "newPath": "/content/dam/new/path1.jpg"},
{"oldPath": "/content/dam/old/path2.jpg", "newPath": "/content/dam/new/path2.jpg"},

and so on..
]
}
This mapping you can update using above EventListener for each asset.


Then in your scheduler you can modify the logic to pick mapping from above node and unpublish all your oldpaths and reindex newPaths.


At the end of your scheduler job, you can clear the above logs from the node as they are no longer needed.



konstantyn_diachenko
Community Advisor
Community Advisor
August 21, 2024

I would add that these movements can be stored in the asset metadata as movements multi-value property. So, no need to worry about permissions under var for the service. 

Kostiantyn Diachenko, Community Advisor, Certified Senior AEM Developer, creator of free AEM VLT Tool, maintainer of AEM Tools plugin.