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
