Highlighted

ResourceChangeListener onChange event not getting trigger

kranthiv7238223

23-04-2019

Hi All,

the following code for onChange used to work in AEM 6.2 but after we migrated to 6.3 , I see onChange is not getting fired, not sure what is going wrong.

@Component(immediate = true)

@Service
@Properties(value = { @Property(name = ResourceChangeListener.PATHS, value = { CommunityConstants.CONTENT_ROOT_PATH }),

   @Property(name = ResourceChangeListener.CHANGES, value = { "ADDED", "CHANGED" }, propertyPrivate = true) })

public class xyz implements ResourceChangeListener {

@Reference
private ResourceResolverFactory resourceResolverFactory;

@Reference
private ContentModelService contentModelService;

@Override
public void onChange(@Nonnull List<ResourceChange> changes) {

//some logic here

}

}

Please help me to understand it further.

Many Thanks,

Kranthi

Replies

Highlighted

Jörg_Hoh

Employee

23-04-2019

Some basic checks first:

* Please check that the bundle containing this service is active.

* Please check that the component "xyz" is active (check on the Components list in the OSGI webconsole).

Jörg

Highlighted

smacdonald2008

23-04-2019

Issue is how session is obtained. You need to use a system user and give correct permissions. This works....

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_ADDED|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);

      }

     }

    }

Highlighted

kranthiv7238223

24-04-2019

Hi Joerg Hoh, yes bundle & component both are active but still onChange event is not getting triggered in AEM 6.3 , but it works fine in AEM 6.2.

Highlighted

kranthiv7238223

24-04-2019

Hi smacdonald2008​ , this is what we are doing. so you suggest us to write @Activate to get the session & @Deactivate to destroy the session ?

package com.xyz.help.conteenginecore.listener;

import java.util.List;

import java.util.Optional;

import com.adobe.cq.social.community.api.CommunityConstants;

import com.xyz.help.conteenginecore.Constants;

import com.xyz.help.conteenginecore.ContentModel;

import com.xyz.help.conteenginecore.ContentModelService;

import com.google.common.annotations.VisibleForTesting;

import javax.annotation.Nonnull;

import org.apache.felix.scr.annotations.Component;

import org.apache.felix.scr.annotations.Properties;

import org.apache.felix.scr.annotations.Property;

import org.apache.felix.scr.annotations.Reference;

import org.apache.felix.scr.annotations.Service;

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

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

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

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

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

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

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

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

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

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

/**
* Listens changing of resources, and in case when was added "articelNo"
* property, adding generated "articleId" property to the same node.
*/
@Component(immediate = true)

@Service
@Properties(value = { @Property(name = ResourceChangeListener.PATHS, value = { CommunityConstants.CONTENT_ROOT_PATH }),

   @Property(name = ResourceChangeListener.CHANGES, value = { "ADDED", "CHANGED" }, propertyPrivate = true) })

public class GenerateArticleIdOnAddingArticleNumber implements ResourceChangeListener {

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

   @Reference
   private ResourceResolverFactory resourceResolverFactory;

   @Reference
   private ContentModelService contentModelService;

   @Override
   public void onChange(@Nonnull List<ResourceChange> changes) {

   try (ResourceResolver resolver = resourceResolverFactory
   .getServiceResourceResolver(Constants.CONTENT_ENGINE_AUTH_INFO)) {

  changes.stream().filter(resourceChange -> resourceChange.getAddedPropertyNames() != null)

  .filter(resourceChange -> !resourceChange.getAddedPropertyNames().isEmpty())

  .filter(resourceChange -> resourceChange.getAddedPropertyNames()

  .contains(ContentModel.HelpArticle.PN_ARTICLE_NUMBER))

  .forEach(resourceChange -> {

  addArticleIdProperty(resourceChange, resolver);

  addDefClassificationProperty(resourceChange, resolver);

  });

  resolver.commit();

  } catch (LoginException e) {

   LOG.error("Can't perform action", e);

  } catch (PersistenceException e) {

   LOG.error("Can't perform action", e);

  }

  }

   private void addArticleIdProperty(ResourceChange resourceChange, ResourceResolver resourceResolver) {

  Resource resource = resourceResolver.resolve(resourceChange.getPath());

  Optional.ofNullable(resource.adaptTo(ModifiableValueMap.class)).ifPresent(valueMap -> valueMap

  .put(ContentModel.HelpArticle.PN_ARTICLE_ID, contentModelService.generateArticleId(resource)));

  }

   private void addDefClassificationProperty(ResourceChange resourceChange, ResourceResolver resourceResolver) {

  Resource resource = resourceResolver.resolve(resourceChange.getPath());

  Optional.ofNullable(resource.adaptTo(ModifiableValueMap.class)).ifPresent(

  valueMap -> valueMap.put(ContentModel.HelpArticle.PN_CLASSIFICATION, "ArticleClassification:help"));

  }

   @VisibleForTesting
   void bindResourceResolverFactory(ResourceResolverFactory resolverFactory) {

   this.resourceResolverFactory = resolverFactory;

  }

   @VisibleForTesting
   void bindContentModelService(ContentModelService contentModelService) {

   this.contentModelService = contentModelService;

  }

}

Highlighted

kranthiv7238223

24-04-2019

when I install the bundle, I see null pointer exception

24.04.2019 09:49:34.993 *INFO* [Background Update com.xyz.help.content-engine-core-bundle (833)] com.xyz.help.conteenginecore.listener.GenerateArticleIdOnAddingArticleNumber activating ExampleObservation

24.04.2019 09:49:35.162 *ERROR* [FelixDispatchQueue] org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerException)

Highlighted

smacdonald2008

24-04-2019

To get an EVENT Handler working on 6.3 - follow this article - see how we created a System user and SLing Mapping.

Creating an Event Listener for Adobe Experience Manager 6.4

You will need to use a 6.3 UBER JAR file - not the 6.4 one in that article.

The application logic that article does result in an Event firing.

Hope this helps.

OH yeah - for an AEM 6.3 project and UBER 6.3 JAR - see:

Creating an Adobe Experience Manager 6.3 Project using Adobe Maven Archetype 12

Highlighted

kranthiv7238223

24-04-2019

smacdonald2008​, yes we are using 6.3 Uber JAR file. onChange event is getting triggerd but I see problem in getting the ResourceResolver

I created the system user too

  1. Create one system user from /crx/explorer console
  2. Give access permissions  from /useradmin console
  3. Go to /system/console/configMgr and search for User Mapper Service
  4. Add your bundles:systemUser:systemUser

now write a method to get the resolver

public static final String CONTENT_ENGINE_SERVICE = "systemUser";

@Reference
private ResourceResolverFactory resourceResolverFactory;

private ResourceResolver getResourceResolver() {

  Map<String, Object> param = new HashMap<String, Object>();

  param.put(ResourceResolverFactory.SUBSERVICE, CONTENT_ENGINE_SERVICE);

  ResourceResolver resolver = null;

   try {

  resolver = resolverFactory.getServiceResourceResolver(param);

  } catch (Exception e) {

   LOG.error("Exception", e);

  }

   return resolver;

}

but I am not getting the ResourceResolver. not sure what is going wrong.

when I install the bundle, I see the following error in the error.log file

1.  bind method [bindResolverFactory] not found; Component  will fail

2. org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerException)

25.04.2019 05:58:40.625 *ERROR* [Background Update com.xyz.help.content-engine-core-bundle (833)] com.xyz.help.content-engine-core-bundle [                                                                      com.xyz.help.conteenginecore.listener.GenerateArticleIdOnAddingArticleNumber(3787)] bind method [bindResolverFactory] not found; Component                                                                       will fail

25.04.2019 05:58:40.625 *ERROR* [Background Update com.xyz.help.content-engine-core-bundle (833)] com.xyz.help.content-engine-core-bundle [                                                                      com.xyz.help.conteenginecore.listener.GenerateArticleIdOnAddingArticleNumber(3787)] bind method [bindResolverFactory] not found

25.04.2019 05:58:41.621 *ERROR* [FelixDispatchQueue] org.apache.sling.resourceresolver FrameworkEvent ERROR (java.lang.NullPointerExcepti                                                                      on)

java.lang.NullPointerException: null

Highlighted

Arun_Patidar

MVP

25-04-2019

Can you share your Apache Sling Service User Mapper service configuration:

It should be in below format because in point 4 above you shared is not correct format

Correct Format is below:

service-name:[sub-service-name]=system-user


Service-name: The service-name is the symbolic name of the bundle providing the service.

Sub-Service-Name:A Service may be comprised of multiple parts, so each part of the service may be further identified by a Subservice Name. This field is optional.

System-User :This will be the name of system user having access to get the resource.

com.demo.aem:dataService=dataUser