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/08/09 18:05:28 UTC

Component discovery/DeferredObjectManager

Lets back up a little bit first so people can follow a bit better. There 
are two things I feel we need to have thorough discussions about. The 
first, which is in this email, I think could be referred to as 
discovery. The second is Configuration, but we'll get to that later. I 
want to outline the case of the BindingFactoryManager here as it 
succinctly encapsulates what we need to do.

In the merged code base we have a class called BindingFactory. This 
class takes metadata about the binding called BindingInfo and turns it 
into classes which actually handle the binding processing. So for SOAP 
it would take our metadata about the style, use, etc and configure 
interceptors which process the xml.

Now we have all these BindingFactorys. One for REST, one for SOAP, one 
for JBI, etc. We need a way to look up the appropriate BindingFactory 
from the code which takes a WSDL and builds a Service from it. This is 
where the BindingFactoryManager comes into play. It has a pretty simple 
interface:

public interface BindingFactoryManager {
 void registerBindingFactory(String name, BindingFactory binding)
 void unregisterBindingFactory(String name)
 BindingFactory getBindingFactory(String name);
}

Now the big question here is - how does the BindingFactoryManager learn 
about the BindingFactorys?

Currently in Celtix there is a binding.properties file like this which 
the BindingFactoryManagerImpl reads in:

<properties>
   <entry 
key="http://schemas.xmlsoap.org/wsdl/soap/">org.objectweb.celtix.bindings.soap.SOAPBindingFactory</entry> 

   <entry 
key="http://schemas.xmlsoap.org/wsdl/soap/http">org.objectweb.celtix.bindings.soap.SOAPBindingFactory</entry> 

   <entry 
key="http://celtix.objectweb.org/transports/jms">org.objectweb.celtix.bindings.soap.SOAPBindingFactory</entry> 

</properties>

One can see each BindingFactory in the xml has a name (aka key) and a 
class. The BindingFactoryManagerImpl reads these in and loads each one.

The proposed DeferredObjectManager is an improvement on this format, 
where there is something like:

<extensions>
<extension namespace="http://cxf.apache.org/bindings" 
name="http://schemas.xmlsoap.org/wsdl/soap/" 
class="org.objectweb.celtix.bindings.soap.SOAPBindingFactory"/>
</extensions>

Now, I believe the point of this is that a) an extension could be 
registered for any manager (TransportManager, BindingFactoryManager, 
etc) and b) that the DeferredObjectManager would not load things until 
they were needed.

I am of the opinion that this kind of thing shouldn't be part of the 
core. It is the job of the container. I.e. BindingFactoryManager should 
not be aware of whatever it is that loads teh transports. So we 
discussed doing something like so:

// this would read in all the <extension> files
DeferredObjectManager dom = new DefferredObjectManager();
// the deferred map looks up extensions in the specified namespace
DeferredMap bindings = new DeferredMap("http://cxf.apache.org/bindings")

BindingFactoryManager bfm = new BindingFactoryManagerImpl(bindings);

This has a couple benefits:
- IMO its nicer because we've inverted control. The 
BindingFactoryManager isn't aware of things that load Bindings. It just 
manages bindings.
- The configuration of the BindingFactoryManager is now separate from 
its implementation. We can move the classes (deferredobjectmanager) out 
of the core and have it be a separate container.
- We now play nicer with other containers - Spring, Plexus, Pico, etc 
could all supply the Map of bindingfactorys.
- The core is now focused on being an excellent API, not being a container.

I am still not 100% sure I like having a deferredobjectmanager when 
there are a bunch of other containers out there that do this type of 
thing. However, this does have benefits because there are a) no 
dependencies and b) it is very small.

Thoughts?
- Dan

Andrea Smyth wrote:

> For an introduction to the subject see the copy attached below of the 
> conversation Dan D, Dan K. and myself had last Friday on a non-public 
> IRC channel:
>
> What about calling the DeferredObjectManager ExtensionManager instead.
> Dan D: Do you really want it in a separate module? Maybe 
> cxf-rt2-extension, and have cxf-rt2-core and at least one of the Bus 
> implementations in the core depend on it?
>
> There is one bit that I don't like about the approach - or maybe I 
> have misunderstood: If a particular object (say: BindingFactory) is 
> marked for deferred loading, the Deferred ObjectManager would store 
> the object class under the namespaceURI for the bindings that this 
> factory can create.
> And when the BindingFactory is finally is loaded, in one of its 
> @PostConstruct annotated methods it registers these same namespaceURIs 
> with the BindingFactoryManager (as that is the instance with which an 
> Endpoint interacts when it needs a Binding created - not the Bus), 
> i.e. we also store the association of a set of namespaceURIs with a 
> BindingFactory in the BindingFactoryManager.
> This seems to be duplicated information at best, but there is the risk 
> that the set of namespaceURIs is not the same.
> Should we inject the list of namespaceURIs into the deferred object to 
> avoid namespaceURI mapping conflicts? Or rely on the fact that the 
> @PostConstruct methods do the right thing?
>
> Regards,
> Andrea.
>
>


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


Re: Component discovery/DeferredObjectManager

Posted by Andrea Smyth <an...@iona.com>.
Some comments below ...

Dan Diephouse wrote:

> Lets back up a little bit first so people can follow a bit better. 
> There are two things I feel we need to have thorough discussions 
> about. The first, which is in this email, I think could be referred to 
> as discovery. The second is Configuration, but we'll get to that 
> later. I want to outline the case of the BindingFactoryManager here as 
> it succinctly encapsulates what we need to do.
>
> In the merged code base we have a class called BindingFactory. This 
> class takes metadata about the binding called BindingInfo and turns it 
> into classes which actually handle the binding processing. So for SOAP 
> it would take our metadata about the style, use, etc and configure 
> interceptors which process the xml.
>
> Now we have all these BindingFactorys. One for REST, one for SOAP, one 
> for JBI, etc. We need a way to look up the appropriate BindingFactory 
> from the code which takes a WSDL and builds a Service from it. This is 
> where the BindingFactoryManager comes into play. It has a pretty 
> simple interface:
>
> public interface BindingFactoryManager {
> void registerBindingFactory(String name, BindingFactory binding)
> void unregisterBindingFactory(String name)
> BindingFactory getBindingFactory(String name);
> }
>
> Now the big question here is - how does the BindingFactoryManager 
> learn about the BindingFactorys?
>
> Currently in Celtix there is a binding.properties file like this which 
> the BindingFactoryManagerImpl reads in:
>
> <properties>
>   <entry 
> key="http://schemas.xmlsoap.org/wsdl/soap/">org.objectweb.celtix.bindings.soap.SOAPBindingFactory</entry> 
>
>   <entry 
> key="http://schemas.xmlsoap.org/wsdl/soap/http">org.objectweb.celtix.bindings.soap.SOAPBindingFactory</entry> 
>
>   <entry 
> key="http://celtix.objectweb.org/transports/jms">org.objectweb.celtix.bindings.soap.SOAPBindingFactory</entry> 
>
> </properties>
>
> One can see each BindingFactory in the xml has a name (aka key) and a 
> class. The BindingFactoryManagerImpl reads these in and loads each one.

One binding factory can serve multiple namespaces (bindingIds) - i.e. we 
can have the same BindingFactory stored under the same key in the 
BindingFactoryManager.

>
> The proposed DeferredObjectManager is an improvement on this format, 
> where there is something like:
>
> <extensions>
> <extension namespace="http://cxf.apache.org/bindings" 
> name="http://schemas.xmlsoap.org/wsdl/soap/" 
> class="org.objectweb.celtix.bindings.soap.SOAPBindingFactory"/>
> </extensions>

It would be more like:
1)
<extension name="bindingFactoryManager" 
class="org.objectweb.celtix.bindings.BindingFactoryManagerImpl" deferred 
="false"/> // no namespace child elements here

and 2)

<extension class="org.objectweb.celtix.bindings.soap.SoapBindingFactory" 
deferred="true">
<namespace>http://schemas.xmlsoap.org/wsdl/soap/</namespace>
<namespace>http://schemas.xmlsoap.org/wsdl/soap/http</namespace>
</extension>

The name attribute of the first extension element is used to make the 
extension available through the Bus via 
getObject("bindingFactoryManager", BindingFactoryManager.class);

Not sure if the second element should have its name attribute set ? To 
"bindingFactoryManager" maybe and use this name in constructor of the 
DeferredMap below? Or do we both a name and a namespace attribute in the 
extension element for that purpose?
I find it a bit confusing to have child elements and attributes of the 
same name.

Andrea.

>
> Now, I believe the point of this is that a) an extension could be 
> registered for any manager (TransportManager, BindingFactoryManager, 
> etc) and b) that the DeferredObjectManager would not load things until 
> they were needed.
>
> I am of the opinion that this kind of thing shouldn't be part of the 
> core. It is the job of the container. I.e. BindingFactoryManager 
> should not be aware of whatever it is that loads teh transports. So we 
> discussed doing something like so:
>
> // this would read in all the <extension> files
> DeferredObjectManager dom = new DefferredObjectManager();
> // the deferred map looks up extensions in the specified namespace
> DeferredMap bindings = new DeferredMap("http://cxf.apache.org/bindings")
>
> BindingFactoryManager bfm = new BindingFactoryManagerImpl(bindings);
>
> This has a couple benefits:
> - IMO its nicer because we've inverted control. The 
> BindingFactoryManager isn't aware of things that load Bindings. It 
> just manages bindings.
> - The configuration of the BindingFactoryManager is now separate from 
> its implementation. We can move the classes (deferredobjectmanager) 
> out of the core and have it be a separate container.
> - We now play nicer with other containers - Spring, Plexus, Pico, etc 
> could all supply the Map of bindingfactorys.
> - The core is now focused on being an excellent API, not being a 
> container.
>
> I am still not 100% sure I like having a deferredobjectmanager when 
> there are a bunch of other containers out there that do this type of 
> thing. However, this does have benefits because there are a) no 
> dependencies and b) it is very small.
>
> Thoughts?
> - Dan
>
> Andrea Smyth wrote:
>
>> For an introduction to the subject see the copy attached below of the 
>> conversation Dan D, Dan K. and myself had last Friday on a non-public 
>> IRC channel:
>>
>> What about calling the DeferredObjectManager ExtensionManager instead.
>> Dan D: Do you really want it in a separate module? Maybe 
>> cxf-rt2-extension, and have cxf-rt2-core and at least one of the Bus 
>> implementations in the core depend on it?
>>
>> There is one bit that I don't like about the approach - or maybe I 
>> have misunderstood: If a particular object (say: BindingFactory) is 
>> marked for deferred loading, the Deferred ObjectManager would store 
>> the object class under the namespaceURI for the bindings that this 
>> factory can create.
>> And when the BindingFactory is finally is loaded, in one of its 
>> @PostConstruct annotated methods it registers these same 
>> namespaceURIs with the BindingFactoryManager (as that is the instance 
>> with which an Endpoint interacts when it needs a Binding created - 
>> not the Bus), i.e. we also store the association of a set of 
>> namespaceURIs with a BindingFactory in the BindingFactoryManager.
>> This seems to be duplicated information at best, but there is the 
>> risk that the set of namespaceURIs is not the same.
>> Should we inject the list of namespaceURIs into the deferred object 
>> to avoid namespaceURI mapping conflicts? Or rely on the fact that the 
>> @PostConstruct methods do the right thing?
>>
>> Regards,
>> Andrea.
>>
>>
>
>