Troubleshooting Caché SOAP Problems
This chapter provides information to help you identify causes of SOAP problems in Caché. It discusses the following topics:
-
Problems consuming WSDLs (problems using the SOAP Wizard)
For information on problems that are obviously related to security, see “Troubleshooting Security Problems” in Securing Caché Web Services.
Information Needed for Troubleshooting
To identify the cause of a SOAP problem, you typically need the following information:
-
The WSDL and all external documents to which it refers.
-
(In the case of message-related problems) Some form of message logging or tracing. You have the following options:
Option Usable with SSL/TLS? Shows HTTP headers? Comments Caché SOAP log Yes No For security errors, this log shows more detail than is contained in the SOAP fault. CSP Gateway trace Yes Yes For problems with SOAP messages that use MTOM (MIME attachment), it is crucial to see HTTP headers. Third-party tracing tools No Depends on the tool Some tracing tools also show lower-level details such as the actual packets being sent, which can be critical when you are troubleshooting. These options are discussed in the following subsections.
It is also extremely useful to handle faults correctly so that you receive the best possible information. See the chapter “SOAP Fault Handling.”
Caché SOAP Log
To log the SOAP calls made to or from a Caché namespace, set the following nodes of the ^ISCSOAP global in that namespace:
Node | Purpose |
---|---|
^ISCSOAP("Log") | Specifies kind of logging. Use one of the following values (case-sensitive):
|
^ISCSOAP("LogFile") | Specifies the complete path and filename of the log file to create. |
The log indicates the sender or the recipient as appropriate, so that you can see which web service or client participated in the exchange.
The following shows a partial example of a log file with line breaks added for readability:
01/05/2010 13:27:02 *********************
Output from web client with SOAP action = http://www.mysecureapp.org/GSOAP.AddComplexSecureWS.Add
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
...
<SOAP-ENV:Header>
<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
</SOAP-ENV:Header>
<SOAP-ENV:Body>
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
01/05/2010 13:27:33 *********************
Input to web client with SOAP action = http://www.mysecureapp.org/GSOAP.AddComplexSecureWS.Add
ERROR #6059: Unable to open TCP/IP socket to server localhost:8080
string
Note the following points:
-
With Caché XML tools, you can validate signatures of signed XML documents and decrypt encrypted XML documents. If you perform these tasks in this namespace, the log contains details for them as well. See Using Caché XML Tools.
-
The Caché SOAP log captures SOAP calls even when no message is sent on the wire (that is, when the service and client are both on a single machine).
-
If a severe error occurs, the system stops writing to the SOAP log. See the console log instead. For information, see “Monitoring Log Files” in the Caché Monitoring Guide.
HTTP Trace in the CSP Gateway
The CSP Web Gateway Management page enables you to trace HTTP requests sent to CSP pages (such as web services) and responses sent in return. See “Viewing HTTP Trace” in the CSP Gateway Configuration Guide.
Third-Party Tracing Tools
To test your web service, you can use tracing tools such as Wireshark, ProxyTrace, tcpTrace, XMLSpy, soapUI, or Web Service Studio Express. Some of these tools are free and others are licensed. Note that InterSystems does not make any specific recommendations about these tools; they are listed here for your general information.
Tracing tools enable you to see the actual method call, as well as the response. A tracing session listens on a certain port, shows you the messages it receives there, forwards those messages to a destination port, shows the responses, and forwards the responses to the listening port.
For example, suppose you have a Cache web service at http://localhost:57772/csp/gsop/GSOP.Divide.CLS
And suppose you have a Cache web client that you created to talk to that service. The web client has a LOCATION parameter equal to "http://localhost:57772/csp/gsop/GSOP.Divide.CLS"
To trace messages between the client and service, you need to do two things:
-
In the tracing tool, start a tracing session that listens on port 8080 (for example) and that uses the destination port 57772.
-
In the web client, edit the LOCATION parameter to use port 8080 instead of 57772. Then recompile.
Or, in your code that invokes the web client, change the Location property of the web client:
//reset location to port 8080 to enable tracing set client.Location="http://localhost:8080/csp/gsop/GSOP.DivideWS.cls"
Now when you use the web client, the tracing tool intercepts and displays messages between the client and the web service, as shown in the following example:
![generated description: trace example](images/gsoap_trace_example.png)
The top area shows the request sent by the client. The bottom area shows the response sent by the web service.
Problems Consuming WSDLs
If you have a problem using the SOAP Wizard (or the %SOAP.WSDL.ReaderOpens in a new tab class, which the wizard uses), the problem is likely to be one of the following:
-
The WSDL is protected by SSL. In this case, the wizard issues the following error:
ERROR #6301: SAX XML Parser Error: invalid document structure while processing Anonymous Stream at line 1 offset 1
You can specify an SSL configuration when using the wizard, but if you have done so, and you receive the preceding error, your SSL configuration is incorrect. You can try accessing the WSDL in another way, downloading it to a file, and using the file WSDL instead.
-
The WSDL is password protected. In this case, the wizard issues an error like the following (notice that the line and offset vary but are different from the previous scenario):
ERROR #6301: SAX XML Parser Error: Expected entity name for reference while processing Anonymous Stream at line 10 offset 27
If you receive this error, check whether a password is required; see the comments in “Using the SOAP Wizard,” earlier in this book.
-
The WSDL uses elements that are currently inaccessible. In this case, the wizard issues an error like the following:
ERROR #6416: Element 'wsdl:definitions' - unrecognized wsdl element 'porttype'
The key word is unrecognized; this indicates that the WSDL refers to an element that is currently inaccessible. Carefully check the WSDL for <import> and <include> directives.
An import directive might look like this:
<import namespace="http://example.com/stockquote/definitions" location="http://example.com/stockquote/stockquote.wsdl"/>
In this case, the workaround is as follows:
-
Download the primary WSDL to a file.
-
Download the referenced WSDL to a file.
-
Edit the primary WSDL to refer to the new location of the referenced WSDL.
Similarly, it is possible for a WSDL to refer to other documents via a relative URL. For example:
xmlns:acme="urn:acme.com.:acme:service:ServiceEndpointInterface"
If you have downloaded the WSDL to a file, this relative reference cannot work. In this case, you must also download the referenced document and edit the WSDL to use its new location.
-
-
The WSDL contains <message> elements with multiple parts and uses document-style binding. In this case, the wizard issues the following error:
ERROR #6425: Element 'wsdl:binding:operation:msg:input' - message 'AddSoapOut' Message Style must be used for document style message with 2 or more parts.
In this case, select the Use unwrapped message format for document style web methods option when you use the wizard.
-
The WSDL is invalid. In such cases, the SOAP wizard issues an error to indicate the problem. The following shows one example:
ERROR #6419: Element 'wsdl:binding:operation' - inconsistent soap:namespace for operation getWidgetInfo
This error message indicates a problem with an <operation> element. The following shows a partial example of the invalid WSDL that produced this error:
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://acme.acmecorp.biz:9999/widget/services" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" = [parts omitted]> <wsdl:message name="getWidgetInfoRequest"> </wsdl:message> <wsdl:message name="getWidgetInfoResponse"> <wsdl:part name="getWidgetInfoReturn" type="xsd:string"/> </wsdl:message> <wsdl:portType name="Version"> <wsdl:operation name="getWidgetInfo"> <wsdl:input message="impl:getWidgetInfoRequest" name="getWidgetInfoRequest"/> <wsdl:output message="impl:getWidgetInfoResponse" name="getWidgetInfoResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="VersionSoapBinding" type="impl:Version"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getWidgetInfo"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="getWidgetInfoRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://acmesubsidiary.com" use="encoded"/> </wsdl:input> <wsdl:output name="getWidgetInfoResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://acme.acmecorp.biz:9999/widget/services" use="encoded"/> </wsdl:output> </wsdl:operation> </wsdl:binding> [parts omitted]
In this case, the problem is that the <input> part of <operation> states that the request message (getVersionRequest) is in the namespace "http://acmesubsidiary.com", but the earlier part of the WSDL shows that this message is the target namespace of the web service: "http://acme.acmecorp.biz:9999/widget/services".
Note that an invalid WSDL document can be a valid XML document, so using a pure XML tool to validate the WSDL is not a sufficient test. Some third-party WSDL validation tools are available, and you can also examine the WSDL directly, using information returned by the SOAP wizard.
-
The WSDL contains features that are not supported in Caché. See the section “Consuming WSDLs” in the first chapter.
Problems Sending Messages
If you have problems when sending SOAP messages to or from a Caché web service or client, consider this list of common scenarios:
-
The SOAP message might include a long string or long binary value, and you have not enabled long string operations in Caché. In this case, Caché throws one of the following errors:
-
A <MAXSTRING> error
-
A datatype validation error (which can have other causes as well):
ERROR #6232: Datatype validation failed for tag your_method_name ...
When the wizard reads a WSDL, it assumes that any string-type input or output can be represented in Caché as %StringOpens in a new tab. Similarly, it assumes that any input or output with XML type base64Binary can be represented in Caché as %xsd.base64BinaryOpens in a new tab). There is no information in a WSDL to inform the SOAP Wizard that this input or output could exceed the Caché long string limit.
See “Adjusting the Generated Classes for Long Strings,” earlier in this book; this information applies to both web clients and services.
-
-
The web service or client might receive WS-Security headers, but not yet be configured to recognize them. This can result in a generic error like the following:
<ZSOAP>zInvokeClient+269^%SOAP.WebClient.1
An error like this can also have other causes. If you receive an error like this, first check whether the messages include WS-Security headers; if so, add the following to the web service or client and recompile it:
Parameter SECURITYIN="REQUIRE";
Also, if Caché generated a security policy (in a configuration class), you might need to edit that policy to provide missing details; see the section “Editing the Generated Policy” in Securing Caché Web Services. If you do not do so, you can receive generic errors as given above.
-
The web service or client might require a more specific message form than should be required, according to the SOAP specifications. (This can occur for a service or client that is not in Caché.) InterSystems has encountered the following scenarios, listed here from (approximately) most common to least common:
-
The web service or client requires the message to specify the xsi:type attribute for all elements in the message. To specify use of this attribute, see “Controlling Use of the xsi:type Attribute,” which applies to both web services and clients.
-
For a null string value, the web service or client requires a null element (rather than omitting the element). To work around this, you can control the form of null string arguments, see “Controlling the Form of Null String Arguments,” which applies to both web services and clients.
-
The web service or client requires specific namespace prefixes. Caché does not provide a way to specify the namespace prefixes in general.
For the SOAP envelope, however, you can specify the prefix to use. See “Specifying the SOAP Envelope Prefix,” which applies to both web services and clients.
-
The web client requires the SOAP action to be quoted. To work around this, see “Quoting the SOAP Action (SOAP 1.1 Only).”
-
The web service or client requires a BOM (byte-order mark) at the start of each SOAP message. The BOM should not be needed because a SOAP message is encoded as UTF-8, which does not have byte order issues. See “Adding a Byte-Order Mark to the SOAP Messages,” which applies to both web services and clients.
The symptoms of these problems depend upon the third-party product in use.
-
-
The web service or client might not comply with the WSDL. This should not be possible for a Caché web service or client, but can occur in other scenarios. InterSystems has seen the following scenarios:
-
An element in the message is not in the namespace required by the WSDL.
-
The message does not have elements in the same order as the WSDL.
To determine whether the service or client complies with the WSDL, compare the messages to the WSDL.
Or, for a third-party web service, to determine whether the web service complies with the WSDL, it is useful to do the following:
-
Generate a web client using a third-party tool.
-
Send messages from that web client:
-
If this is successful, it is likely that the web service does expect and send messages that are consistent with its WSDL, and the cause of the problem is elsewhere. In this case, compare the messages sent by this client to the messages sent by the Caché client.
-
If this is not successful, it is likely that the web service does not expect or send messages that are consistent with its WSDL.
-
-
-
The web service or client might send messages of a form not supported in Caché. It is useful to examine the WSDL in use and make sure it is supported in Caché; see the section “Consuming WSDLs” in the first chapter. Note that these details have changed in Caché over time.