Search code examples
javaosgiaemsling

AEM 6.3 - Creating Event handler using OSGi R6 annotations


I have created an Event handler by following https://github.com/nateyolles/aem-osgi-annotation-demo/blob/master/core/src/main/java/com/nateyolles/aem/osgiannotationdemo/core/listeners/SampleOsgiResourceListener.java and it works fine. However, I get the warning "The field SlingConstants.TOPIC_RESOURCE_ADDED is deprecated". I did some searching and found this thread :https://forums.adobe.com/thread/2325819

Here are the challenges that I am facing:

1) I want to create a separate configuration interface for my event handler. I tried this and it isn't working

package com.aem.sites.interfaces;

import org.apache.sling.api.SlingConstants;
import org.osgi.service.event.EventConstants;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "Temperature Listener Configuration")
public @interface TemperatureListenerConfiguration {

    @AttributeDefinition(
            name = EventConstants.EVENT_FILTER,
            description = "Configurable paths for temperature event listener",
            type = AttributeType.STRING
            )
    String getPaths() default "/content/aemsite/en/jcr:content/root/responsivegrid/banner";

    @AttributeDefinition(
            name = EventConstants.EVENT_TOPIC,
            description = "Event types",
            type = AttributeType.STRING
            )
    String[] getEventTypes() default  {SlingConstants.TOPIC_RESOURCE_ADDED,SlingConstants.TOPIC_RESOURCE_CHANGED, SlingConstants.TOPIC_RESOURCE_REMOVED};

}

package com.aem.sites.listeners;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.interfaces.TemperatureListenerConfiguration;

@Component(immediate=true,
service=EventHandler.class,
configurationPid = "com.aem.sites.listeners.EventHandler")
@Designate(ocd=TemperatureListenerConfiguration.class)
public class TemperaturePropertyListener implements EventHandler{

     private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void handleEvent(Event event) {
        logger.info("*********************Event handler*****************************");

    }

    @Activate
    @Modified
    public void activate(TemperatureListenerConfiguration config) {
        //config.getPaths();
        logger.info("**************************TemperaturePropertyListener******************activate**********************");
    }

}

I also want the solution for SlingConstants deprecated issue. Not sure if ResourceChangeListener is the answer to my problem and if yes then how everything is going to work together in the code.

Thanks in advance

=============================== Latest Code

package com.aem.sites.listeners;

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.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aem.sites.interfaces.TemperatureListenerConfiguration;


@Component(immediate=true,
service=ResourceChangeListener.class,
configurationPid = "com.aem.sites.listeners.TemperaturePropertyListener")
@Designate(ocd=TemperatureListenerConfiguration.class)
public class TemperaturePropertyListener implements ResourceChangeListener{

     private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void onChange(List<ResourceChange> changes) {
        for (final ResourceChange change : changes) {
            logger.info("**************************TemperaturePropertyListener******************change type**********************"+change.getType());
        }

    }


    @Activate
    @Modified
    public void activate(TemperatureListenerConfiguration config) {
        //config.getPaths();
        logger.info("**************************TemperaturePropertyListener******************activate**********************");
    }
}

The Interface

package com.aem.sites.interfaces;

import org.apache.sling.api.resource.observation.ResourceChangeListener;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "Temperature Listener Configuration")
public @interface TemperatureListenerConfiguration {

    @AttributeDefinition(
            name = ResourceChangeListener.PATHS,
            description = "Configurable paths for temperature event listener",
            type = AttributeType.STRING
            )
    String[] getPaths() default {"/content/aemsite/en/jcr:content/root/responsivegrid/banner"};

    @AttributeDefinition(
            name = ResourceChangeListener.CHANGES,
            description = "Event types",
            type = AttributeType.STRING
            )
    String[] getEventTypes() default  {"ADDED","REMOVED","CHANGED","PROVIDER_ADDED", "PROVIDER_REMOVED"};

}

Solution

  • Looking at the Javadoc for org.apache.sling.api.SlingConstants in sling 9 documentation here: http://sling.apache.org/apidocs/sling9/org/apache/sling/api/SlingConstants.html

    it tells you specifically that TOPIC_RESOURCE_ADDED is deprecated:

    Deprecated. Register a ResourceChangeListener instead

    Read the documentation for ResourceChangeListener, additionally, you can take a look at a sample SCR service impl from ACS Samples:

    It should not be hard to convert that to R6 declarative service.

    Also, here are two examples from the sling project ResourceBackedPojoChangeMonitor and OsgiObservationBridge

    Try to mimic those classes with the properties in the same class.