Return-Path: Delivered-To: apmail-incubator-cxf-dev-archive@locus.apache.org Received: (qmail 76858 invoked from network); 22 Jan 2007 19:36:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 22 Jan 2007 19:36:17 -0000 Received: (qmail 74957 invoked by uid 500); 22 Jan 2007 19:36:21 -0000 Delivered-To: apmail-incubator-cxf-dev-archive@incubator.apache.org Received: (qmail 74891 invoked by uid 500); 22 Jan 2007 19:36:21 -0000 Mailing-List: contact cxf-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: cxf-dev@incubator.apache.org Delivered-To: mailing list cxf-dev@incubator.apache.org Received: (qmail 74854 invoked by uid 99); 22 Jan 2007 19:36:21 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Jan 2007 11:36:21 -0800 X-ASF-Spam-Status: No, hits=2.0 required=10.0 tests=HTML_MESSAGE X-Spam-Check-By: apache.org Received-SPF: neutral (herse.apache.org: local policy) Received: from [64.233.184.235] (HELO wr-out-0506.google.com) (64.233.184.235) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 22 Jan 2007 11:36:12 -0800 Received: by wr-out-0506.google.com with SMTP id i23so771231wra for ; Mon, 22 Jan 2007 11:35:51 -0800 (PST) Received: by 10.90.115.4 with SMTP id n4mr6788212agc.1169494551437; Mon, 22 Jan 2007 11:35:51 -0800 (PST) Received: by 10.90.63.13 with HTTP; Mon, 22 Jan 2007 11:35:51 -0800 (PST) Message-ID: <7b774c950701221135m5d46bf92y5365cbc692498a9d@mail.gmail.com> Date: Mon, 22 Jan 2007 14:35:51 -0500 From: "Dan Diephouse" To: cxf-dev@incubator.apache.org Subject: Re: Configuration In-Reply-To: <45B4D7BF.9050707@iona.com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_174662_8142566.1169494551261" References: <7b774c950701181428g19c5af20gfaad699fda67139d@mail.gmail.com> <45B4D7BF.9050707@iona.com> X-Virus-Checked: Checked by ClamAV on apache.org ------=_Part_174662_8142566.1169494551261 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 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 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 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 getConfigurationValue(AbstractPropertiesHolder, T defaultValue, > > Class 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 ------=_Part_174662_8142566.1169494551261--