Julian Sedding wrote > Definitely +1 on doing this right. > > Regardless of the above, the goals I read in this thread are the following: > - only register a service if the required service-user is available > (ServiceUserMapped) > - announce service-users lazily > > An implementation could consist of a component, let's call it > ServiceUserRegistry. The ServiceUserRegistry looks for > ServiceUserProvider services (e.g. a SlingRepository implementation > could also implement this interface). Furthermore, the > ServiceUserRegistry implements FindHook (in theory I think a > ListenerHook would be better, but this does not work with the current > Felix SCR implementation) looking for requests for ServiceUserMapped > services and their (optional) sub-service name. If a service is > requested that is not yet available, the ServiceUserRegistry asks all > ServiceUserProviders if they can provide a suitable service user. If > that is the case it registers an appropriately configured service > (this could be achieved by means of a ComponentFactory). > > Unregistering of service users that go away could be handled on two > levels: 1. if a ServiceUserProvider is unregistered, all service-users > it provided need to be unregistered as well. 2. A ServiceUserProvider > needs to be able to signal the ServiceUserRegistry that a user has > disappeared. > > With the introduction of a default service-user mapping, at least the > name ServiceUserMapped seems no longer appropriate. We could rename it > to ServiceUser or ServiceUserAvailable. And/or I could imagine going a > step further and provide a ServiceResourceResolverFactory (an > interface with a single method "createResourceResolver(Map authInfo)" > or maybe a second one with no args for convenience). A consumer would > inject the ServiceResourceResolverFactory instead of a > ResourceResolverFactory. The @Reference target filter could optionally > indicate a subservice name. > > Please feel free to rip this apart or improve on it! ;)
:) Thanks, yes we could do something along these lines. But it gets more complicated with having N resource providers as potentially each resource provider (which uses authentication) has to have this service user. Still doable. Let's assume for the sake of the discussion that we keep the name ServiceUserMapped. We could register service hooks: if a ServiceUserMapped is requested which doesn't exist, the hook could: - get "all" resource providers requiring authentication (let's talk about "all" below) - ask each of them through some interface whether they have the requested service user - if all of them respond with "yes" or if there is no resource provider requiring authentication, the ServiceUserMapped service is registered If a ServiceUserMapped is registered and a resource provider requiring authentication is added, the above check needs to be done for the new provider and potentially the ServiceUserMapped gets unregistered. I mentioned above that "all" resource providers need to be asked, we could also argue that only resource providers which require authentication and are not lazy need to provide the service user. Lazy resource providers are optional anyway. If we can go with that assumption, the check whether a service user exists becomes pretty easy: simply try to get a resource resolver with that service user - if a login exception occurs, it's not available -> no ServiceUserMapped. Otherwise register the ServiceUserMapped. I think with the above simplification it becomes fairly easy to implement. It neither exposes service users to the world nor does it require API changes Regards Carsten -- Carsten Ziegeler Adobe Research Switzerland [email protected]
