Multiple paths handling in EventHandler not working | Community
Skip to main content
thatsmeadarsh
October 7, 2021
Solved

Multiple paths handling in EventHandler not working

  • October 7, 2021
  • 3 replies
  • 6508 views

I need to get the events while the property 'jcr:lastModified' is either added or modified. Also I only need to watch certain paths. I tried to add properties like this. I also checked the event console http://localhost:4502/system/console/events where I couldn't find my class. The debugger is also not reaching to the handleEvent method. Is this the correct way to do this.

 

@8220494(immediate = true, service = EventHandler.class, property = {
Constants.SERVICE_DESCRIPTION + "= This event handler listens the events on asset addition/modification",
EventConstants.EVENT_TOPIC + "=org/apache/sling/api/resource/Resource/ADDED",
EventConstants.EVENT_TOPIC + "=org/apache/sling/api/resource/Resource/CHANGED",
EventConstants.EVENT_FILTER + "(&" + "(|(path=/content/dam/custom-path1/*/jcr:content)(path=/content/dam/custom-path2/*/jcr:content)) (|("
+ SlingConstants.PROPERTY_CHANGED_ATTRIBUTES + "=*jcr:lastModified) " + "(" + ResourceChangeListener.CHANGES
+ "=*jcr:lastModified)))" })
public class PreviewS3AssetEventHandler implements EventHandler {

@9944223
public void handleEvent(Event event) {
String event1 = event.getTopic();
String event2 = event1;

}

}

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 Vijayalakshmi_S

Hi @thatsmeadarsh,

Since we are looking for property change/add event on a Resource, we can make use of specific Listener named "ResourceChangeListener"https://sling.apache.org/apidocs/sling9/org/apache/sling/api/resource/observation/ResourceChangeListener.html

Sample snippet : (tried and works in my local - AEM 6.5.0)

Have used the PATHS as is without pattern. Glob pattern is allowed, check the description and use per your need - https://sling.apache.org/apidocs/sling9/org/apache/sling/api/resource/observation/ResourceChangeListener.html#PATHS

package com.aem.demoproject.core.listeners;

import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

@Component(service = ResourceChangeListener.class, immediate = true, property = {
        ResourceChangeListener.PATHS + "=/content/dam/demo",
        ResourceChangeListener.PATHS + "=/content/dam/we-retail/en/features",
        ResourceChangeListener.CHANGES + "=CHANGED",
        ResourceChangeListener.CHANGES + "=ADDED",
        ResourceChangeListener.PROPERTY_NAMES_HINT + "=jcr:lastModified"
})
public class SampleResourceChangeListener implements ResourceChangeListener {

    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    @Override
    public void onChange(List<ResourceChange> list) {
        LOG.info("On add/change of jcr:lastModified");
    }
}

3 replies

Vijayalakshmi_S
Vijayalakshmi_SAccepted solution
October 7, 2021

Hi @thatsmeadarsh,

Since we are looking for property change/add event on a Resource, we can make use of specific Listener named "ResourceChangeListener"https://sling.apache.org/apidocs/sling9/org/apache/sling/api/resource/observation/ResourceChangeListener.html

Sample snippet : (tried and works in my local - AEM 6.5.0)

Have used the PATHS as is without pattern. Glob pattern is allowed, check the description and use per your need - https://sling.apache.org/apidocs/sling9/org/apache/sling/api/resource/observation/ResourceChangeListener.html#PATHS

package com.aem.demoproject.core.listeners;

import org.apache.sling.api.resource.observation.ResourceChange;
import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

@Component(service = ResourceChangeListener.class, immediate = true, property = {
        ResourceChangeListener.PATHS + "=/content/dam/demo",
        ResourceChangeListener.PATHS + "=/content/dam/we-retail/en/features",
        ResourceChangeListener.CHANGES + "=CHANGED",
        ResourceChangeListener.CHANGES + "=ADDED",
        ResourceChangeListener.PROPERTY_NAMES_HINT + "=jcr:lastModified"
})
public class SampleResourceChangeListener implements ResourceChangeListener {

    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    @Override
    public void onChange(List<ResourceChange> list) {
        LOG.info("On add/change of jcr:lastModified");
    }
}
thatsmeadarsh
October 7, 2021

Thanks @vijayalakshmi_s  and @arunpatidar  for your response. Resource change listener seems to be more appropriate option for me. However I am wondering if it is possible to inject the path properties from an OSGI configuration, cause we are looking for dynamic path listener.

thatsmeadarsh
October 8, 2021

The type of thePATHS property must either be String, or a String array and

The value for annotation attribute Component.property must be a constant expression.

 

So you can't pass dynamic value here.


Thanks @arunpatidar  for the clarification. I was thinking maybe some factory service injecting OSGi config properties as constructor would work. 

arunpatidar
Community Advisor
Community Advisor
October 7, 2021

Hi,

You can combine the path in single rule e.g.

path=/content/dam/myproj/(folder1|folder2)/*/jcr:content

EventConstants.EVENT_FILTER + "(&" + "(|(path=/content/dam/myproj/(folder1|folder2)/*/jcr:content)(|("
+ SlingConstants.PROPERTY_CHANGED_ATTRIBUTES + "=*jcr:lastModified) " + "(" + ResourceChangeListener.CHANGES
+ "=*jcr:lastModified)))" })

 

Arun Patidar
Adobe Employee
September 26, 2023

In my case adding multiple paths worked with below syntax

 

@Component(service = EventHandler.class, immediate = true, property = { EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC, EventConstants.EVENT_FILTER + "=(|(paths=/content/projectname/*)(paths=/content/dam/projectname/*))" }) @ServiceDescription("Listener to listen on replication action in the resource tree") @Designate(ocd = ReplicationListener.SolrSearchPropertiesConfiguration.class) public class ReplicationListener implements EventHandler {

  Especially when we are working on Sling events like Activate or deactivate, the above code will be convenient because you have to listen to activate or deactivate events on specific paths under your project-related folders only in Assets and Sites. Something similar was even suggested by @arunpatidar  in an answer here.