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 2006/12/04 21:30:56 UTC

[proposal] ConfigurationProvider/Bean configuration

Hi All,

I've been looking through the configuration code and I wanted to make a few
suggestions for cleaning things up. It seems we've simplified things a bit,
but I think they can be simpler and cleaner yet. (BTW, I'm volunteering to
make these changes)

[Bean Configuration]
Currently all the generated beans extend AbstractConfigurableBeanBase. ACBB
has a list of "overwriteProviders" and "fallkbackProviders."  These are
lists of ConfigurationProviders. When a bean's getter is called, an
overwrite provider is queried first to see if it has a value. If it doesn't,
the bean's field is queried. If it doesn't have a value, the
fallbackproviders are tried. Currently ConfigurationProviders are only used
in the HTTP and JMS code to provide data for a couple values.

Lets take a peek at what happens when we want to find the HTTPServerPolicy
for a JettyHTTPDestination:
1. HTTPDestinationConfigBean.getServer() is called. JettyHTTPDestination
indirectly extends HTTPDestinationConfigBean.
2. The overwrite providers are tried.
3. The HTTP module has a provider called ServiceModelHttpProvider which is
in the provider list. ServiceModelHttpProvider.getObject("server") is
called.
4. Inside SMHP there is conditional code for each property - if
("server".equals(name))... else if ("client".equals(name))... etc. Since
we're looking for the server property that conditioinal is triggered
5. SMHP returns the value from EndpointInfo.getExtensor(
HTTPServerPolicy.class);
6. If the result from #5 was null, the field from HTTPDestinationConfigBean
is checked to see if it has a value. If it does (and it does), it returns
7. If there were no value, the fallback providers would have been checked.

This is an OK process, but I think it is unnecessarily complex for what we
need to do. Why?

   - Currently there no fallback providers and there are only two
   ConfigurationProviders. I don't see any obvious need for them either. Am I
   missing something?
   - The two configuration providers are for the JMS and HTTP modules.
   They are both responsible for querying the service model. This seems to hint
   that maybe there is a pattern here which we should be aware of... (more
   below)
   - The configuration providers need to be explicitly aware of the
   properties being queried and the values expected for that property.

I think the above boils down to this:
1. Check to see if there is a configuration bean in the service model
2. If so return that bean.
3. If not return a default configuration bean.

My proposal is simply this: Lets just do the above 3 steps wherever we need
to find the appropriate configuration bean. Or in code form:

HttpServerPolicy getServer() {
  HttpServerPolicy policy = endpointInfo.getExtensor(HttpServerPolicy.class
);
  if (policy == null) policy = getDefaultPolicy();
  return policy;
}

Or we could add a utility method to traverse the service model and check the
binding/service as well. I think there are several advantages: simpler code,
less code, and no need for highly customized jaxb beans. I don't see any
downsides - is there something I'm missing here?

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

Re: [proposal] ConfigurationProvider/Bean configuration

Posted by Dan Diephouse <da...@envoisolutions.com>.
Andrea, others - can you let me know if I'm missing something or if we can
go ahead and simplify the configuration layer? Thanks,
- Dan

On 12/6/06, Dan Diephouse <da...@envoisolutions.com> wrote:
>
> Hi Andrea,
>
> On 12/6/06, Andrea Smyth <an...@iona.com> wrote:
> >
> > Dan Diephouse wrote:
> >
> > Hi Dan,
> >
> > The idea is to be able to supersede the information in the service model
> > with a non-default configuration bean, and only if the latter is not
> > available,  use a default bean. I.e. consider two very different sources
> > (service model on the one hand and bean provider/container on the other)
> > for non-default values.
> > I would consider the service model as something rather static, and beans
> > as more dynamic.
> > One could argue that a contract is a contract, and should not be
> > changed, but in practice it seems a useful thing to do at least in a
> > development environment:  it's easier to change a bean configuration
> > file locally than a wsdl in a possibly remote location.
>
>
> Part of the idea is that the bean configuration file sets properties on
> the the service model. So I could do:
>
> endpoint.setProperty(HttpServicePolicy.class , myEndpointPolicy);
>
> (this can be done in both the Java API and via Spring). And then if we
> support contextual lookups we can even do it at the message level:
>
> endpoint.put(HttpServicePolicy.class, myEndpointPolicy);
>
> Does that alleviate your concerns? I don't think the service model
> configuration beans always need to come from WSDL.
>
> BTW aside from transport policies, WS-policies such as the RMAssertion
> > are candidates where we may want to supersede the settings with beans
> > supplied by the container (the provider to obtain the assertion from the
> > service model is just not implemented/installed yet).
>
>
> So if an endpoint has its own policy the bus policy should override it?
> I'm not sure this makes sense to me. This for governance type scenarios
> where we want to make sure services are conforming to the global policy?
>
> I'm guess that we might actually want to support a bus first approach and
> a service model first approach. Again, it seems simpler to just code things
> in:
>
> WSRMPolicy policy;
> if (isBusFirst()) policy = getPolicyFromBus();
> else {
>   policy = getPolicyFromServiceModel()
>   if (policy == null) policy getPolicyFromBus();
> }
>
> // catch all
> if (policy == null) policy = getDefaultPolicy()
>
> Looking at this type of logic, I don't know that it even works well with
> the configurationprovider approach. Granted in the configurationProvider you
> could have an if "(isBusFirst()) return busPolicy; else return null" - but I
> don't really think thats more flexible ore more desirable than the above.
> The semantics are still hard coded in. And I don't see any use cases which
> aren't covered by setting the beans on the service model or
> message/exchange.
>
> Thoughts?
>
> - Dan
>
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
>



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

Re: [proposal] ConfigurationProvider/Bean configuration

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

On 12/6/06, Andrea Smyth <an...@iona.com> wrote:
>
> Dan Diephouse wrote:
>
> Hi Dan,
>
> The idea is to be able to supersede the information in the service model
> with a non-default configuration bean, and only if the latter is not
> available,  use a default bean. I.e. consider two very different sources
> (service model on the one hand and bean provider/container on the other)
> for non-default values.
> I would consider the service model as something rather static, and beans
> as more dynamic.
> One could argue that a contract is a contract, and should not be
> changed, but in practice it seems a useful thing to do at least in a
> development environment:  it's easier to change a bean configuration
> file locally than a wsdl in a possibly remote location.


Part of the idea is that the bean configuration file sets properties on the
the service model. So I could do:

endpoint.setProperty(HttpServicePolicy.class, myEndpointPolicy);

(this can be done in both the Java API and via Spring). And then if we
support contextual lookups we can even do it at the message level:

endpoint.put(HttpServicePolicy.class, myEndpointPolicy);

Does that alleviate your concerns? I don't think the service model
configuration beans always need to come from WSDL.

BTW aside from transport policies, WS-policies such as the RMAssertion
> are candidates where we may want to supersede the settings with beans
> supplied by the container (the provider to obtain the assertion from the
> service model is just not implemented/installed yet).


So if an endpoint has its own policy the bus policy should override it? I'm
not sure this makes sense to me. This for governance type scenarios where we
want to make sure services are conforming to the global policy?

I'm guess that we might actually want to support a bus first approach and a
service model first approach. Again, it seems simpler to just code things
in:

WSRMPolicy policy;
if (isBusFirst()) policy = getPolicyFromBus();
else {
  policy = getPolicyFromServiceModel()
  if (policy == null) policy getPolicyFromBus();
}

// catch all
if (policy == null) policy = getDefaultPolicy()

Looking at this type of logic, I don't know that it even works well with the
configurationprovider approach. Granted in the configurationProvider you
could have an if "(isBusFirst()) return busPolicy; else return null" - but I
don't really think thats more flexible ore more desirable than the above.
The semantics are still hard coded in. And I don't see any use cases which
aren't covered by setting the beans on the service model or
message/exchange.

Thoughts?

- Dan

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

Re: [proposal] ConfigurationProvider/Bean configuration

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

> Hi All,
>
> I've been looking through the configuration code and I wanted to make 
> a few
> suggestions for cleaning things up. It seems we've simplified things a 
> bit,
> but I think they can be simpler and cleaner yet. (BTW, I'm 
> volunteering to
> make these changes)
>
> [Bean Configuration]
> Currently all the generated beans extend AbstractConfigurableBeanBase. 
> ACBB
> has a list of "overwriteProviders" and "fallkbackProviders."  These are
> lists of ConfigurationProviders. When a bean's getter is called, an
> overwrite provider is queried first to see if it has a value. If it 
> doesn't,
> the bean's field is queried. If it doesn't have a value, the
> fallbackproviders are tried. Currently ConfigurationProviders are only 
> used
> in the HTTP and JMS code to provide data for a couple values.
>
> Lets take a peek at what happens when we want to find the 
> HTTPServerPolicy
> for a JettyHTTPDestination:
> 1. HTTPDestinationConfigBean.getServer() is called. JettyHTTPDestination
> indirectly extends HTTPDestinationConfigBean.
> 2. The overwrite providers are tried.
> 3. The HTTP module has a provider called ServiceModelHttpProvider 
> which is
> in the provider list. ServiceModelHttpProvider.getObject("server") is
> called.
> 4. Inside SMHP there is conditional code for each property - if
> ("server".equals(name))... else if ("client".equals(name))... etc. Since
> we're looking for the server property that conditioinal is triggered
> 5. SMHP returns the value from EndpointInfo.getExtensor(
> HTTPServerPolicy.class);
> 6. If the result from #5 was null, the field from 
> HTTPDestinationConfigBean
> is checked to see if it has a value. If it does (and it does), it returns
> 7. If there were no value, the fallback providers would have been 
> checked.
>
> This is an OK process, but I think it is unnecessarily complex for 
> what we
> need to do. Why?
>
>   - Currently there no fallback providers and there are only two
>   ConfigurationProviders. I don't see any obvious need for them 
> either. Am I
>   missing something?
>   - The two configuration providers are for the JMS and HTTP modules.
>   They are both responsible for querying the service model. This seems 
> to hint
>   that maybe there is a pattern here which we should be aware of... (more
>   below)
>   - The configuration providers need to be explicitly aware of the
>   properties being queried and the values expected for that property.
>
> I think the above boils down to this:
> 1. Check to see if there is a configuration bean in the service model
> 2. If so return that bean.
> 3. If not return a default configuration bean.

Hi Dan,

The idea is to be able to supersede the information in the service model 
with a non-default configuration bean, and only if the latter is not 
available,  use a default bean. I.e. consider two very different sources 
(service model on the one hand and bean provider/container on the other) 
for non-default values.
I would consider the service model as something rather static, and beans 
as more dynamic.
One could argue that a contract is a contract, and should not be 
changed, but in practice it seems a useful thing to do at least in a 
development environment:  it's easier to change a bean configuration 
file locally than a wsdl in a possibly remote location.

BTW aside from transport policies, WS-policies such as the RMAssertion 
are candidates where we may want to supersede the settings with beans 
supplied by the container (the provider to obtain the assertion from the 
service model is just not implemented/installed yet).

I agree that the approach is complex, but considering that the 
complexity is hidden to the consumer, I'd be wary to remove it. Beans 
for which property values will never be found anywhere except in the 
bean definition need not be generated using the xjc plugins.

Andrea.

>
> My proposal is simply this: Lets just do the above 3 steps wherever we 
> need
> to find the appropriate configuration bean. Or in code form:
>
> HttpServerPolicy getServer() {
>  HttpServerPolicy policy = 
> endpointInfo.getExtensor(HttpServerPolicy.class
> );
>  if (policy == null) policy = getDefaultPolicy();
>  return policy;
> }
>
> Or we could add a utility method to traverse the service model and 
> check the
> binding/service as well. I think there are several advantages: simpler 
> code,
> less code, and no need for highly customized jaxb beans. I don't see any
> downsides - is there something I'm missing here?
>
> Regards,
> - Dan



RE: issue in CXFServlet and EndpointImpl

Posted by Jim Ma <ji...@iona.com>.
Thank you , Dan.

It's definitely a convenient way to accommodate this case .  The
jaxwsConfiguration is for internally used and get the configuration info
from annotation .

IMO , ServiceFactory also needs a constructor to pass in the external
configuration  that we can override the WSDLUrl , executor,  wrappedStyle
and other stuff we want to override.

Regards

Jim


> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> Sent: Wednesday, December 06, 2006 11:31 AM
> To: cxf-dev@incubator.apache.org
> Subject: Re: issue in CXFServlet and EndpointImpl
>
>
> Hi Jim,
> we *could* do that, but why? You just wnat to override the WSDL
> URL, right?
> This can currently be done by:
>
> serviceFactory = new JaxWsServiceFactory();
> serviceFactory.setWsdlUrl(new URL(...));
> ...
> new EndpointImpl(bus, object, serviceFactory);
>
> There should be no need to provide a custom service configuration. Why not
> add a more convenient constructor to accommodate this case?
>
> Regards,
> - Dan
>
> On 12/5/06, Jim Ma <ji...@iona.com> wrote:
> >
> > Hi Dan ,
> >
> > Can we pass the JaxwsConfiguration in the constructor:
> >
> > new EndpointImpl(bus, object, bindingUri, jaxWsConfiguration);
> >
> > and then we do :
> >
> > JaxWsServiceFactoryBean(implInfo, jaxWsConfiguration);
> >
> > or
> >
> > JaxWsServiceFactoryBean(implInfo)
> >
> > JaxWsServiceFactoryBean.setJaxwsConfiguration(jaxWsConfiguration);
> >
> > But setJaxWsconfiguration does not seems to work, It does not add the
> > jaxwsConfiguration to the configuration list  .
> >
> >
> > Regards
> >
> > Jim
> >
> > > -----Original Message-----
> > > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > > Sent: Tuesday, December 05, 2006 12:04 PM
> > > To: cxf-dev@incubator.apache.org
> > > Subject: Re: issue in CXFServlet and EndpointImpl
> > >
> > >
> > > We could add an additional constructor which passes in the WSDL:
> > >
> > > new EndpointImpl(bus, object, bindingUri, wsdlUrl);
> > >
> > > Internally this would just do:
> > >
> > > serverFactoryBean.getServiceFactory().setWsdlUrl(wsdlUrl);
> > >
> > > Regards,
> > > - Dan
> > >
> > > On 12/4/06, Jim Ma <ji...@iona.com> wrote:
> > > >
> > > > Hi all ,
> > > >
> > > > I just found we do not set the wsdl url for the
> ServiceFactoryBean in
> > > > CXFServlet . ServiceFactoryBean still get the wsdl location from the
> > > > annotaion by invoking JaxWsConfiguration .  When we deployed the war
> > to
> > > > another machine ,  the service will fail to start  because
> it can not
> > > > find
> > > > the wsdl .
> > > >
> > > > To fix this issue , I think we need to  add a method in
> > EndpointImpl  to
> > > > create EndpointImpl with (bus, implementor ,
> > > > abstractWsServiceFactoryBean).
> > > >
> > > > Thoughts ?
> > > >
> > > > Regards
> > > >
> > > > Jim
> > > >
> > > >
> > > >
> > >
> > >
> > > --
> > > Dan Diephouse
> > > Envoi Solutions
> > > http://envoisolutions.com | http://netzooid.com/blog
> > >
> >
> >
>
>
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
>


Re: issue in CXFServlet and EndpointImpl

Posted by Dan Diephouse <da...@envoisolutions.com>.
Hi Jim,
we *could* do that, but why? You just wnat to override the WSDL URL, right?
This can currently be done by:

serviceFactory = new JaxWsServiceFactory();
serviceFactory.setWsdlUrl(new URL(...));
...
new EndpointImpl(bus, object, serviceFactory);

There should be no need to provide a custom service configuration. Why not
add a more convenient constructor to accommodate this case?

Regards,
- Dan

On 12/5/06, Jim Ma <ji...@iona.com> wrote:
>
> Hi Dan ,
>
> Can we pass the JaxwsConfiguration in the constructor:
>
> new EndpointImpl(bus, object, bindingUri, jaxWsConfiguration);
>
> and then we do :
>
> JaxWsServiceFactoryBean(implInfo, jaxWsConfiguration);
>
> or
>
> JaxWsServiceFactoryBean(implInfo)
>
> JaxWsServiceFactoryBean.setJaxwsConfiguration(jaxWsConfiguration);
>
> But setJaxWsconfiguration does not seems to work, It does not add the
> jaxwsConfiguration to the configuration list  .
>
>
> Regards
>
> Jim
>
> > -----Original Message-----
> > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > Sent: Tuesday, December 05, 2006 12:04 PM
> > To: cxf-dev@incubator.apache.org
> > Subject: Re: issue in CXFServlet and EndpointImpl
> >
> >
> > We could add an additional constructor which passes in the WSDL:
> >
> > new EndpointImpl(bus, object, bindingUri, wsdlUrl);
> >
> > Internally this would just do:
> >
> > serverFactoryBean.getServiceFactory().setWsdlUrl(wsdlUrl);
> >
> > Regards,
> > - Dan
> >
> > On 12/4/06, Jim Ma <ji...@iona.com> wrote:
> > >
> > > Hi all ,
> > >
> > > I just found we do not set the wsdl url for the ServiceFactoryBean in
> > > CXFServlet . ServiceFactoryBean still get the wsdl location from the
> > > annotaion by invoking JaxWsConfiguration .  When we deployed the war
> to
> > > another machine ,  the service will fail to start  because  it can not
> > > find
> > > the wsdl .
> > >
> > > To fix this issue , I think we need to  add a method in
> EndpointImpl  to
> > > create EndpointImpl with (bus, implementor ,
> > > abstractWsServiceFactoryBean).
> > >
> > > Thoughts ?
> > >
> > > Regards
> > >
> > > Jim
> > >
> > >
> > >
> >
> >
> > --
> > Dan Diephouse
> > Envoi Solutions
> > http://envoisolutions.com | http://netzooid.com/blog
> >
>
>


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

RE: issue in CXFServlet and EndpointImpl

Posted by Jim Ma <ji...@iona.com>.
Hi Dan ,

Can we pass the JaxwsConfiguration in the constructor:

new EndpointImpl(bus, object, bindingUri, jaxWsConfiguration);

and then we do :

JaxWsServiceFactoryBean(implInfo, jaxWsConfiguration);

or

JaxWsServiceFactoryBean(implInfo)

JaxWsServiceFactoryBean.setJaxwsConfiguration(jaxWsConfiguration);

But setJaxWsconfiguration does not seems to work, It does not add the
jaxwsConfiguration to the configuration list  .


Regards

Jim

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> Sent: Tuesday, December 05, 2006 12:04 PM
> To: cxf-dev@incubator.apache.org
> Subject: Re: issue in CXFServlet and EndpointImpl
>
>
> We could add an additional constructor which passes in the WSDL:
>
> new EndpointImpl(bus, object, bindingUri, wsdlUrl);
>
> Internally this would just do:
>
> serverFactoryBean.getServiceFactory().setWsdlUrl(wsdlUrl);
>
> Regards,
> - Dan
>
> On 12/4/06, Jim Ma <ji...@iona.com> wrote:
> >
> > Hi all ,
> >
> > I just found we do not set the wsdl url for the ServiceFactoryBean in
> > CXFServlet . ServiceFactoryBean still get the wsdl location from the
> > annotaion by invoking JaxWsConfiguration .  When we deployed the war to
> > another machine ,  the service will fail to start  because  it can not
> > find
> > the wsdl .
> >
> > To fix this issue , I think we need to  add a method in EndpointImpl  to
> > create EndpointImpl with (bus, implementor ,
> > abstractWsServiceFactoryBean).
> >
> > Thoughts ?
> >
> > Regards
> >
> > Jim
> >
> >
> >
>
>
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
>


Re: issue in CXFServlet and EndpointImpl

Posted by Dan Diephouse <da...@envoisolutions.com>.
We could add an additional constructor which passes in the WSDL:

new EndpointImpl(bus, object, bindingUri, wsdlUrl);

Internally this would just do:

serverFactoryBean.getServiceFactory().setWsdlUrl(wsdlUrl);

Regards,
- Dan

On 12/4/06, Jim Ma <ji...@iona.com> wrote:
>
> Hi all ,
>
> I just found we do not set the wsdl url for the ServiceFactoryBean in
> CXFServlet . ServiceFactoryBean still get the wsdl location from the
> annotaion by invoking JaxWsConfiguration .  When we deployed the war to
> another machine ,  the service will fail to start  because  it can not
> find
> the wsdl .
>
> To fix this issue , I think we need to  add a method in EndpointImpl  to
> create EndpointImpl with (bus, implementor ,
> abstractWsServiceFactoryBean).
>
> Thoughts ?
>
> Regards
>
> Jim
>
>
>


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

issue in CXFServlet and EndpointImpl

Posted by Jim Ma <ji...@iona.com>.
Hi all ,

I just found we do not set the wsdl url for the ServiceFactoryBean in
CXFServlet . ServiceFactoryBean still get the wsdl location from the
annotaion by invoking JaxWsConfiguration .  When we deployed the war to
another machine ,  the service will fail to start  because  it can not find
the wsdl .

To fix this issue , I think we need to  add a method in EndpointImpl  to
create EndpointImpl with (bus, implementor , abstractWsServiceFactoryBean).

Thoughts ?

Regards

Jim