Daniel Kulp wrote:
> (I apologize in advance for the length of this email...   After meeting 
> with Jim and Sebastien for the last two days, there are a LOT of thoughts 
> swirling around in my head....)
> 
> One of the questions that came up in the discussions was something along 
> the lines of "if a user wants to replace the Axis 2 ws implementation 
> with Celtix, how would they do it?"    Or, more generally:  "In tuscany, 
> if I want to replace XXXX with YYYY where YYYY is functionally 
> equivalent, how can I do it?"   (XXXX being a binding.*, container.*, 
> etc...)
> 
> The "simple" answer is something along the lines of: delete the XXXX jars, 
> add the YYYY jars, muck with the classpath, done.    However, that really 
> sucks.   Telling users to muck with things down on that level is usually 
> not a good idea and can generally result in bad things happening.    The 
> other problem with this approach is that there is no way that a user 
> could use BOTH XXXX and YYYY in the same system since XXXX is completely 
> deleted.
> 

This has been an area I have been wondering about as well as we start to
increase the number of system services included in the runtime.

In the SCA specification a module can be built up from multiple
fragments which "magically" get combined together. In Java this is done
by merging all "sca.fragment" files found on the classpath, coupling
together the concepts of assembly with the provision of code.

To be blunt, I think this sucks. It means that, as you describe, users
end up mixing mucking with the classpath to perform SCA assembly, and
potentially means they end up adding components to their application
just because they needed a class from some jar file.

It also does not deal with how configuration is done at the module
level. Yes, one way is to include it in a subsystem definition but there
is not consistency on how it is done for a bare module. For example,
when a WAR file is deployed with an sca.module file in it then in
Tuscany our approach is to define the module component name and URI from
the webapps context path and leave all configuration properties as defaults.

I would prefer to see a solution where we treated a module file as a
type (which it is) and had configuration information in some other
artifact - like a module component configuration file. This file would
allow us to specify values for that module and would also allow us to
define the location of the type (e.g. as the URL of the sca.module file).

I know the argument has been that this requires the user to have a
configuration file for the component. But, as a user, I actually prefer
a model like that where I remain in control of what is running than one
where things get configured by "magic."

> One idea I came up with is a concept of "aliasing".    All components 
> would always register with a very specific name.   Instead of binding.ws, 
> it would be binding.axis2; instead of container.js, it would be 
> container.rhino, etc...      Tuscany would then have some configuration 
> that would "bind" the specific name to the "generic" name.   This could 
> come from a config file, a system property, etc....     If the user want 
> to change the underlying implementation of one of the generic 
> 
> One advantage of this that the user then has more control in their 
> assembly.    If they want to use a more "portable" form and allow the 
> sca/tuscany runtime to use the default, they can do something like 
> "implementation.js" or "binding.ws" and the tuscany runtime would use the 
> appropriate one that is configured.    However, if the user wants the 
> specific version (using some advanced feature of axis or something...), 
> they can specifically use "binding.axis2" or "implementation.rhino".   It 
> allows complete coexistence.   In a module, you could actually use both 
> "binding.axis2" and "binding.celtix" as well as the default "binding.ws" 
> that may or may not point to one of them.
> 

I think we need to extend this concept to the general level, applying to
 both user components and system services (like containers, bindings,
etc). Any service provider must declare metadata about the services that
it offers and any service consumer similarly declare what services it is
willing to consume.

For example, a JavaScipt service provider could declare that it provides
"implementation.js", "implementation.rhino", "implementation.rhino.1R6"
containers. Similarly, when deploying a component implementation the
user could declare that it requires a "implementation.rhino" container
environment. The deployment system would then be able to deploy that
component to any runtime where "implementation.rhino" was available but
not where some other implementation of .js was used.

One idea I have floated before (but perhaps not on this list) is that
the user can provide alternative implementations of a component. For
example, they may choose to provide both Java and C++ implementations.
This would allow the deployment system to select the most appropriate
for the selected runtime (e.g. Java if deployed to a J2EE environment,
C++ if front-end deployment to Apache HTTPD was selected).

The key thing is that providers and consumers provider sufficient
metadata about the service they are using to interact. This is not jsut
functional (i.e. the API) but also non-function requirements like
implementation language, version, quality of service, licensing, ...

> 
> The next "issue" this brings up is how to provide a usable system if the 
> user HASN'T configured anything (zero config) as well as validate that a 
> user that has configured something hasn't shot themself in the foot.    On 
> thought with this is that when something registers with the system, it 
> not only registers it's name, but also can return a list of services it 
> can provide.    Example:    Name: binding.axis2, Provides: binding.ws
> 
> With that additional bit of information, the runtime could automatically 
> wire stuff up with no configuration as well as validate configuration.  
> (example: I alias "binding.ws" to "binding.jsonrpc".   That shouldn't 
> work since jsonrpc doesn't provide that service.)     In the case where 
> there are two or more implementations that provide a service, it could be 
> a "first one registered" or "undetermined" or anything.     The other 
> thing about this is that a single "thing" could possibly provide  
> multiple services.    Example:    Name: binding.celtix  Provides: 
> binding.ws, binding.corba, binding.blah)
> 

I think this is a good direction to move in. We want as rich a metadata
environment as possible, ideally one that captures all the criteria
users use to determine which provider any consumer will use. I hope that
if we have a rich enough model we don't end up with those kind of
ambiguities, or if we do then it is because the user really doesn't care
and so any of the available choices are valid.

--
Jeremy

Reply via email to