[ 
https://issues.apache.org/jira/browse/OAK-3201?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14734718#comment-14734718
 ] 

Francesco Mari commented on OAK-3201:
-------------------------------------

[~chetanm], I'm aware of the change of behaviour. I decided to fix the issue 
this way because I didn't find contexts where {{SecurityProviderImpl}} uses 
multiple implementations of its dependencies. 

Personally, I think that {{cardinality.minimum}} is a workaround for a use case 
that was probably not well defined. {{cardinality.minimum}} would prevent 
{{SecurityProviderImpl}} to start unless the minimum amount of implementations 
for a reference are found. But who defines what is the minimum amount of 
implementations to expect? In example, just because Oak provides one 
implementation of {{AuthorizableActionProvider}} that we use as a default, we 
can't arbitrarily use a {{cardinality.minimum=1}} for the reference to 
{{AuthorizableActionProvider}}. What if a user writes a custom implementation 
of {{AuthorizableActionProvider}} that is supposed to live along our default 
implementation? What if this user wants {{SecurityProviderImpl}} to start only 
if the two implementations of {{AuthorizableActionProvider}} are available?

Sure, we can define our own mechanism to substitute {{cardinality.minimum}}. 
But I think that a different approach would be cleaner:
- Create a new implementation of {{AuthorizableActionProvider}}.
- If multiple implementation of {{AuthorizableActionProvider}} should be wired 
together, use {{CompositeAuthorizableActionProvider}} as a base class for the 
implementation.
- Register the new implementation.
- Disable the default implementation or give the new implementation a higher 
service ranking (restart bundles as needed).
With this approach, we don't have to hardcode a {{cardinality.minimum}} in 
{{SecurityManagerImpl}}, or implement a similar mechanism on our own.

This solution would also allowed us to switch to a dynamic approach, like we 
currently have. We could create an implementation like the following:

{code}
public class DynamicAuthorizableActionProvider implements 
AuthorizableActionProvider {
  public List<? extends AuthorizableAction> getAuthorizableActions(@Nonnull 
SecurityProvider securityProvider) {
    return 
getComposite(lookupImplementationsOtherThanMe()).getAuthorizableActions(securityProvider)
  }
}
{code}

But at least, it would be clear that, by using this dynamic solution, you could 
have a potentially half-iniitialized repository.

> Use static references in SecurityProviderImpl for composite services
> --------------------------------------------------------------------
>
>                 Key: OAK-3201
>                 URL: https://issues.apache.org/jira/browse/OAK-3201
>             Project: Jackrabbit Oak
>          Issue Type: Bug
>          Components: core
>            Reporter: Francesco Mari
>            Assignee: Francesco Mari
>             Fix For: 1.3.6
>
>         Attachments: OAK-3201-01.patch, OAK-3201-02.patch, OAK-3201-03.patch, 
> mbean-test.log
>
>
> {{SecurityProviderImpl}} has dynamic references to many other services, like 
> {{RestrictionProvider}}, that represent the configuration of this component.
> Being these services dynamic, the OSGi runtime has no clear dependency 
> relationship between the {{SecurityProviderImpl}} and the required services. 
> Thus, it may happen that an instance of {{SecurityProviderImpl}} is published 
> before the services it requires are started, creating a window where the 
> {{SecurityProviderimpl}} is operating differently from the way it's 
> configured.
> I suggest to turn the dynamic references in {{SecurityProviderImpl}} to 
> static ones to improve the consistency of the implementation.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to