Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
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