How to use ResourceChangeListener to listen for added metadata nodes?

278 Views Asked by At

I'm using ResourceChangeListener from Sling in my AEM application. I want the changeListener only to trigger when on path /content/dam/formsanddocuments/demofolder and ends with metadata node name.

Examples:

  • /content/dam/formsanddocuments/demofolder/form1/jcr:content/metadata
  • /content/dam/formsanddocuments/demofolder/subfolder/form1/jcr:content/metadata
  • /content/dam/formsanddocuments/demofolder/subfolder/secured/form2/jcr:content/metadata

I tried using this code:

@Component(
  service = ResourceChangeListener.class,
  property = {
    ResourceChangeListener.PATHS + "=glob:/content/dam/formsanddocuments/demofolder/**/metadata"
  }
)
public class MyResourceChangeListener implements ResourceChangeListener {
  //implementation
}

also tried glob:/content/dam/formsanddocuments/demofolder/**/*metadata and glob:/content/dam/formsanddocuments/demofolder/**/*(/metadata)

But it doesn't seem to work as expected. I don't get any events when I add a form. What am I doing wrong? How can I use ResourceChangeListener to listen for form creation events?

With path glob:/content/dam/formsanddocuments/demofolder it of course works. But seems not that performant.

@Override
public void onChange(List<ResourceChange> changes) {
    LOG.debug("FormCreationListener onChange triggered");
    changes.forEach((change) -> {
        final String path = change.getPath();
        if (isMetadataPath(path)) {
            //implementation
        }
    });
}
1

There are 1 best solutions below

1
Alexander Berndt On

Your PATHS-property was right, but the service was not activated. Add the immediate=true to the service configuration.

@Component(service = ResourceChangeListener.class, immediate = true, property = {
    ResourceChangeListener.PATHS + "=glob:/content/dam/formsanddocuments/demofolder/**/metadata"

})

OSGi services are not activated (= started) by default. Only if another active OSGi-component requires that service, then the OSGi-framework is looking for services implementing the requested service-interface - and ONE (=1) of the services is activated and wired into the requesting component.

But for consumer types a "whiteboard" service is usually looking for all active services, that implement the Consumer-Type Interface (same is true for the Sling Scheduler, or the HTTP whiteboard service.) So it sends change-events only to services that are already activated for another reason. If not, your configuration doesn't matter.

https://github.com/apache/sling-org-apache-sling-resourceresolver/blob/master/src/main/java/org/apache/sling/resourceresolver/impl/observation/ResourceChangeListenerWhiteboard.java

PS: SlingServlets are automatically activated. So it would be possible to "auto-activate" consumer-services. But it is a decision of the whiteboard service.