[wildfly-dev] Preparation for requirements and capabilities.

Brian Stansberry brian.stansberry at redhat.com
Wed Mar 25 10:44:41 EDT 2015


On 3/25/15 9:36 AM, Darran Lofthouse wrote:
>
>
> 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'
>

That's fine so long as they don't appear in the configuration in the 
same "context". Context meaning the same profile. A domain can have 
both, just not in the same profile. A standalone server of course only 
has one profile.

>> 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
>>>
>>
>>
> _______________________________________________
> wildfly-dev mailing list
> wildfly-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/wildfly-dev
>


-- 
Brian Stansberry
Senior Principal Software Engineer
JBoss by Red Hat


More information about the wildfly-dev mailing list