On Tuesday 18 January 2011 5:14:31 am Andrei Shakirin wrote: > > 3. 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. > > Basically I agree with you for case if just additional physical transport > should be implemented (for example UDP). But in my scenario I would like > deliberately to replace all possible transports transparently for the > WSDL. WSDL will still contain http://schemas.xmlsoap.org/soap/http > transports and even real http endpoint will be used later by SOPERA/SBB to > send a message. But my conduit and destination are activated for all > transports and replace "real transport call" to "sbb call" that is > transport independent (supports http, https, jms, etc). Messages > originally intended to be send via http will be transparently tunneled via > SOPERA/SBB. In some aspects it is similar to local transport that also > replaces default soap transportURI > (http://cxf.apache.org/docs/local-transport.html).
If that's the case, you should register it on all the SOAP URI's as well: "http://schemas.xmlsoap.org/soap/", "http://schemas.xmlsoap.org/wsdl/soap/", "http://schemas.xmlsoap.org/wsdl/soap12/", "http://schemas.xmlsoap.org/soap/http/", "http://schemas.xmlsoap.org/wsdl/soap/http", "http://www.w3.org/2010/soapjms/", "http://www.w3.org/2003/05/soap/bindings/HTTP/", "http://schemas.xmlsoap.org/soap/http" Dan > > > 4. Most likely, the ConduitInitiator needs to go into "search" mode > > It can also explain effect by web deployment scenario. I register my > factory via spring in web application: <bean > class="org.sopera.cxf.transport.SBBTransportFactory" lazy-init="false"> > <property name="transportIds"> > <list> > <value>http://cxf.apache.org/transports/sbb</value> > <value>http://schemas.xmlsoap.org/soap/http</value> > <value>http://schemas.xmlsoap.org/wsdl/soap/http</value> > <value>http://cxf.apache.org/transports/http</value> > > <value>http://cxf.apache.org/transports/http/configuration</value> </list> > </property> > </bean> > That has the following effect: my factory is instantiated (constructor was > called), but destination and conduit are not requested. If I register > factory additionally in factory constructor programmatically (via > DestinationFactoryManager and ConduitInitator) - scenario works (my > destination and conduit are requested). > > Interesting is that in standalone scenario just spring registration is > enough. I will look in this a little bit deeper now. > > Regards, > Andrei. > > -----Original Message----- > From: Daniel Kulp [mailto:[email protected]] > Sent: Montag, 17. Januar 2011 18:02 > To: [email protected] > Cc: Andrei Shakirin > Subject: Re: Registration of custom transport factory is overwritten if > service created with WSDL URL > > 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/s > > bb", > > sbbTransport); > > extension.registerConduitInitiator("http://schemas.xmlsoap.org/soap/ht > > tp", > > sbbTransport); > > extension.registerConduitInitiator("http://schemas.xmlsoap.org/wsdl/so > > ap/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 -- Daniel Kulp [email protected] http://dankulp.com/blog
