Is it possible to register new filters at runtime in OSGI ?
Use case is the following. We use Adobe AEM CMS with multiple tenants. Now we have a filter that protects access to particular resources based on filter patterns. Here is the header of a filter class that intercepts requests to paths that contain the fragment "protected" for tenant1.
@Component(service = Filter.class,
property = {
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
EngineConstants.SLING_FILTER_PATTERN + "=" + "/content/dam/tenant1/.*/protected/.*"
})
public class ProtectedResourcesFilter implements Filter ....
Now, whenevever we get tenant2 we would like to extend the ProtectedResourcesFilter with another pattern. Is it possible to modify the EngineConstants.SLING_FILTER_PATTERN
and reload the filter?
Or is it better to create and register a new filter at runtime in OSGI ?
You can register new OSGi services at runtime.
To do so, you need to have a BundleContext
object around. This may happen in a different component that you register with Declarative Services ( via @Component
) or in a Bundle Activator.
A sample method is below
private ServiceRegistration<Filter> registerService(BundleContext ctx, String tenantId) {
Filter newService = createFilterInstance();
Dictionary<String, ?> props = new Hashtable<>();
props.put(EngineConstants.SLING_FILTER_SCOPE, EngineConstants.FILTER_SCOPE_REQUEST);
props.put(EngineConstants.SLING_FILTER_PATTERN, "/content/dam/" + tenantId + "/.*/protected/.*");
return ctx.registerService(Filter.class, newService, props);
}
The only catch here is that you need to manage the lifecycle of these services, so you are responsible for figuring out when to register a new service and also when to unregister it.