document types and inheritance

I’m trying to consume a remote serivce. The WSDL of the remote service looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<definitions name="Messages"
    targetNamespace="http://test.tom.com"
    xmlns:tns="http://test.tom.com"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
    <types>
    <xs:schema
        targetNamespace="http://test.tom.com"
        xmlns="http://test.tom.com"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified">

        <xs:element name="AbstractDocument" type="AbstractDocument"/>
        <xs:complexType name="AbstractDocument" abstract="true">
            <xs:sequence>
                <xs:element name="content" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>

        <xs:element name="ExampleDocument" type="ExampleDocument"/>
        <xs:complexType name="ExampleDocument">
            <xs:complexContent>
              <xs:extension base="AbstractDocument">
                <xs:sequence>
                  <xs:element name="name" type="xs:string"/>
                </xs:sequence>
              </xs:extension>
            </xs:complexContent>
        </xs:complexType>

    </xs:schema>
    </types>
    
    <message name="SaveDocumentRequest">
        <part name="doc" element="tns:AbstractDocument"/>
    </message>
    <message name="SaveDocumentResponse"/>
    <portType name="SaveDocumentPort">
        <operation name="SaveDocument">
            <input name="SaveDocumentRequestPT" message="tns:SaveDocumentRequest"/>
            <output name="SaveDocumentResponsePT" message="tns:SaveDocumentResponse"/>
        </operation>
    </portType>
    
    <binding name="SaveDocumentBinding" type="tns:SaveDocumentPort">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        
        <operation name="SaveDocument">
            <soap:operation soapAction="SaveDocument" style="document"/>
            <input name="SaveDocumentRequestPT">
                <soap:body use="literal"/>
            </input>
            <output name="SaveDocumentResponsePT">
                <soap:body use="literal"/>
            </output>
        </operation>
    </binding>
    
    <service name="SaveDocumentService">
        <port name="SaveDocument" binding="tns:SaveDocumentBinding">
            <soap:address location="http://127.0.0.1:5555/ws/SaveDocument"/>
        </port>
    </service>
</definitions>

Note that the complex type used as a parameter of the SaveDocument service is abstract.
I used the import wizard in developer to create a connector. Interestingly developer did not create a document type for the subtype ExampleDocument. Whereas the schema generated does contain this complex type.
Now when I want to pass a soap message to the connector that contains an ExampleDocument, i get the error that the document does not validate against the targetInputSignature of the soapClient Service used inside
of the connector. IS complains about the additional element ‘name’ of the ExampleDocument.
The behaviour in fact makes the connector unuseable. So i have the following questions:

  • Can I somehow tell the soapClient not to validate the message or rather: how do i need to adjust to accept derived types as well ?
  • Does webMethods support inheritance and abstract types at all (i did not find anything on that topic in the documentation).
  • Why is the concrete type ‘ExampleDocument’ not created ?

Thank you in advance for your answers,

tom

Hi Tom, not sure what you are trying to achieve.

As far as I can tell, ExampleDocument is not used by any of the operations, so there is no need for generating it…? Importing this in IS 7.1.2 is no issue. What version are you on?

Chris

thank you for your reply. you are right that ExmapleDoc ist not used in the WSDL directly . But since it inherits from AbstractDocument and AbstractDocument is part of the WSDL, it indirectly is used in the WSDL.

I guess the problem becomes more clear, if i explain in detail what we are trying to achive (caution: long post :wink:
We want to add aditional processing logic to my existing services which run in AXIS2. Since we did not want to change those services, we decided to create a ‘ProxyService’ in IS, which contains the additional logic and then passes the request to the service running in AXIS2.
Clients would then call the ProxyService instead of the AXIS2-Service directly. In order to achive that we did the following:

  • Import the WSDL of the AXIS2 Service as Consumer (this creates a connector).
  • Import the WSDL of the AXIS2 Service as Provider (this creates a flow service, our ProxyService).
  • Add the additional logic to the FlowService and at the end use the connector to pass the message to the AXIS2-Service.
  • Call the ProxyService from the Client.

This usually works but with the WSDL posted it does not because of the following reasons:

  • When importing the WSDL as consumer or provider, no subtype of AbstractDocument is created, although messages might actually contain one of the subtypes.
  • When importing the WSDL as consumer or provider, AbstractDocument is no longer abstract. Clients may actually send a message containing an AbstractDocument to the service.
  • The connecotr (more specifically the pub.client.soapClient always validates against AbstractDocument. When a messages containg a subtype are sent, it complains about the additional elements and rejects forwarding.

An additional problem is that, we use import elements to import our XSDs in the WSDLs of our AXIS-Services. When we import that WSDL to create a provider, the import sill points to our AXIS2-Serivce-XSDs. So messages containing a subtype are valid although the providing FlowService (ProxyService) only accepts AbstractDocument. This problem can be solved by disabling the validation for the flow service.

i found out that creating a document type that contains all elements of all subtypes of abstract document in IS might be solution. But i haven’t yet tried.

tom

OK… Would it not be a lot easier to build the proxy services in Axis as well…? You already have the objects there and can call the methods within the same JVM.
Proxying through webMethods gives you twice XML parsing as well, so performance wise it is also not the best option.
I am a hugh fan of IS but I think there are some cases, such as these, when the IS is not the best solution…
Alternatively, can you not rebuild the service logic in webM?

Good luck!

I know this setup sounds a little bit wird :slight_smile:
The reason for not using Axis is that i can not alter the legacy services. In addition the IntegrationServer was set as the integration platform in this project.
Nevertheless as posted already before, my real problem is that services with abstract type definitions can not really be build/accessed in webMethods.
Although it is possible to publish a serivce that will accept multiple subtypes by creating a document type in wm that contains all attributes of all subtypes and turning off validation, it is not possible to consum service with abstract types in the service definition (without creating the soap message yourself). I wasn’t aware of that limitation and i am trying to find a workaround…

We got a chance to talk with sag consultants about the problem described in this thread. For those interested, this post contains a brief summary of our findings:

The cause of the problem is that pub.client.SoapClient does not include the xsi:type=“…” attribute when creating SOAP messages to specify the actual subtype being send. Since this is dictated by the XML speficication, the resulting xml is actually invalid. Thus intended receivers are not able to process the soap message.
The exclusion of that attribute apperently is a know limitation of IS. Furthermore there is no straightforward workaround for the problem other than programming the addition of the attribute yourself (for example in a soap processor).

The suggested solution is to wait for the upcoming ‘webMethods Mediator’. With the Mediator it should be possible to achive our goal by implementing Pre and Post processing steps. In these steps the appropriate flow services will be called.

Dang it, this is biting me 3 years after the last posting to this thread.

Im having the same problem - is there now a solution?

Is there a way to specify an element type in the SOAP env? As in setting the xsi:type attribute?

Again, I’m consuming a WSDL that defines abstract and sub-types. The outbound SOAP env does not specify an xsi:type=“…” attribute on a sub-type element.

Thanks!

i’m sorry but i can’t help you on that topic any more. As i mentioned in my last post, the consultants from sag suggested not to use IS and Flow but rather the new “Mediator”. Unfortunately we could not follow this approach any more because the project had already failed when the Mediator was released. And obviously we did not contiune searching for a solution.
I guess the best solution to this problem is to avoid IS when using a WSDL with abstract types. I guess that post #4 contains the best workaround for the problem.

best regards, tom

Tom - thanks for your response. I will follow your advise.

I did find a work-around. I edited one of the generated doc types (generated when creating WS consumer). I added a string element to the sub-type document - “@xsi:=type”. On conversion to xml, the “@” elements are set as attributes. I set the value to be the name of the sub-type. This produced a soap envelope with valid xml.

This is not my preferred choice as that the modification is hidden.

Thanks again