Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Listeners and handlers are not giving changed or added property names issue in 6.4

Avatar

Level 3

Hi All,

As I can check there are multiple issues with different types of listeners we are facing in AEM 6.4, SP-1 & SP-2.

First Listener:

The below listener is getting called in AEM 6.4, SP-1 & SP-2. But, its not giving the changed and added property. It only gives the resource path which got chnaged and operation performed (changed and added).

import java.util.List;

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;

@Component(

        service = ResourceChangeListener.class,

        property = {

                ResourceChangeListener.PATHS+"="+"/content",

                ResourceChangeListener.CHANGES+"="+"ADDED",

                ResourceChangeListener.CHANGES+"="+"REMOVED",

                ResourceChangeListener.CHANGES+"="+"CHANGED"

        }

)

public class SampleResourceChangeListener implements ResourceChangeListener{

    public static final Logger LOGGER = LoggerFactory.getLogger(SampleResourceChangeListener.class);

    @Override

    public void onChange(List<ResourceChange> list) {

        list.forEach((change) -> {

            LOGGER.info(change.getPath());

            LOGGER.info(change.getType().toString());

        });

    }

}

OUTPUT:

resource_listener.PNG

Second Listener:

The below listener is getting called in AEM 6.4, SP-1 & SP-2. But, its not giving the changed and added property. It only gives the resource path which got chnaged and operation performed (changed and added).

package ikpackage.core.listeners;

import org.apache.sling.api.SlingConstants;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.apache.sling.api.resource.observation.ResourceChangeListener;

import org.osgi.framework.Constants;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Reference;

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(service = EventHandler.class, immediate = true, property = {

        Constants.SERVICE_DESCRIPTION + "=Demo to listen event.job.topic on page Activation ",

        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/we-retail/us/en/*/jcr:content) (|("

                + SlingConstants.PROPERTY_CHANGED_ATTRIBUTES + "=*jcr:title) " + "(" + ResourceChangeListener.CHANGES

                + "=*jcr:title)))" })

public class TestEventListener implements EventHandler {

    private static final Logger LOG = LoggerFactory.getLogger(TestEventListener.class);

    @Reference

    private ResourceResolverFactory resourceResolverFactory;

    @Override

    public void handleEvent(Event event) {

        LOG.info("Hi event is called ......");

    }

}

OUTPUT: No added or changed property given as was earlier

eventhandler.PNG

Conclusion: I both the workflow we are not getting addedPropertyNames, changedPropertyNames and removedPropertyName.

Please let me know in case anyone able to find addedPropertyNames, changedPropertyNames and removedPropertyName in listener.

If I got something will post the same here for sure.

Thanks

1 Accepted Solution

Avatar

Correct answer by
Level 10

You need to use a system user and then give the required permissions. See the article i posted above. Then use SLing Mapping as described in the article.

You can then use this line of code to get session:

adminSession = repository.loginService("datawrite",null);

Once you do that - this code will work for listening for a prop change

import java.util.HashMap;

import java.util.Map;

import javax.jcr.Property;

import javax.jcr.RepositoryException;

import javax.jcr.Session;

import javax.jcr.observation.Event;

import javax.jcr.observation.EventListener;

import javax.jcr.observation.ObservationManager;

import org.apache.sling.api.resource.LoginException;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.osgi.service.component.annotations.Activate;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Deactivate;

import org.osgi.service.component.annotations.Modified;

import org.osgi.service.component.annotations.Reference;

import org.osgi.service.metatype.annotations.Designate;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.osgi.service.component.ComponentContext;

import javax.jcr.observation.EventIterator ;

@Component(immediate=true,

service= EventListener.class)

public class SimpleResourceListener implements EventListener{

    Logger log = LoggerFactory.getLogger(this.getClass());

     private Session adminSession;

   

  

     @Reference

     org.apache.sling.jcr.api.SlingRepository repository;

   

     @Activate

     public void activate(ComponentContext context) throws Exception {

     log.info("activating ExampleObservation");

     try {

    adminSession = repository.loginService("datawrite",null);

         adminSession.getWorkspace().getObservationManager().addEventListener(

          this, //handler

          Event.PROPERTY_CHANGED |Event.NODE_ADDED, //binary combination of event types

          "/apps/example", //path

          true, //is Deep?

          null, //uuids filter

          null, //nodetypes filter

          false);

   

       

     } catch (RepositoryException e){

      log.error("unable to register session",e);

      throw new Exception(e);

     }

    }

    @Deactivate

    public void deactivate(){

     if (adminSession != null){

      adminSession.logout();

     }

    }

   

    public void onEvent(EventIterator eventIterator) {

      try {

        while (eventIterator.hasNext()){

          log.info("something has been added : {}", eventIterator.nextEvent().getPath());

        }

       } catch(RepositoryException e){

       log.error("Error while treating events",e);

      }

     }

    }

I changed a component under apps/example and this log was generated by the listener

foo55.png

View solution in original post

6 Replies

Avatar

Level 10

We just released 6.4 article was works. In this example - the event is fired when a node is added.

Creating an Event Listener for Adobe Experience Manager 6.4

Avatar

Level 10

I will test this use case for when a prop is changed - see if the event handler is fired. Also on 6.4 - are you using a system user?

Avatar

Level 3

No for this code, we are not using system user.

Avatar

Correct answer by
Level 10

You need to use a system user and then give the required permissions. See the article i posted above. Then use SLing Mapping as described in the article.

You can then use this line of code to get session:

adminSession = repository.loginService("datawrite",null);

Once you do that - this code will work for listening for a prop change

import java.util.HashMap;

import java.util.Map;

import javax.jcr.Property;

import javax.jcr.RepositoryException;

import javax.jcr.Session;

import javax.jcr.observation.Event;

import javax.jcr.observation.EventListener;

import javax.jcr.observation.ObservationManager;

import org.apache.sling.api.resource.LoginException;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.osgi.service.component.annotations.Activate;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Deactivate;

import org.osgi.service.component.annotations.Modified;

import org.osgi.service.component.annotations.Reference;

import org.osgi.service.metatype.annotations.Designate;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.osgi.service.component.ComponentContext;

import javax.jcr.observation.EventIterator ;

@Component(immediate=true,

service= EventListener.class)

public class SimpleResourceListener implements EventListener{

    Logger log = LoggerFactory.getLogger(this.getClass());

     private Session adminSession;

   

  

     @Reference

     org.apache.sling.jcr.api.SlingRepository repository;

   

     @Activate

     public void activate(ComponentContext context) throws Exception {

     log.info("activating ExampleObservation");

     try {

    adminSession = repository.loginService("datawrite",null);

         adminSession.getWorkspace().getObservationManager().addEventListener(

          this, //handler

          Event.PROPERTY_CHANGED |Event.NODE_ADDED, //binary combination of event types

          "/apps/example", //path

          true, //is Deep?

          null, //uuids filter

          null, //nodetypes filter

          false);

   

       

     } catch (RepositoryException e){

      log.error("unable to register session",e);

      throw new Exception(e);

     }

    }

    @Deactivate

    public void deactivate(){

     if (adminSession != null){

      adminSession.logout();

     }

    }

   

    public void onEvent(EventIterator eventIterator) {

      try {

        while (eventIterator.hasNext()){

          log.info("something has been added : {}", eventIterator.nextEvent().getPath());

        }

       } catch(RepositoryException e){

       log.error("Error while treating events",e);

      }

     }

    }

I changed a component under apps/example and this log was generated by the listener

foo55.png

Avatar

Level 3

Thanks scott,

It was a great help. This code successfully ran in my local and I am able to the changed parameter names. Please find below screen shot for the same.

1621270_pastedImage_0.png