< Return to Feed
David Bernstein - 07.18.2019

Creating an AEM Event Listener

While creating a service in AEM that reads an asset into the JCR, I ran into an issue with triggering the service when the file was updated. The way I chose to do this was by using this OSGI event handler. The event handler works by listening to messages that are sent following the publish-subscribe pattern. In this case, AEM was sending messages and I wanted to catch the messages that said my file was updated.

When assets in AEM are updated an event is published that has a topic of com/day/cq/dam. This can be used by the event handler to specify what types of messages to listen for. Looking at the list of events types that are supported by assets, I first chose to listen for METADATA_UPDATED. This ended up firing my function twice and potentially costing the client double in paid API calls. To try to figure out why this was happening I opened the events console. This showed me all of the events that were sent when an asset was updated. The following screenshot shows the order of all event types I could use:

Screenshot of AEM showing order of all event types.

The console confirmed the issue is with the METADATA_UPDATED event type. It also showed an event type I didn't see on the asset api. That's because it was added in AEM 6.3 and the first documentation I found was for 6.2. Switching to the list of event types for 6.3, I found the better suited option to listen for. The DAM_UPDATE_ASSET_WORKFLOW_COMPLETED event type represents completion of DAM update asset workflow. Using the following code everything was working as intended.

@Designate(ocd = Configuration.class)
@Component(
        configurationPid = "com.examples.cq.sites.example.core.servlets.UpdateAssetListener",
        service = EventHandler.class,
        immediate = true,
        enabled = true,
        property = {
            EventConstants.EVENT_TOPIC + "=" + DamEvent.EVENT_TOPIC
        }
)
public class UpdateAssetListener implements EventHandler {

    private String filePath;

    @Activate
    protected void activate(Configuration config) {
        filePath = filePath = config.filePath();
    }

    @Reference
    HandleAssetService handleAsset;

    @Override
    public void handleEvent(Event event) {
        Object type = event.getProperty("type");

        if (type == DamEvent.Type.DAM_UPDATE_ASSET_WORKFLOW_COMPLETED) {
            String path = DamEvent.fromEvent(event).getAssetPath();
            if (path.equals(filePath)) {
                handleAsset.loadAssetData(filePath);
            }
        }
    }
},/pre>

This event handler listens for anything sent from assets. When events from an asset trigger the handleEvent method, they are checked to be of the type DAM_UPDATE_ASSET_WORKFLOW_COMPLETED. Then the path of the DamEvent is checked against the expected path of the target file. This helps to ensure only the correct file will be passed into our service.