Best Practices - Newsletter Nr. 2 - Event Handler

In Projekten fällt immer wieder auf, dass in Eventhandlern teilweise die komplette Verarbeitung synchron durchgeführt wird. Bei Eventhandlern in CQ (zumindest bis 5.6.1) gibt es ein Timeout, wie lange die Verarbeitung eines einzelnen Eventhandlers dauern darf. Überschreitet ein Eventhandler dieses Timeout, welches im Standard fünf Sekunden sind, erhält dieser danach keine weiteren Events. Entsprechend ist der Eventhandler nicht mehr aktiv und führt seine Aufgaben nicht mehr aus. Die Fehlersuche gestaltet sich in solchen Fällen sehr schwierig, da es dafür auch kein Monitoring gibt.

Früher wurde für die asynchrone Verarbeitung der org.apache.sling.event.jobs.JobProcessor benutzt.

Dieser ist aber als Deprecated markiert und sollte nicht mehr verwendet werden. Die Migration auf AEM 6 wird es danken.

Folgendes Beispiel zeigt wie es richtig geht. Eine Teilung von JobConsumer und Eventhandler in unterschiedliche Klassen ist nicht notwendig.

 

import java.util.HashMap;

import java.util.Map;

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.event.EventUtil;

import org.apache.sling.event.jobs.Job;

import org.apache.sling.event.jobs.JobManager;

import org.apache.sling.event.jobs.consumer.JobConsumer;

import org.osgi.service.event.Event;

import org.osgi.service.event.EventHandler;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


@Component(label ="Any Replication Handler", immediate =true)

@Service

@Properties({ @Property(name ="event.topics", value ={"com/adobe/granite/replication"}),

                @Property(name = JobConsumer.PROPERTY_TOPICS, value ={ EventListener.JOB_TOPIC })})

publicclass EventListener implements EventHandler, JobConsumer {

    privatestaticfinal Logger LOG = LoggerFactory.getLogger(EventListener.class);

     /** topic key for job processing event */

    publicstaticfinal String JOB_TOPIC ="com/cq/services/ReplicationEvent";

     /** property of modifications on replication event forwarded to for job */

    publicstaticfinal String PROPERTY_MODIFICATIONS ="modifications";

     @Reference

    private JobManager jobManager;

     @Override

   

    publicvoid handleEvent(Event event){

        if(EventUtil.isLocal(event)){

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

            payload.put(PROPERTY_MODIFICATIONS, event.getProperty(PROPERTY_MODIFICATIONS));

            final Job addJob = jobManager.addJob(JOB_TOPIC, payload);

            if(addJob ==null){

                LOG.error("Job for processing the event '{}' couldn't be added to the jobmanager.", event);

            }

        }

    }

    @Override

    public JobResult process(Job job){

         // process the job

        return JobResult.OK;

    }

}

Ihr Ansprechpartner