You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Dan Diephouse <da...@envoisolutions.com> on 2007/01/18 23:28:49 UTC

Configuration

Hi All,

Just wanted to propose something a bit more concrete via Configuration
before going about it. Basically we have these cases:
1. Configuration comes from Spring XML
2. Configuration comes from service model (WSDL, API)
3. Configuration may come from some data source (Database, properties file)

Instead of the ConfigurationProvider approach we can simplify by
1. Making beans just beans without our code generation customization
2. Creating a method on the Bus to get configuration values:

HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);

The method definition would be something like this:

<T> T getConfigurationValue(AbstractPropertiesHolder, T defaultValue,
Class<T> type);

This method would then search through the Bus, Endpoint, etc for the
HTTPServerPolicy value. If none is found the default value is returned.

You may ask, isn't it simpler to just call getHTTPServerPolicy() on the
current code? In actuality no, because we need to write
ConfigurationProviders which actually search the service model, so its more
code. Additionally it requires code customization for the beans which is a
pain. This would be easier for people writing extensions to CXF to use.

The getConfigurationValue() method would delegate to a ConfigurationManager
interface which would contain this method and allow people to plug in
different ways of doing resolution. For instance, by having the bus always
override values.

Spring can actually take configuration from the database and properties
files, so I think this covers all our bases. And if the container can't
cover some edge case I think people can pretty easily override the default
ConfigurationManager with their own.

(BTW, I'm not too keen on the getConfigurationValue name, so if you have
suggestions let me know)

Thoughts?
Cheers,

- Dan

-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
Crap. I hit tab-enter accidentally while composing. :-( Will send off a
finished version soon....

On 1/22/07, Dan Diephouse <da...@envoisolutions.com> wrote:
>
> OK, first let me try to give a little more context, and then I'll try to
> answer your specific questions.
>
> In our current code we have a ConfigurationProvider mechanism. As I
> understand the motivation for this as it allows configuration values to come
> form places other than the bean itself. Supporting this use case is a Good
> Thing.
>
> As I dug through Spring 2's documentation, I noticed the
> BeanFactoryPostProcessor interface [1]. This allows customizing of how the
> beans are configured. One example of this bean is the PropertyOverrideConfigurer
> bean. It can take values from a properties file and override a bean's
> properties with them. Other examples take configuration from web.xml files
> or from databases. Spring can take a list of these BeanFactoryPostProcessors
> and they can be ordered. This means our configuration can come from anywhere
> with the one notable exception of the service model.
>
> I'm thinking, this seems to do exactly what we want and it doesn't req
>
>
> 1.
> http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html
>
> On 1/22/07, Andrea Smyth <an...@iona.com> wrote:
> >
> > Dan Diephouse wrote:
> >
> > > Hi All,
> > >
> > > Just wanted to propose something a bit more concrete via Configuration
> > > before going about it. Basically we have these cases:
> > > 1. Configuration comes from Spring XML
> > > 2. Configuration comes from service model (WSDL, API)
> > > 3. Configuration may come from some data source (Database, properties
> > > file)
> > >
> > > Instead of the ConfigurationProvider approach we can simplify by
> > > 1. Making beans just beans without our code generation customization
> > > 2. Creating a method on the Bus to get configuration values:
> > >
> > > HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
> > > getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);
> >
> >
> > Do you want to reintroduce configuration APIs -  what about testability?
> > It looks like every bean client will need access to the bus ...
> >
> > Also not sure how this API is to be used, specifically
> > a) when should a bean client use the bean's getter only/when should it
> > use the bean's getter and/or the above API?
>
>
> Any time
>
> b) where does the default value come from? In order to distinguish
> > default value from in injected value (i.e. value coming from sources 1.
> > and 3. above) and value coming from service model it looks like every
> > bean should have a
> > T getTProperty();
> > and a
> > // no (public) setter for this one
> > T getDefaultTProperty(); ?
> > Where is the preference of injected value vs. default value vs. obtained
> > from service model determined? IMO it's important this happens in one
> > place only, and if it's in bus.getConfigurationValue(...) we need to
> > pass both the default and the injected value.
> >
> > >
> > > The method definition would be something like this:
> > >
> > > <T> T getConfigurationValue(AbstractPropertiesHolder, T defaultValue,
> > > Class<T> type);
> > >
> > > This method would then search through the Bus, Endpoint, etc for the
> > > HTTPServerPolicy value. If none is found the default value is
> > returned.
> >
> > What do you mean with searching through the Bus?
> >
> > >
> > > You may ask, isn't it simpler to just call getHTTPServerPolicy() on
> > the
> > > current code? In actuality no, because we need to write
> > > ConfigurationProviders which actually search the service model, so its
> >
> > > more
> > > code.
> >
> > One generic ConfigurationProvider can be used in most if not all cases,
> > and there would be no more code to that than there would be to the
> > implementation of the above getConfigurationValue - in fact they'd be
> > pretty much the same thing.
> >
> The point
>
>
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
OK, first let me try to give a little more context, and then I'll try to
answer your specific questions.

In our current code we have a ConfigurationProvider mechanism. As I
understand the motivation for this as it allows configuration values to come
form places other than the bean itself. Supporting this use case is a Good
Thing.

As I dug through Spring 2's documentation, I noticed the
BeanFactoryPostProcessor interface [1]. This allows customizing of how the
beans are configured. One example of this bean is the
PropertyOverrideConfigurer
bean. It can take values from a properties file and override a bean's
properties with them. Other examples take configuration from web.xml files
or from databases. Spring can take a list of these BeanFactoryPostProcessors
and they can be ordered. This means our configuration can come from anywhere
with the one notable exception of the service model.

I'm thinking, this seems to do exactly what we want and it doesn't req


1.
http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html

On 1/22/07, Andrea Smyth <an...@iona.com> wrote:
>
> Dan Diephouse wrote:
>
> > Hi All,
> >
> > Just wanted to propose something a bit more concrete via Configuration
> > before going about it. Basically we have these cases:
> > 1. Configuration comes from Spring XML
> > 2. Configuration comes from service model (WSDL, API)
> > 3. Configuration may come from some data source (Database, properties
> > file)
> >
> > Instead of the ConfigurationProvider approach we can simplify by
> > 1. Making beans just beans without our code generation customization
> > 2. Creating a method on the Bus to get configuration values:
> >
> > HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
> > getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);
>
>
> Do you want to reintroduce configuration APIs -  what about testability?
> It looks like every bean client will need access to the bus ...
>
> Also not sure how this API is to be used, specifically
> a) when should a bean client use the bean's getter only/when should it
> use the bean's getter and/or the above API?


Any time

b) where does the default value come from? In order to distinguish
> default value from in injected value (i.e. value coming from sources 1.
> and 3. above) and value coming from service model it looks like every
> bean should have a
> T getTProperty();
> and a
> // no (public) setter for this one
> T getDefaultTProperty(); ?
> Where is the preference of injected value vs. default value vs. obtained
> from service model determined? IMO it's important this happens in one
> place only, and if it's in bus.getConfigurationValue(...) we need to
> pass both the default and the injected value.
>
> >
> > The method definition would be something like this:
> >
> > <T> T getConfigurationValue(AbstractPropertiesHolder, T defaultValue,
> > Class<T> type);
> >
> > This method would then search through the Bus, Endpoint, etc for the
> > HTTPServerPolicy value. If none is found the default value is returned.
>
> What do you mean with searching through the Bus?
>
> >
> > You may ask, isn't it simpler to just call getHTTPServerPolicy() on the
> > current code? In actuality no, because we need to write
> > ConfigurationProviders which actually search the service model, so its
> > more
> > code.
>
> One generic ConfigurationProvider can be used in most if not all cases,
> and there would be no more code to that than there would be to the
> implementation of the above getConfigurationValue - in fact they'd be
> pretty much the same thing.
>
The point


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
Is the CXF-390 backwards? Or is the proposed implementation backwards?

I agree with the comments in 390 and the way I proposed does support it.
First, you find/construct your default value. Then you do
setFoo(getConfigurationValue(serviceModel, defaultValue)) in the contructor.
That will set the "foo" property on the bean when it is constructed. Then
spring will come in and set its properties on the bean via <property
name="foo".../> or via post processors.

There does seem to be a possibility that the person could set the
configuration property to the service model value after the bean is built
though.

- Dan

On 1/24/07, Daniel Kulp <da...@iona.com> wrote:
>
>
>
> Thinking about this some more......
>
> Isn't this backwords anyway?
> https://issues.apache.org/jira/browse/CXF-390
>
> Shouldn't the spring fed value override the wsdl value?   Or at least
> merge
> in?     Use the values specified from spring to merge into the service
> model?
> (so the resulting wsdl generated from the service model has the "active"
> information?)
>
> Dan
>
>
>
> On Wednesday 24 January 2007 14:37, Daniel Kulp wrote:
> > On Wednesday 24 January 2007 14:23, Dan Diephouse wrote:
> > > On 1/24/07, Andrea Smyth <an...@iona.com> wrote:
> > > > To sum up,  my main concerns are:
> > > >
> > > > * Use of static APIs (I don't see how this can get around keeping
> > > > references to the bus all over the place as the bus itself is not
> > > > static).
> > >
> > > I meant something like this:
> > >
> > > public static  <T> T getConfiguration(AbstractPropertiesHolder props,
> T
> > > defaultValue, Class<T> type);
> > >
> > > The point of the getConfiguration method isn't to introduce a
> > > Configuration type interface, its merely to encapsulate the logic
> which
> > > traverses the service model. For example:
> >
> > Out of curiosity, could this just moved into the model directly?
> > Basically, add a method to AbstractPropertiesHolder like:
> > public <T> T traverseAndGetExtensor(T defaultValue, Class<T> type) {
> >         T t = getExtensor
> >         if (t == null) {
> >              t = defaultValue;
> >         }
> >       return t;
> > }
> >
> > and then override it in  EndpointInfo and any of the other servicemodel
> > components that may need to do so.
> >
> > Would that work?
> > Dan
> >
> > >     public <T> T getConfiguration(AbstractPropertiesHolder props, T
> > > defaultValue, Class<T> type) {
> > >         T value = props.getExtensor(type);
> > >
> > >         if (value == null) {
> > >             if (props instanceof EndpointInfo) {
> > >                 value = getServiceModelValue((EndpointInfo) props,
> type);
> > >             }
> > >
> > >             if (value == null) {
> > >                 value = defaultValue;
> > >             }
> > >         }
> > >
> > >         return value;
> > >     }
> > >
> > >     private <T> T getServiceModelValue(EndpointInfo info, Class<T>
> type)
> > > { T value = null;
> > >
> > >         BindingInfo b = info.getBinding();
> > >         if (value == null && b != null) {
> > >             value = b.getExtensor(type);
> > >         }
> > >
> > >         ServiceInfo s = info.getService();
> > >         if (s != null && value == null) {
> > >             value = s.getExtensor(type);
> > >         }
> > >
> > >         return value;
> > >     }
> > >
> > > Ideally there would be support for getting properties from Messages
> and
> > > Operations as well though.
> > >
> > > * Reintroduction of configuration APIs - although IMO this would not
> be
> > >
> > > > so bad,  Celtix has lived with cfg APIs long enough. I just find the
> > > > idea surprising after the discussions that took place on this
> mailing
> > > > list half a year earlier.
> > >
> > > I view this as quite different from the Configuration APIs. The
> > > Configuration APIs were basically a hierarchical tree of values.
> > > getConfiguration().getChild(...).getValue(). The proposed solution is
> > > just a convenience method for finding values in the service model.
> This
> > > allows the containers to do their thing (xml/db/properties config,
> > > wiring) and still allows us to get values from the service model.
> > >
> > > The method really might be better named "getServiceModelExtensor"
> instead
> > > of getConfigurationValue...
> > >
> > > * If configuration APIs are reintroduced I would like to see them used
> > >
> > > > consistently. If bean clients end up doing this:
> > > > T t = bean.getTValue();
> > > > in some places and:
> > > > T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
> > > > or:
> > > > T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
> > > > in others places I'd consider that a source of
> > > > problems/inconsistencies.  But maybe others don't think it's as big
> > > > problem as I think it is?
> > >
> > > I think the same consistencies arise with the  current approach. I can
> > > easily forget or not realize that I have to have a
> ConfigurationProvider
> > > check for a value in the service model. Both approaches require some
> > > manual wiring.
> > >
> > > - Dan
>
> --
> J. Daniel Kulp
> Principal Engineer
> IONA
> P: 781-902-8727    C: 508-380-7194
> daniel.kulp@iona.com
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Daniel Kulp <da...@iona.com>.

Thinking about this some more......

Isn't this backwords anyway?    
https://issues.apache.org/jira/browse/CXF-390

Shouldn't the spring fed value override the wsdl value?   Or at least merge 
in?     Use the values specified from spring to merge into the service model? 
(so the resulting wsdl generated from the service model has the "active" 
information?)

Dan



On Wednesday 24 January 2007 14:37, Daniel Kulp wrote:
> On Wednesday 24 January 2007 14:23, Dan Diephouse wrote:
> > On 1/24/07, Andrea Smyth <an...@iona.com> wrote:
> > > To sum up,  my main concerns are:
> > >
> > > * Use of static APIs (I don't see how this can get around keeping
> > > references to the bus all over the place as the bus itself is not
> > > static).
> >
> > I meant something like this:
> >
> > public static  <T> T getConfiguration(AbstractPropertiesHolder props, T
> > defaultValue, Class<T> type);
> >
> > The point of the getConfiguration method isn't to introduce a
> > Configuration type interface, its merely to encapsulate the logic which
> > traverses the service model. For example:
>
> Out of curiosity, could this just moved into the model directly?  
> Basically, add a method to AbstractPropertiesHolder like:
> public <T> T traverseAndGetExtensor(T defaultValue, Class<T> type) {
>         T t = getExtensor
>         if (t == null) {
>              t = defaultValue;
>         }
> 	return t;
> }
>
> and then override it in  EndpointInfo and any of the other servicemodel
> components that may need to do so.
>
> Would that work?
> Dan
>
> >     public <T> T getConfiguration(AbstractPropertiesHolder props, T
> > defaultValue, Class<T> type) {
> >         T value = props.getExtensor(type);
> >
> >         if (value == null) {
> >             if (props instanceof EndpointInfo) {
> >                 value = getServiceModelValue((EndpointInfo) props, type);
> >             }
> >
> >             if (value == null) {
> >                 value = defaultValue;
> >             }
> >         }
> >
> >         return value;
> >     }
> >
> >     private <T> T getServiceModelValue(EndpointInfo info, Class<T> type)
> > { T value = null;
> >
> >         BindingInfo b = info.getBinding();
> >         if (value == null && b != null) {
> >             value = b.getExtensor(type);
> >         }
> >
> >         ServiceInfo s = info.getService();
> >         if (s != null && value == null) {
> >             value = s.getExtensor(type);
> >         }
> >
> >         return value;
> >     }
> >
> > Ideally there would be support for getting properties from Messages and
> > Operations as well though.
> >
> > * Reintroduction of configuration APIs - although IMO this would not be
> >
> > > so bad,  Celtix has lived with cfg APIs long enough. I just find the
> > > idea surprising after the discussions that took place on this mailing
> > > list half a year earlier.
> >
> > I view this as quite different from the Configuration APIs. The
> > Configuration APIs were basically a hierarchical tree of values.
> > getConfiguration().getChild(...).getValue(). The proposed solution is
> > just a convenience method for finding values in the service model. This
> > allows the containers to do their thing (xml/db/properties config,
> > wiring) and still allows us to get values from the service model.
> >
> > The method really might be better named "getServiceModelExtensor" instead
> > of getConfigurationValue...
> >
> > * If configuration APIs are reintroduced I would like to see them used
> >
> > > consistently. If bean clients end up doing this:
> > > T t = bean.getTValue();
> > > in some places and:
> > > T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
> > > or:
> > > T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
> > > in others places I'd consider that a source of
> > > problems/inconsistencies.  But maybe others don't think it's as big
> > > problem as I think it is?
> >
> > I think the same consistencies arise with the  current approach. I can
> > easily forget or not realize that I have to have a ConfigurationProvider
> > check for a value in the service model. Both approaches require some
> > manual wiring.
> >
> > - Dan

-- 
J. Daniel Kulp
Principal Engineer
IONA
P: 781-902-8727    C: 508-380-7194
daniel.kulp@iona.com

Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
I think I'd be ok with this. I don't see any downside at the moment.
- Dan

On 1/24/07, Daniel Kulp <da...@iona.com> wrote:
>
>
>
> On Wednesday 24 January 2007 14:23, Dan Diephouse wrote:
> > On 1/24/07, Andrea Smyth <an...@iona.com> wrote:
> > > To sum up,  my main concerns are:
> > >
> > > * Use of static APIs (I don't see how this can get around keeping
> > > references to the bus all over the place as the bus itself is not
> > > static).
> >
> > I meant something like this:
> >
> > public static  <T> T getConfiguration(AbstractPropertiesHolder props, T
> > defaultValue, Class<T> type);
> >
> > The point of the getConfiguration method isn't to introduce a
> Configuration
> > type interface, its merely to encapsulate the logic which traverses the
> > service model. For example:
>
> Out of curiosity, could this just moved into the model directly?
> Basically,
> add a method to AbstractPropertiesHolder like:
> public <T> T traverseAndGetExtensor(T defaultValue, Class<T> type) {
>         T t = getExtensor
>         if (t == null) {
>              t = defaultValue;
>         }
>         return t;
> }
>
> and then override it in  EndpointInfo and any of the other servicemodel
> components that may need to do so.
>
> Would that work?
> Dan
>
>
> >
> >     public <T> T getConfiguration(AbstractPropertiesHolder props, T
> > defaultValue, Class<T> type) {
> >         T value = props.getExtensor(type);
> >
> >         if (value == null) {
> >             if (props instanceof EndpointInfo) {
> >                 value = getServiceModelValue((EndpointInfo) props,
> type);
> >             }
> >
> >             if (value == null) {
> >                 value = defaultValue;
> >             }
> >         }
> >
> >         return value;
> >     }
> >
> >     private <T> T getServiceModelValue(EndpointInfo info, Class<T> type)
> {
> >         T value = null;
> >
> >         BindingInfo b = info.getBinding();
> >         if (value == null && b != null) {
> >             value = b.getExtensor(type);
> >         }
> >
> >         ServiceInfo s = info.getService();
> >         if (s != null && value == null) {
> >             value = s.getExtensor(type);
> >         }
> >
> >         return value;
> >     }
> >
> > Ideally there would be support for getting properties from Messages and
> > Operations as well though.
> >
> > * Reintroduction of configuration APIs - although IMO this would not be
> >
> > > so bad,  Celtix has lived with cfg APIs long enough. I just find the
> > > idea surprising after the discussions that took place on this mailing
> > > list half a year earlier.
> >
> > I view this as quite different from the Configuration APIs. The
> > Configuration APIs were basically a hierarchical tree of values.
> > getConfiguration().getChild(...).getValue(). The proposed solution is
> just
> > a convenience method for finding values in the service model. This
> allows
> > the containers to do their thing (xml/db/properties config, wiring) and
> > still allows us to get values from the service model.
> >
> > The method really might be better named "getServiceModelExtensor"
> instead
> > of getConfigurationValue...
> >
> > * If configuration APIs are reintroduced I would like to see them used
> >
> > > consistently. If bean clients end up doing this:
> > > T t = bean.getTValue();
> > > in some places and:
> > > T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
> > > or:
> > > T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
> > > in others places I'd consider that a source of
> > > problems/inconsistencies.  But maybe others don't think it's as big
> > > problem as I think it is?
> >
> > I think the same consistencies arise with the  current approach. I can
> > easily forget or not realize that I have to have a ConfigurationProvider
> > check for a value in the service model. Both approaches require some
> manual
> > wiring.
> >
> > - Dan
>
> --
> J. Daniel Kulp
> Principal Engineer
> IONA
> P: 781-902-8727    C: 508-380-7194
> daniel.kulp@iona.com
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Daniel Kulp <da...@iona.com>.

On Wednesday 24 January 2007 14:23, Dan Diephouse wrote:
> On 1/24/07, Andrea Smyth <an...@iona.com> wrote:
> > To sum up,  my main concerns are:
> >
> > * Use of static APIs (I don't see how this can get around keeping
> > references to the bus all over the place as the bus itself is not
> > static).
>
> I meant something like this:
>
> public static  <T> T getConfiguration(AbstractPropertiesHolder props, T
> defaultValue, Class<T> type);
>
> The point of the getConfiguration method isn't to introduce a Configuration
> type interface, its merely to encapsulate the logic which traverses the
> service model. For example:

Out of curiosity, could this just moved into the model directly?   Basically, 
add a method to AbstractPropertiesHolder like:
public <T> T traverseAndGetExtensor(T defaultValue, Class<T> type) {
        T t = getExtensor
        if (t == null) {
             t = defaultValue;
        }
	return t;
}

and then override it in  EndpointInfo and any of the other servicemodel 
components that may need to do so.

Would that work?
Dan


>
>     public <T> T getConfiguration(AbstractPropertiesHolder props, T
> defaultValue, Class<T> type) {
>         T value = props.getExtensor(type);
>
>         if (value == null) {
>             if (props instanceof EndpointInfo) {
>                 value = getServiceModelValue((EndpointInfo) props, type);
>             }
>
>             if (value == null) {
>                 value = defaultValue;
>             }
>         }
>
>         return value;
>     }
>
>     private <T> T getServiceModelValue(EndpointInfo info, Class<T> type) {
>         T value = null;
>
>         BindingInfo b = info.getBinding();
>         if (value == null && b != null) {
>             value = b.getExtensor(type);
>         }
>
>         ServiceInfo s = info.getService();
>         if (s != null && value == null) {
>             value = s.getExtensor(type);
>         }
>
>         return value;
>     }
>
> Ideally there would be support for getting properties from Messages and
> Operations as well though.
>
> * Reintroduction of configuration APIs - although IMO this would not be
>
> > so bad,  Celtix has lived with cfg APIs long enough. I just find the
> > idea surprising after the discussions that took place on this mailing
> > list half a year earlier.
>
> I view this as quite different from the Configuration APIs. The
> Configuration APIs were basically a hierarchical tree of values.
> getConfiguration().getChild(...).getValue(). The proposed solution is just
> a convenience method for finding values in the service model. This allows
> the containers to do their thing (xml/db/properties config, wiring) and
> still allows us to get values from the service model.
>
> The method really might be better named "getServiceModelExtensor" instead
> of getConfigurationValue...
>
> * If configuration APIs are reintroduced I would like to see them used
>
> > consistently. If bean clients end up doing this:
> > T t = bean.getTValue();
> > in some places and:
> > T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
> > or:
> > T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
> > in others places I'd consider that a source of
> > problems/inconsistencies.  But maybe others don't think it's as big
> > problem as I think it is?
>
> I think the same consistencies arise with the  current approach. I can
> easily forget or not realize that I have to have a ConfigurationProvider
> check for a value in the service model. Both approaches require some manual
> wiring.
>
> - Dan

-- 
J. Daniel Kulp
Principal Engineer
IONA
P: 781-902-8727    C: 508-380-7194
daniel.kulp@iona.com

Re: Configuration

Posted by Andrea Smyth <an...@iona.com>.
Dan Diephouse wrote:

> Hi Andrea,
>
> On 1/24/07, Andrea Smyth <an...@iona.com> wrote:
>
>>
>> To sum up,  my main concerns are:
>>
>> * Use of static APIs (I don't see how this can get around keeping
>> references to the bus all over the place as the bus itself is not 
>> static).
>
>
>
> I meant something like this:
>
> public static  <T> T getConfiguration(AbstractPropertiesHolder props, T
> defaultValue, Class<T> type);
>
> The point of the getConfiguration method isn't to introduce a 
> Configuration
> type interface, its merely to encapsulate the logic which traverses the
> service model. For example:
>
>    public <T> T getConfiguration(AbstractPropertiesHolder props, T
> defaultValue, Class<T> type) {
>        T value = props.getExtensor(type);
>
>        if (value == null) {
>            if (props instanceof EndpointInfo) {
>                value = getServiceModelValue((EndpointInfo) props, type);
>            }
>
>            if (value == null) {
>                value = defaultValue;
>            }
>        }
>
>        return value;
>    }
>
>    private <T> T getServiceModelValue(EndpointInfo info, Class<T> type) {
>        T value = null;
>
>        BindingInfo b = info.getBinding();
>        if (value == null && b != null) {
>            value = b.getExtensor(type);
>        }
>
>        ServiceInfo s = info.getService();
>        if (s != null && value == null) {
>            value = s.getExtensor(type);
>        }
>
>        return value;
>    }
>
> Ideally there would be support for getting properties from Messages and
> Operations as well though.

My impression was that bus.getConfiguration(...), or something else,  
was supposed to do all of what you listed earlier:
 >The resolution order would be like this:
 >1. The default value - i.e. new HTTPServerPolicy();
 >2. The value found on the service model - this would potentially be 
from the WSDL.
 >3. The value set on the bean in the config file
 >4. The value set on the bean via "other stuff" aka 
BeanFactoryPostProcessors/BeanPostProcessors

But I realise it's really only seaching the service model  (and as such 
there is no need for it to be static), and that there will be no 
mechanism in place to ensure that steps 1. to 3. are done consistently 
every time a property is needed (4. is not an issue as it happens in the 
background).

>
> * Reintroduction of configuration APIs - although IMO this would not be
>
>> so bad,  Celtix has lived with cfg APIs long enough. I just find the
>> idea surprising after the discussions that took place on this mailing
>> list half a year earlier.
>
>
>
> I view this as quite different from the Configuration APIs. The
> Configuration APIs were basically a hierarchical tree of values.
> getConfiguration().getChild(...).getValue(). 

No - the hierarchy was gone by the time code was dropped into the apache 
repository. It was instead like:
getConfiguration().getValue(...)

> The proposed solution is just a
> convenience method for finding values in the service model. This 
> allows the
> containers to do their thing (xml/db/properties config, wiring) and still
> allows us to get values from the service model.
>
> The method really might be better named "getServiceModelExtensor" 
> instead of
> getConfigurationValue...
>
> * If configuration APIs are reintroduced I would like to see them used
>
>> consistently. If bean clients end up doing this:
>> T t = bean.getTValue();
>> in some places and:
>> T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
>> or:
>> T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
>> in others places I'd consider that a source of
>> problems/inconsistencies.  But maybe others don't think it's as big
>> problem as I think it is?
>
>
>
> I think the same consistencies arise with the  current approach. I can
> easily forget or not realize that I have to have a ConfigurationProvider
> check for a value in the service model. Both approaches require some 
> manual
> wiring.

No - this is one of the main  advantages of the current/previous 
approaches: clients only ever make *one call* to the bean's getter/to 
the component'ss configuration object. The traversal of the service 
model,  and the precedence between default, injected and service model 
value need were never of concern to the client.
Do you not think that instead of repeat coding steps 1. to 3.  above,  
people end up writing wrappers that do just that (effectively making up 
for what was previously hidden in the the 'extended getters'/the 
configuration API)? I would.

Andrea.

> - Dan
>
>
>


Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
Hi Andrea,

On 1/24/07, Andrea Smyth <an...@iona.com> wrote:
>
> To sum up,  my main concerns are:
>
> * Use of static APIs (I don't see how this can get around keeping
> references to the bus all over the place as the bus itself is not static).


I meant something like this:

public static  <T> T getConfiguration(AbstractPropertiesHolder props, T
defaultValue, Class<T> type);

The point of the getConfiguration method isn't to introduce a Configuration
type interface, its merely to encapsulate the logic which traverses the
service model. For example:

    public <T> T getConfiguration(AbstractPropertiesHolder props, T
defaultValue, Class<T> type) {
        T value = props.getExtensor(type);

        if (value == null) {
            if (props instanceof EndpointInfo) {
                value = getServiceModelValue((EndpointInfo) props, type);
            }

            if (value == null) {
                value = defaultValue;
            }
        }

        return value;
    }

    private <T> T getServiceModelValue(EndpointInfo info, Class<T> type) {
        T value = null;

        BindingInfo b = info.getBinding();
        if (value == null && b != null) {
            value = b.getExtensor(type);
        }

        ServiceInfo s = info.getService();
        if (s != null && value == null) {
            value = s.getExtensor(type);
        }

        return value;
    }

Ideally there would be support for getting properties from Messages and
Operations as well though.

* Reintroduction of configuration APIs - although IMO this would not be
> so bad,  Celtix has lived with cfg APIs long enough. I just find the
> idea surprising after the discussions that took place on this mailing
> list half a year earlier.


I view this as quite different from the Configuration APIs. The
Configuration APIs were basically a hierarchical tree of values.
getConfiguration().getChild(...).getValue(). The proposed solution is just a
convenience method for finding values in the service model. This allows the
containers to do their thing (xml/db/properties config, wiring) and still
allows us to get values from the service model.

The method really might be better named "getServiceModelExtensor" instead of
getConfigurationValue...

* If configuration APIs are reintroduced I would like to see them used
> consistently. If bean clients end up doing this:
> T t = bean.getTValue();
> in some places and:
> T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
> or:
> T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
> in others places I'd consider that a source of
> problems/inconsistencies.  But maybe others don't think it's as big
> problem as I think it is?


I think the same consistencies arise with the  current approach. I can
easily forget or not realize that I have to have a ConfigurationProvider
check for a value in the service model. Both approaches require some manual
wiring.

- Dan



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Andrea Smyth <an...@iona.com>.
To sum up,  my main concerns are:

* Use of static APIs (I don't see how this can get around keeping 
references to the bus all over the place as the bus itself is not static).
* Reintroduction of configuration APIs - although IMO this would not be 
so bad,  Celtix has lived with cfg APIs long enough. I just find the 
idea surprising after the discussions that took place on this mailing 
list half a year earlier.
* If configuration APIs are reintroduced I would like to see them used 
consistently. If bean clients end up doing this:
T t = bean.getTValue();
in some places and:
T t = bus.getConfiguration(endpointInfo, defaultT, T.class);
or:
T t = bus.getConfiguration(endpointInfo, bean.getTValue(), T.class);
in others places I'd consider that a source of 
problems/inconsistencies.  But maybe others don't think it's as big 
problem as I think it is?

Andrea.

Some more comments below...

Dan Diephouse wrote:

> I wanted to make one more point explicit from my previous email. Both the
> current and the proposed approach require you to explicitly write code 
> which
> grabs configuration from the service model. In the current code this 
> takes
> the form of writing a ConfigurationProvider class and doing something 
> like
> this (from the JMS module)
>
>    public ServiceModelJMSConfigurationProvider(EndpointInfo i) {
>        info = i;
>    }
>
>    public Object getObject(String name) {
>
>        if (null == info) {
>            return null;
>        }
>
>        if ("server".equals(name)) {
>            return info.getExtensor(JMSServerBehaviorPolicyType.class);
>        }
> ...
>
> In the proposed approach this would just boil down to:
>
> setServer(bus.getConfiguration(endpointInfo, 
> defaultJMSServerBehaviorPolicy,
> JMSServerBehaviorPolicyType.class));

I don't know what are trying to get at by comparing the use of one API 
with the  implementation of another?

>
> Neither are 100% transparent, but the later seems a bit simpler to me.
>
> - Dan
>
>
> On 1/22/07, Dan Diephouse <da...@envoisolutions.com> wrote:
>
>>
>> OK, first let me try to give a little more context, as my last email was
>> rather vague. Then I'll try to answer your specific questions.
>>
>> In our current code we have a ConfigurationProvider mechanism. As I
>> understand the motivation for this as it allows configuration values 
>> to come
>> form places other than the bean itself. Supporting this use case is a 
>> Good
>> Thing.
>>
>> As I dug through Spring 2's documentation, I noticed the
>> BeanFactoryPostProcessor [1] and BeanPostProcessor interfaces [2]. These
>> allow customizing of how the beans are configured. One example of 
>> this bean
>> is the PropertyOverrideConfigurer bean. It can take values from a
>> properties file and override a bean's properties with them. Other 
>> examples
>> take configuration from web.xml files or from databases. Spring can 
>> take a
>> list of these BeanFactoryPostProcessors and they can be ordered. 
>> Since any
>> bean that takes configuration values goes through the Configurer or 
>> comes
>> from Spring itself, this means our configuration could be done via these
>> mechanisms.
>>
>> I'm thinking, this seems to do exactly what we want and so lets see 
>> if we
>> can reuse it instead of writing our own mechanism. The one notable 
>> problem
>> is how to wire in the service model.
>>
>> I'll divide our configuration sources into 3 areas: the bean (i.e.
>> HTTPDestinationConfigBean), the service model (i.e. EndpointInfo), and
>> "other stuff" (i.e. JDBC). And lets look at it in the context of our
>> favorite hypothetical example, the HTTPServerPolicy. Under the 
>> proposal we
>> would have a call like this in the AbstractHTTPDestination constructor:
>>
>> setServer(bus.getConfiguration(endpointInfo, new HTTPServerPolicy(),
>> HTTPServerPolicy.class));
>>
>> The resolution order would be like this:
>> 1. The default value - i.e. new HTTPServerPolicy();
>> 2. The value found on the service model - this would potentially be from
>> the WSDL.
>> 3. The value set on the bean in the config file
>
how can getConfiguration get the value of the bean in the config file 
with the given parametrization?

>> 4. The value set on the bean via "other stuff" aka
>> BeanFactoryPostProcessors/BeanPostProcessors
>>
>> Note that all the getConfiguration() method is doing is simply
>> encapsulating our service model traversing logic. So it would check the
>> endpointInfo, then the bindingInfo, then the ServiceInfo. If no value 
>> was
>> found, it would return the "new HTTPServerPolicy".
>>
>> I'm going to guess that the #1 objection toward this would be that the
>> resolution model isn't configurable. For instance I could have 
>> specified a
>> configuration in the WSDL, in a <bean> and in a property file. Which one
>> should CXF use? First, this highlights that in the current code there 
>> is no
>> way to merge these values at all as its kind of an all or nothing 
>> approach.
>
>> A ConfigurationProvider would simply grab the value from the service 
>> model
>> and give that to the HTTP transport. But, if we let Spring handle 
>> this, our
>> merging will occur automatically. Example:
>> 1. The value from the service model gets set on the JettyHTTPDestination
>> via our setServer(...) call above.
>> 2. There is a <property name="server.contentType" value="text/json"/> on
>> the Spring bean definition. This calls
>> getServer().setContentType("text/json") instead of creating a new
>> HTTPServerPolicy
>> 3. The -D...JettyHTTPDestination.server.receiveTimeout=300 property 
>> is set
>> from the command line. This operates similarly to #2.
>>
>> All three would then be merged into one HTTPServerPolicy object then. So
>> we have some added flexibility here IMO. Second, I don't know that I 
>> really
>> see any use cases for changing the ordering. This is partly because I 
>> don't
>> see multiple configuration sources being a case that occurs much (if 
>> at all?
>> Maybe wsdl + xml, or wsdl+properties, but I doubt all three). But also
>> because I'm not sure that I would want my WSDL to override what I set 
>> in my
>> xml config or specify via command line. If there are objections to the
>> ordering of the resolution, or it not being flexible enough, could you
>> please elaborate on some use cases?
>
Additional sources and in fact a more complicated lookup may come in 
with WS-Policy. A server endpoint's policy can come from the attachment 
of a policy to the port, portType, or binding element (i.e. different 
kind of navigation in the service model), combined with the effective 
policy for the service which apples to all of its endpoints.
There is also the option of external policy attachments, where you'd 
find policies along with an appliesTo that is expressed in the form of a 
URI domain expression, e.g.
<wsp:PolicyAttachment>
    <wsp:AppliesTo>
       
<wsp:URI>http://example.org/TicketAgent.wsdl20#wsdl.endpoint(TicketAgentService/Endpoint)</wsp:URI>
    </wsp:AppliesTo>
  <wsp:Policy>
    <http:server>....</http:server>
  </wsp:Policy>
</wsp:PolicyAttachment>

WS-Policy vs. configuration is a big issue though, and I think we should 
focus on bringing the current discussion to an end,  it's been going on 
for too long. If changes will be needed in support of a common approach 
to configuration and WS-Policy we'll make them later.

>>
>> More comments inline...
>>
>> 1.
>> http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html 
>>
>> 2.
>> http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanPostProcessor.html 
>>
>>
>> On 1/22/07, Andrea Smyth < andrea.smyth@iona.com> wrote:
>> >
>> > Dan Diephouse wrote:
>> >
>> > > Hi All,
>> > >
>> > > Just wanted to propose something a bit more concrete via 
>> Configuration
>> > > before going about it. Basically we have these cases:
>> > > 1. Configuration comes from Spring XML
>> > > 2. Configuration comes from service model (WSDL, API)
>> > > 3. Configuration may come from some data source (Database, 
>> properties
>> > > file)
>> > >
>> > > Instead of the ConfigurationProvider approach we can simplify by
>> > > 1. Making beans just beans without our code generation customization
>> > > 2. Creating a method on the Bus to get configuration values:
>> > >
>> > > HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
>> > > getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);
>> >
>> >
>> > Do you want to reintroduce configuration APIs -  what about 
>> testability?
>>
>>
>>  I don't think testability changes much from our current code to what 
>> this
>> proposal outlines. We set a value on our service model and then we run a
>> unit test to make sure the component used it.
>>
>> It looks like every bean client will need access to the bus ...
>>
>>
>> I'd consider making the getConfigurationValue method a static. The 
>> one use
>> case you had raised is that if you want to have a default value that 
>> is set
>> globally on the Bus (i.e. a Bus had a default HTTPServerPolicy). 
>> Although
>> I think that could just as easily be done with a BeanPostProcessor. 
>> So maybe
>> a static method is in order.
>>
>> Also not sure how this API is to be used, specifically
>> > a) when should a bean client use the bean's getter only/when should it
>> > use the bean's getter and/or the above API?
>>
>>
>> You would pretty much only use the getConfigurationValue if you 
>> needed to
>> get the value out of the service model. So its quite a bit different 
>> than
>> the original Configuration interface.
>>
>> b) where does the default value come from? In order to distinguish
>> > default value from in injected value ( i.e. value coming from 
>> sources 1.
>> > and 3. above) and value coming from service model it looks like every
>> > bean should have a
>> > T getTProperty();
>> > and a
>> > // no (public) setter for this one
>> > T getDefaultTProperty(); ?
>> > Where is the preference of injected value vs. default value vs. 
>> obtained
>> > from service model determined? IMO it's important this happens in one
>> > place only, and if it's in bus.getConfigurationValue(...) we need to
>> > pass both the default and the injected value.
>>
>>
>> See my explanation at the top.
>>
>> >
>> > > The method definition would be something like this:
>> > >
>> > > <T> T getConfigurationValue(AbstractPropertiesHolder, T 
>> defaultValue,
>> > > Class<T> type);
>> > >
>> > > This method would then search through the Bus, Endpoint, etc for the
>> > > HTTPServerPolicy value. If none is found the default value is
>> > returned.
>> >
>> > What do you mean with searching through the Bus?
>>
>>
>> See my above example of setting the HTTPServerPolicy on the Bus.
>>
>> >
>> > > You may ask, isn't it simpler to just call getHTTPServerPolicy() on
>> > the
>> > > current code? In actuality no, because we need to write
>> > > ConfigurationProviders which actually search the service model, 
>> so its
>> > > more
>> > > code.
>> >
>> > One generic ConfigurationProvider can be used in most if not all 
>> cases,
>> > and there would be no more code to that than there would be to the
>> > implementation of the above getConfigurationValue - in fact they'd be
>> > pretty much the same thing.
>> >
>> > Its not that ConfigurationProvider doesn't work, its that I want to 
>> have
>> Spring do as much of the work as possible and require as little
>> configuration code as possible for implementors.
>>
>> Cheers,
>> - Dan
>> -- 
>> Dan Diephouse
>> Envoi Solutions
>> http://envoisolutions.com | http://netzooid.com/blog
>>
>
>
>


Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
I wanted to make one more point explicit from my previous email. Both the
current and the proposed approach require you to explicitly write code which
grabs configuration from the service model. In the current code this takes
the form of writing a ConfigurationProvider class and doing something like
this (from the JMS module)

    public ServiceModelJMSConfigurationProvider(EndpointInfo i) {
        info = i;
    }

    public Object getObject(String name) {

        if (null == info) {
            return null;
        }

        if ("server".equals(name)) {
            return info.getExtensor(JMSServerBehaviorPolicyType.class);
        }
...

In the proposed approach this would just boil down to:

setServer(bus.getConfiguration(endpointInfo, defaultJMSServerBehaviorPolicy,
JMSServerBehaviorPolicyType.class));

Neither are 100% transparent, but the later seems a bit simpler to me.

- Dan


On 1/22/07, Dan Diephouse <da...@envoisolutions.com> wrote:
>
> OK, first let me try to give a little more context, as my last email was
> rather vague. Then I'll try to answer your specific questions.
>
> In our current code we have a ConfigurationProvider mechanism. As I
> understand the motivation for this as it allows configuration values to come
> form places other than the bean itself. Supporting this use case is a Good
> Thing.
>
> As I dug through Spring 2's documentation, I noticed the
> BeanFactoryPostProcessor [1] and BeanPostProcessor interfaces [2]. These
> allow customizing of how the beans are configured. One example of this bean
> is the PropertyOverrideConfigurer bean. It can take values from a
> properties file and override a bean's properties with them. Other examples
> take configuration from web.xml files or from databases. Spring can take a
> list of these BeanFactoryPostProcessors and they can be ordered. Since any
> bean that takes configuration values goes through the Configurer or comes
> from Spring itself, this means our configuration could be done via these
> mechanisms.
>
> I'm thinking, this seems to do exactly what we want and so lets see if we
> can reuse it instead of writing our own mechanism. The one notable problem
> is how to wire in the service model.
>
> I'll divide our configuration sources into 3 areas: the bean (i.e.
> HTTPDestinationConfigBean), the service model (i.e. EndpointInfo), and
> "other stuff" (i.e. JDBC). And lets look at it in the context of our
> favorite hypothetical example, the HTTPServerPolicy. Under the proposal we
> would have a call like this in the AbstractHTTPDestination constructor:
>
> setServer(bus.getConfiguration(endpointInfo, new HTTPServerPolicy(),
> HTTPServerPolicy.class));
>
> The resolution order would be like this:
> 1. The default value - i.e. new HTTPServerPolicy();
> 2. The value found on the service model - this would potentially be from
> the WSDL.
> 3. The value set on the bean in the config file
> 4. The value set on the bean via "other stuff" aka
> BeanFactoryPostProcessors/BeanPostProcessors
>
> Note that all the getConfiguration() method is doing is simply
> encapsulating our service model traversing logic. So it would check the
> endpointInfo, then the bindingInfo, then the ServiceInfo. If no value was
> found, it would return the "new HTTPServerPolicy".
>
> I'm going to guess that the #1 objection toward this would be that the
> resolution model isn't configurable. For instance I could have specified a
> configuration in the WSDL, in a <bean> and in a property file. Which one
> should CXF use? First, this highlights that in the current code there is no
> way to merge these values at all as its kind of an all or nothing approach.
> A ConfigurationProvider would simply grab the value from the service model
> and give that to the HTTP transport. But, if we let Spring handle this, our
> merging will occur automatically. Example:
> 1. The value from the service model gets set on the JettyHTTPDestination
> via our setServer(...) call above.
> 2. There is a <property name="server.contentType" value="text/json"/> on
> the Spring bean definition. This calls
> getServer().setContentType("text/json") instead of creating a new
> HTTPServerPolicy
> 3. The -D...JettyHTTPDestination.server.receiveTimeout=300 property is set
> from the command line. This operates similarly to #2.
>
> All three would then be merged into one HTTPServerPolicy object then. So
> we have some added flexibility here IMO. Second, I don't know that I really
> see any use cases for changing the ordering. This is partly because I don't
> see multiple configuration sources being a case that occurs much (if at all?
> Maybe wsdl + xml, or wsdl+properties, but I doubt all three). But also
> because I'm not sure that I would want my WSDL to override what I set in my
> xml config or specify via command line. If there are objections to the
> ordering of the resolution, or it not being flexible enough, could you
> please elaborate on some use cases?
>
> More comments inline...
>
> 1.
> http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html
> 2.
> http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanPostProcessor.html
>
> On 1/22/07, Andrea Smyth < andrea.smyth@iona.com> wrote:
> >
> > Dan Diephouse wrote:
> >
> > > Hi All,
> > >
> > > Just wanted to propose something a bit more concrete via Configuration
> > > before going about it. Basically we have these cases:
> > > 1. Configuration comes from Spring XML
> > > 2. Configuration comes from service model (WSDL, API)
> > > 3. Configuration may come from some data source (Database, properties
> > > file)
> > >
> > > Instead of the ConfigurationProvider approach we can simplify by
> > > 1. Making beans just beans without our code generation customization
> > > 2. Creating a method on the Bus to get configuration values:
> > >
> > > HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
> > > getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);
> >
> >
> > Do you want to reintroduce configuration APIs -  what about testability?
>
>
>  I don't think testability changes much from our current code to what this
> proposal outlines. We set a value on our service model and then we run a
> unit test to make sure the component used it.
>
> It looks like every bean client will need access to the bus ...
>
>
> I'd consider making the getConfigurationValue method a static. The one use
> case you had raised is that if you want to have a default value that is set
> globally on the Bus (i.e. a Bus had a default HTTPServerPolicy). Although
> I think that could just as easily be done with a BeanPostProcessor. So maybe
> a static method is in order.
>
> Also not sure how this API is to be used, specifically
> > a) when should a bean client use the bean's getter only/when should it
> > use the bean's getter and/or the above API?
>
>
> You would pretty much only use the getConfigurationValue if you needed to
> get the value out of the service model. So its quite a bit different than
> the original Configuration interface.
>
> b) where does the default value come from? In order to distinguish
> > default value from in injected value ( i.e. value coming from sources 1.
> > and 3. above) and value coming from service model it looks like every
> > bean should have a
> > T getTProperty();
> > and a
> > // no (public) setter for this one
> > T getDefaultTProperty(); ?
> > Where is the preference of injected value vs. default value vs. obtained
> > from service model determined? IMO it's important this happens in one
> > place only, and if it's in bus.getConfigurationValue(...) we need to
> > pass both the default and the injected value.
>
>
> See my explanation at the top.
>
> >
> > > The method definition would be something like this:
> > >
> > > <T> T getConfigurationValue(AbstractPropertiesHolder, T defaultValue,
> > > Class<T> type);
> > >
> > > This method would then search through the Bus, Endpoint, etc for the
> > > HTTPServerPolicy value. If none is found the default value is
> > returned.
> >
> > What do you mean with searching through the Bus?
>
>
> See my above example of setting the HTTPServerPolicy on the Bus.
>
> >
> > > You may ask, isn't it simpler to just call getHTTPServerPolicy() on
> > the
> > > current code? In actuality no, because we need to write
> > > ConfigurationProviders which actually search the service model, so its
> > > more
> > > code.
> >
> > One generic ConfigurationProvider can be used in most if not all cases,
> > and there would be no more code to that than there would be to the
> > implementation of the above getConfigurationValue - in fact they'd be
> > pretty much the same thing.
> >
> > Its not that ConfigurationProvider doesn't work, its that I want to have
> Spring do as much of the work as possible and require as little
> configuration code as possible for implementors.
>
> Cheers,
> - Dan
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
OK, first let me try to give a little more context, as my last email was
rather vague. Then I'll try to answer your specific questions.

In our current code we have a ConfigurationProvider mechanism. As I
understand the motivation for this as it allows configuration values to come
form places other than the bean itself. Supporting this use case is a Good
Thing.

As I dug through Spring 2's documentation, I noticed the
BeanFactoryPostProcessor [1] and BeanPostProcessor interfaces [2]. These
allow customizing of how the beans are configured. One example of this bean
is the PropertyOverrideConfigurer bean. It can take values from a properties
file and override a bean's properties with them. Other examples take
configuration from web.xml files or from databases. Spring can take a list
of these BeanFactoryPostProcessors and they can be ordered. Since any bean
that takes configuration values goes through the Configurer or comes from
Spring itself, this means our configuration could be done via these
mechanisms.

I'm thinking, this seems to do exactly what we want and so lets see if we
can reuse it instead of writing our own mechanism. The one notable problem
is how to wire in the service model.

I'll divide our configuration sources into 3 areas: the bean (i.e.
HTTPDestinationConfigBean), the service model (i.e. EndpointInfo), and
"other stuff" (i.e. JDBC). And lets look at it in the context of our
favorite hypothetical example, the HTTPServerPolicy. Under the proposal we
would have a call like this in the AbstractHTTPDestination constructor:

setServer(bus.getConfiguration(endpointInfo, new HTTPServerPolicy(),
HTTPServerPolicy.class));

The resolution order would be like this:
1. The default value - i.e. new HTTPServerPolicy();
2. The value found on the service model - this would potentially be from the
WSDL.
3. The value set on the bean in the config file
4. The value set on the bean via "other stuff" aka
BeanFactoryPostProcessors/BeanPostProcessors

Note that all the getConfiguration() method is doing is simply encapsulating
our service model traversing logic. So it would check the endpointInfo, then
the bindingInfo, then the ServiceInfo. If no value was found, it would
return the "new HTTPServerPolicy".

I'm going to guess that the #1 objection toward this would be that the
resolution model isn't configurable. For instance I could have specified a
configuration in the WSDL, in a <bean> and in a property file. Which one
should CXF use? First, this highlights that in the current code there is no
way to merge these values at all as its kind of an all or nothing approach.
A ConfigurationProvider would simply grab the value from the service model
and give that to the HTTP transport. But, if we let Spring handle this, our
merging will occur automatically. Example:
1. The value from the service model gets set on the JettyHTTPDestination via
our setServer(...) call above.
2. There is a <property name="server.contentType" value="text/json"/> on the
Spring bean definition. This calls getServer().setContentType("text/json")
instead of creating a new HTTPServerPolicy
3. The -D...JettyHTTPDestination.server.receiveTimeout=300 property is set
from the command line. This operates similarly to #2.

All three would then be merged into one HTTPServerPolicy object then. So we
have some added flexibility here IMO. Second, I don't know that I really see
any use cases for changing the ordering. This is partly because I don't see
multiple configuration sources being a case that occurs much (if at all?
Maybe wsdl + xml, or wsdl+properties, but I doubt all three). But also
because I'm not sure that I would want my WSDL to override what I set in my
xml config or specify via command line. If there are objections to the
ordering of the resolution, or it not being flexible enough, could you
please elaborate on some use cases?

More comments inline...

1.
http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html
2.
http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/config/BeanPostProcessor.html

On 1/22/07, Andrea Smyth <an...@iona.com> wrote:
>
> Dan Diephouse wrote:
>
> > Hi All,
> >
> > Just wanted to propose something a bit more concrete via Configuration
> > before going about it. Basically we have these cases:
> > 1. Configuration comes from Spring XML
> > 2. Configuration comes from service model (WSDL, API)
> > 3. Configuration may come from some data source (Database, properties
> > file)
> >
> > Instead of the ConfigurationProvider approach we can simplify by
> > 1. Making beans just beans without our code generation customization
> > 2. Creating a method on the Bus to get configuration values:
> >
> > HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
> > getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);
>
>
> Do you want to reintroduce configuration APIs -  what about testability?


 I don't think testability changes much from our current code to what this
proposal outlines. We set a value on our service model and then we run a
unit test to make sure the component used it.

It looks like every bean client will need access to the bus ...


I'd consider making the getConfigurationValue method a static. The one use
case you had raised is that if you want to have a default value that is set
globally on the Bus (i.e. a Bus had a default HTTPServerPolicy). Although I
think that could just as easily be done with a BeanPostProcessor. So maybe a
static method is in order.

Also not sure how this API is to be used, specifically
> a) when should a bean client use the bean's getter only/when should it
> use the bean's getter and/or the above API?


You would pretty much only use the getConfigurationValue if you needed to
get the value out of the service model. So its quite a bit different than
the original Configuration interface.

b) where does the default value come from? In order to distinguish
> default value from in injected value (i.e. value coming from sources 1.
> and 3. above) and value coming from service model it looks like every
> bean should have a
> T getTProperty();
> and a
> // no (public) setter for this one
> T getDefaultTProperty(); ?
> Where is the preference of injected value vs. default value vs. obtained
> from service model determined? IMO it's important this happens in one
> place only, and if it's in bus.getConfigurationValue(...) we need to
> pass both the default and the injected value.


See my explanation at the top.

>
> > The method definition would be something like this:
> >
> > <T> T getConfigurationValue(AbstractPropertiesHolder, T defaultValue,
> > Class<T> type);
> >
> > This method would then search through the Bus, Endpoint, etc for the
> > HTTPServerPolicy value. If none is found the default value is returned.
>
> What do you mean with searching through the Bus?


See my above example of setting the HTTPServerPolicy on the Bus.

>
> > You may ask, isn't it simpler to just call getHTTPServerPolicy() on the
> > current code? In actuality no, because we need to write
> > ConfigurationProviders which actually search the service model, so its
> > more
> > code.
>
> One generic ConfigurationProvider can be used in most if not all cases,
> and there would be no more code to that than there would be to the
> implementation of the above getConfigurationValue - in fact they'd be
> pretty much the same thing.
>
> Its not that ConfigurationProvider doesn't work, its that I want to have
Spring do as much of the work as possible and require as little
configuration code as possible for implementors.

Cheers,
- Dan
-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: Configuration

Posted by Andrea Smyth <an...@iona.com>.
Dan Diephouse wrote:

> Hi All,
>
> Just wanted to propose something a bit more concrete via Configuration
> before going about it. Basically we have these cases:
> 1. Configuration comes from Spring XML
> 2. Configuration comes from service model (WSDL, API)
> 3. Configuration may come from some data source (Database, properties 
> file)
>
> Instead of the ConfigurationProvider approach we can simplify by
> 1. Making beans just beans without our code generation customization
> 2. Creating a method on the Bus to get configuration values:
>
> HTTPServerPolicy p = bus.getConfigurationValue(endpointInfo,
> getDefaultHTTPServerPolicy(), HTTTPServerPolicy.class);


Do you want to reintroduce configuration APIs -  what about testability?
It looks like every bean client will need access to the bus ...

Also not sure how this API is to be used, specifically
a) when should a bean client use the bean's getter only/when should it 
use the bean's getter and/or the above API?
b) where does the default value come from? In order to distinguish 
default value from in injected value (i.e. value coming from sources 1. 
and 3. above) and value coming from service model it looks like every 
bean should have a
T getTProperty();
and a
// no (public) setter for this one
T getDefaultTProperty(); ?
Where is the preference of injected value vs. default value vs. obtained 
from service model determined? IMO it's important this happens in one 
place only, and if it's in bus.getConfigurationValue(...) we need to 
pass both the default and the injected value.

>
> The method definition would be something like this:
>
> <T> T getConfigurationValue(AbstractPropertiesHolder, T defaultValue,
> Class<T> type);
>
> This method would then search through the Bus, Endpoint, etc for the
> HTTPServerPolicy value. If none is found the default value is returned.

What do you mean with searching through the Bus?

>
> You may ask, isn't it simpler to just call getHTTPServerPolicy() on the
> current code? In actuality no, because we need to write
> ConfigurationProviders which actually search the service model, so its 
> more
> code.

One generic ConfigurationProvider can be used in most if not all cases, 
and there would be no more code to that than there would be to the 
implementation of the above getConfigurationValue - in fact they'd be 
pretty much the same thing.

Andrea.

> Additionally it requires code customization for the beans which is a
> pain. This would be easier for people writing extensions to CXF to use.
>
> The getConfigurationValue() method would delegate to a 
> ConfigurationManager
> interface which would contain this method and allow people to plug in
> different ways of doing resolution. For instance, by having the bus 
> always
> override values.
> Spring can actually take configuration from the database and properties
> files, so I think this covers all our bases. 

> And if the container can't
> cover some edge case I think people can pretty easily override the 
> default
> ConfigurationManager with their own.
>
> (BTW, I'm not too keen on the getConfigurationValue name, so if you have
> suggestions let me know)
>
> Thoughts?
> Cheers,
>
> - Dan
>