[wildfly-dev] Preparation for requirements and capabilities.

Darran Lofthouse darran.lofthouse at jboss.com
Wed Mar 25 10:36:55 EDT 2015



On 25/03/15 14:28, Brian Stansberry wrote:
> On 3/25/15 7:01 AM, Darran Lofthouse wrote:
>>
>>
>>
>> On 24/03/15 20:11, Brian Stansberry wrote:
>>    > On 3/24/15 1:08 PM, Darran Lofthouse wrote:
>>    >> My first questions in this area are - What are the constraints going to
>>    >> be about unique naming of capabilities?
>>    >
>>    > They must be namespaced. See
>>    >
>> https://developer.jboss.org/wiki/CoreAndSubsystemCapabilitiesAndRequirements.
>>    >
>>    > The ones we provide must be in the org.wildfly namespace, which is
>>    > reserved for us. Use org.wildfly.extension.xxxx for stuff this is
>>    > provided by an extension, and isn't part of the kernel.
>>    >
>>    > (OT: I'm going to start using the term 'kernel' to mean what used to be
>>    > called the 'core' since now WildFly Core means the kernel plus a few
>>    > subsystems.)
>>
>> (OT: Personally I wish kernel was it's own build )
>>
>>    >
>>    >> Will the implementation / API
>>    >> provide methods a subsystem can use to help enforce this?
>>    >>
>>    >
>>    > The OperationContext will enforce uniqueness. I don't think a subsystem
>>    > will help enforce this; the subsystem authors will just create a
>>    > reasonable namespace and stick to it.
>>
>> I may be thinking of this the opposite way around, or it may be that my
>> capabilities are more ingrained with the application server as a whole.
>>
>> In the case of Elytron I think we have a successful API/SPI separation
>> if we can say the Elytron Subsystem is optional, primarily this gives us
>> two different situations: -
>>     - No capabilities provided and nothing requiring them - essentially a
>> completely unsecured server.
>>     - An alternative subsystem providing all of the capabilities, maybe
>> this is a pure KeyCloak server or maybe an ISV wants the security
>> tightly built on their product.
>>
>> As I type this having the namespace defined by the subsystem is probably
>> not an issue provided that every place say a security realm can be
>> referenced this is a qualified reference including the namespace.  Also
>> the discovery of available security realms would need to take into
>> account different namespaces being available.
>>
>
> I think it's best to decouple the concepts of capabilities and subsystems.
>
> A capability is a form of API/SPI. It has a name, and it can provide an
> API. (Note that this API is not limited to service injection; we do
> other things in other cases.)
>
> A subsystem can provide a capability, but that doesn't mean it has to
> "own" the capability. There can be a capability named
> org.wildfly.extension.security.security-realm that is owned by the
> WildFly dev team, but that doesn't mean the Elytron subsystem has to own
> it. Someone else could provide it as well. This is logically analogous
> to some library providing an API/SPI and then also an impl.

That part sounds perfect for me.  The capabilities we are thinking about 
here will be integral to the whole application server.

> If the user configures two providers of the same capability in the same
> context, it's a configuration error. The server will reject that. Over
> time hopefully provisioning tooling will come along that will reject it
> in advance.

The case I have now is say the Elytron subsystem is installed and the 
KeyCloak subsystem is installed - it is quite conceivable that both 
would provide capabilities for 
'org.wildfly.extension.security.security-realm'

> If some consumer of capabilities just wants Service<SecurityRealm> and
> doesn't care which of a menu of capabilities provides it, I consider
> that to be corner case detail, and something to be handled by that
> consumer (by registering an optional requirement for each and using
> whichever is available.)
>
>
>> (OT:  Wonder if we should think about access control here, I am waiting
>> till I have the majority of the model in place to really look into it
>> but we do have the issue of no longer being able to tell which parts of
>> security are app and which parts are management)
>>
>>    >> When it comes to resource definitions the definition can either be
>>    >> focused on the implementation behind the service or the type the service
>>    >> returns.  My preference is to focus on the implementation.
>>    >>
>>    >> As an example I have a few different security realm implementations: -
>>    >>
>>    >> keystore-realm=*
>>    >> ldap-realm=*
>>    >> jaas-realm=*
>>    >>
>>    >> All of these would register a service that returns 'SecurityRealm' so
>>    >> 'SecurityRealm' would be the capability.
>>    >>
>>    >> So this is really the basis of my question as now the model does not
>>    >> enforce unique names.  The reason for this type of split is so each can
>>    >> have it's own set of attribute definitions.
>>    >>
>>    >> If I turned this on it's head and have: -
>>    >>
>>    >> security-realm=*
>>    >>
>>    >> Now the model will enforce unique names within my subsystem but I have
>>    >> lost the association of type specific attributes.  A security realm
>>    >> could support all attribute types but now it becomes hard to work with
>>    >> and understand what does what depending on the type.  Or I could add a
>>    >> child resource for type specific settings but that moves away from my
>>    >> aim of a 1:1 mapping between resource and service.
>>    >>
>>    >> Although the model enforces unique names this is specific to my
>>    >> subsystem only, if another subsystem is also capable of supplying
>>    >> SecurityRealm implementations duplicates are again possible.
>>    >>
>>    >
>>    > Within a given context (i.e. a standalone server or a domain profile)
>>    > some other subsystem providing a capability with the same name will not
>>    > be allowed. If someone else wants to provide access to
>>    > Service<SecurityRealm> for some unrelated reason then they need to
>>    > provide their own capability name. If they are actually another
>>    > implementation of the same capability, then the user has to pick one or
>>    > the other within a context.
>>    >
>>    >> So overall my preference would be let capabilities and requirements
>>    >> worry about naming constraints and leave subsystem implementations to
>>    >> focus on understandable typed resources.
>>    >>
>>    >
>>    > That's fine. If keystore-realm=* et al are all providing instances of
>>    > the same capability, then the OperationContext can enforce that as part
>>    > of model validation by detecting duplicate instance names registered
>>    > within a single capability namespace.
>>    >
>>    > Having keystore-realm=*, ldap-realm=*, jaas-realm=* all registering
>>    > instance names in the same capability namespace will add some complexity
>>    > to the validation though, so thanks for pointing that use case out. The
>>    > complexity is discriminating your use case (legal) from two completely
>>    > different subsystems using the same namespace in the same context
>>    > (illegal). A possible solution is the parent resource for those is what
>>    > declares that it provides capability org.wildfly.extension.xxx and then
>>    > the kernel accepts instance name registrations from children, while
>>    > rejecting them from non-children.
>>    >
>>    >> Regards,
>>    >> Darran Lofthouse.
>>    >>
>>    >>
>>    >>
>>    >>
>>    >> On 24/03/15 14:41, Brian Stansberry wrote:
>>    >>> On 3/24/15 9:33 AM, Darran Lofthouse wrote:
>>    >>>>
>>    >>>>
>>    >>>> On 24/03/15 14:24, Brian Stansberry wrote:
>>    >>>>> On 3/19/15 12:08 PM, Darran Lofthouse wrote:
>>    >>>>>> On 19/03/15 10:20, Darran Lofthouse wrote:
>>    >>>>>>> Assuming the title still covers the scenarios I have in mind is
>> there
>>    >>>>>>> anything we can be doing now to prepare for requirements and
>>    >>>>>>> capabilities support to make transitioning easier once it is
>> available.
>>    >>>>>>>
>>    >>>>>>> As an example within Elytron we will have a number of services that
>>    >>>>>>> define either standard types or types defined by API that we
>> want to
>>    >>>>>>> inject - is there anything we can do today for subsystems that
>> want to
>>    >>>>>>> say "I want a type X, named Y injected here" whilst minimising
>>    >>>>>>> interaction with and knowledge of the Elytron subsystem.
>>    >>>>>>
>>    >>>>>> For the service naming issue I have one idea, I create a utility
>> class
>>    >>>>>> in wildfly-core with the following method: -
>>    >>>>>>
>>    >>>>>> public static ServiceName createServiceName(Class<?> type,
>>    >>>>>>            String simpleName);
>>    >>>>>>
>>    >>>>>> The type here is the type that the service returns, this methods
>>    >>>>>> constructs a ServiceName taking into account the class name of
>> the type
>>    >>>>>> and the supplied simpleName which really is just it's reference.
>>    >>>>>>
>>    >>>>>> Within the Elytron subsystem I install services by using this
>> method to
>>    >>>>>> construct the names.
>>    >>>>>>
>>    >>>>>> For any other service that depends on one of these types the
>> same method
>>    >>>>>> is used when creating the dependency.
>>    >>>>>>
>>    >>>>>> This way details of the Elytron subsystem do not leak out to other
>>    >>>>>> subsystems.
>>    >>>>>>
>>    >>>>>
>>    >>>>> I like the notion of both the capability code and the requiring code
>>    >>>>> turning over the mechanics of service name creation to the core. I
>>    >>>>> expect that will go into the OperationContext though, as it has the
>>    >>>>> knowledge of what capabilities exist. If it's purely a mechanical
>>    >>>>> function though with no validation required it could just go in some
>>    >>>>> static method somewhere, but it's likely in the real use cases there
>>    >>>>> will be some validation.
>>    >>>>>
>>    >>>>> I don't see a type as being valid data for creating a
>> ServiceName. There
>>    >>>>> isn't a 1:1 correspondence between a type and the various things that
>>    >>>>> can provide services whose value is of that type. Simplest case being
>>    >>>>> Service<Void>, but I bet we have some Service<String> out there.
>>    >>>>>
>>    >>>>> If we limit a capability to providing just a single type for
>> injections,
>>    >>>>> then it can just be:
>>    >>>>>
>>    >>>>> public ServiceName getServiceName(String capability, String
>> instanceName)
>>    >>>>>
>>    >>>>> A capability provides a namespace, as does the prefix for a
>> ServiceName
>>    >>>>> so it seems reasonable enough to me to reuse one for the other.
>>    >>>>> Particularly if it's all hidden behind a method the core provides.
>>    >>>>>
>>    >>>>> I was a bit reluctant to limit a capability to providing just a
>> single
>>    >>>>> injection type, as there are some cases where it's a bit fine
>> grained.
>>    >>>>> For example IIOP provides both an ORB and a CORBA
>> NamingContextExt. But
>>    >>>>> I don't think there are enough such cases to outweigh the simplicity
>>    >>>>> advantages of having a single injection type per capability.
>>    >>>>
>>    >>>> +1 Take my suggestion extremely lightly, that was only going to be a
>>    >>>> temporary step towards being capability based - from your other e-mail
>>    >>>> it sounds like that is going to be actively developed now so I can
>> just
>>    >>>> use the real thing.
>>    >>>>
>>    >>>
>>    >>> Yes, it will be. I did a fair amount last summer/fall but then hit a
>>    >>> point where I wanted to let ideas percolate, plus I had to do a lot of
>>    >>> other tasks. But I think enough percolation has happened (including
>> your
>>    >>> helpful suggestion above) and the list other stuff I've had to do is
>>    >>> getting short.
>>    >>>
>>    >>>> I am at the point now where I am starting to wire things together
>> in the
>>    >>>> server and have just started an incubation fork of wildfly-core for my
>>    >>>> development so let me know if there is anything you want me to try
>> out.
>>    >>>>
>>    >>>
>>    >>> Thanks; I'll do that for sure.
>>    >>>
>>    >>>>>>> Secondly is there anything we can do at the model level regarding
>>    >>>>>>> assisting the user with referential integrity, as an example
>> say I am
>>    >>>>>>> writing an attribute using the CLI called 'keystore', this is
>> going to
>>    >>>>>>> be a reference to a named KeyStore - how about some form of op
>>    >>>>>>> associated with that attribute that can dynamically generate
>> the list of
>>    >>>>>>> accepted values on demand, e.g. by querying the model and
>> finding out
>>    >>>>>>> which KeyStores are actually available.
>>    >>>>>>>
>>    >>>>>>> Regards,
>>    >>>>>>> Darran Lofthouse.
>>    >>>>>>> _______________________________________________
>>    >>>>>>> wildfly-dev mailing list
>>    >>>>>>> wildfly-dev at lists.jboss.org
>>    >>>>>>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>    >>>>>>>
>>    >>>>>> _______________________________________________
>>    >>>>>> wildfly-dev mailing list
>>    >>>>>> wildfly-dev at lists.jboss.org
>>    >>>>>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>    >>>>>>
>>    >>>>>
>>    >>>>>
>>    >>>> _______________________________________________
>>    >>>> wildfly-dev mailing list
>>    >>>> wildfly-dev at lists.jboss.org
>>    >>>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>    >>>>
>>    >>>
>>    >>>
>>    >> _______________________________________________
>>    >> wildfly-dev mailing list
>>    >> wildfly-dev at lists.jboss.org
>>    >> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>    >>
>>    >
>>    >
>>
>> _______________________________________________
>> wildfly-dev mailing list
>> wildfly-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>
>
>


More information about the wildfly-dev mailing list