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:
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
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
Solved! Go to Solution.
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
Views
Replies
Total Likes
We just released 6.4 article was works. In this example - the event is fired when a node is added.
Views
Replies
Total Likes
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?
Views
Replies
Total Likes
No for this code, we are not using system user.
Views
Replies
Total Likes
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
Views
Replies
Total Likes
Another thing I did to make logging for the EVENT Listener easier was to write to a custom log -- Scott's Digital Community: Creating a custom log file for an Adobe Experience Manager project
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.
Views
Replies
Total Likes