cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Strachan" <james.strac...@gmail.com>
Subject Re: Configuration APIs
Date Wed, 23 Aug 2006 13:28:01 GMT
On 8/23/06, Andrea Smyth <andrea.smyth@iona.com> wrote:
> Dan Diephouse wrote:
>
> > Andrea Smyth wrote:
> >
> >> 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;")
> >>>
> >> Hi Dan,
> >>
> >> For 1. and 2 to work - do you envision the configurable components to
> >> inherit from their generated beans (instead of delegate to them as is
> >> the case now)?
> >
> > I'd probably prefer that the Transports took a configuration as a
> > property instead. That way we can find the most appropriate
> > configuration, and then apply. For instance:
> >
> > HTTPTransportPolicy transportPolicy =
> > operation.get(HTTP_TRANSPORT_POLICY);
> > if (transportPolicy == null)
> >  transportPolicy = endpoint.get(HTTP_TRANSPORT_POLICY):
> >
> > if (transportPolicy == null)
> >  transportPolicy = service.get(HTTP_TRANSPORT_POLICY):
> >
> > if (transportPolicy == null)
> >  transportPolicy = getDefaultPolicy();
> >
> > Obviously we could encode this logic to be more compact (i.e. I want a
> > method which will search a hierarchy of Maps for any property), but I
> > think it gets the idea across that a transport policy could come from
> > any location. So I don't think it makes sense to have transports
> > extend their configuration.
>
> I am not sure I understand what you are getting at here:
> If you say you want to use getter/setter/constructor injection, what do
> you want to inject into? Say in the case of the http server transport,
> the transport itself has properties httpServer, authorization,
> sslServer, contextMatchStrategy (of  type HTTPServerPolicy,
> AuthorizationPolicy, SSLServerPolicy, String resp), and these get injected.
> Now, for "nice xml" in Spring configuration, you'd have to associate
> associate (via a NamespaceHandler, BeanDefinitionParser) a schema with
> the http server transport (the bean).
> While Spring 2,0 rc3 docs describe how to do this mapping manually and
> does not mention tools for automation, I believe it should be automated.

It is - thats what the xbeans-spring Maven plugin does along with the Ant task

http://geronimo.apache.org/xbean/xbean-ant-task.html


> There are two ways do do that:
> a) Start with a schema and generate an (abstract base) bean - from which
> the real bean inherits (that's what I was referring to), or
> b) Start with the bean implementation and generate the schema, using
> standard @Resource or some custom annotation.

Its the latter approach we use in xbean-spring. We're currently using
@XBean doclet tags to avoid Java 5 dependency

So no code generation of beans is required, you just annotate the
POJOs that make up your services and components. We're using this
already on ActiveMQ for example to be able to use XML like the
following inside any Spring 2 XML configuration file

http://incubator.apache.org/activemq/xml-configuration.html

There are no separate generated POJOs for these XML elements; they are
just the POJOs to implement the service with some doclet tags.

xbean-spring also auto-generates an XSD and HTML documentation reference

http://incubator.apache.org/activemq/xml-reference.html
-- 

James
-------
http://radio.weblogs.com/0112098/

Mime
View raw message