cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Diephouse <...@envoisolutions.com>
Subject Re: Configuration APIs
Date Fri, 11 Aug 2006 17:34:24 GMT
Hani Suleiman wrote:

> Why spend any effort in having our own configuration API, when there  
> are better tools to handle this? I much prefer the current xfire  
> approach of allowing you to either wire things manually (setter  
> injection) or let a container do it for you, with implementations for  
> various popular (and less so) containers.
>
> If we do go with that approach and we still really really want to  
> have our own container that nobody else uses, then our Configuration  
> implementations can just be another instance of that.
>
> The actual configurable objects themselves shouldn't care either way.  
> It makes life so much easier for embedders.
>
> I'm also not a big fan of hitching our wagon to xbean (at least, in  
> preference to anything else), it's a tiny niche product with very few  
> users or real traction.
>
Sorry if I wasn't being clear here. I wouldn't want to tie ourselves to 
it. One of the points of this email is that to help make ourselves less 
tied to containers.

However, there are some reasons user might want to use XBean. One thing 
for instance that David Blevins is adding/has added is allowing 
properties to be specified from the command line. I.e. -Dfoo.bar=baz 
would override the bar property of the foo bean from the command line.

I would however like to come up with a "here is the simplest way to use 
CXF if you don't care about what container you use"type of scenario - 
which would in essence be some hidden container underneath the covers. 
Spring 2.x would be a good choice here IMO, and we could add some of the 
XBean stuff if we need any additional functionality.

> On Aug 11, 2006, at 1:01 PM, Andrea Smyth wrote:
>
>> I won't address all of the issues Dan brought up here now, but  
>> before focusing too much on the hierarchical aspect I want to point  
>> out that I am in the process of changing this:
>>
>> There is no tree of Configuration objects any more - just a  
>> ConfigurationBuilder from which components that need configuration  
>> request it specifying their identity in the form of a CompoundName   
>> (not the javax.naming one, but a simple String[] based one) and the  
>> configuration namespace. You can look at id and namespace as the  
>> equivalents to bean id and bean class in Spring.
>>
>> So, the http client does this now:
>>
>> CompoundName id; // identify myself
>> ConfigurationBuilder builder; // obtained as bus extension
>> Configuration cfg = builder.getConfiguration 
>> (HTTP_LISTENER_CONFIGURATION_URI, id);
>> HTTPListenerPolicy policy = config.getObject 
>> (HTTPListenerPolicy.class, id);
>>
>> The bus is only used to obtain the ConfigurationBuilder - the http  
>> client does need the bus's own configuration, it does not even need  
>> to know that the bus has a configuration itself.
>> The http client still uses information about its position in the  
>> component hierarchy in order to identify itself (I am the http  
>> client for service XYZ in bus ABC) - but it does not depend in that  
>> on other components' configurations.
>>
>> Cheers,
>> Andrea.
>>
>>
>> Dan Diephouse wrote:
>>
>>> I'd like to start discussing the Configuration apis for CXF. The  
>>> main celtix configuration APIs which have integrated by default  are 
>>> here:
>>>
>>> http://svn.forge.objectweb.org/cgi-bin/viewcvs.cgi/celtix/trunk/ 
>>> celtix-common/src/main/java/org/objectweb/celtix/configuration/
>>>
>>> For those who aren't familiar with Celtix, let me try to outline  
>>> how this works. There is a tree of Configuration objects.  
>>> Configurations allow to look up a value like so:
>>>
>>> Configuration config = getBus().getConfiguration().get.Child 
>>> (HTTP_LISTENER_CONFIGURATION_URI);
>>> HTTPListenerPolicy policy = config.getObject 
>>> (HTTPListenerPolicy.class, "httpListener");
>>>
>>> Where the Bus is kind of the central object in Celtix. It has a  
>>> configuration root node which is accessed via bus.getConfiguration 
>>> ().  When initializing the bus a ConfigurationBuilder is used to  
>>> build Configurations. These Configurations are backed by   
>>> ConfigurationProviders. ConfigurationProviders provide the actual  
>>> objects. So there is a Spring ConfigurationProvider which looks up  
>>> beans from the Spring context. There is also one which will pull  
>>> configuration out of a WSDL. The objects (like HTTPListenerPolicy)  
>>> are built from XML and are JAXB beans defined by a schema.
>>>
>>> Here's a more concrete example:
>>>
>>> http://svn.forge.objectweb.org/cgi-bin/viewcvs.cgi/celtix/trunk/ 
>>> celtix-distribution/src/main/samples/configuration/client.xml? 
>>> view=auto&rev=947
>>>
>>> Here the configuration is backed by spring. The beans are looked  up 
>>> by convention - to get the configuration for the web service  port 
>>> Celtix uses the id format of "BUS_ID.SERVICE_NAME.PORT_NAME".  Which 
>>> turns into the <bean id /> format you see there.
>>>
>>> Requirements that this meets:
>>> 1. Live replacement of a configuration in the system. Since an  
>>> HTTPListenerPolicy is queried every time a listener is created, we
>>> just need to replace it in the configuration tree and the effects  
>>> will be seen across the system. It is relatively easy to have a  JMX 
>>> component which does this.
>>> 2. Ability to have configuration come from multiple sources -  wsdl, 
>>> spring, etc. For instance, I could set up a policy for a  specific
>>> endpoint in my WSDL and have a default policy in my spring config.
>>> 3. Allows configuration to be schema validated. (This is oppsed to  
>>> say the spring approach where you type <propert name="foo"/> and  
>>> hope that it is actually a property).
>>> 4. Creates a relatively straightforward way to supply  
>>> configurations in the standard case. A user just writes their  
>>> Spring definition with the standard name and its configured.
>>>
>>> ---
>>>
>>> Hopefully I've explained this somewhat well. Now, I want to talk  
>>> about what I don't like about it.
>>>
>>> 1. Its not very IoC like. Control is not inverted. For instance,  
>>> the Celtix spring integration looks up beans from the context  
>>> instead of
>>> having the beans be injected in. This loses a lot of the power of  
>>> Spring as I can't control how things are wired up. Instead Celtix  
>>> is controlling it for me.
>>>
>>> 2. It is not very friendly to people just using the API and wiring  
>>> things up themselves (like embedders and people doing unit tests) .
>>> Instead of doing something like this:
>>>
>>> HTTPListenerPolicy policy = new HTTPListenerPolicy()
>>> httptransport = new HTTPTransport();
>>> httptransport.setPolicy(policy);
>>>
>>> I have to do:
>>>
>>> HTTPListenerPolicy policy = new HTTPListenerPolicy()
>>> ConfigurationImpl c = new ConfigurationImpl();
>>> c.setObject("httpListenerPolicy", policy);
>>> getBus().getConfiguration().setChild 
>>> (HTTP_LISTENER_CONFIGURATION_URI, c);
>>> new HTTPTransport(getBus());
>>>
>>> IMO, the API should focus on making itself a great API and  friendly 
>>> to developers. This isn't very developer friendly, it is  completely 
>>> focused on people building things from XML.
>>>
>>> Furthermore this relies on me instantiating the Bus and loading  all 
>>> the configurations. What if I don't want to load the Bus? What  if I 
>>> want to mock the bus? This isn't very easy with the current  setup.
>>>
>>> 3. It is not very friendly to other containers
>>> Not all containers provide an String/id based mechanism to look up  
>>> objects. And not all provide easy ways to setup jaxb beans. Some,  
>>> like Plexus/Pico, are more component based than bean based. It  
>>> would be much easier if the configuration was part of the object  
>>> (ala point #2 above), than if it had to be looked up from a  
>>> Configuration.
>>>
>>> ---
>>>
>>> What I would like to propose is this:
>>> 1. Remove the Configuration APIs and use getter/setter/constructor  
>>> injenction.
>>>
>>> 2  Still use JAXB generated beans from schema. In addition to this  
>>> though, take the default values which are in the schema and have  
>>> the "default value plugin" from the JAXB project preinit the  
>>> private fields with those values. (i.e. <element name="timeout"  
>>> default="10"/> would turn into "private int timeout = 10;")
>>>
>>> 3. For the case where we need to override the settings (i.e.  
>>> overriding settings at an endpoint) we would create JAXB objects  
>>> from the WSDL and put them in the service model (our internal  
>>> representation of the service). Say we had some HTTPPolicy object  
>>> with a timeout setting. We would have something like this:
>>>
>>> Endpoint endpoint = exchange.get(ENDPOINT);
>>> HTTPPolicy httpPolicy = endpoint.get(HTTP_POLICY);
>>> if (httpPolicy == null)
>>>    httpPolicy = getDefaultHTTPPolicy();
>>>
>>> int timeout = httpPolicy.getTimeout();
>>>
>>> 4. Have a container responsible for injection of the configuration  
>>> beans. This should be a layer on top, not in the core. (This can  be 
>>> our own container if we really want which uses the  Configuration 
>>> stuff).
>>>
>>> I'll try to preempt a couple of objections people had to this last  
>>> point. It was mentioned that if this was done via Spring the  
>>> configuration would get obscenely complex for users. For instance,  
>>> lets say we have a master cxf.xml containing all the default bean  
>>> definitions. If we want to override just one default value, we  have 
>>> a lot of XML to write. I don't think this is true. First, the  
>>> default value plugin for jaxb makes it so that you only have to  set 
>>> the non default values in your spring xml. Second, say I have  a 
>>> master cxf.xml with all the standard bean definitions. If I have  my 
>>> own context with my own httpPolicy bean in it, I can have  spring 
>>> load just mine and not the one in cxf.xml. This is because  if you 
>>> give Spring a list of configuration files and a bean with  an id is 
>>> in multiple configurations, it will only load the last  one added. 
>>> This gives a clear way to override settings without  complex 
>>> configuration.
>>>
>>> There are probably other/better ways to do configuration in a more  
>>> IoC way as well, and I'd be interested to hear what other people  
>>> think. On a related note, I think that we should work closely with  
>>> the XBean project as their goals are quite close to ours. They are  
>>> providing configuration for Geronimo, SerivceMix, ActiveMQ, etc. I  
>>> would be very surprised if we have any use cases that they don't  
>>> have. (And I believe someone already wrote JAXB2 integration for  
>>> it...)
>>>
>>> Sorry for the long windedness here. But as Eoghan once said...  
>>> "bring on the flames"... :-)
>>>
>>> - Dan
>>>
>>
>


-- 
Dan Diephouse
(616) 971-2053
Envoi Solutions LLC
http://netzooid.com


Mime
View raw message