On Monday 17 January 2011 7:30:39 am Andrei Shakirin wrote:
> Hi folks,
>
> By developing of custom CXF transport factory I faced one strange behavior
> looks like a bug.
>
> Scenario:
> 1. I register my factory using
> Bus bus = BusFactory.getDefaultBus();
> DestinationFactoryManagerImpl dfm = new
> DestinationFactoryManagerImpl(bus); SBBTransportFactory sbbTransport = new
> SBBTransportFactory();
> dfm.registerDestinationFactory("http://cxf.apache.org/transports/sbb",
> sbbTransport);
> dfm.registerDestinationFactory("http://schemas.xmlsoap.org/soap/http",
> sbbTransport);
> dfm.registerDestinationFactory("http://schemas.xmlsoap.org/wsdl/soap/http"
> , sbbTransport);
Why are you creating a new DesintinationFactory? That should just be:
DestinationFactoryManager dfm =
bus.getExtension(DestinationFactoryManager.class)
as well. I think you are ending up wiping out any registrations that may
have already occurred. Not really sure though, but definitely use the the
one that is there, don't create a new one.
> ConduitInitiatorManager extension =
> bus.getExtension(ConduitInitiatorManager.class);
> extension.registerConduitInitiator("http://cxf.apache.org/transports/sbb",
> sbbTransport);
> extension.registerConduitInitiator("http://schemas.xmlsoap.org/soap/http",
> sbbTransport);
> extension.registerConduitInitiator("http://schemas.xmlsoap.org/wsdl/soap/h
> ttp", sbbTransport);
In both cases, I would not register the soap ID's. That would cause the
soap transport (not http) to be unregistered from those and that MAY cause
issues.
> 2. If I call consumer via ClientProxyFactoryBean or via Service without
> WSDL URL: Service service = Service.create(SERVICE_NAME);
> HelloWorld hw = service.getPort(HelloWorld.class);
> hw.write(TEST_REQUEST);
> my factory is activated as expected -ok.
Honestly, I'm surprised this works at all. I need to check the spec, but I
actually would have expected an exception as there isn't an addPort call first
to associate a port with an address.
>
> 3. If I try to call consumer via Service, but additionally pass WSDL URL:
> URL wsdlURL = this.getClass().getResource("/HelloWorld.wsdl");
> Service service = Service.create(wsdlURL, SERVICE_NAME);
> HelloWorld hw = service.getPort(HelloWorld.class);
> String result = hw.sayHi(TEST_REQUEST);
> my factory is not activated.
In the wsdl, the first extensor in the port (that can map to a conduit) is the
soap:address element. It's namespace is http://schemas.xmlsoap.org/wsdl/soap/
and thus the soap transport is activated. The soap transport maps the HTTP
URL transport ID's to the CXF HTTP transport. That's a soap level mapping.
If you want your transport used, change the wsdl to say:
<soap:binding style="document"
transport="http://cxf.apache.org/transports/sbb" />
OR
remove the soap:address and stick something like:
<sbb:address> or something that would cause your transport to be activated
automatically.
> But if I make the same registration again after getPort() call - it works.
> It seems that registration in this case is somehow overwritten and should
> be actualized.
Most likely, the ConduitInitiator needs to go into "search" mode (by default,
everything is lazy initialized and only loaded if it needs to search) to find
the appropriate conduit and the search is causing the override. You could
probably "fix" it by doing:
ConduitInitiatorManager extension =
bus.getExtension(ConduitInitiatorManager.class);
extension.getConduitInitiator("http://schemas.xmlsoap.org/soap/http");
extension.register(....);
The "get" would force a search which would force the load and then you would
override the load. Normally, in spring config, this would be similar to a
"depends-on" type scenario to force the other one first..
> I attach the small project illustrated this effect.
> consumerRequestResponseOK - use service without WSDL URL
> consumerRequestResponseFailed - iluustrates the problem
> consumerRequestResponseFixed - shows the fix.
>
> Another workaround is just to read DestinationFactory and ConduitInitor
> before registration (call printRegistration() in setup()).
>
> Do you have any ideas regarding this effect?
> For me it looks like a bug.
Well, the "bugs" to me are:
1) In the first case, I need to see if an exception should be thrown or not.
If not, it still should be activating the soap transport, not yours. I may
need to look at that.
2) Case 2: not a bug.
3) I need to look at this more. It should be the same as case 2 I think.
--
Daniel Kulp
[email protected]
http://dankulp.com/blog