Sophie

Sophie

distrib > Mageia > 7 > i586 > media > core-release > by-pkgid > e5b501e96823201f44cb057859a8bf79 > files > 1846

gsoap-2.8.67-2.mga7.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>gSOAP WS-Addressing: The wsa plugin for stand-alone services</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.3.8 -->
<div class="qindex"><a class="qindex" href="index.html">Main&nbsp;Page</a> | <a class="qindex" href="annotated.html">Class&nbsp;List</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Class&nbsp;Members</a> | <a class="qindex" href="globals.html">File&nbsp;Members</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
<h1><a class="anchor" name="wsa">The wsa plugin for stand-alone services</a></h1><h2><a class="anchor" name="wsa_1">
WS-Addressing Setup</a></h2>
The material in this section relates to the WS-Addressing specification.<p>
To use the wsa plugin:<ol>
<li>Run wsdl2h -t typemap.dat on a WSDL of a service that requires WS-Addressing headers. The typemap.dat file included in the gSOAP package is used to recognize and translate Addressing header blocks.</li><li>Run soapcpp2 -a on the header file produced by wsdl2h. To enable addressing-based service operation selection, you MUST use soapcpp2 option -a. This allows the service to dispatch methods based on the WS-Addressing action information header value (assuming the wsa plugin is registered).</li><li>(Re-)compile stdsoap2.c/pp, dom.c/pp, <a class="el" href="wsaapi_8c.html">wsaapi.c</a> and the generated source files.</li><li>Use the wsa plugin API functions described below.</li></ol>
<p>
An example wsa client/server application can be found in samples/wsa.<p>
The header file with a wsa import is automatically generated by wsdl2h for a set of WSDLs that use WS-Addressing. The gSOAP header file is further processed by soapcpp2 to generate the binding code. The wsdl2h-generated header file might include the following imports: <div class="fragment"><pre><span class="preprocessor">#import "soap12.h"</span>
<span class="preprocessor">#import "wsa.h"</span> <span class="comment">// or wsa3.h (2003/03), wsa4.h (2004/03), wsa5.h (2005/03)</span>
</pre></div>The gSOAP header file is processed with soapcpp2 to generate the client-side and/or server-side binding code.<p>
Note that the wsa.h header file located in the import directory of the gSOAP package declares the WS-Addressing information header elements and types. The soap12.h header file enables SOAP 1.2 messaging.<p>
For developers: the WS-Addressing header blocks in wsa.h were generated from the WS-Addressing schema with the wsdl2h tool and WS/WS-typemap.dat as follows:<p>
<div class="fragment"><pre>    $ wsdl2h -cegy -o wsa.h -t WS/WS-typemap.dat WS/WS-Addressing.xsd
</pre></div>Refer to wsa.h for more details.<h2><a class="anchor" name="wsa_2">
Client-side Usage</a></h2>
<h3><a class="anchor" name="wsa_2_1">
Constructing WS-Addressing Information Headers</a></h3>
To associate WS-Addressing information headers with service operations, the SOAP Header struct must have been defined and for each service operation that uses WS-Addressing method-header-part directives should be used in the gSOAP header file of the service as follows: <div class="fragment"><pre><span class="preprocessor">#import "wsa.h"</span>

<span class="comment">//gsoap ns service method-header-part: example wsa__MessageID</span>
<span class="comment">//gsoap ns service method-header-part: example wsa__RelatesTo</span>
<span class="comment">//gsoap ns service method-header-part: example wsa__From</span>
<span class="comment">//gsoap ns service method-header-part: example wsa__ReplyTo</span>
<span class="comment">//gsoap ns service method-header-part: example wsa__FaultTo</span>
<span class="comment">//gsoap ns service method-header-part: example wsa__To</span>
<span class="comment">//gsoap ns service method-header-part: example wsa__Action</span>
<span class="comment">//gsoap ns service method-action: example urn:example/examplePort/example</span>
<span class="keywordtype">int</span> ns__example(<span class="keywordtype">char</span> *in, <span class="keyword">struct</span> ns__exampleResponse *out);
</pre></div>Note that the use of wsa versions determines the wsa prefix, e.g. use wsa5 for the latest WS-Addressing as in wsa5__MessageID.<p>
In the client-side code, the WS-Addressing information headers are set with <a class="el" href="wsaapi_8h.html#a9">soap_wsa_request()</a> by passing an optional message UUID string, a mandatory destination address URI string, and a mandatory request action URI string. The wsa plugin should be registered with the current soap struct context. An optional source address information header can be added with <a class="el" href="wsaapi_8h.html#a10">soap_wsa_add_From()</a> (must be invoked after the soap_wsa_request call).<p>
For example: <div class="fragment"><pre>soap_register_plugin(soap, soap_wsa);

<span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a9">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction))
 || <a class="code" href="wsaapi_8h.html#a10">soap_wsa_add_From</a>(soap, FromAddress)) <span class="comment">// optional: add a 'From' address</span>
  ... <span class="comment">// error: out of memory</span>

<span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))
  soap_print_fault(soap, stderr); <span class="comment">// an error occurred</span>
<span class="keywordflow">else</span>
  <span class="comment">// process the response </span>
</pre></div><h3><a class="anchor" name="wsa_2_2">
Information Headers for Relaying Server Responses</a></h3>
To relay the response to another destination, the WS-Addressing ReplyTo information header is added with <a class="el" href="wsaapi_8h.html#a12">soap_wsa_add_ReplyTo()</a> by passing a reply address URI string. The service returns HTTP 202 ACCEPTED to the client when the response message relay was successful.<p>
For example: <div class="fragment"><pre>soap_register_plugin(soap, soap_wsa);

<span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a9">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction)
 || <a class="code" href="wsaapi_8h.html#a10">soap_wsa_add_From</a>(soap, FromAddress) <span class="comment">// optional: add a 'From' address</span>
 || <a class="code" href="wsaapi_8h.html#a12">soap_wsa_add_ReplyTo</a>(soap, ReplyToAddress))
  ... <span class="comment">// error: out of memory</span>

<span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))
{
  <span class="keywordflow">if</span> (soap-&gt;error == 202) <span class="comment">// HTTP ACCEPTED</span>
    printf(<span class="stringliteral">"Request was accepted and results were forwarded\n"</span>);
  <span class="keywordflow">else</span>
    soap_print_fault(soap, stderr); <span class="comment">// an error occurred</span>
}
<span class="keywordflow">else</span>
  <span class="comment">// unexpected OK: for some reason the response was not relayed</span>
</pre></div><p>
Note: the response message will be relayed when the From address is absent or different than the ReplyTo address<h3><a class="anchor" name="wsa_2_3">
Information Headers for Relaying Server Faults</a></h3>
To relay a server fault message to another destination, the WS-Addressing FaultTo information header is added with <a class="el" href="wsaapi_8h.html#a13">soap_wsa_add_FaultTo()</a> by passing a relay address URI string. The service returns HTTP 202 ACCEPTED to the client when the fault was relayed.<p>
For example: <div class="fragment"><pre>soap_register_plugin(soap, soap_wsa);

<span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a9">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction)
 || <a class="code" href="wsaapi_8h.html#a10">soap_wsa_add_From</a>(soap, FromAddress) <span class="comment">// optional: add a 'From' address</span>
 || <a class="code" href="wsaapi_8h.html#a13">soap_wsa_add_FaultTo</a>(soap, FaultToAddress))
  ... <span class="comment">// error: out of memory</span>

<span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))
{
  <span class="keywordflow">if</span> (soap-&gt;error == 202) <span class="comment">// HTTP ACCEPTED</span>
    printf(<span class="stringliteral">"A fault occurred and the fault details were forwarded\n"</span>);
  <span class="keywordflow">else</span>
    soap_print_fault(soap, stderr); <span class="comment">// a connection error occurred</span>
}
<span class="keywordflow">else</span>
  <span class="comment">// process response </span>
</pre></div><p>
Note that the call can still return a fault, such as a connection error when the service is not responding. In addition to the fault relay, the responses can be relayed with <a class="el" href="wsaapi_8h.html#a12">soap_wsa_add_ReplyTo()</a>.<h3><a class="anchor" name="wsa_2_4">
Error Handling</a></h3>
SOAP and HTTP errors set the soap-&gt;error attribute, as shown in this example: <div class="fragment"><pre><span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))
{
  <span class="keywordflow">if</span> (soap-&gt;error == 202) <span class="comment">// HTTP ACCEPTED</span>
    printf(<span class="stringliteral">"A fault occurred and the fault details were forwarded\n"</span>);
  <span class="keywordflow">else</span>
    soap_print_fault(soap, stderr); <span class="comment">// a connection error occurred</span>
}
<span class="keywordflow">else</span>
  <span class="comment">// process response </span>
</pre></div>When a WS-Addressing error occurred, the wsa error code is stored in the SOAP Fault Subcode field. This information can be retrieved with: <div class="fragment"><pre>wsa__FaultSubcodeValues fault;
<span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a20">soap_wsa_check_fault</a>(soap, &amp;fault))
{
  <span class="keywordflow">switch</span> (fault)
  {
    <span class="keywordflow">case</span> wsa__InvalidMessageInformationHeader: ...
    <span class="keywordflow">case</span> wsa__MessageInformationHeaderRequired: ...
    <span class="keywordflow">case</span> wsa__DestinationUreachable: ...
    <span class="keywordflow">case</span> wsa__ActionNotSupported: ...
    <span class="keywordflow">case</span> wsa__EndpointUnavailable: ...
  }
}
</pre></div>When using wsa5.h, please refer to the standards and fault codes for this implementation. For the wsa5.h 2005/03 standard, several faults have an additional parameter (SOAP Fault detail): <div class="fragment"><pre>wsa5__FaultCodesType fault;
<span class="keywordtype">char</span> *info;
<span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a20">soap_wsa_check_fault</a>(soap, &amp;fault, &amp;info))
{
  <span class="keywordflow">switch</span> (fault)
  {
    <span class="keywordflow">case</span> wsa5__InvalidAddressingHeader:
      <span class="keywordflow">if</span> (info)
        printf(<span class="stringliteral">"The invalid addressing header element is %s\n"</span>, info);
    ...
  }
}
</pre></div><h2><a class="anchor" name="wsa_3">
Server-side Usage</a></h2>
The wsa plugin should be registered with: <div class="fragment"><pre>soap_register_plugin(soap, soap_wsa);
</pre></div><p>
Once the plugin is registered, the soap_bind(), soap_accept(), and soap_serve() functions can be called to process requests.<p>
Important: to dispatch service operations based on the WS-Addressing wsa:Action information header, use soapcpp2 option -a. The generates a new dispatcher (in soapServer.c) based on the action value.<p>
A service operation implementation should use <a class="el" href="wsaapi_8h.html#a14">soap_wsa_check()</a> to verify the validity of the WS-Addressing information headers in the SOAP request message. To allow response message to be automatically relayed based on the ReplyTo information header, the service operation should return <a class="el" href="wsaapi_8h.html#a15">soap_wsa_reply()</a> with an optional message UUID string and a mandatory response action string.<p>
For example: <div class="fragment"><pre><span class="keywordtype">int</span> ns__example(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *in, <span class="keyword">struct</span> ns__exampleResponse *out)
{ <span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a14">soap_wsa_check</a>(soap))
    <span class="keywordflow">return</span> soap-&gt;error;
  <span class="comment">// ... service logic</span>
  <span class="keywordflow">return</span> <a class="code" href="wsaapi_8h.html#a15">soap_wsa_reply</a>(soap, ResponseMessageID, ResponseAction);
}
</pre></div><p>
To return a SOAP fault that is automatically relayed to a fault service based on the FaultTo information header, the <a class="el" href="wsaapi_8h.html#a18">soap_wsa_sender_fault()</a>, <a class="el" href="wsaapi_8h.html#a19">soap_wsa_receiver_fault()</a>, <a class="el" href="wsaapi_8h.html#a16">soap_wsa_sender_fault_subcode()</a>, and <a class="el" href="wsaapi_8h.html#a17">soap_wsa_receiver_fault_subcode()</a> functions should be used instead of the soap_sender_fault(), soap_receiver_fault(), soap_sender_fault_subcode(), and soap_receiver_fault_subcode(), respectively.<p>
For example: <div class="fragment"><pre><span class="keywordtype">int</span> ns__example(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *in, <span class="keyword">struct</span> ns__exampleResponse *out)
{ <span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a14">soap_wsa_check</a>(soap))
    <span class="keywordflow">return</span> soap-&gt;error;
  <span class="comment">// ... service logic</span>
  <span class="comment">// ... an error occurred, need to return fault possibly to fault service:</span>
    <span class="keywordflow">return</span> <a class="code" href="wsaapi_8h.html#a18">soap_wsa_sender_fault</a>(soap, <span class="stringliteral">"Exception in service operation"</span>, NULL);
  <span class="comment">// ... normal execution continues</span>
  <span class="keywordflow">return</span> <a class="code" href="wsaapi_8h.html#a15">soap_wsa_reply</a>(soap, ResponseMessageID, ResponseAction);
}
</pre></div><h2><a class="anchor" name="wsa_4">
Implementing a Server for Handling ReplyTo Response Messages</a></h2>
To implement a separate server for handling relayed SOAP response messages based on the ReplyTo information header in the request message, the gSOAP header file should include a one-way service operation for the response message.<p>
For example, suppose a service operation returns an exampleResponse message. We declare the one-way exampleResponse operation as follows: <div class="fragment"><pre><span class="preprocessor">#import "wsa.h"</span>

<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__MessageID</span>
<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__RelatesTo</span>
<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__From</span>
<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__ReplyTo</span>
<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__FaultTo</span>
<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__To</span>
<span class="comment">//gsoap ns service method-header-part: exampleResult wsa__Action</span>
<span class="comment">//gsoap ns service method-action: exampleResult urn:example/examplePort/exampleResponse</span>
<span class="keywordtype">int</span> ns__exampleResponse(<span class="keywordtype">char</span> *out, <span class="keywordtype">void</span>);
</pre></div><p>
Note that the action information is important, because it is used by the service dispatcher (assuming soapcpp2 option -a is used).<p>
The implementation in the server code uses <a class="el" href="wsaapi_8h.html#a14">soap_wsa_check()</a> to check the presense and validity of the WS-Addressing information header in the message. The soap_send_empty_response() function should be used to return an acknowledgment HTTP header with HTTP 202 ACCEPTED to the sender: <div class="fragment"><pre><span class="keywordtype">int</span> ns__exampleResponse(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *out)
{ <span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a14">soap_wsa_check</a>(soap))
    <span class="keywordflow">return</span> soap_send_empty_response(soap, 500); <span class="comment">// HTTP 500 Internal Server Error</span>
  <span class="comment">// ... service logic</span>
  <span class="keywordflow">return</span> soap_send_empty_response(soap, SOAP_OK); <span class="comment">// HTTP 202 ACCEPTED</span>
}
</pre></div><h2><a class="anchor" name="wsa_5">
Implementing a Server for Handling FaultTo Fault Messages</a></h2>
To implement a separate server for handling relayed SOAP fault messages based on the FaultTo information header in the request message, the gSOAP header file for soapcpp2 should include a SOAP fault service operation. This operation accepts fault messages that are relayed by other services.<p>
Basically, we use a trick to generate the SOAP-ENV:Fault struct via a one-way service operation. This allows us both to implement a one-way service operation that accepts faults and to automatically generate the fault struct for fault data storage and manipulation.<p>
The fault operation in the header file should be declared as follows (for the 2004/08 standard): <div class="fragment"><pre><span class="comment">//gsoap SOAP_ENV service method-action: Fault http://schemas.xmlsoap.org/ws/2004/08/addressing/fault</span>
<span class="keywordtype">int</span> SOAP_ENV__Fault
(       _QName                   faultcode,             <span class="comment">// SOAP 1.1</span>
        <span class="keywordtype">char</span>                    *faultstring,           <span class="comment">// SOAP 1.1</span>
        <span class="keywordtype">char</span>                    *faultactor,            <span class="comment">// SOAP 1.1</span>
        <span class="keyword">struct </span>SOAP_ENV__Detail *detail,                <span class="comment">// SOAP 1.1</span>
        <span class="keyword">struct </span>SOAP_ENV__Code   *SOAP_ENV__Code,        <span class="comment">// SOAP 1.2</span>
        <span class="keyword">struct </span>SOAP_ENV__Reason *SOAP_ENV__Reason,      <span class="comment">// SOAP 1.2</span>
        <span class="keywordtype">char</span>                    *SOAP_ENV__Node,        <span class="comment">// SOAP 1.2</span>
        <span class="keywordtype">char</span>                    *SOAP_ENV__Role,        <span class="comment">// SOAP 1.2</span>
        <span class="keyword">struct </span>SOAP_ENV__Detail *SOAP_ENV__Detail,      <span class="comment">// SOAP 1.2</span>
        <span class="keywordtype">void</span>
);
</pre></div><p>
Because each service operation has a struct to hold its input parameters, we automatically generate the (original) SOAP_ENV__Fault struct on the fly!<p>
Note: it is important to associate the wsa fault action with this operation as shown above.<p>
The implementation of the service operation in the server code is: <div class="fragment"><pre><span class="keywordtype">int</span> SOAP_ENV__Fault(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *faultcode, <span class="keywordtype">char</span> *faultstring, <span class="keywordtype">char</span> *faultactor, <span class="keyword">struct</span> SOAP_ENV__Detail *detail, <span class="keyword">struct</span> SOAP_ENV__Code *SOAP_ENV__Code, <span class="keyword">struct</span> SOAP_ENV__Reason *SOAP_ENV__Reason, <span class="keywordtype">char</span> *SOAP_ENV__Node, <span class="keywordtype">char</span> *SOAP_ENV__Role, <span class="keyword">struct</span> SOAP_ENV__Detail *SOAP_ENV__Detail)
{ 
  ... = faultcode; <span class="comment">// SOAP 1.1 fault code string (QName)</span>
  ... = faultstring; <span class="comment">// SOAP 1.1 fault string</span>
  ... = faultactor; <span class="comment">// SOAP 1.1 fault actor string</span>
  ... = detail; <span class="comment">// SOAP 1.1 fault detail struct</span>
  ... = SOAP_ENV__Code; <span class="comment">// SOAP 1.2 fault code struct</span>
  ... = SOAP_ENV__Reason; <span class="comment">// SOAP 1.2 reason struct</span>
  ... = SOAP_ENV__Node; <span class="comment">// SOAP 1.2 node string</span>
  ... = SOAP_ENV__Role; <span class="comment">// SOAP 1.2 role string</span>
  ... = SOAP_ENV__Detail; <span class="comment">// SOAP 1.2 detail struct</span>
  <span class="keywordflow">return</span> SOAP_OK;
}
</pre></div><p>
Note that SOAP 1.1 or SOAP 1.2 parameters are set based on the 1.1/1.2 messaging requirements. <hr size="1"><address style="align: right;"><small>Generated on Fri Mar 19 13:59:43 2010 for gSOAP WS-Addressing by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.8 </small></address>
</body>
</html>