[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