HI Team,
We have a requirement :
when Page got activated or deactivated we need to send the page info( path, title ,uuid) to other systems.
We are writing a event handler for it. It is working as expected. But, Event handler is getting Triggered twice. Below is the code.
@Slf4j
@component( service = EventHandler.class, immediate = true,
property = { EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC, })
public class ReplicationEventHandler implements EventHandler {
If we subscribe to org/apache/sling/event/notification/job/FINISHED or org/apache/sling/distribution/agent/package/distributed
Then Event handler is not getting triggered at all. Below is the code.
@Slf4j
@component(immediate = true, service = EventHandler.class,
property = { "event.topics=org/apache/sling/event/notification/job/FINISHED",
"event.filter=(|(distribution.type=ADD)(distribution.type=DELETE))" })
public class ReplicationEventHandler implements EventHandler {
OR
@Slf4j @component(immediate = true, service = EventHandler.class, property = { "event.topics=org/apache/sling/distribution/agent/package/distributed",
"event.filter=(|(distribution.type=ADD)(distribution.type=DELETE))" })
public class ReplicationEventHandler implements EventHandler {
Could you please review the sample code and provide guidance on resolving this issue?
Views
Replies
Total Likes
Event Handler triggering twice generally happens with multiple events trigger when a page is activated (like one ReplicationAction event and/or ResourceEvent for any change in resources etc.)
To handle this - write a condition to handle your ReplicationAction event only
@Slf4j
@component( service = EventHandler.class, immediate = true,
property = { EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC, })
public class ReplicationEventHandler implements EventHandler {
Hi Suresh, Thanks for the response.
I wrote the same kind of code. Still it is triggered twice. Because in Cloud it is cluster and it will have minimum 2 clusters at any time. This issue occurs only in cloud but not in local.
ReplicationAction action =ReplicationAction.fromEvent(event);
ReplicationActionType actionType =action.getType();
if (actionType != ReplicationActionType.DELETE && actionType != ReplicationActionType.ACTIVATE
&& actionType != ReplicationActionType.DEACTIVATE) {
log.error("The action type {} is not allowed for the page {}.", actionType.getName(), actionPath);
return;
}
@Rudra-2024 For the case where the event handler is not getting triggered, could it be due to the fact that your event handler execution takes more than 5000 ms and hence causing it become blacklisted. Once that happens, your event handler is no longer functional. We ran into this type of scenario recently.
If that is the case, you might want to look at your implementation and see if there is anything that is potentially causing this.
You can read more on this in a similar discussion thread -
Thanks for the response. I restarted the instance. Still the same issue.
can you provide complete code ? class file
Hi @SureshDhulipudi , Please find below code
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.discovery.DiscoveryService;
import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.JobManager;
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;
/**
* The Class ReplicationEventHandler.
*/
@Slf4j
@Component(
service = EventHandler.class,
immediate = true,
property = {
EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC,
})
public class ReplicationEventHandler implements EventHandler {
/**
* The DiscoveryService.
*/
@Reference
private DiscoveryService discoveryService;
/**
* The RunModeConfigService.
*/
@Reference
private RunModeConfigService runModeConfigService;
/**
* The jobManager service.
*/
@Reference
private JobManager jobManager;
/**
* {@inheritDoc}
*/
@Override
public void handleEvent(Event event) {
ReplicationAction action = getAction(event);
String actionPath = action.getPath();
log.debug("\n Replication Event occurred at the path {} and the action is {}", actionPath,
action.getType().getName());
String instanceName =
discoveryService.getTopology().getLocalInstance().getProperty("org.apache.sling.instance.name");
String ins = runModeConfigService.getInstance();
log.debug("instanceName from Topology {}", instanceName);
log.debug("Is it Local instance {}", discoveryService.getTopology().getLocalInstance().isLocal());
log.debug("Is it Leader instance {}", discoveryService.getTopology().getLocalInstance().isLeader());
log.debug("instanceName from Run mode {}", ins);
syncAemContentToExternalSystem(action, actionPath);
}
private void syncAemContentToExternalSystem(ReplicationAction action, String actionPath) {
//actual Business logic
}
}
@Rudra-2024 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.
Views
Replies
Total Likes
Issue is not resolved yet.
Hi @kautuk_sahni I didn't find the answer yet. Could you please help me on this.
Hi @Rudra-2024
Could you please check https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/scheduled-jobs-not-execute...
Hi @arunpatidar
Thanks for the response.
I pretty much followed the same as below article.
https://sudeshaempodcast.wordpress.com/2021/07/04/aemaacs-slingjobs/
Only problem is when the topic is EventConstants.EVENT_TOPIC + "=" + ReplicationAction.EVENT_TOPIC, It is getting triggered twice.
when the topic is"event.topics=org/apache/sling/distribution/agent/package/distributed", or
"event.topics=org/apache/sling/event/notification/job/FINISHED
is not triggered at all.
HI @Rudra-2024
Are you doing this on publish or author?
Can you check the number of events at http://localhost:4502/system/console/events
ON Author instance only.
I tried below logs
String instanceName =discoveryService.getTopology().getLocalInstance().getProperty("org.apache.sling.instance.name");
String ins = runModeConfigService.getInstance();
log.debug("instanceName from Topology {}", instanceName);
log.debug("Is it Local instance {}", discoveryService.getTopology().getLocalInstance().isLocal());
log.debug("Is it Leader instance {}", discoveryService.getTopology().getLocalInstance().isLeader());
log.debug("instanceName from Run mode {}", ins);
Every time it is printing the same answer 2 times in author instance.
Please verify is Sling Jobs would suit your need. They are better suited to work on AEMaaCS Clusters.
https://techrevel.blog/2023/11/06/enhancing-efficiency-and-reliability-by-sling-jobs/
Thank you for your response. In my scenario, it's crucial to react to both page activation and deactivation events. While Sling jobs might not directly address this requirement, I've devised the following approach:
However, if you believe that Sling jobs will directly listen page activation and deactivation events, I would greatly appreciate any reference links or sample code you could provide.
@SureshDhulipudi @arunpatidar @aanchal-sikka @Harwinder-singh
I tried
@Component(immediate = true, service = EventHandler.class, property = {EVENT_TOPIC + "=" + AGENT_PACKAGE_DISTRIBUTED,
"event.filter=(|(distribution.type=ADD)(distribution.type=DELETE))"})
public class ContentDistributionEventHandler implements EventHandler {
I tried below options. Still it is printing the logs twice.
@Component(immediate = true, service = EventHandler.class, property = {EVENT_TOPIC + "=" + AGENT_PACKAGE_DISTRIBUTED,
"event.filter=(|(distribution.type=ADD)(distribution.type=DELETE))"})
public class ContentDistributionEventHandler implements EventHandler {
@Slf4j
@Component(service = ResourceChangeListener.class, immediate = true, property = {
ResourceChangeListener.PATHS + "=" + GlobalConstants.ONTENT_ROOT_PATH,
ResourceChangeListener.CHANGES + "=" + "ADDED",
ResourceChangeListener.CHANGES + "=" + "CHANGED",
ResourceChangeListener.PROPERTY_NAMES_HINT + "=" + "cq:lastReplicated"
})
@ServiceDescription("TEST REPLICATION PROPERTY")
public class ReplicationChangeListener implements ResourceChangeListener {
Any suggestions/leads on this?
can you keep a condition for resourceType (I,e if the replication action happened only on Page) something like that?
or filter the resourceType or filter based on the page path.
duplicate events might be with any of the node properties also getting replicated??
Hi Suresh,
Thanks for the response.
I tried the same. still it is getting triggered twice.
@Rudra-2024
Hello. I have faced the same issue both of EventListener and EventHandler.
You can try one of the following options mentioned below.
1) Add this in your OSGi filter !(event.application=*). This makes sure, that the event is emitted only once, on clustered authors.
2) Use org.apache.sling.discovery.DiscoveryService#getTopology().getLocalInstance().isLeader() - this will make sure that the event processing will be handled only on master/leader pod.
P.S Sample OSGi Filter - (&(|(distribution.type=ADD)(distribution.type=DELETE))(!(event.application=*)))
Hope this helps.
Views
Likes
Replies