On Mar 22, 2013, at 5:09 AM, Andrei Shakirin <[email protected]> wrote:

> Hi Rastislav,
> 
> To be honest, I have resolved the similar case only through self-contained 
> WSDL (all schemas are embedded into WSDL).
> Anyway I find the topic quite interesting. Perhaps Dan can give you some more 
> entry points to digging.

Someplace in the stack of resolving all of this should be the 
TransportURIResolver thing which uses the CXF transports to resolve wsdl 
things.   Thus, you COULD write a CXF ConduitInitiator/Conduit implementation 
that talks to a DB and us a "db:…" URL.   Likely not exactly what you want 
though.   Since this really is a resource, going through the ResourceManager 
likely makes sense.   Any patches to make that easier would be welcome.

Dan


> 
> Regards,
> Andrei.
> 
> 
>> -----Original Message-----
>> From: Rastislav Cesnek [mailto:[email protected]]
>> Sent: Dienstag, 19. März 2013 16:16
>> To: [email protected]
>> Subject: Dynamic service from WSDL+imports loaded from database
>> 
>> HI all.
>> 
>> I am trying to tweak CXF into a very dynamic scenario, where services would
>> be published dynamically from a priori unknown WSLDs uploaded at run time
>> (together with an interpreted service implementation).
>> 
>> Basically, I already have some idea about the dynamic publish (using custom
>> Invoker and custom DataBinding, etc.).
>> 
>> What I concept-proofed right now is loading the WSDLs + its imports from
>> database.
>> 
>> Here I stumble upon some show stoppers, when I try to create ServiceInfos
>> from a definition like:
>> WSDLServiceBuilder builder = new WSDLServiceBuilder(bus);
>> List<ServiceInfo> serviceInfos = builder.buildServices(definition);
>> 
>> The problem is that I am able to read the Definition while serving the 
>> content
>> as I wish (from DB, 2 approaches desribed below), however, the
>> WSDLServiceBuilder fails when it tries to get the schemas (I cannot find a
>> possibility to tweak the resource resolving here, as there is a
>> CatalogXmlSchemaURIResolver hard-registered as schema collection
>> resolver):
>> 
>> org.apache.ws.commons.schema.XmlSchemaException: Unable to locate
>> imported document at 'db#RootXSD.xsd', relative to
>> 'db#SubWSDL.wsdl#types1'.
>> at
>> org.apache.cxf.catalog.CatalogXmlSchemaURIResolver.resolveEntity(Catalog
>> XmlSchemaURIResolver.java:76)
>> at
>> org.apache.ws.commons.schema.SchemaBuilder.resolveXmlSchema(Schem
>> aBuilder.java:684)
>> at
>> org.apache.ws.commons.schema.SchemaBuilder.handleImport(SchemaBuild
>> er.java:538)
>> at
>> org.apache.ws.commons.schema.SchemaBuilder.handleSchemaElementChil
>> d(SchemaBuilder.java:1513)
>> at
>> org.apache.ws.commons.schema.SchemaBuilder.handleXmlSchemaElement
>> (SchemaBuilder.java:659)
>> at
>> org.apache.ws.commons.schema.XmlSchemaCollection.read(XmlSchemaColl
>> ection.java:540)
>> at
>> org.apache.cxf.common.xmlschema.SchemaCollection.read(SchemaCollectio
>> n.java:129)
>> at org.apache.cxf.wsdl11.SchemaUtil.extractSchema(SchemaUtil.java:133)
>> at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:81)
>> at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:65)
>> at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:60)
>> at
>> org.apache.cxf.wsdl11.WSDLServiceBuilder.getSchemas(WSDLServiceBuilder
>> .java:372)
>> 
>> Any ideas? Can anything like this be done?
>> 
>> 
>> Basically, for the Definition reading, I tried two approaches which both
>> work:
>> 
>> 1) Implementing and registering a CustomResourceResolver with the
>> ResourceManager in the Bus and using standard
>> WSDLManager.getDefinition(String url) method.
>> In the CustomResourceResolver:
>> - in "public InputStream getAsStream(String name)" I recognize the resource
>> name (like "db#name") name and provide na InputSream.
>> - in "public <T> T resolve(String resourceName, Class<T> resourceType)"
>> I always return null (for the URL), so the systemId/publicId of the
>> constructed InputSource stays in the "db#name" form.
>> 
>> 2) Copying some code from CXF and implementing custom WSDLLocator and
>> doing completely custom definition reading like:
>> WSDLManager wsdlManager = bus.getExtension(WSDLManager.class);
>> WSDLFactory wsdlFactory = wsdlManager.getWSDLFactory();
>> ExtensionRegistry extensionRegistry = wsdlManager.getExtensionRegistry();
>> 
>> WSDLReader reader = wsdlFactory.newWSDLReader();
>> reader.setFeature("javax.wsdl.verbose", false);
>> reader.setFeature("javax.wsdl.importDocuments", true);
>> reader.setExtensionRegistry(extensionRegistry);
>> 
>> CatalogWSDLLocator catLocator = new CatalogWSDLLocator(url, bus);
>> CustomDelegatingWSDLLocator = new CustomDelegatingWSDLLocator(url,
>> catLocator, bus); Definition def = reader.readWSDL(wsdlLocator);
>> wsdlManager.addDefinition(url, def); In the CustomDelegatingWSDLLocator I
>> do similar stuff like in the CustomResourceResolver, i.e. provide InputSource
>> or delegate and return an URI (which again stays in the form "db#name" and
>> gets set to
>> systemId/publicId) or delegate.
>> 
>> This works charming and the definition is read.
>> 
>> 
>> I considered using custom URL protocol handler but this is a show-stopper
>> too, as the application runs on JEE server, where I cannot register a custom
>> protocol handler easily (usually, a URLStreamHandlerFactory is already set
>> and it cannot be set a second time). The option to use the system
>> environment property -Djava.protocol.handler.pkgs is also cumbersome as it
>> requires installing classes/modules deep into the server/java core.
>> 
>> Please, notice that Whitestein Slovakia has moved to a new location.
>> Prosím, všimnite si že Whitestein Slovensko sa presťahovalo na novú adresu.
>> 
>> --
>> Rastislav Cesnek | [email protected]
>> Senior Software Engineer | Advanced Technologies Whitestein Technologies
>> s.r.o. | www.whitestein.com Moskovska 13 | 811 08 Bratislava-Staré Mesto |
>> Slovak Republic Main +421 2 5443-5502 | Fax +421 2 5443-5512
> 

-- 
Daniel Kulp
[email protected] - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Reply via email to