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.

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

Reply via email to