AEM CRX Event Listener | Community
Skip to main content
Level 5
May 16, 2022
Solved

AEM CRX Event Listener

  • May 16, 2022
  • 3 replies
  • 3143 views

Hi All,

 

I have a crx event listener been working all time in AEM 6.0. After migrating to AEM 6.5, it stops working. I basically want to observe a node created under /crx/de, then it will trigger something.

 

Here is the code:

 

// -- component & service definition here
public class CRXObservation implements EventListener {
@580286
public void activate(ComponentContext context) throws Exception {
log.info("Activating crx observation");
try {
String[] nodetypes = {"cq:Page"};
ResourceResolver resolver = getResourceResolver();
Session adminSession = resolver.adaptTo(Session.class);

adminSession.getWorkspace().getObservationManager().addEventListener(
this,
Event.NODE_ADDED,
"/content/site/news", //path
true,
null,
nodetypes, //nodetypes filter
false
);
log.trace("After adding listener, session=>{}, resolver=>{}", adminSession, resolver);
} catch (RepositoryException e) {
log.error("Unable to register session",e);
throw new Exception(e);
}
}

@3038739
public void deactivate(){
if (adminSession != null) {
adminSession.logout();
}
}

private ResourceResolver getResourceResolver() {
try {
Map<String, Object> param = new HashMap<String, Object>();
param.put(ResourceResolverFactory.SUBSERVICE, "writeService");
return resourceResolverFactory.getServiceResourceResolver(param);
} catch (Exception e) {
ExceptionUtils eu = new ExceptionUtils();
log.debug("Cannot get resourceresolver: {}", eu.getFullStackTrace(e));
return null;
}
}

public void onEvent(EventIterator eventIterator)
{
try {
resourceResolver = getResourceResolver();
log.trace("triggering crx event");
while (eventIterator.hasNext()) {
Event newEvent = eventIterator.nextEvent();
String node=newEvent.getPath();
Resource resource = resourceResolver.getResource(node);

// -- adding node code
// ...
}

adminSession.save();
} catch(Exception e){
log.error("Error while adding page\n",e);
}
}

@ObjectClassDefinition(name="CRX Observation")
public @interface Configuration {
// -- service configuration
}
}

 

When starting the bundle, I can see the activate log message of log.info("Activating crx observation"); . But the log message in the onEvent function cannot be triggered after adding a page on /crx/de. Any suggestion?

 

Thanks!

-k

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 arunpatidar

Hi,

Are you getting jcr session or getting sling resource resolver from subservice?

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

Can you check if this example works in your instance.

 

Can you also check a log where subservice session may not be able to mapped.

3 replies

SantoshSai
Community Advisor
Community Advisor
May 16, 2022

Hi @kevin_gta 

Did you checked what you are getting in session? can you try below code?

// ResourceResolver resolver = resolverFactory.getAdministrativeResourceResolver(null); 
// Session sessObj = resolver.adaptTo(Session.class);
session = repository.loginAdministrative(null);
log.info("sessObj is live?"+session.isLive());
obsMgnr = session.getWorkspace().getObservationManager();


Regards,
Santosh

 
Santosh Sai
Kevin_GTaAuthor
Level 5
May 16, 2022

Hi Santosh,

Thanks for your suggestion.

We used to have loginAdministrative(), but it's deprecated (https://sling.apache.org/apidocs/sling7/org/apache/sling/jcr/api/SlingRepository.html#loginAdministrative-java.lang.String-). So we changed it to use resourceResolver to get the session. I can see the session is live in the log. 

 

-k

SantoshSai
Community Advisor
Community Advisor
May 16, 2022

That's right it is deprecated, I just wanted to confirm if session is live!


Santosh Sai
lukasz-m
Community Advisor
Community Advisor
May 16, 2022

Hi @kevin_gta,

Could you please check bellow aspects:

  1. Service user that you are using is created correctly (including service user mapping etc) and have proper level of permissions to access observed path, in your case it is /content/site/news. You can find some guideline under:
    1. https://experienceleague.adobe.com/docs/experience-manager-65/administering/security/security-service-users.html?lang=en
    2. http://www.aemcq5tutorials.com/tutorials/create-system-user-in-aem/
  2. Check if repository structure you would like to observer - /content/site/news - has been build using proper types. In other words you've specified cq:Page as a node type. According to JCR documentation, content, site, news or it's children needs to be type of cq:Page. So if you are creating node directly under news node, and news node is not cq:Page then onEvent method will not be executed because it does not match filtering you have defined. onEvent will be only executed if you are creating node under /content/site/news and direct root of node you are creating is cq:Page type.
Kevin_GTaAuthor
Level 5
May 16, 2022

HI @lukasz-m ,

 

Thanks for your reply. Yes, cq:Page is the node I need to create, and it is working on AEM 6.0. I actually toggled it from cq:Page to null on AEM 6.5 but got no luck. The service user is mapped correctly because there is another module using it to write something on jcr:content. Further more, my understanding is that it's not even an issue reaching the user permission yet because it needs to fire the onEvent first. 

 

-k

arunpatidar
Community Advisor
Community Advisor
May 17, 2022
Kevin_GTaAuthor
Level 5
May 17, 2022

Hi @arunpatidar ,

 

Thanks for your code. Mine almost exactly the same as yours, except that ours listens to Event.NODE_ADDED, and the code works on our current AEM 6.0 instances. As the debugging perspective, I am looking at the event specification changes, if there is any, or my content migration because I migrated partial contents from AEM 6.0, which might affect the underlying system config. 

 

I have two services on AEM 6.5, they are all involved with the system user permissions.

First one, it's not involved with CRX eventing. It can create nodes on /crx/de after executing.

Second one, which is this one, it's involved with CRX eventing. I can see the system user gets the right session, certainly via the User Mapper service. But the point is that it's not even getting to the user permissions yet because all /crx/de modification code is within onEvent function, and that function is not fired.

 

The pseudo code is:

 

class A implement event listener{

      @Activate 

       function activate(..)

       {

                get system user // create a system user and configure it via User Mapper

                get resourceresolver via system user

                session = resourceresolver.adaptTo(session.class)

                // -- successul getting session by session.isLive() verification

                add_event_listener(...lots of params, with Event.NODE_ADDED as event type);

                // no exception thrown, seeing regular log.info here, assuming listener is added successfully.

       }

       public void onEvent(EventIterator eventIterator){

               log.info("onEvent is called");

               // -- Can't see this message in the log file.

      }

      // -- ... other methods below such as deactivate, service configuration, etc

}

 

As you can see, onEvent is not called, but session is created successfully.

 

-k 

Kevin_GTaAuthor
Level 5
May 17, 2022

By the way, when I say onEvent is not called means after I create a node in the path defined in the add listener function.