Expand my Community achievements bar.

July 31st AEM Gems Webinar: Elevate your AEM development to master the integration of private GitHub repositories within AEM Cloud Manager.
SOLVED

Events handlers are not with Page Events when i try to listen on specific paths

Avatar

Level 2

When i try to add event filters property for page events .Event handlers are not able to listen to the page events ,But the same code is working with different event topics like resource added ,remove ,changed .When i remove the event filters property its working fine for page events also like page created ,modified ,deleted activities.

The sample code snippet 

@Component(service = .class,
immediate = true,
property = {
EventConstants.EVENT_TOPIC +"=" + PageEvent.EVENT_TOPIC,
EventConstants.EVENT_FILTER + "=(path=/content/trainingproject/en_us/*)"
}
)
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Is there any possibility to listen events in certain paths with jcr event listener. If it is possible then I will use jcr event listener.  Yes, you can

 

public void addEventListener(EventListener listener,
                             int eventTypes,
                             java.lang.String absPath,
                             boolean isDeep,
                             java.lang.String[] uuid,
                             java.lang.String[] nodeTypeName,
                             boolean noLocal)
                      throws RepositoryException

 

Adds an event listener that listens for the specified eventTypes (a combination of one or more event types encoded as a bit mask value).

The set of events can be filtered by specifying restrictions based on characteristics of the node associated with the event. In the case of event types NODE_ADDED and NODE_REMOVED, the node associated with an event is the node at (or formerly at) the path returned by Event.getPath. In the case of event types PROPERTY_ADDED, PROPERTY_REMOVED and PROPERTY_CHANGED, the node associated with an event is the parent node of the property at (or formerly at) the path returned by Event.getPath:

  • absPath, isDeep: Only events whose associated node is at absPath (or within its subtree, if isDeep is true) will be received. It is permissible to register a listener for a path where no node currently exists.
  • uuid: Only events whose associated node has one of the UUIDs in this list will be received. If his parameter is null then no UUID-related restriction is placed on events received.
  • nodeTypeName: Only events whose associated node has one of the node types (or a subtype of one of the node types) in this list will be received. If his parameter is null then no node type-related restriction is placed on events received.

The restrictions are "ANDed" together. In other words, for a particular node to be "listened to" it must meet all the restrictions.

Additionally, if noLocal is true, then events generated by the session through which the listener was registered are ignored. Otherwise, they are not ignored.

The filters of an already-registered EventListener can be changed at runtime by re-registering the same EventListener object (i.e. the same actual Java object) with a new set of filter arguments. The implementation must ensure that no events are lost during the changeover.

 

Parameters:
listener - an EventListener object.
eventTypes - A combination of one or more event type constants encoded as a bitmask.
absPath - an absolute path.
isDeep - a boolean.
uuid - array of UUIDs.
nodeTypeName - array of node type names.
noLocal - a boolean.
Throws:
RepositoryException - If an error occurs.

 

 



Arun Patidar

View solution in original post

15 Replies

Avatar

Level 2

Sorry i forgot to add EventHandler.class in the above snippet .its there in my actual code.

Avatar

Level 10

@RaviK1 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/ResourceChangeList...

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/ResourceChangeList...

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/trainingproject/en_us/*",
        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");
    }
}

 

Reference: https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/multiple-paths-handling-in...

Avatar

Level 2

This will work .But i want to  listen pageevent and then we are making changes to jcr:content for that Page .this resource listener will listen if we make any changes in the page so we can't listen page creation events with this one

Avatar

Level 8

Hi @RaviK1 

 

Will this help in your case?

@Component(service = EventHandler.class,
        immediate = true,
        property = {
                EventConstants.EVENT_FILTER + "=(|(paths=/content/abc/mobile/*)(paths=/content/xyz/desktop/*))",
                EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC,
        })
public class CustomReplicationEventHandler implements EventHandler {


		public void handleEvent(final Event event) {..}
		
}

 

Avatar

Level 2

Hi Mahesh,

                    I tried with above solution as well. still it's not working with event filters. May I know what is the right way to add event filters property for page event topics. The above solution will work for replication events. 

Avatar

Level 2

Hi @arunpatidar,

                              This solution working with resource changes but this one is not working for page events. Is it like that for page events we can't use event filters property. The solution you provided is for org/apache/sling/api/resource/*.but here I am trying to listen page events like com/day/cq/wcm/core/page. Have any tried with this one? By adding event filters

Avatar

Community Advisor

Hi @RaviK1 
What user actions/events are you trying to target?

 

Can you check the events at http://localhost:4502/system/console/events ?
For example, you author a component, following are the 2 events out of 16

arunpatidar_0-1709638110866.png

 



Arun Patidar

Avatar

Level 2
  • I am targeting for page creation events. when a page is created we are adding a property to that respective page. But if I use resource listener or resource events I can't get the exact page creation events because if we added a component in any another page it will take it as a resource added. So we can 't use resource  related events here. 

Avatar

Community Advisor

Hi @RaviK1 
In that case below event is also performing very bad, because it will be executing with every page related event

PageEvent.EVENT_TOPIC

 you can go with JCR event, there you can restrict events with type as well.

https://github.com/arunpatidar02/aem63app-repo/blob/master/java/SampleJCREvent.java 



Arun Patidar

Avatar

Level 2

It will execute every page related event but we can filter page creation events from page modifications object but the real problem it will listen to all the pages. We have nearly 5000+pages in prod. If that is the case it will trigger on every page related events. Is there any possibility to listen events in certain paths with jcr event listener. If it is possible then I will use jcr event listener. 

Avatar

Correct answer by
Community Advisor

Is there any possibility to listen events in certain paths with jcr event listener. If it is possible then I will use jcr event listener.  Yes, you can

 

public void addEventListener(EventListener listener,
                             int eventTypes,
                             java.lang.String absPath,
                             boolean isDeep,
                             java.lang.String[] uuid,
                             java.lang.String[] nodeTypeName,
                             boolean noLocal)
                      throws RepositoryException

 

Adds an event listener that listens for the specified eventTypes (a combination of one or more event types encoded as a bit mask value).

The set of events can be filtered by specifying restrictions based on characteristics of the node associated with the event. In the case of event types NODE_ADDED and NODE_REMOVED, the node associated with an event is the node at (or formerly at) the path returned by Event.getPath. In the case of event types PROPERTY_ADDED, PROPERTY_REMOVED and PROPERTY_CHANGED, the node associated with an event is the parent node of the property at (or formerly at) the path returned by Event.getPath:

  • absPath, isDeep: Only events whose associated node is at absPath (or within its subtree, if isDeep is true) will be received. It is permissible to register a listener for a path where no node currently exists.
  • uuid: Only events whose associated node has one of the UUIDs in this list will be received. If his parameter is null then no UUID-related restriction is placed on events received.
  • nodeTypeName: Only events whose associated node has one of the node types (or a subtype of one of the node types) in this list will be received. If his parameter is null then no node type-related restriction is placed on events received.

The restrictions are "ANDed" together. In other words, for a particular node to be "listened to" it must meet all the restrictions.

Additionally, if noLocal is true, then events generated by the session through which the listener was registered are ignored. Otherwise, they are not ignored.

The filters of an already-registered EventListener can be changed at runtime by re-registering the same EventListener object (i.e. the same actual Java object) with a new set of filter arguments. The implementation must ensure that no events are lost during the changeover.

 

Parameters:
listener - an EventListener object.
eventTypes - A combination of one or more event type constants encoded as a bitmask.
absPath - an absolute path.
isDeep - a boolean.
uuid - array of UUIDs.
nodeTypeName - array of node type names.
noLocal - a boolean.
Throws:
RepositoryException - If an error occurs.

 

 



Arun Patidar

Avatar

Level 2

Hi @arunpatidar,

                              I achieved the same thing with jcr event listener. Its working as expected. But do we need to close the resource resolver and session that we activated in activate method. I want to close the resource resolver but we can't close that in activate and on event methods. We can close that in deactivate method but that will run when we closed the instance, or an update has been happened for that component or bundle. What is the right way to close resource resolver and session here. 

Avatar

Community Advisor

Hi @RaviK1 
You can try autoclosable.

 

you should not create session in the activate method, you should open resource resolver when you needed and close after that.



Arun Patidar

Avatar

Administrator

@RaviK1 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni