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

AEM CRX Event Listener

Avatar

Level 6

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 {
@activate
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);
}
}

@deactivate
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

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

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.



Arun Patidar

View solution in original post

11 Replies

Avatar

Community Advisor

Hi @kevingtan 

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

 

Avatar

Level 6

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#loginAdministr...). So we changed it to use resourceResolver to get the session. I can see the session is live in the log. 

 

-k

Avatar

Community Advisor

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


Avatar

Community Advisor

Hi @kevingtan,

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-servic...
    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.

Avatar

Level 6

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

Avatar

Level 6

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 

Avatar

Level 6

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.

Avatar

Community Advisor

Hi,

This is happened when you use resource resolver instead of jcr session for jcr events

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



Arun Patidar

Avatar

Correct answer by
Community Advisor

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.



Arun Patidar

Avatar

Level 6

Hi @arunpatidar 

 

Yes, this works, thank you! I am getting the session from loginService instead of getting it from the resource resolver. 

 

-k