Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > 71d40963b505df4524269198e237b3e3 > files > 876

virtuoso-opensource-doc-6.1.4-2.fc14.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
 <head profile="http://internetalchemy.org/2003/02/profile">
  <link rel="foaf" type="application/rdf+xml" title="FOAF" href="http://www.openlinksw.com/dataspace/uda/about.rdf" />
  <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" />
  <meta name="dc.title" content="15. Web Services" />
  <meta name="dc.subject" content="15. Web Services" />
  <meta name="dc.creator" content="OpenLink Software Documentation Team ;&#10;" />
  <meta name="dc.copyright" content="OpenLink Software, 1999 - 2009" />
  <link rel="top" href="index.html" title="OpenLink Virtuoso Universal Server: Documentation" />
  <link rel="search" href="/doc/adv_search.vspx" title="Search OpenLink Virtuoso Universal Server: Documentation" />
  <link rel="parent" href="webservices.html" title="Chapter Contents" />
  <link rel="prev" href=".html" title="" />
  <link rel="next" href="wsdl.html" title="WSDL" />
  <link rel="shortcut icon" href="../images/misc/favicon.ico" type="image/x-icon" />
  <link rel="stylesheet" type="text/css" href="doc.css" />
  <link rel="stylesheet" type="text/css" href="/doc/translation.css" />
  <title>15. Web Services</title>
  <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" />
  <meta name="author" content="OpenLink Software Documentation Team ;&#10;" />
  <meta name="copyright" content="OpenLink Software, 1999 - 2009" />
  <meta name="keywords" content="" />
  <meta name="GENERATOR" content="OpenLink XSLT Team" />
 </head>
 <body>
  <div id="header">
    <a name="soap" />
    <img src="../images/misc/logo.jpg" alt="" />
    <h1>15. Web Services</h1>
  </div>
  <div id="navbartop">
   <div>
      <a class="link" href="webservices.html">Chapter Contents</a> | <a class="link" href="webservices.html" title="Web Services">Prev</a> | <a class="link" href="wsdl.html" title="WSDL">Next</a>
   </div>
  </div>
  <div id="currenttoc">
   <form method="post" action="/doc/adv_search.vspx">
    <div class="search">Keyword Search: <br />
        <input type="text" name="q" /> <input type="submit" name="go" value="Go" />
    </div>
   </form>
   <div>
      <a href="http://www.openlinksw.com/">www.openlinksw.com</a>
   </div>
   <div>
      <a href="http://docs.openlinksw.com/">docs.openlinksw.com</a>
   </div>
    <br />
   <div>
      <a href="index.html">Book Home</a>
   </div>
    <br />
   <div>
      <a href="contents.html">Contents</a>
   </div>
   <div>
      <a href="preface.html">Preface</a>
   </div>
    <br />
   <div class="selected">
      <a href="webservices.html">Web Services</a>
   </div>
    <br />
   <div class="selected">
      <a href="soap.html">SOAP</a>
    <div>
        <a href="#soapovervw" title="Virtuoso SOAP Support Overview">Virtuoso SOAP Support Overview</a>
        <a href="#soapcallhandling" title="Handling of SOAP HTTP Requests">Handling of SOAP HTTP Requests</a>
        <a href="#dtschsoaps" title="Extending Datatypes for SOAP Objects">Extending Datatypes for SOAP Objects</a>
        <a href="#dtsch_inherit" title="Inheritance of Datatypes for SOAP Objects">Inheritance of Datatypes for SOAP Objects</a>
        <a href="#dtsoapcplx" title="Complex Types in PL Procedure and UDT Method Definition">Complex Types in PL Procedure and UDT Method Definition</a>
        <a href="#dtsch_procdef" title="Complex Types in Procedure Definition using a pre-defined XML Schema datatypes">Complex Types in Procedure Definition using a pre-defined XML Schema datatypes</a>
        <a href="#defaultsoapsqltypes" title="Default SOAP-SQL Datatype Mappings">Default SOAP-SQL Datatype Mappings</a>
        <a href="#exposingprocsassoaps" title="Exposing Stored Procedures as SOAP Objects">Exposing Stored Procedures as SOAP Objects</a>
        <a href="#soapudtproxy" title="Creation of SOAP proxy based on User Defined Types">Creation of SOAP proxy based on User Defined Types</a>
        <a href="#exposingudtssoap" title="Exposing User Defined Type Methods as SOAP Objects">Exposing User Defined Type Methods as SOAP Objects</a>
        <a href="#exposrmtprocsoap" title="Exposing Remote Third Party SQL Stored Procedures as SOAP Services">Exposing Remote Third Party SQL Stored Procedures as SOAP Services</a>
        <a href="#soapclient" title="Virtuoso/PL SOAP Client">Virtuoso/PL SOAP Client</a>
        <a href="#execpriv" title="Execution Privileges">Execution Privileges</a>
        <a href="#customsoapsrv" title="Custom Soap Server Support">Custom Soap Server Support</a>
        <a href="#soapextendedsyntax" title="PL Procedures and UDT Methods Syntax Affecting WSDL &amp; SOAP Processing">PL Procedures and UDT Methods Syntax Affecting WSDL &amp; SOAP Processing</a>
        <a href="#soapheadermessages" title="Exposing &amp; Processing SOAP Header Messages">Exposing &amp; Processing SOAP Header Messages</a>
        <a href="#soapfaultmessages" title="Exposing &amp; Processing SOAP Fault Messages">Exposing &amp; Processing SOAP Fault Messages</a>
        <a href="#soapdoclitenc1" title="Document Literal Encoding">Document Literal Encoding</a>
        <a href="#soapdimeenc" title="DIME encapsulation of SOAP messages">DIME encapsulation of SOAP messages</a>
        <a href="#soapoptions" title="SOAP Endpoint Options">SOAP Endpoint Options</a>
    </div>
   </div>
   <div>
      <a href="wsdl.html">WSDL</a>
   </div>
   <div>
      <a href="vfoafssl.html">WebID Protocol Support</a>
   </div>
   <div>
      <a href="voauth.html">OAuth Support</a>
   </div>
   <div>
      <a href="vwsssupport.html">WS-Security (WSS) Support in Virtuoso SOAP Server</a>
   </div>
   <div>
      <a href="ws-routing.html">Web Services Routing Protocol (WS-Routing)</a>
   </div>
   <div>
      <a href="warm.html">Web Services Reliable Messaging Protocol (WS-ReliableMessaging)</a>
   </div>
   <div>
      <a href="vwstrust.html">Web Services Trust Protocol (WS-Trust)</a>
   </div>
   <div>
      <a href="xmlxmla.html">XML for Analysis Provider</a>
   </div>
   <div>
      <a href="xmlrpc.html">XML-RPC support</a>
   </div>
   <div>
      <a href="syncml.html">SyncML</a>
   </div>
   <div>
      <a href="uddi.html">UDDI</a>
   </div>
   <div>
      <a href="expwsmodules.html">Exposing Persistent Stored Modules as Web Services</a>
   </div>
   <div>
      <a href="vsmx.html">Testing Web Published Web Services</a>
   </div>
   <div>
      <a href="bpel.html">BPEL Reference</a>
   </div>
   <div>
      <a href="xsql.html">XSQL</a>
   </div>
    <br />
  </div>
  <div id="text">
  <a name="soap" />
    <h2>15.1. SOAP</h2>

  <p>The Simple Object Access Protocol (SOAP) is a lightweight, extensible,
  XML-based application layer protocol for information exchange in a decentralized,
  distributed environment.
  SOAP defines a framework for message structures and a message processing
  model. SOAP also defines a set of encoding rules for serializing data and a
  convention for making remote procedure calls. The SOAP extensibility
  model provides a foundation for a wide range of composable modules and protocols.
  Although the most common way to transport SOAP messages is HTTP, it may also be
  run on top of other protocols.</p>
  <p>SOAP includes:</p>
  <ul>
      <li>an envelope that defines a framework for describing what
    is in a message and how to process it</li>
      <li>a set of encoding rules for expressing instances of
    application-defined datatypes</li>
      <li>a convention for representing remote procedure calls and responses.</li>
    </ul>
  
    <a name="soapovervw" />
    <h3>15.1.1. Virtuoso SOAP Support Overview</h3>
    <p>
Virtuoso provides a framework for both consuming SOAP services (acting as a
client) and producing them (acting as a server).  The Virtuoso web server
has a mechanism for handling SOAP messages and passing them to stored procedures
for processing.  Both SOAP 1.0 and SOAP 1.1 messages and data types are supported.
You may use all base SQL data types, as well as heterogeneous arrays, as both arguments and return values of
Virtuoso SOAP services.  A full-featured set of functions for handling SOAP objects is provided.
Services using a transport mechanism other than HTTP can also be constructed using the API.  The SOAP
framework may be used independently of any of the other web-related services.
    </p>
    <p>
Virtuoso/PL can also issue requests to SOAP servers.  SOAP can be used to access any application
servers, including those running within the Virtuoso server.
    </p>
    <p>
The Virtuoso SOAP server extends Virtuoso/PL parameter handling by adding complex data types
declared with XML schema as parameter values for stored procedures.
The Virtuoso SOAP server provides
automatic validation of the parameters in requests, based on schema declarations.
    </p>
  <br />
  
    <a name="soapcallhandling" />
    <h3>15.1.2. Handling of SOAP HTTP Requests</h3>
    <p>
The Virtuoso web server recognizes SOAP HTTP requests and their
version in the POST method handler.  When
<span class="computeroutput">SOAPMethodName</span> or
<span class="computeroutput">SOAPAction</span> HTTP header attributes are present
with <span class="computeroutput">Content-Type: text/xml</span>, the
server initiates SOAP call handling. The XML namespace of the SOAP
method name is stripped off and Virtuoso searches for a stored
procedure with the same name, ignoring case.
</p>
<p> The search is done within the default qualifier of the SQL user
account assigned for SOAP call execution defined for the virtual host.
For example, if the database user assigned in the virtual host&#39;s
definition for SOAP execution is called SOAPDBUSER and this user has a
default qualifier &#39;SOAPDB&#39; and the request contains an
invocation of method called
<span class="computeroutput">OurSoapMethod</span>, Virtuoso would
attempt to find a stored procedure named
<span class="computeroutput">SOAPDB.SOAPDBUSER.OurSoapMethod</span>.
    </p>
    <p>
When a matching stored procedure is found, any of its parameters that have names matching parameter
entity names in the SOAP call are bound to the call parameter. The parameter name match is also
case-insensitive.
    </p>
    <p>
Virtuoso maps the procedure parameter datatypes internally
by <a href="sqlrefDATATYPES.html#dtcasting">casting</a>
from XML data (a string) to the declared parameter datatype of the
stored procedure.  There is one exception: When an array is being
passed, the server creates an array with values of types inferred from
the XML Schema of its elements.
It is possible to declare that a user defined SQL type be used to represent a
specific XML element in a SOAP request.  Thus SQL objects can be constructed
and serialized automatically.  Note that this also means that the implementation
of the user defined type instance may be in a hosted language, thus Java or
CLR code may be transparently involved.
    </p>
    <p>
Two special parameters - <span class="computeroutput">ws_soap_headers</span>
and <span class="computeroutput">ws_http_headers</span> - are available to a
stored procedure handling a SOAP method invocation.  If declared as
input parameters for the procedure,
<span class="computeroutput">ws_soap_headers</span> must contain an XML parse tree
of the <span class="computeroutput">SOAP:Header</span> in same format as returned
by <a href="fn_xml_tree.html">xml_tree()</a>.
<span class="computeroutput">ws_http_headers</span> should hold a one-dimensional
array of attribute/value pairs representing the HTTP header fields in
the request.
    </p>
  <br />
  
    <a name="dtschsoaps" />
    <h3>15.1.3. Extending Datatypes for SOAP Objects</h3>
    <p>
Complex datatypes can be defined using XMLSchema and represented by WSDL.
Any of the declared types may be used as arguments and return types of
Virtuoso/PL procedures.  Any procedures can thus be exposed as SOAP methods.
    </p>
    <p>
Complex data type definitions are used for values that cannot be contained by
simple scalar datatypes.  Typical examples are arrays of scalars, structures
of scalars, arrays of structures or structures of arrays.  A complex datatype
may contain scalar and complex datatypes.  When a complex type is used in
the definition of another complex type, the definition of the contained complex
type must exist.
    </p>
    <p>
In addition to &#39;usual&#39; complex types as structures and arrays Virtuoso implements support for
&#39;choice&#39;, &#39;enumeration&#39;, anyType and anyElement and extensions to the  simple types.
Inheritance of complex types is also possible and is discussed further in next chapter.
    </p>
    <p>
The &#39;nillable&#39; and &#39;minOccurs&#39; attributes in schema definitions have special meaning
for PL values returned by PL procedure via SOAP.  If this attribute is &#39;true&#39; then
output of NULL values will be serialized in their XML form with XMLSchema instance
attribute &#39;nil&#39; as &#39;true&#39;.  Otherwise if elements have &#39;minOccurs&#39; equal to 0 (zero),
the element will be omitted. If minOccurs is equal to 1 (one) an empty element will
be sent to the client. The same algorithm applies to the serialization of PL values
passed as parameters to soap_client() function. Therefore it&#39;s important to make
proper use of these attributes when defining complex structures.
    </p>
    <p>
The &#39;__VOID__&#39; string constant has a special meaning in XMLSchema Datatypes.
It is used to designate no output for return value. In other words returned
value from PL procedure will not be serialized nor exposed in the WSDL file.
    </p>
    <p>
You define complex datatypes using
<a href="fn_soap_dt_define.html">soap_dt_define()</a>.
The function accepts a schema definition excerpt, based on the element
<span class="computeroutput">complexType</span>. The definition must be a valid XML document.
    </p>
    <a name="ex_soap_complex_dt_def" />
    <div class="example">
      <div class="exampletitle">Declaring and using complex datatypes in SOAP</div>
      <p>
In this example we define two complex datatypes. The first one, <span class="computeroutput">SOAPStruct</span>,
consists of scalars; the second one, <span class="computeroutput">ArrayOfSOAPStruct</span>, is an array
of these structures. These schema excerpts
are stored in the filesystem as <span class="computeroutput">struct.xsd</span> and <span class="computeroutput">array.xsd</span>.
      </p>

<p>
        <strong>struct.xsd:</strong>
      </p>
<div>
        <pre class="programlisting">
&lt;!-- a SOAPStruct type declaration
     file name: struct.xsd --&gt;
&lt;complexType name=&quot;SOAPStruct&quot;
   targetNamespace=&quot;http://tempuri.tmp/&quot;
   xmlns:enc=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
   xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
   xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
   xmlns:tns=&quot;services.wsdl&quot;&gt;

   &lt;sequence&gt;
     &lt;element name=&quot;varString&quot; type=&quot;string&quot; nillable=&quot;true&quot;/&gt;
     &lt;element name=&quot;varInt&quot; type=&quot;int&quot; nillable=&quot;true&quot;/&gt;
     &lt;element name=&quot;varFloat&quot; type=&quot;float&quot; nillable=&quot;true&quot;/&gt;
   &lt;/sequence&gt;
&lt;/complexType&gt;

</pre>
      </div>

<p>
        <strong>array.xsd:</strong>
      </p>
          <div>
        <pre class="programlisting">
&lt;!-- array of SOAPStruct
     file name: array.xsd --&gt;
&lt;complexType name=&quot;ArrayOfSOAPStruct&quot;
   targetNamespace=&quot;http://tempuri.tmp/&quot;
   xmlns:enc=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
   xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
   xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
   xmlns:tns=&quot;services.wsdl&quot;&gt;

   &lt;complexContent&gt;
   &lt;restriction base=&quot;enc:Array&quot;&gt;
   &lt;sequence&gt;
   &lt;element name=&quot;item&quot; type=&quot;tns:SOAPStruct&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot;/&gt;
   &lt;/sequence&gt;
   &lt;attribute ref=&quot;enc:arrayType&quot; wsdl:arrayType=&quot;tns:SOAPStruct[]&quot;/&gt;
   &lt;attributeGroup ref=&quot;enc:commonAttributes&quot;/&gt;
   &lt;attribute ref=&quot;enc:offset&quot;/&gt;
   &lt;/restriction&gt;
   &lt;/complexContent&gt;
&lt;/complexType&gt;
</pre>
      </div>

      <p>
Next, we issue commands to define a new complex datatype.  Correct
order is important.  (SQL&gt; is the prompt of the Interactive
SQL utility included with Virtuoso and should not be typed)
      </p>
      <div>
        <pre class="programlisting">
SQL&gt; DB..soap_dt_define (&#39;SOAPStruct&#39;, file_to_string (&#39;struct.xsd&#39;));
SQL&gt; DB..soap_dt_define (&#39;ArrayOfSOAPStruct&#39;, file_to_string (&#39;array.xsd&#39;));
</pre>
      </div>
    </div>

      <div class="note">
      <div class="notetitle">Note:</div>
      <p>The WSDL specification requires that array names be prefixed with <span class="computeroutput">ArrayOf</span>.</p>
      </div>
  <br />

  
    <a name="dtsch_inherit" />
    <h3>15.1.4. Inheritance of Datatypes for SOAP Objects</h3>
    <p>
   The Virtuoso SOAP server implements handling of inherited XSD types.
   The simple example of such relation between types can be explained as</p>
   <div>
      <pre class="programlisting">
   Type  A, also know as the &#39;base&#39; type,
   and type B an extension of A.
   +---+   +---+
   | a |--&gt;| c |
   | b |   | d |
   +---+   +---+

   which can be defined by two separate types without relation

   A type   B type
   +---+   +---+
   | a |   | a |
   | b |   | b |
   +---+   +- -+
           | c |
           | d |
           +---+
   </pre>
    </div>
   <p>
   But when type A has changed, type B will not be changed in second representation.
   This is because B is not a relative to A per se. </p>
   <p>
   To work in such situations Virtuoso SOAP server handles extensions to
   XSD types as follows:
   </p>
   <ol>
      <li>each type and base type have defined a User Defined SQL type (UDT).</li>
      <li>the XSD types defined for SOAP processing are defined with UDT relation (see soap_dt_define)</li>
      <li>the inheritance is declared with &#39;extension&#39; element in XSD type declaration</li>
    </ol>
  <p>
   When we have these preliminaries the WSDL will declare in &#39;schema&#39; part of WSDL all
   depending types. Furthermore the SOAP processor will handle inherited members of derived types.
    </p>

    <a name="inhertype" />
    <div class="example">
      <div class="exampletitle">Declaration and usage of depending types</div>
    <p>Consider the following XSD and User Defined Type declaration for a base type
    &#39;BaseStruct&#39;:
    </p>
    <div>
        <pre class="programlisting">
        &lt;!-- XSD type declaration, file base.xsd --&gt;
	&lt;complexType name=&quot;BaseStruct&quot;&gt;
		&lt;sequence&gt;
			&lt;element name=&quot;floatMessage&quot; type=&quot;xsd:float&quot;/&gt;
			&lt;element name=&quot;shortMessage&quot; type=&quot;xsd:short&quot;/&gt;
		&lt;/sequence&gt;
	&lt;/complexType&gt;

	-- corresponding user defined sql type
        create type DB.DBA.BaseStruct as (floatMessage real, shortMessage int __soap_type &#39;short&#39;);
    
    </pre>
      </div>
    <p>Furthermore we are extending the BaseStruct with adding three more elements (members)
    with declaration of ExtendedStruct:
    </p>
    <div>
        <pre class="programlisting">
        &lt;!-- XSD type declaration, file ext.xsd --&gt;
	&lt;complexType name=&quot;ExtendedStruct&quot;&gt;
		&lt;complexContent&gt;
			&lt;extension base=&quot;tns:BaseStruct&quot;&gt;
				&lt;sequence&gt;
					&lt;element name=&quot;stringMessage&quot; type=&quot;xsd:string&quot;/&gt;
					&lt;element name=&quot;intMessage&quot; type=&quot;xsd:int&quot;/&gt;
					&lt;element name=&quot;anotherIntMessage&quot; type=&quot;xsd:int&quot;/&gt;
				&lt;/sequence&gt;
			&lt;/extension&gt;
		&lt;/complexContent&gt;
	&lt;/complexType&gt;

	-- corresponding user defined SQL type
       create type DB.DBA.ExtendedStruct under DB.DBA.BaseStruct as (
	    stringMessage nvarchar __soap_type &#39;string&#39;,
	    intMessage int __soap_type &#39;int&#39;,
	    anotherIntMessage int __soap_type &#39;int&#39;);
    
    </pre>
      </div>
    <p>
    Once we are done with declarations as XSD files and user defined SQL types,
    we must register them as SOAP types for processing:
    </p>
    <div>
        <pre class="programlisting">
SQL&gt; soap_dt_define (&#39;&#39;, file_to_string (&#39;base.xsd&#39;), &#39;DB.DBA.BaseStruct&#39;);
SQL&gt; soap_dt_define (&#39;&#39;, file_to_string (&#39;ext.xsd&#39;), &#39;DB.DBA.ExtendedStruct&#39;);
    
    </pre>
      </div>
    <p>
    Now we are able to create a PL procedure to use as a SOAP method,
    which simply will accept an ExtendedStruct and echo it back to the client.
    </p>
    <div>
        <pre class="programlisting">
create procedure
echoExtendedStruct (in param DB.DBA.ExtendedStruct __soap_type &#39;http://soapinterop.org/types:ExtendedStruct&#39;)
returns DB.DBA.ExtendedStruct __soap_type &#39;http://soapinterop.org/types:ExtendedStruct&#39;
{
  --  All members  of DB.DBA.ExtendedStruct and DB.DBA.BaseStruct are available in param.
  return param;
}
;

grant execute on echoExtendedStruct to SOAP;
    
    </pre>
      </div>

    <p>
    The SOAP request to that method will be  as follows:
    </p>
    <div>
        <pre class="programlisting">
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;
  xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
  xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
  xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
  SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
  xmlns:m0=&quot;http://soapinterop.org/types&quot;&gt;
  &lt;SOAP-ENV:Body&gt;
    &lt;m:echoExtendedStruct xmlns:m=&quot;http://soapinterop.org/wsdl&quot;&gt;
      &lt;param xsi:type=&quot;m0:ExtendedStruct&quot;&gt;
        &lt;floatMessage xsi:type=&quot;xsd:float&quot;&gt;3.14159&lt;/floatMessage&gt;
        &lt;shortMessage xsi:type=&quot;xsd:short&quot;&gt;4096&lt;/shortMessage&gt;
        &lt;stringMessage xsi:type=&quot;xsd:string&quot;&gt;String&lt;/stringMessage&gt;
        &lt;intMessage xsi:type=&quot;xsd:int&quot;&gt;0&lt;/intMessage&gt;
        &lt;anotherIntMessage xsi:type=&quot;xsd:int&quot;&gt;0&lt;/anotherIntMessage&gt;
      &lt;/param&gt;
    &lt;/m:echoExtendedStruct&gt;
  &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
    
    </pre>
      </div>
    <p>
    The SOAP response to the above request  will be as follows:
    </p>
    <div>
        <pre class="programlisting">

&lt;SOAP:Envelope
SOAP:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
xmlns:SOAP=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;
xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
xmlns:dt=&quot;urn:schemas-microsoft-com:datatypes&quot;
xmlns:ds=&quot;http://www.w3.org/2000/09/xmldsig#&quot;
xmlns:xenc=&quot;http://www.w3.org/2001/04/xmlenc#&quot;
xmlns:wsse=&quot;http://schemas.xmlsoap.org/ws/2002/07/secext&quot;
xmlns:ref=&quot;http://schemas.xmlsoap.org/ws/2002/04/reference/&quot;
xmlns:ns0=&quot;http://soapinterop.org/types&quot; xmlns:wsdl=&quot;services.wsdl&quot;&gt;

  &lt;SOAP:Body&gt;
    &lt;cli:echoExtendedStructResponse xmlns:cli=&quot;http://soapinterop.org/wsdl&quot;&gt;
      &lt;CallReturn xsi:type=&quot;ns0:ExtendedStruct&quot;&gt;
        &lt;stringMessage xsi:type=&quot;xsd:string&quot;&gt;String&lt;/stringMessage&gt;
        &lt;intMessage xsi:type=&quot;xsd:int&quot;&gt;0&lt;/intMessage&gt;
        &lt;anotherIntMessage xsi:type=&quot;xsd:int&quot;&gt;0&lt;/anotherIntMessage&gt;
        &lt;floatMessage xsi:type=&quot;xsd:float&quot;&gt;3.14159&lt;/floatMessage&gt;
        &lt;shortMessage xsi:type=&quot;xsd:short&quot;&gt;4096&lt;/shortMessage&gt;
      &lt;/CallReturn&gt;
    &lt;/cli:echoExtendedStructResponse&gt;
  &lt;/SOAP:Body&gt;
&lt;/SOAP:Envelope&gt;
    
    </pre>
      </div>
    <div class="note">
        <div class="notetitle">Note:</div>
    <p>Although the namespace declarations of XSD types are skipped for better
    readability, these must be present when declaring (see the Extending Datatypes
    for SOAP Objects section, discussed earlier)</p>
      </div>
    </div>

  <br />

  
    <a name="dtsoapcplx" />
    <h3>15.1.5. Complex Types in PL Procedure and UDT Method Definition</h3>
    <p>
	Virtuoso/PL allows parameters to be declared as  complex
	objects (structures and arrays) without special XMLSchema datatype defined.
	To declare a structure as a type of a parameter an UDT must be created
	and parameter to have it as datatype reference. Also all permitted
	datatypes (including UDTs) could be declared as elements of an ARRAY of unlimited or limited length.
    </p>
    <p>
	Important: when a UDT is used in a SOAP context, it MUST be granted to the
        SQL user for SOAP invocation. In other words the user on whose behalf the SOAP
        call is processed.
    </p>
    <a name="ex_dtsoapcplx_1" />
    <div class="example">
	<div class="exampletitle">Procedure definition with a input and output as a structure</div>
	<p>
	    The following example defines a UDT &#39;SOAP_Struct&#39;
	    (containing varchar, integer and float members) and declares
	    the input parameter and return value of a PL procedure to be of the SOAP_Struct type.
	    The input will be verified, UDT will be instantiated with given values for members
	    and it will be echoed back to the client.
	</p>
	<div>
        <pre class="programlisting">
	    create type SOAP_Struct as (varString varchar, varInt integer, varFloat real);

	    create procedure echoStruct (in s DB.DBA.SOAP_Struct) returns DB.DBA.SOAP_Struct
	    {
	      return s;
	    };
	    </pre>
      </div>
    </div>
    <a name="ex_dtsoapcplx_2" />
    <div class="example">
	<div class="exampletitle">Procedure definition with a input and output as an integer array</div>
	<p>
	    This example declares that input must be an array of integer values
	    with maximum length of 5. If input or output contains more than five
	    integers then a SOAP Fault will be sent back to the client containing
	    an appropriate error message ; otherwise the input array will be echoed back.
	</p>
	<div>
        <pre class="programlisting">
	    create procedure echoIntArray (in ia integer array[5]) returns integer array[5]
	    {
	      return ia;
	    };
	    </pre>
      </div>
    </div>
    <a name="ex_dtsoapcplx_3" />
    <div class="example">
	<div class="exampletitle">Procedure definition with a input and output as a two-dimensional varchar array</div>
	<p>
	    This example declares that the input must be an array of integer array values
	    with unlimited length. If the input SOAP message contains a valid array following
	    the current XML encoding rules then an array of integer arrays
	    (vector containing vectors of integers) will be created and passed to the procedure.
	    On success the input array will be echoed back to the client.
	</p>
	<div>
        <pre class="programlisting">
	    create procedure echoIntMulArray (in iaa integer array array) returns integer array array
	    {
	      return iaa;
	    };
	    </pre>
      </div>
    </div>
    <a name="ex_dtsoapcplx_4" />
    <div class="example">
	<div class="exampletitle">Procedure definition with a input and output as an struct array</div>
	<p>
	    This example shows how to use an array of structures (UDTs) and also shows
	    usage of the array type as an member of the structure. The UDT &#39;SOAP_StructA&#39;
	    is similar to the those in first example except 4the member which is
	    an array of integers. This is to demonstrate that arrays are not limited
	    to the Stored Procedure&#39;s parameters declaration, they also can be used
	    as a type of UDT member.
	    Upon success the procedure will echo of the input back to the client.
	</p>
	<div>
        <pre class="programlisting">
	    create type SOAP_StructA as (varString varchar, varInt integer, varFloat real, varArray integer array);

	    create procedure echoStructArray (in sa DB.DBA.SOAP_StructA array) returns DB.DBA.SOAP_StructA array
	    {
	      return sa;
	    };
	    </pre>
      </div>
	<p>
	    The SOAP request to an endpoint which exposes the echoStructArray as a
	    document/literal encoded SOAP method would be as follows:
	</p>
	<div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
  &lt;SOAP-ENV:Body&gt;
    &lt;ns0:echoStructArray xmlns:ns0=&quot;http://temp.uri&quot;&gt;
      &lt;sa&gt;
        &lt;item&gt;
          &lt;varString&gt;abcd&lt;/varString&gt;
          &lt;varInt&gt;1234&lt;/varInt&gt;
          &lt;varFloat&gt;3.14&lt;/varFloat&gt;
          &lt;varArray&gt;
            &lt;item&gt;3&lt;/item&gt;
            &lt;item&gt;4&lt;/item&gt;
          &lt;/varArray&gt;
        &lt;/item&gt;
      &lt;/sa&gt;
    &lt;/ns0:echoStructArray&gt;
  &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
	    </pre>
      </div>
	<p>
	    The SOAP server will receive and array of one element containing a
	    structure with string, integer, float and integer array of two elements.
	    Then the response from the SOAP server to the requestor will be:
	</p>
	<div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot; ?&gt;
&lt;SOAP:Envelope xmlns:SOAP=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
  &lt;SOAP:Body&gt;
    &lt;cli:echoStructArrayResponse xmlns:cli=&quot;http://temp.uri&quot;&gt;
      &lt;CallReturn&gt;
        &lt;item&gt;
          &lt;varString&gt;abcd&lt;/varString&gt;
          &lt;varInt&gt;1234&lt;/varInt&gt;
          &lt;varFloat&gt;3.14&lt;/varFloat&gt;
          &lt;varArray&gt;
            &lt;item&gt;3&lt;/item&gt;
            &lt;item&gt;4&lt;/item&gt;
          &lt;/varArray&gt;
        &lt;/item&gt;
      &lt;/CallReturn&gt;
    &lt;/cli:echoStructArrayResponse&gt;
  &lt;/SOAP:Body&gt;
&lt;/SOAP:Envelope&gt;
	    </pre>
      </div>
    </div>
    <p>
	See also the WSDL file generation section for details how such PL procedures with parameters of
	complex datatypes are exposed via SOAP enabled virtual HTTP directories.
    </p>
  <br />


  
    <a name="dtsch_procdef" />
    <h3>15.1.6. Complex Types in Procedure Definition using a pre-defined XML Schema datatypes</h3>
    <p>
Declaration of a complex datatype as a parameter is done by adding a special
keyword <span class="computeroutput">__soap_type</span> followed by the name of the defined complex
type after normal parameter declaration in the parameter list. The type name is given
as a string literal.  The same syntax extension also applies to declaration of the return type.
This is shown in the following example.
    </p>
    <a name="ex_soap_complex_parm_proc_def" />
    <div class="example">
      <div class="exampletitle">Procedure Definition with Complex Datatype Parameters</div>
        <p>
We create a  procedure that will accept an array of structures (as defined in the previous example) and
return it to the client.  It instructs the WSDL generator to assign <span class="computeroutput">ArrayOfSOAPStruct</span> as
the input parameter and return value types when
<span class="computeroutput">WS.SOAP.echoSOAPArray()</span> is exposed as a
SOAP method. The type information is available to SOAP clients that read the WSDL description.
Upon receiving an incoming SOAP request, Virtuoso converts the XML
representation of the data, after validation, to the
form <span class="computeroutput">vector(vector([varchar],[integer],[real]), ...)</span> and passed to the
<span class="computeroutput">WS.SOAP.echoSOAPArray</span>. Failed parameter validation is reported to the client.
        </p>
        <div>
        <pre class="programlisting">
SQL&gt; CREATE PROCEDURE WS.SOAP.echoSOAPArray (in inArray any __soap_type &#39;ArrayOfSOAPStruct&#39;)
            RETURNS any __soap_type &#39;ArrayOfSOAPStruct&#39;
    {
      return inArray;
    };
</pre>
      </div>
    </div>
    <br />
    <a name="defaultsoapsqltypes" />
    <h3>15.1.7. Default SOAP-SQL Datatype Mappings</h3>
    <p>
When no alternative datatype is assigned, the WSDL generator and SOAP server
will use the default mapping described below:
    </p>
    <table class="data">
      <caption>Table: 15.1.7.1. Default datatype mappings in SOAP</caption>
      
        
          <tr>
            <th class="data">Datatype</th>
            <th class="data">Maps to</th>
          </tr>
        
        
	  <tr>
	    <td class="data">integer</td>
	    <td class="data">xsd:int</td>
	  </tr>
	  <tr>
	    <td class="data">real</td>
	    <td class="data">xsd:float</td>
	  </tr>
	  <tr>
	    <td class="data">double precision</td>
	    <td class="data">xsd:double</td>
          </tr>
	  <tr>
	    <td class="data">numeric</td>
	    <td class="data">xsd:decimal</td>
	  </tr>
	  <tr>
	    <td class="data">datetime</td>
	    <td class="data">xsd:timeInstant</td>
          </tr>
	  <tr>
	    <td class="data">any other type</td>
	    <td class="data">xsd:string</td>
	  </tr>
        
      
    </table>
    <br />

  <p>The REAL SQL type is mapped to the xsd:float SOAP datatype by default
  and so loss of precision can occur.  To improve the precision, the SOAP
  server will map the xsd:float to the PL double precision datatype instead,
  but only if the SOAP type is specified.  The explicit declaration of
  __soap_type &#39;xsd:float&#39; is required to instruct Virtuoso to use the mapping
  to double precision.</p>

  <p>All strings from a SOAP request declared with the SOAP datatype
  xsd:string will be treated as NVARCHARs on input.  All string data such a
  CHAR, VARCHAR, or NVARCHAR will be encoded as UTF-8 in a SOAP response.
  This makes processing of wide character sets in SOAP operations possible.</p>

  <p>If a User Defined Type (UDT) is used as a type of parameter and no
      explicit XML Schema datatype given (see special syntax for PL procedures)
      then in WSDL will be included as a struct definition. Further upon
      SOAP processing the input struct will be encoded as a UDT instance and passed
      to the given PL procedure.
  </p>

  <p>
      The parameters which are declared as an array (see PL procedure syntax)
      and having no explicit XML Schema datatype given will be exposed as
      array by means of SOAP encoding rules (see also &#39;Use&#39; SOAP option to the
      virtual directory).
  </p>

  <p>Some SOAP applications need a void return as opposed to an empty return,
  from SOAP operations.  To distinguish the empty return from the void return
  a special SOAP datatype &#39;__VOID__&#39; has been introduced.   This will cause
  the SOAP server to omit the procedure return value when responding to a
  SOAP request.  Also, the return message will be discarded from the
  WSDL description file.</p>

  <br />
  
    <a name="exposingprocsassoaps" />
    <h3>15.1.8. Exposing Stored Procedures as SOAP Objects</h3>
    <p>
The special physical path <span class="computeroutput">/SOAP/</span> in the Virtuoso
Web server is reserved for SOAP objects.  Virtuoso makes available any
stored procedure created in the default qualifier of the SOAP user,
with execution privileges granted to the SOAP user.
You can also use Virtuoso&#39;s <a href="webserver.html#virtdir">virtual
host</a> mechanism to create new logical paths for accessing SOAP
objects.  A logical path property <span class="computeroutput">soap_user</span>
determines the db user for SOAP.  If a logical path points to the
<span class="computeroutput">/SOAP/</span> special physical path, it will expose any
procedures created in the default qualifier of, and with execution
privileges to, <span class="computeroutput">soap_user</span> to the world as SOAP
objects.
    </p>
	<p>If the physical path of <span class="computeroutput">/SOAP</span>
	exists under the VSP root directory
	then any non-SOAP specific HTTP requests will be directed there for content.
	This can be useful for helping to establish the presence and location of a SOAP
	endpoint - some applications attempt a standard HTTP connection first.
	You might configure a virtual directory, intended for SOAP, with a
	default page referencing a description of the SOAP endpoint, a page
	in the &lt;VSPROOT&gt;/SOAP directory, preventing an
	<span class="computeroutput">HTTP 404</span> style error misleading an
	application into believing the SOAP endpoint is down regardless of whether
	it tried to talk SOAP to it or not.</p>
    <div class="note">
      <div class="notetitle">Note:</div>
      <p>
Procedures exposed as SOAP procedures run as any other stored procedure in Virtuoso
and can call and get return values from other procedures and functions not exposed through SOAP.
The ability to execute procedures attached from remote data sources facilitates
SOAP-enabling existing database applications in a heterogeneous environment.
      </p>
    </div>
    <a name="ex_soap_new_vhost" />
    <div class="example">
      <div class="exampletitle">Creating a new virtual host for SOAP execution</div>
      <p>
Create new user in the database for SOAP:
      </p>
      <div>
        <pre class="screen">
SQL&gt;CREATE USER SOAPDEMO;
</pre>
      </div>
      <p>
Set the default catalogue/qualifier for the new user to WS. This is where
procedures to be used as SOAP objects will be created:
      </p>
      <div>
        <pre class="screen">
SQL&gt;USER_SET_QUALIFIER (&#39;SOAPDEMO&#39;, &#39;WS&#39;);
</pre>
      </div>
        <p>
Create a new virtual host definition, using
<a href="fn_vhost_define.html">vhost_define()</a>.
        </p>
        <div>
        <pre class="screen">
SQL&gt;VHOST_DEFINE (vhost=&gt;&#39;*ini*&#39;,lhost=&gt;&#39;*ini*&#39;,lpath=&gt;&#39;/mysoapdomain&#39;,ppath=&gt;&#39;/SOAP/&#39;,soap_user=&gt;&#39;SOAPDEMO&#39;);
</pre>
      </div>
        <p>
An existing mapping could be removed using the command:
        </p>
        <div>
        <pre class="screen">
SQL&gt;VHOST_REMOVE (vhost=&gt;&#39;*ini*&#39;,lhost=&gt;&#39;*ini*&#39;,lpath=&gt;&#39;/mysoapdomain&#39;)
</pre>
      </div>
        <div class="note">
          <div class="notetitle">Note:</div>
          <p>
&#39;<span class="computeroutput">*ini*</span>&#39; is a special value that instructs Virtuoso to use the default
values from the Virtuoso initialization file.
          </p>
        </div>
        <p>
All procedures that are created with the WS.SOAPDEMO qualifier and then
granted execution to SOAPDEMO will be visible to SOAP.
Make a simple SOAPTEST procedure and grant the appropriate
privileges to the SOAPDEMO user:
        </p>
        <div>
        <pre class="screen">
SQL&gt; create procedure
  WS.SOAPDEMO.SOAPTEST (in par varchar)
{
  return (upper(par));
};

SQL&gt; grant execute on WS.SOAPDEMO.SOAPTEST to SOAPDEMO;
</pre>
      </div>
        <p>
The SOAP object may now be tested by
using the <a href="fn_soap_client.html">soap_client()</a>
function, which returns a vector representation of
the SOAP object returned by the call. The example below simply extracts
the returned string with <a href="fn_aref.html">aref()</a>, as
the exact format of the object returned is known:
        </p>
<div>
        <pre class="screen">
SQL&gt;select aref(aref(
	soap_client (url=&gt;sprintf (&#39;http://localhost:%s/mysoapdomain&#39;, server_http_port ()),
	operation=&gt;&#39;SOAPTEST&#39;,
	parameters=&gt;vector(&#39;par&#39;, &#39;demotext&#39;)),
	1), 1);
callret
VARCHAR
_______

DEMOTEXT
</pre>
      </div>
        <p>
Printing the output on the console or server log with
<a href="fn_dbg_obj_print.html">dbg_obj_print()</a> would
output something like:
        </p>
        <div>
        <pre class="screen">
((&quot;SOAPTESTResponse&quot; ) ((&quot;CallReturn&quot; ) &quot;DEMOTEXT&quot; ) )
</pre>
      </div>
        <p>
The automatic service description generation can be verified by retrieving
<span class="computeroutput">http://&lt;server:port&gt;/mysoapdomain/services.wsdl</span>,
and preferably tested by pointing a web browser at
<span class="computeroutput">http://&lt;server:port&gt;/mysoapdomain/services.vsmx</span>

        </p>
        <div>
        <pre class="screen">
SQL&gt; select http_get (sprintf (&#39;http://localhost:%s/mysoapdomain/services.wsdl&#39;, server_http_port()));
callret
VARCHAR
_______________________________________________________________________________

&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;definitions
 xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
 xmlns:http=&quot;http://schemas.xmlsoap.org/wsdl/http/&quot;
 xmlns:mime=&quot;http://schemas.xmlsoap.org/wsdl/mime/&quot;
 xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;
 xmlns:soapenc=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
 xmlns:s=&quot;services.wsdl&quot;
 xmlns:tns=&quot;services.wsdl&quot;
 targetNamespace=&quot;services.wsdl&quot;
 name=&quot;VirtuosoSOAP&quot; xmlns=&quot;http://schemas.xmlsoap.org/wsdl/&quot;&gt;

  &lt;types&gt;
  &lt;schema targetNamespace=&quot;services.wsdl&quot;
   xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
   xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;&gt;
    &lt;complexType name=&quot;echoStringArrayResponse&quot;&gt;
      &lt;sequence&gt;
        &lt;element name=&quot;return&quot; type=&quot;ArrayOfstring_literal&quot;/&gt;
      &lt;/sequence&gt;
    &lt;/complexType&gt;
    &lt;complexType name=&quot;echoVoid&quot;/&gt;
    &lt;complexType name=&quot;ArrayOffloat&quot;&gt;
      &lt;complexContent&gt;
        &lt;restriction base=&quot;soapenc:Array&quot;&gt;
          &lt;sequence&gt;
            &lt;element name=&quot;item&quot; type=&quot;float&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot;/&gt;
          &lt;/sequence&gt;
          &lt;attributeGroup ref=&quot;soapenc:commonAttributes&quot;/&gt;
          &lt;attribute ref=&quot;soapenc:offset&quot; /&gt;
          &lt;attribute ref=&quot;soapenc:arrayType&quot; wsdl:arrayType=&quot;float[]&quot;/&gt;
        &lt;/restriction&gt;
      &lt;/complexContent&gt;
    &lt;/complexType&gt;
    &lt;complexType name=&quot;SOAPStruct&quot;&gt;
      &lt;sequence&gt;
        &lt;element name=&quot;varString&quot; type=&quot;string&quot;/&gt;
        &lt;element name=&quot;varInt&quot; type=&quot;int&quot;/&gt;
        &lt;element name=&quot;varFloat&quot; type=&quot;float&quot;/&gt;
      &lt;/sequence&gt;
    &lt;/complexType&gt;
    &lt;complexType name=&quot;echoStructResponse&quot;&gt;
      &lt;sequence&gt;
        &lt;element name=&quot;return&quot; type=&quot;SOAPStruct&quot;/&gt;
      &lt;/sequence&gt;
    &lt;/complexType&gt;
    &lt;complexType name=&quot;echoVoidResponse&quot;/&gt;
    &lt;complexType name=&quot;ArrayOfString2D&quot;&gt;
    ...

</pre>
      </div>
    </div>

    <div class="tip">
      <div class="tiptitle">See Also:</div>
    <p>
        <a href="vsmx.html">Testing Web Services using VSMX</a>
      </p>
    </div>

  <br />

  <a name="soapudtproxy" />
    <h3>15.1.9. Creation of SOAP proxy based on User Defined Types</h3>

      <p>It is possible to automatically generate PL procedures or UDT classes for invoking a remote SOAP service.
      </p>

      <div class="tip">
      <div class="tiptitle">See Also</div>
       <p>The <a href="fn_wsdl_import_udt.html">WSDL_IMPORT_UDT()</a> function for details and examples.</p>
      </div>

      <p>The proxy-creation function <span class="computeroutput">WSDL_IMPORT_UDT()</span> performs the following purposes:</p>

      <ul>
      <li>retrieve and expand the WSDL file published by the end point to be called</li>
      <li>compile the result and make SQL script with UDT definition</li>
      <li>generate and register XML Schema definition for special types used in the source service</li>
      <li>optionally execute the SQL script generated</li>
    </ul>


      <p>Once such UDT SOAP proxy is defined it can be used within application code
	  or be re-exposed as a SOAP service on local server instance (see next chapter how to
	  expose UDT as service).
      </p>


      <div class="tip">
      <div class="tiptitle">See Also</div>
	  <p>The Virtuoso Administration Interface provides a web based
	      interface for importing WSDL definitions and creating UDTs and procedures.
	      This can be found in the <a href="htmlconductorbar.html#admiui.wsdl">Virtuoso Server Administration
		  Interface</a> Chapter.</p>
      </div>
  <br />

  
    <a name="exposingudtssoap" />
    <h3>15.1.10. Exposing User Defined Type Methods as SOAP Objects</h3>
    <p>
	SQL User Defined Types may define  methods. In context of
	Virtuoso SOAP server they can be exposed as  SOAP methods.
	To do that the UDT must be published at an endpoint. So publishing could be done in
        two ways: using SQL INSERT statement or using Admin UI: Publishing UI via
	Virtual directories section.
    </p>
    <p>
	The published UDTs will then expose all methods to the given virtual directory
	assigned for SOAP execution. In this case the default constructor will be called
	for method invocation if the UDT method is non-static.
    </p>
    <p>
	Note: The method definitions may also contains special SOAP syntax for XML Schema datatypes, using the same options  as
	for PL procedures. (see &quot;PL Procedures and UDT Methods Syntax Affecting WSDL &amp; SOAP Processing&quot; section for details)
    </p>
    <p>
	The following table specifies which UDTs are published at which end points.</p>&gt;
        <div>
      <pre class="programlisting">
create table SYS_SOAP_UDT_PUB
	    (SUP_CLASS varchar, -- name of the published UDT, referencing SYS_USER_TYPES.UT_NAME
	     SUP_LHOST varchar, -- listen host, referencing HTTP_PATH.HP_LISTEN_HOST
	     SUP_HOST varchar,  -- virtual host, referencing HTTP_PATH.HP_HOST
	     SUP_END_POINT varchar, -- logical path, referencing HTTP_PATH.HP_LPATH
	     primary key (SUP_LHOST, SUP_HOST, SUP_END_POINT, SUP_CLASS))
;
	    </pre>
    </div>

    <a name="ex_soap_expose_udt" />
    <div class="example">
	<div class="exampletitle">Exposing a UDT Method using SQL statement</div>
	<p>
	    The below code  creates a UDT containing two methods: static and non-static
	    and exposes them on a virtual directory &#39;/soap-udt&#39;
        </p>
	<div>
        <pre class="programlisting">
create user SOAP_U2;

VHOST_DEFINE (lpath=&gt;&#39;/soap-udt&#39;, ppath=&gt;&#39;/SOAP/&#39;, soap_user=&gt;&#39;SOAP_U2&#39;,
    soap_opts=&gt;
    vector (&#39;ServiceName&#39;, &#39;UDT&#39;,
	    &#39;Namespace&#39;, &#39;http://temp.uri&#39;,
	    &#39;SchemaNS&#39;, &#39;http://temp.uri&#39;,
	    &#39;MethodInSoapAction&#39;, &#39;yes&#39;,
	    &#39;elementFormDefault&#39;, &#39;unqualified&#39;,
	    &#39;Use&#39;, &#39;encoded&#39;)
);

create type MyWebSvc
static method echoStatInt (in a int) returns int,
method echoInt (in a int) returns int;

create static method echoStatInt (in a int)
returns int for MyWebSvc
{
  return a;
}
;


create method echoInt (in a int)
returns int for MyWebSvc
{
  return a;
}
;

-- Important: without grant publishing is not final as
-- user for SOAP invocation will not have permissions to instantiate the UDT nor
-- to call its methods
grant execute on MyWebSvc to SOAP_U2;

-- exposing the UDT methods to the /soap-udt endpoint
insert soft SYS_SOAP_UDT_PUB values (&#39;MyWebSvc&#39;, &#39;*ini*&#39;, &#39;*ini*&#39;, &#39;/soap-udt&#39;);
</pre>
      </div>
    </div>
    <p>
	Exposing the  methods of a UDT could be done using Admin UI/Virtual Directories:
         Create a new or edit an existing SOAP enabled virtual directory and navigate to the
        SOAP options section, click on the &#39;Publish&#39; button and from presented list of
	Database qualifiers select the qualifier containing target UDT, then select
	it from the User Defined Types list and follow the wizard.
    </p>
  <br />

  
    <a name="exposrmtprocsoap" />
    <h3>15.1.11. Exposing Remote Third Party SQL Stored Procedures as SOAP Services</h3>
    <p>Virtuoso can expose any of its available PL resources to the SOAP
world.  This includes data from remote attached tables and procedures.  To do this, one needs to
write a wrapper procedure in Virtuoso/PL.</p>
    <a name="ex_exposrmtprocsoap" />
    <div class="example">
      <div class="exampletitle">Exposing a MS SQL Server procedure to SOAP using Virtuoso</div>
      <p>Here we have a sample MS SQL Server procedure and an accompanying Virtuoso wrapper
function.  The MS SQL Server function returns a result set based on a simple join
query with a filter input.  The Virtuoso procedure calls the remote procedure,
iterates through the result set returned and produces XML output. First the MS SQL Server procedure:
      </p>
      <div>
        <pre class="programlisting">
create procedure ms_remote
        @mask varchar(15)
as
  select c.CustomerID, c.CompanyName, o.OrderDate,
      o.ShippedDate,ol.ProductID, ol.Quantity, ol.Discount
    from Northwind..Customers c
      inner join Northwind..Orders o on c.CustomerID = o.CustomerID
      inner join Northwind..&quot;Order Details&quot; ol on o.OrderID = ol.OrderID
    where c.CustomerID like @mask
;
</pre>
      </div>
    <p>Then the Virtuoso wrapper function:</p>
    <div>
        <pre class="programlisting">
create procedure WS.SOAP.ms_remote_call (
  in dsn varchar, in uid varchar, in pwd varchar, in mask varchar)
{
  declare m, r, ses any;
  vd_remote_data_source (dsn, &#39;&#39;, uid, pwd);
  rexecute (dsn, &#39;ms_remote ?&#39;, null, null, vector (mask), 1000, m, r);
  ses := string_output ();
  http (&#39;&lt;?xml version=&quot;1.0&quot; ?&gt;\n&lt;remote&gt;\n&#39;, ses);
  if (isarray(m) and isarray (r))
    {
      declare i, l, j, k integer;
      declare md, rs any;
      md := m[0];
      i := 0; l := length (md); k := length (r); j := 0;
      while (j &lt; k)
       {
	 http (&#39;&lt;record &#39;, ses);
         i:=0;
         while (i &lt; l)
           {
	     dbg_obj_print (md[i][0],r[j][i]);
	     http (sprintf (&#39; %s=&quot;%s&quot;&#39;, trim(md[i][0]), trim(cast (r[j][i] as varchar))), ses);
             i := i + 1;
	   }
	 http (&#39; /&gt;\n&#39;, ses);
         j := j + 1;
       }
    }
  http (&#39;&lt;/remote&gt;&#39;, ses);
  return string_output_string (ses);
};
</pre>
      </div>
    <p>
Now, as before, we grant execute rights to the SOAP user:
    </p>
    <div>
        <pre class="screen">
grant execute on WS.SOAP.ms_remote_call to SOAP;
    </pre>
      </div>
    <p>
The remote procedure <span class="computeroutput">ms_remote()</span> can now be accessed via SOAP.
    </p>
</div>
     <div class="tip">
      <div class="tiptitle">See Also:</div>
      <p>The <a href="">Virtual Database</a> chapter for information regarding use of
remote datasources and their tables.</p>
    </div>
  <br />
  <a name="soapclient" />
    <h3>15.1.12. Virtuoso/PL SOAP Client</h3>
    <p>
Virtuoso has generic SOAP client functionality.  This was demonstrated in an example
above, where we showed that we had correctly exposed a stored procedure
as a SOAP object.  The entry point to the SOAP client is
<a href="fn_soap_client.html">soap_client ()</a>.
    </p>
    <div class="tip">
      <div class="tiptitle">See Also:</div>
    <p>
        <a href="">Importing A WSDL File</a>
      </p>
    </div>
  <br />
  <a name="execpriv" />
    <h3>15.1.13. Execution Privileges</h3>
    <p>
<a href="webserver.html#virtandmultihosting">Virtual directory</a> mappings allow you to define a
specific database user on behalf of which to execute code invoked via SOAP.  By
default Virtuoso disables SOAP calls unless the database account
&#39;SOAP&#39; exists or a virtual directory mapping is
defined for SOAP call execution.  If we map a logical HTTP path to <span class="computeroutput">/SOAP</span> and
specify the user &#39;demo&#39; as the SOAP user then stored procedures or UDT methods will be executed
with demo&#39;s privileges.
    </p>
  <br />
  
    <a name="customsoapsrv" />
    <h3>15.1.14. Custom Soap Server Support</h3>
    <p>
Virtuoso allows any VSP page to act as a SOAP endpoint.
This permits preprocessing of the SOAP requests to extract
additional information - such as one placed for ebXML - and
conversion of the SOAP replies to put any additional information in them.
SOAP messages with attachments can also be processed this way.
    </p>
    <p>
SOAP extensions, such as the ones required for ebXML, can be programmed
as VSP services that can handle the additional information contained in the
SOAP requests.  The <a href="fn_xpath_eval.html">xpath_eval()</a> function
is useful here.  The SOAP server could be called
after removing extension information; this removal could be done with an XSL transformation.
After the SOAP request is processed, additional information can be
placed in the result by another XSL transformation.
    </p>
    <p>
Having a SOAP server outside the <span class="computeroutput">/SOAP</span> physical
path allows a greater degree of
control over what procedures are executed by providing a list of mappings.
Having this suite of functions allows SOAP requests to be processed outside an
HTTP context (for example after doing <span class="computeroutput">mime_tree()</span> over an e-mail) and sending
the SOAP replies as SMTP messages.
    </p>
    <p>
The following built-in functions are relevant in this context:
    </p>

<p>
      <a href="fn_soap_server.html">soap_server()</a>
    </p>
<p>
      <a href="fn_soap_make_error.html">soap_make_error()</a>
    </p>
<p>
      <a href="fn_soap_box_xml_entity.html">soap_box_xml_entity()</a>
    </p>
<p>
      <a href="fn_soap_print_box.html">soap_print_box()</a>
    </p>
<p>
      <a href="fn_http_body_read.html">http_body_read()</a>
    </p>

    <a name="soap1.1server" />
    <div class="example">
      <div class="exampletitle">Sample SOAP 1.1 server</div>
      <div>
        <pre class="screen">
&lt;?vsp
        dbg_obj_print (&#39;vspsoap called&#39;);
	declare content_type, soap_method, soap_xml varchar;
	declare payloads any;

	-- get the encoding to find out where the SOAP request should be searched for

        content_type := http_request_header (lines, &#39;Content-Type&#39;);
	if (isstring (content_type))
           content_type := lower (content_type);

	-- get the SOAP method name to execute

        soap_method := http_request_header (lines, &#39;SOAPAction&#39;);
        soap_xml := NULL;
        payloads := NULL;

	-- get the SOAP request
        if (content_type = &#39;multipart/related&#39;)
	  {
	    -- as in SOAP messages with attachments
	    declare attrs any;
	    declare inx integer;
	    declare start_req varchar;

	    -- the SOAP body is in the root part
	    -- so get the root part&#39;s name
            start_req := http_request_header (lines, &#39;Content-Type&#39;, &#39;start&#39;);

	    -- loop over the parts and get the root one.
	    -- Others are placed in the payload array

	    inx := 1;
	    soap_xml := null;
	    attrs := vector (1);
	    while (isarray (attrs))
	     {
	       declare content_id varchar;

	       -- get the part&#39;s MIME header
	       attrs := get_keyword (sprintf (&#39;attr-mime_part%d&#39;, inx), params);

	       if (isarray (attrs))
		 {
		   -- extract the Content-ID from it
		   content_id := get_keyword (&#39;Content-ID&#39;, attrs);
		   dbg_obj_print (&#39;cont-id&#39;, content_id);

		   if (isstring (content_id))
		     {
		       -- if it is the root part (SOAP request) parse it.
		       if (content_id = start_req)
			 soap_xml := xml_tree_doc (xml_tree (
                      get_keyword (sprintf (&#39;mime_part%d&#39;, inx), params)));
		       else
			 {
			   -- otherwise consider it a payload and store a info about the payload
			   -- for later retrieval by get_keyword () VSE based on Content-ID
			   if (payloads is null)
			     payloads := vector (vector (content_id, inx));
			   else
			     payloads := vector_concat (payloads, vector (content_id, inx));
			 }
		     }
		 }
	       inx := inx + 1;
	     }
	  }
	else if (content_type = &#39;text/xml&#39;)
          {
	    -- it&#39;s a SOAP request without attachments
            -- so get the POST body and parse it.
	    soap_xml := xml_tree_doc (xml_tree (http_body_read ()));
	  }
        else
	  signal (&#39;42000&#39;, &#39;unsupported encoding&#39;);

        -- the things retrieved so far
	dbg_obj_print (&#39;vspsoap message&#39;, soap_xml);
	dbg_obj_print (&#39;vspsoap payloads&#39;, payloads);

	-- execute the message

	-- catch any subsequent SQL error and generate and return SOAP reply XML for it.

	declare exit handler for SQLSTATE &#39;*&#39; {
	  dbg_obj_print (&#39;vspsoap in error handler for &#39;, __SQL_MESSAGE);
	  declare err_msg varchar;
	  err_msg := soap_make_error (&#39;300&#39;, __SQL_STATE, __SQL_MESSAGE);
	  dbg_obj_print (&#39;vspsoap error&#39;, err_msg);
	  http (err_msg);

	  -- note the SOAP SQL state - this is required since based on this value the
	  -- HTTP server will not generate any additional reply if the SQL state starts with SOAP
	  -- and this way the client will get a properly formatted reply
	  resignal &#39;SOAP&#39;;
	};

        -- now check what is required and act accordingly
        if (soap_method = &#39;ebXML&#39;)
          {
	    signal (&#39;42000&#39;, &#39;ebXML not implemented yet&#39;);
	  }
        else if (soap_method in (&#39;fake#test&#39;))
          {
	    declare res any;

	    -- note the mapping here : the SOAP call to fake:test will result in a
            -- call to DB.DBA.SOAPTEST PL procedure and it&#39;s results returned.

	    res := soap_server (soap_xml, soap_method, lines, 11,
                    vector (&#39;fake:test&#39;, &#39;DB.DBA.SOAPTEST&#39;));

	    dbg_obj_print (&#39;vspsoap result&#39;, res);
	    http (res);
	  }
        else
	  {
	    -- simple signal will do as this will be cached by the handler
          -- and formatted as an SOAP error XML
	    signal (&#39;42000&#39;, concat (&#39;Procedure &#39;, soap_method, &#39; not defined&#39;));
	  }
?&gt;
      </pre>
      </div>
    </div>
  <br />
  <a name="soapextendedsyntax" />
    <h3>15.1.15. PL Procedures and UDT Methods Syntax Affecting WSDL &amp; SOAP Processing</h3>

  <p>Special PL syntax can be applied to any of the parameters (including the
  return value) in a declaration.  All of these begins with __SOAP_ prefix and
  have special meaning.   To manipulate more than the XMLSchema type
  representation and SOAP encoding style, extended syntax is available.  With
  this syntax we can further override the default request/response namespace,
  name of the output elements, &quot;soapAction&quot; corresponding to the PL procedure
  and such.</p>

  <p>The syntax is as follows:</p>
<div>
      <pre class="programlisting">
   ...
   CREATE (PROCEDURE|METHOD) ([param_decl [rout_alt_type]] ...) { [BODY] } [RETURNS ....] [rout_alt_type]
   ...

rout_alt_type
	:  /* no SOAP options */
	| soap_kwd STRING opt_soap_enc_mode 	/* the basic syntax */
	| __SOAP_OPTIONS &#39;(&#39; soap_kwd EQUALS STRING opt_soap_enc_mode &#39;,&#39; soap_proc_opt_list &#39;)&#39;/* extended syntax */
	;

soap_proc_opt_list
	: soap_proc_opt
	| soap_proc_opt_list &#39;,&#39; soap_proc_opt
	;

soap_proc_opt /* extension options as PartName:=&#39;part2&#39; */
	: NAME EQUALS signed_literal
	;

soap_kwd
	: __SOAP_TYPE  	/* denotes XML datatype, RPC encoding style if applied to the procedure */
	| __SOAP_HEADER	/* the parameter is a message in the SOAP Header */
	| __SOAP_FAULT	/* the parameter is a message in SOAP Fault */
	| __SOAP_DOC	/* applies to the procedure, free-form of encoding (literal) */
	| __SOAP_XML_TYPE /*applies to the parameters, the input will be XML tree */
	| __SOAP_DOCW		/* applies to the procedure, literal encoding in style like RPC */
	| __SOAP_HTTP		/* HTTP GET/POST binding will be used */
	;

opt_soap_enc_mode 		/* which part of traffic will be encapsulated and in what way : DIME or MIME */
	: /* no encapsulation */
	| __SOAP_DIME_ENC IN
	| __SOAP_DIME_ENC OUT
	| __SOAP_DIME_ENC INOUT
	| __SOAP_MIME_ENC IN
	| __SOAP_MIME_ENC OUT
	| __SOAP_MIME_ENC INOUT
	;

param_decl
	: (IN|OUT|INOUT) param_name data_type_ref [(DEFAULT|:=)	literal]
	;

data_type_ref
	: (data_type_name|udt_name) [ARRAY [intnum] ...]
	;
</pre>
    </div>

   <p>The above syntax can be applied to the parameter and to the whole
   procedure, so both places designate different purposes and limitations.
   When it is applied to the parameter the following keywords can be used:
   __SOAP_TYPE, __SOAP_HEADER, __SOAP_FAULT and __SOAP_XML_TYPE.
   The __SOAP_TYPE means that only XSD type will be used to interpret the data,
   in contrast __SOAP_XML_TYPE designates no deserialization from XML, only
   parses the parameter XML representation to XML tree and passes it to the
   procedure.  The __SOAP_HEADER and __SOAP_FAULT designate that parameter
   will be exposed in the SOAP Header or in the SOAP Fault elements.  In the
   second case, that parameter needs to be an &#39;OUT&#39; parameter (not IN or INOUT).
   The string after these keywords always denotes the XSD type for SOAP serialization.
   When it is applied to the PL procedure (after procedure&#39;s body), the
   __SOAP_TYPE, __SOAP_DOC, __SOAP_DOCW, __SOAP_HTTP, __SOAP_DIME_ENC and
   __SOAP_MIME_ENC can be used.  The string after these keywords always denotes
   the XSD type for SOAP serialization, except __SOAP_DIME_ENC and __SOAP_MIME_ENC
   which are used for other purposes and can be combined with other keywords.
   The __SOAP_TYPE denotes RPC style encoding, __SOAP_DOC for document literal
   (bare parameters) encoding, __SOAP_DOCW for the free-form literal (wrapped)
   encoding.  __SOAP_HTTP is used to denote HTTP style binding instead of SOAP
   one, in that way procedure can be called via HTTP GET/POST methods without
   SOAP XML encoding.  </p>
   <p>The following keywords are supported as extended options:</p>
   <ul>
      <li>
        <strong>PartName</strong> - changes the name of a OUT parameter
    to the string as specified, affects WSDL generation and SOAP serialization.</li>
      <li>
        <strong>RequestNamespace</strong> - designate namespace for
    the message in the request, affects header, fault and body WSDL declaration,
    and serialization of SOAP in RPC encoding style.</li>
      <li>
        <strong>ResponseNamespace</strong> - the same as RequestNamespace,
    but for SOAP response and output in WSDL declaration.</li>
      <li>
        <strong>soapAction</strong> - sets the &#39;soapAction&#39; attribute
    in WSDL generation, can be applied to the procedure only.</li>
    </ul>
   <p>The RequestNamespace and ResponseNamespace can be used only for
       the procedure and together with the __SOAP_FAULT and __SOAP_HEADER keywords.</p>

   <p>The &#39;ARRAY&#39; modifier to the SQL datatype is allowed  when no XML Schema datatype is
       assigned to the given parameter of the PL procedure or UDT method. In this case
       the input and output value will be verified to confirm to the rules applicable for
       an array. Furthermore in this case an XSD definition will be added in the WSDL
       file at run time.
   </p>

<a name="ex_soapextsynt" />
    <div class="example">
      <div class="exampletitle">SOAP Extension</div>
 <p>This example shows both approaches to define parameters and
   SOAP encoding style.  In practice this definition is part of the Interop tests
   round 4 (group H).  The meaning of this is: the SOAP operation is uses RPC
   encoding style, &#39;whichFault&#39; is integer, &#39;param1&#39; and &#39;param2&#39; are strings.
   The out parameters &#39;part2_1&#39; and &#39;part2_2&#39; will be printed in SOAP:Fault element
   (see Exposing &amp; Processing SOAP Fault Messages for more
   details).  The interesting fact is that the last two parameters will be serialized
   as &quot;part2&quot; in different namespaces.  And finally no return of the SOAP
   operation is defined (it&#39;s empty).  </p>

   <div>
        <pre class="programlisting">
create procedure
&quot;echoMultipleFaults3&quot; (
    in whichFault int __soap_type &#39;http://www.w3.org/2001/XMLSchema:int&#39;,
    in param1 varchar __soap_type &#39;http://www.w3.org/2001/XMLSchema:string&#39;,
    in param2 varchar __soap_type &#39;http://www.w3.org/2001/XMLSchema:string&#39;,
    out part2_1 varchar __soap_options (
        __soap_fault:=&#39;http://www.w3.org/2001/XMLSchema:string&#39;,
	PartName:=&#39;part2&#39;,
        ResponseNamespace:=&#39;http://soapinterop.org/wsdl/fault1&#39;),
    out part2_2 varchar __soap_options (
        __soap_fault:=&#39;http://www.w3.org/2001/XMLSchema:string&#39;,
	PartName:=&#39;part2&#39;,
        ResponseNamespace:=&#39;http://soapinterop.org/wsdl/fault2&#39;)
    )
   __soap_type &#39;__VOID__&#39;
{

  if (whichFault &gt; 2)
    whichFault := mod (whichFault, 3) + 1;
  declare exit handler for sqlstate &#39;SF000&#39;
    {
      http_request_status (&#39;HTTP/1.1 500 Internal Server Error&#39;);
      if (whichFault = 1)
	{
          part2_1 := param1;
	}
      else if (whichFault = 2)
	{
	  part2_2 := param2;
	}
      connection_set (&#39;SOAPFault&#39;, vector (&#39;400&#39;, &#39;echoMultipleFaults3&#39;));
      return;
    };
  signal (&#39;SF000&#39;, &#39;echoEmptyFault&#39;);
}
;
</pre>
      </div>
</div>
  <br />
  <a name="soapheadermessages" />
    <h3>15.1.16. Exposing &amp; Processing SOAP Header Messages</h3>

  <p>The Virtuoso SOAP server can be used to process the SOAP Header
  messages as  described in the W3C recommendation
  (<a href="http://www.w3c.org/TR/SOAP/">http://www.w3c.org/TR/SOAP</a>,
  SOAP Header section).  They can also be exposed in the WSDL file
  (services.wsdl) as per W3C WSDL recommendation, using the RPC style encoding.</p>

  <p>To bind a message to a SOAP header the special keyword __soap_header
  is reserved for input and output parameters.  The __soap_header followed by the
  SOAP datatype can be specified for any input or output parameter after
  normal datatype declarations.  This will expose parameters as input or
  output messages separately.  Header binding will also be added to an
  appropriate section of the WSDL description file for the SOAP message.</p>


  <a name="procsoapheader" />
    <div class="example">
      <div class="exampletitle">Processing of the SOAP Header element</div>
  <p>Consider the following simple SOAP request message with Header element:</p>

<div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;SOAP-ENV:Envelope
       xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;
       xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
       xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;&gt;
    &lt;SOAP-ENV:Header&gt;
      &lt;h:echoMeStringRequest
	 xmlns:h=&quot;http://soapinterop.org/echoheader/&quot;
	 SOAP-ENV:actor=&quot;http://schemas.xmlsoap.org/soap/actor/next&quot;
	 mustUnderstand=&quot;1&quot;&gt;hello world&lt;/h:echoMeStringRequest&gt;
    &lt;/SOAP-ENV:Header&gt;
    &lt;SOAP-ENV:Body&gt;
      &lt;m:echoVoid xmlns:m=&quot;http://soapinterop.org/&quot;&gt;&lt;/m:echoVoid&gt;
    &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;</pre>
      </div>

  <p>This request will be processed by the Virtuoso SOAP server in the
  following way:</p>

  <ol>
        <li>Check whether the echoVoid operation is defined for the given
  web directory mapping (see: exposing a PL procedure as a SOAP operation)</li>
        <li>Test whether there is an in-parameter echoMeStringRequest defined
  for header processing (see below exposing a header parameters)</li>
        <li>Test the mustUnderstand attribute:
    <ul>
    <li>If mustUnderstand is 0 or is undefined the request will continue
    without an error.</li>
    <li>If mustUnderstand is 1 and the actor attribute is not empty
    or defined with the http://schemas.xmlsoap.org/soap/actor/next special URI,
    the request will continue without an error.</li>
    <li>If the two conditions about fail then the request will be
    rejected with a SOAP MustUnderstand error.</li>
          </ul>
    </li>
        <li>The value of the echoMeStringRequest will be passed as a parameter
  to the echoVoid procedure.</li>
        <li>If the call to the echoVoid succeeds, and the corresponding out
  parameter is supplied for the SOAP response header then it will be
  sent to the SOAP client.</li>
      </ol>

  <p>The following procedure, which represents a part from echoHeaderBindings
  iterop test (round C), for the demonstration purposes is designed to process
  the above SOAP message.</p>

  <div>
        <pre class="programlisting">
create procedure
Interop.INTEROP.echoVoid
   (in echoMeStringRequest nvarchar := NULL __soap_header &#39;http://www.w3.org/2001/XMLSchema:string&#39;,
    out echoMeStringResponse nvarchar := NULL __soap_header &#39;http://www.w3.org/2001/XMLSchema:string&#39;)
   __soap_type &#39;__VOID__&#39;
{
  if (echoMeStringRequest is not null)
    echoMeStringResponse := echoMeStringRequest;
};</pre>
      </div>

  <div class="note">
        <div class="notetitle">Note:</div>
  <p>The __soap_header keyword that instructs the SOAP server to process this
  parameter via a SOAP Header with datatype string.  Also, the condition in
  the procedure is needed to return the value in SOAP header only if it is
  supplied.  In some other cases it can be returned always, but in this
  particular example it will be echoed only if the appropriate header is sent.</p>
  </div>
  </div>
  <br />
  <a name="soapfaultmessages" />
    <h3>15.1.17. Exposing &amp; Processing SOAP Fault Messages</h3>
  <p>
   The SOAP:Fault message is used to indicate which part of SOAP request fails,
   so in its general form it may not have a detailed error.  But in some cases it is
   useful to report in detail which element&#39;s input(s) are not correct.</p>
   <p>
Custom soap:fault messages can be generated by application logic as illustrated below:
</p>
   <p>Have a procedure to generate custom SOAP:Fault messages with at least one OUT parameter
   denoted by __SOAP_FAULT instead of __SOAP_TYPE keyword following by type to be returned as literal.</p>
   <p>Once we have such parameter(s) declared we can set these to some value (of atomic, simple or complex type) as may be appropriate.

</p>
   <p>
   And finally we need to set a special connection variable &#39;SOAPFault&#39;, in order to signal custom SOAP:Fault
   on output. The value of the connection variable needs to be an array of two elements :
   An integer of 100, 200, 300, 400 which represents the SOAP:VersionMismatch, SOAP:MustUnderstand,
   SOAP:Client and SOAP:Server errors.
   And a string which will be printed in textual explanation, human readable format.
   In real life we will not need to generate 100 or 200 fault messages, but anyway it is possible to do that.
  </p>
  <a name="procsoapfault" />
    <div class="example">
      <div class="exampletitle">Signalling a custom SOAP Fault element</div>
  <p>Consider we need to indicate to the client that some string is not a valid input, we can use
  the custom fault message mechanism as.</p>
  <div>
        <pre class="programlisting">
create procedure
echoStringFault (in param nvarchar,
                 out part2 nvarchar __soap_fault &#39;string&#39;)
returns nvarchar
{
  declare exit handler for sqlstate &#39;SF000&#39;
    {
      http_request_status (&#39;HTTP/1.1 500 Internal Server Error&#39;);
      -- we are setting the fault message
      part2 := param;
      -- and instructing the SOAP server to make error 400 with text explanation StringFault
      connection_set (&#39;SOAPFault&#39;, vector (&#39;400&#39;, &#39;StringFault&#39;));
      ----------------^^^^^^^^^^
      return;
    };
  -- in real life signalling of the error is under some condition
  -- for example if string is longer that 10 chars
  signal (&#39;SF000&#39;, &#39;echoEmptyFault&#39;);
}
;

  
  </pre>
      </div>
  <p>And an wire dump of SOAP request</p>
  <div>
        <pre class="programlisting">
&lt;SOAP-ENV:Envelope SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot; ...&gt;
  &lt;SOAP-ENV:Body&gt;
    &lt;m:echoStringFault xmlns:m=&quot;http://soapinterop.org/wsdl&quot;&gt;
      &lt;param xsi:type=&quot;xsd:string&quot;&gt;String&lt;/param&gt;
    &lt;/m:echoStringFault&gt;
  &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
  
  </pre>
      </div>
  <p>And SOAP Fault response</p>
  <div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;SOAP:Envelope SOAP:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot; ...&gt;
  &lt;SOAP:Body&gt;
    &lt;SOAP:Fault&gt;
      &lt;faultcode&gt;SOAP:Server&lt;/faultcode&gt;
      &lt;faultstring&gt;[Virtuoso SOAP server] StringFault&lt;/faultstring&gt;
      &lt;detail&gt;
        &lt;h:part2 xmlns:h=&quot;http://soapinterop.org/wsdl&quot; xsi:type=&quot;xsd:string&quot;&gt;String&lt;/h:part2&gt;
      &lt;/detail&gt;
    &lt;/SOAP:Fault&gt;
  &lt;/SOAP:Body&gt;
&lt;/SOAP:Envelope&gt;
  
  </pre>
      </div>
  <p>Please note that in wire dumps there is no namespace declarations for brevity (places are denoted with &#39;...&#39;).
  </p>
  </div>
  <br />

<a name="soapdoclitenc1" />
    <h3>15.1.18. Document Literal Encoding</h3>

<p>The Virtuoso SOAP server and client support Document Literal encoding
for processing as an alternative to SOAP/RPC.  The document/literal
encoding allows the transmission of any arbitrary valid XML document instead
  of  a SOAP call following rules from section 5 from
SOAP/1.1 specification.  This allows us to send and receive SOAP packets that
are more free-form (&quot;document&quot; style).   If you create a service that can accept
more free-form type packets, you can employ constraints within the methods so
that they can be independent (bare) or serialized as embedded elements within
the method&#39;s SOAP structure (wrapped parameters style).</p>

<a name="ex_soapi3doclit" />
    <div class="example">
      <div class="exampletitle">Comparing SOAP Types</div>
<p>Here are examples of SOAP requests that represent the RPC, Doc/Literal
and Doc/Literal with parameters types of SOAP message</p>

<p>-- RPC encoded --</p>
<div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;SOAP-ENV:Envelope
      xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
      xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
   &lt;SOAP-ENV:Body&gt;
     &lt;m:echoString
         SOAP-ENV:encodingStyle=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
	 xmlns:m=&quot;http://soapinterop.org/&quot;&gt;
	   &lt;param0 xsi:type=&quot;xsd:string&quot;&gt;Enter a message here&lt;/param0&gt;
     &lt;/m:echoString&gt;
   &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
</pre>
      </div>

<p>-- Document Literal --</p>
<div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;SOAP-ENV:Envelope
      xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
   &lt;SOAP-ENV:Body&gt;
     &lt;ns1:echoStringParam xmlns:ns1=&quot;http://soapinterop.org/xsd&quot;&gt;Enter a message here&lt;/ns1:echoStringParam&gt;
   &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
</pre>
      </div>

<p>-- Document Literal with parameters --</p>
<div>
        <pre class="programlisting">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;SOAP-ENV:Envelope
      xmlns:SOAP-ENC=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
      xmlns:SOAP-ENV=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
   &lt;SOAP-ENV:Body&gt;
     &lt;ns1:echoString xmlns:ns1=&quot;http://soapinterop.org/xsd&quot;&gt;
       &lt;param0&gt;Enter a message here&lt;/param0&gt;
     &lt;/ns1:echoString&gt;
   &lt;/SOAP-ENV:Body&gt;
&lt;/SOAP-ENV:Envelope&gt;
</pre>
      </div>
</div>

<p>SOAP operations can be designated as document/literal or RPC by using the
appropriate values in the WSDL description file associated to that SOAP endpoint.
As Virtuoso SOAP operations are PL procedures special keywords are used within
the procedure to indicate that the document/literal encoding should be used.
These special keywords are:</p>

  <ul>
      <li>__soap_doc</li>
      <li>__soap_docw</li>
    </ul>

<p>These should be placed after the &#39;returns&#39; keyword in a Virtuoso procedure
definition.  If &#39;returns ... __soap_type&#39; is omitted the procedure return type
will be equivalent to &#39;returns varchar __soap_type &#39;http://www.w3.org/2001/XMLSchema:string&#39;.</p>

<p>Another way to expose a PL procedure or UDT method as a document/literal SOAP
    methods is to use non-explicit XMLSchema datatypes and to force encoding rules
    via virtual directory option &#39;Use&#39; (see also SOAP options section in this chapter and in WSDL chapter section: &quot;Exposing SQL Stored Procedures containing complex datatype definitions&quot; for details and examples).
</p>

<div class="tip">
      <div class="tiptitle">See Also:</div>
<p>
        <a href="http://www.w3.org/TR/wsdl">WSDL 1.1 Specification</a>
      </p>
    </div>

<a name="ex_soapreturnrpc" />
    <div class="example">
      <div class="exampletitle">SOAP Returns RPC</div>
<p>The following example shows a procedure that will be exposed as an RPC
encoded SOAP operation:</p>

<div>
        <pre class="programlisting">
create procedure
Import1.echoString (in x nvarchar __soap_type &#39;http://www.w3.org/2001/XMLSchema:string&#39;)
returns nvarchar __soap_type &#39;http://www.w3.org/2001/XMLSchema:string&#39;
{
  return x;
};
</pre>
      </div>
</div>

<a name="ex_soapreturndoclit" />
    <div class="example">
      <div class="exampletitle">SOAP Returns Document Literal</div>
<p>The following example shows a procedure that will be exposed as a document
literal encoded operation.  Note the __soap_doc keyword after &#39;returns&#39;, also
in this case __soap_type for each parameter must be specified since the incoming
request must be validated by the given schema element declaration (see below
for XMLSchema elements declaration).</p>

<div>
        <pre class="programlisting">
create procedure
DocLit.echoString (in echoStringParam varchar __soap_type &#39;http://soapinterop.org/xsd:echoStringParam&#39;)
      returns any __soap_doc &#39;http://soapinterop.org/xsd:echoStringReturn&#39;
{
      return echoStringParam;
};
</pre>
      </div>
</div>

<a name="ex_soapreturndoclitwrapped" />
    <div class="example">
      <div class="exampletitle">SOAP Returns Document Literal with Parameters</div>
<p>The following example shows a procedure that will be exposed as document
literal encoding operation with parameters style (wrapped).  note the __soap_docw
keyword after &#39;returns&#39;.</p>

<div>
        <pre class="programlisting">
create procedure
DocPars.echoString (in echoString varchar __soap_type &#39;http://soapinterop.org/xsd:echoString&#39;)
      returns any __soap_docw &#39;http://soapinterop.org/xsd:echoStringResponse&#39;
{
      return echoString;
};
</pre>
      </div>
</div>

<p>In both cases of Document Literal encoding we need to specify the schema
element for validation of the incoming SOAP request.  Furthermore, this applies
to the output elements and return value, as they need to be encoded/validated
properly.</p>

<a name="wsdlschemadtandelts" />
    <h4>15.1.18.1. Defining WSDL Schema Data Type and Elements</h4>

<p>When defining a schema data type (for use within SOAP) the
&#39;targetNamespace&#39; attribute on top level element must be specified in order
to describe in which namespace this type is valid.  In other words, this type
will be used to validate request only within this namespace.  Therefore it
will be exposed only at this WSDL point where it is used to describe a
parameter of an operation associated to it.</p>

<p>
      <span class="important">
        <strong>Important:</strong> All datatypes and elements defined for use in SOAP must have
namespace (QName), which means that &#39;targetNamespace&#39; must be specified in the
definition.  All non-qualified types will be rejected in SOAP validation and
will not be described in the WSDL file.</span>
    </p>

<a name="ex_soapi3stringarray" />
    <div class="example">
      <div class="exampletitle">Making an array of string data type</div>
<p>Here is an example demonstrating making an array-of-string datatype:</p>

<div>
        <pre class="programlisting">
select soap_dt_define(&#39;&#39;,&#39;&lt;complexType name=&quot;ArrayOfstring&quot;
   targetNamespace=&quot;http://soapinterop.org/xsd&quot;
   xmlns:enc=&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;
   xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
   xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
   xmlns:tns=&quot;http://soapinterop.org/xsd&quot;&gt;
  &lt;complexContent&gt;
     &lt;restriction base=&quot;enc:Array&quot;&gt;
	&lt;sequence&gt;
	   &lt;element name=&quot;item&quot; type=&quot;string&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot; nillable=&quot;true&quot;/&gt;
	&lt;/sequence&gt;
	&lt;attributeGroup ref=&quot;enc:commonAttributes&quot;/&gt;
	&lt;attribute ref=&quot;enc:arrayType&quot; wsdl:arrayType=&quot;string[]&quot;/&gt;
     &lt;/restriction&gt;
  &lt;/complexContent&gt;
&lt;/complexType&gt;&#39;);
</pre>
      </div>
</div>

<p>As document literal encodings work with elements, the elements must be
declared as a part of the WSDL file (in the types/schema section).  The declared
elements can be used to define a doc/literal encoded SOAP operation.  This
allows for the definition of an element of request and response to enable
the server to understand the requests (validate and process) and respond to
them (validate the PL data and serialize properly).</p>

<a name="ex_si3params" />
    <div class="example">
      <div class="exampletitle">Example of defining elements</div>
<p>Here is an example for the DocLit.echoString SOAP operation using
parameters (input parameter and return type):</p>

<div>
        <pre class="programlisting">
select soap_dt_define(&#39;&#39;,&#39;&lt;element xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
                                   name=&quot;echoStringParam&quot;
                                   targetNamespace=&quot;http://soapinterop.org/xsd&quot; type=&quot;string&quot; /&gt;&#39;);

select soap_dt_define(&#39;&#39;,&#39;&lt;element xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
                                   name=&quot;echoStringReturn&quot;
				   targetNamespace=&quot;http://soapinterop.org/xsd&quot; type=&quot;string&quot; /&gt;&#39;);
</pre>
      </div>
</div>
<br />

<a name="soapexttosimptypes" />
    <h4>15.1.18.2. Extensions to Simple Types</h4>

<p>The attribute extensions to the simple types (string, float, etc...) can
be defined and used in SOAP messages.  In that case a PL value is
represented as a special structure of 3 elements as follows:</p>

<div>
      <pre class="programlisting">
vector (&lt;composite&gt;, vector (&lt;attr-name&gt;, &lt;attr-value&gt;, ...), &lt;simple type value&gt;)
</pre>
    </div>

<a name="ex_defsimptypedocument" />
    <div class="example">
      <div class="exampletitle">An example to define a simple type &#39;Document&#39;</div>

<div>
        <pre class="programlisting">
select soap_dt_define(&#39;&#39;,&#39;&lt;complexType name=&quot;Document&quot;
             xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
             xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
             targetNamespace=&quot;http://soapinterop.org/xsd&quot;&gt;
  &lt;simpleContent&gt;
    &lt;extension base=&quot;string&quot;&gt;
      &lt;xsd:attribute name =&quot;ID&quot; type=&quot;string&quot;/&gt;
    &lt;/extension&gt;
  &lt;/simpleContent&gt;
&lt;/complexType&gt;&#39;);
</pre>
      </div>

<p>Note that soap_dt_define() does not need the name to be specified when
adding a new type, the name/namespace will be extracted from XSD fragment.</p>
</div>
<br />

<a name="wsdlgeneration" />
    <h4>15.1.18.3. WSDL Generation</h4>

<p>As the WSDL file generation is based on granted PL procedures exposed to
a given SOAP endpoint, only SOAP datatypes and schema elements used for them will
be printed in &lt;types&gt; section.  If an undeclared datatype is used for an
exposed procedure, the error will be printed in an XML comment where the type
definition was expected and not found.  If an element or datatype refers to
other (dependent) types they will also be automatically included.  For example,
if we have exposed for a SOAP endpoint only the following procedure:</p>

<div>
      <pre class="programlisting">
create procedure
INTEROP.echoStructArray (
    in inputStructArray any __soap_type &#39;http://soapinterop.org/xsd:ArrayOfSOAPStruct&#39;)
    __soap_type &#39;http://soapinterop.org/xsd:ArrayOfSOAPStruct&#39;
{
  return inputStructArray;
};
</pre>
    </div>

<p>The schema fragment will consist of both SOAPStructure and ArrayOfSOAPStruct
data types declaration:</p>

<div>
      <pre class="programlisting">
&lt;schema targetNamespace=&quot;http://soapinterop.org/xsd&quot;
   xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
   xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot; &gt;
     &lt;complexType name=&quot;ArrayOfSOAPStruct&quot; &gt;
       &lt;complexContent&gt;
         &lt;restriction base=&quot;soapenc:Array&quot;&gt;
           &lt;sequence&gt;
             &lt;element name=&quot;item&quot; type=&quot;ns0:SOAPStruct&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot;/&gt;
           &lt;/sequence&gt;
           &lt;attribute ref=&quot;soapenc:arrayType&quot; wsdl:arrayType=&quot;ns0:SOAPStruct[]&quot;/&gt;
           &lt;attributeGroup ref=&quot;soapenc:commonAttributes&quot;/&gt;
           &lt;attribute ref=&quot;soapenc:offset&quot;/&gt;
         &lt;/restriction&gt;
      &lt;/complexContent&gt;
    &lt;/complexType&gt;
    &lt;!-- Note this fragment, it&#39;s included because ArrayOfSOAPStruct depends from it --&gt;
    &lt;complexType name=&quot;SOAPStruct&quot; &gt;
       &lt;all&gt;
	  &lt;element name=&quot;varString&quot; type=&quot;string&quot; nillable=&quot;true&quot;/&gt;
	  &lt;element name=&quot;varInt&quot; type=&quot;int&quot; nillable=&quot;true&quot;/&gt;
	  &lt;element name=&quot;varFloat&quot; type=&quot;float&quot; nillable=&quot;true&quot;/&gt;
       &lt;/all&gt;
    &lt;/complexType&gt;
&lt;/schema&gt;
</pre>
    </div>
<br />

<a name="multnswsdlsoap" />
    <h4>15.1.18.4. Multiple Namespaces in WSDL and SOAP</h4>

<p>When you define a SOAP operation that has parameters from different
namespaces or a type referring to a type in another namespace, both will be defined
and printed as a separate schema definition in the WSDL file.  Hence,
we can define a data type in different namespace so they will live together in
a single WSDL file.  This allows us to make more complex and flexible
document-centric style SOAP operations.</p>

<a name="ex_mnsi3test" />
    <div class="example">
      <div class="exampletitle">Example from the SOAP Interop 3 Tests</div>
<p>This example is of the echoEmployee operation from interop 3 tests:</p>

<div>
        <pre class="programlisting">
create procedure
Compound2.echoEmployee (in x any __soap_type &#39;http://soapinterop.org/employee:x_Employee&#39;)
      returns any __soap_doc &#39;http://soapinterop.org/employee:result_Employee&#39;
{
  return x;
};
</pre>
      </div>

<p>This will generate the following schema in the WSDL file (only affected
parts are shown):</p>

<div>
        <pre class="programlisting">
&lt;definitions
...
xmlns:ns1=&quot;http://soapinterop.org/person&quot;
xmlns:ns0=&quot;http://soapinterop.org/employee&quot;
... &gt;

&lt;types&gt;
	&lt;schema targetNamespace=&quot;http://soapinterop.org/person&quot;
		xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
		xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot; elementFormDefault=&quot;qualified&quot; &gt;
	   &lt;complexType name=&quot;Person&quot; &gt;
	      &lt;sequence&gt;
		&lt;element minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; name=&quot;Name&quot; type=&quot;string&quot;/&gt;
	        &lt;element minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; name=&quot;Male&quot; type=&quot;boolean&quot;/&gt;
	      &lt;/sequence&gt;
	   &lt;/complexType&gt;
 	&lt;/schema&gt;

	&lt;schema targetNamespace=&quot;http://soapinterop.org/employee&quot;
		xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
		xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot; elementFormDefault=&quot;qualified&quot; &gt;
		&lt;import namespace=&#39;http://soapinterop.org/person&#39; /&gt;
	    &lt;complexType name=&quot;Employee&quot; &gt;
		&lt;sequence&gt;
		   &lt;element minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; name=&quot;person&quot; type=&quot;ns1:Person&quot;/&gt;
		   &lt;element minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; name=&quot;salary&quot; type=&quot;double&quot;/&gt;
	           &lt;element minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; name=&quot;ID&quot; type=&quot;int&quot;/&gt;
	    	&lt;/sequence&gt;
	   &lt;/complexType&gt;

	   &lt;element name=&quot;result_Employee&quot; type=&quot;ns0:Employee&quot; /&gt;
	   &lt;element name=&quot;x_Employee&quot; type=&quot;ns0:Employee&quot; /&gt;

	&lt;/schema&gt;
&lt;/types&gt;
...
</pre>
      </div>

<p>The PL procedure is defined to use element declaration x_Employee and result_Employee,
so this will automatically include the Employee and Person type, upon which they
depend.  Also, as these types are defined in different namespace, two schema
parts will be specified in the WSDL file.</p>
</div>

<p>In practice the SOAP developer needs to define elements and
types (using soap_dt_define() function), after this, specifying a parameter of
PL procedure (or return type) will cause automatic generation of the
associated WSDL description in the manner described.  Hence, no user intervention
is required besides the initial element/type definition.</p>
<br />

<a name="soapi3endpoints" />
    <h4>15.1.18.5. SOAP Interop round III Endpoints</h4>

<p>The following endpoints are pre-defined in the Demo database for
SOAP interop III testing (the WSDL files are in the usual services.wsdl for
each group of tests):</p>

<ul>
  <li>
     <p>
          <strong>D tests</strong>
     </p>
    <ul>
      <li>/r3/EmptySA/ - echoString operation with empty (&quot;&quot;) soapAction (PRC encoded)</li>
      <li>/r3/Import1/ - echoString operation, rpc encoded</li>
      <li>/r3/Import2/ - echoStruct operation, rpc encoded</li>
      <li>/r3/Import3/ - echoStruct and adds method echoStructArray, rpc encoded (echoStruct is in different namespace)</li>
      <li>/r3/Compound1/ - Use of attributes in SOAP payload, including attribute on element of simpleType , doc/literal</li>
      <li>/r3/Compound2/ - Two schema sections, types in 1st schema references types in the 2nd schema, doc/literal</li>
      <li>/r3/DocPars/  -  Reduced version of SOAPBuilders Interop test wsdl with &quot;parameters&quot; way of describing rpc requests in Document/Literal (Document/Literal - Wrapped). Version has operations echoString, echoArrayOfString and echoStruct</li>
      <li>/r3/DocLit/ - Reduced version of SOAPBuilders InteropTest test, document/literal mode. Version has operations echoString, echoArrayOfString and echoStruct</li>
      <li>/r3/RpcEnc/ - Reduced version of SOAPBuilders InteropTest test, rpc/encoded mode. Version has operations echoString, echoArrayOfString and echoStruct</li>
    </ul>
  </li>
  <li>
     <p>
          <strong>E tests</strong>
     </p>
    <ul>
      <li>
            <p>/r3/List/ -  echo of list structure (as shown) , RPC encoded</p>
        <div>
              <pre class="programlisting">
struct list {
  int varInt;
  string varString;
  list child; //nullable
}
</pre>
            </div>
      </li>
    </ul>
  </li>
  <li>
     <p>
          <strong>F tests</strong>
     </p>
    <ul>
      <li>/r3/Hdr/ - Modified version of SOAPBuilders InteropTest test, document/literal mode Version has one operation echoString with 2 headers defined.</li>
    </ul>
  </li>
</ul>
<br />

<br />

<a name="soapdimeenc" />
    <h3>15.1.19. DIME encapsulation of SOAP messages</h3>
<p>
   The Direct Message Encapsulation (DiME) format is a message format
   that can be used to encapsulate one or more payloads of arbitrary type and size.
   This format can be used in place of MIME, but benefits of DIME are  ease of parsing  and
   low memory consumption, as DIME does not require  loading the whole message body in order to parse it.

   This is due to the  fact that MIME does not have mechanism for specifying the  length of payloads etc.  DIME prefixes all data with length and type information.

   </p>
   <p>
   The structure of a DIME message as per draft-nielsen-dime-02 is:
   </p>
   <div>
      <pre class="programlisting">
/*
      Legend:

      VERSION = 0x01
      RESRVD  = 0x00
      MB - begin mark
      ME - end mark
      CF - chunked flag
      TYPE_T - type of content type field


      0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |         |M|M|C|       |       |                               |
     | VERSION |B|E|F| TYPE_T| RESRVD|         OPTIONS_LENGTH        |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |            ID_LENGTH          |           TYPE_LENGTH         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                          DATA_LENGTH                          |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                     OPTIONS + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                          ID + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                        TYPE + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                               /
     /                        DATA + PADDING                         /
     /                                                               |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
   
   </pre>
    </div>
   <p>
    The MB,ME,CF flags are used to indicate which part of the DIME message is the
    current block of data.  Also, we notice that there are four length fields
    of fixed length before any data, id or type payload. This is to make the payload
    easier to read.
   </p>
<p>

   The Virtuoso server implements a DIME parser and composer as functions and filter for DIME in SOAP server.
   Furthermore the Virtuoso WSDL generator can be instructed to specify a DIME extension to the
   PL procedure exposed as SOAP method.  The implementation is based on draft-nielsen-dime-02 RFC proposal.
   Please note that in the rest of document we will use &#39;DIME attachment&#39; term , which is about
   SOAP message with attachment encapsulated with DIME as per draft-nielsen-dime-soap-01. The special case in these messages is type of first payload, so it&#39;s supposed to be a SOAP:Envelope message.
 </p>
<p>
   Note: Option fields are not supported.
</p>
<p>
To setup a SOAP endpoint to recognize DIME encapsulation the &quot;DIME-ENC&quot; option to SOAP in virtual directory
must  be set to &#39;yes&#39;. Furthermore the WSDL description of endpoint defined as DIME enabled will contain
WSDL extensions to DIME.
</p>
<p>
As not in all cases input and output of the SOAP server needs to be DIME encoded,
the particular PL procedure exposed as SOAP method needs to be defined in special way to indicate which
traffic is encoded as DIME.
This is done by using special keywords on procedure declaration:
</p>

   <div>
      <pre class="programlisting">
   
   CREATE PROCEDURE ([PARAMETERS DECLARATION])
    [RETURNS TYPE] [(__SOAP_TYPE|__SOAP_DOC|_SOAP_DOCW) &#39;LITERAL&#39;] [__SOAP_DIME_ENC (IN/OUT/INOUT)]
   
   </pre>
    </div>

   <p>
   The &#39;__SOAP_DIME_ENC IN&#39; indicate that the procedure expects a DIME attachments on input.
   This can also be used with OUT and INOUT.
   This will also be indicated in WSDL file (services.wsdl) as DIME extension in
   appropriate place of &#39;soap:operation&#39; element.
   </p>

   <p>
   The format of SOAP attachments passed to PL procedure defined in this way
   is an array which consists of three string elements: ID, content-type, and attachment data itself.
   The same format must be used when parameter is an output which needs to be sent as DIME attachment.
   There is also a special parameter of PL procedure exposed as SOAP method named &#39;ws_soap_attachments&#39;,
   so when we have such, all attachments received  will be passed thru it. In practice we will not need to use &#39;ws_soap_attachments&#39; , but anyway it&#39;s practical use is to handle unreferenced parameters or to debug the request.
   </p>

   <p>
   Finally we must say that type of parameter needs to have datatype declared as per &#39;WSDL Extension for SOAP in DIME&#39; proposal, this is needed for indicating in the WSDL what to expect and how to send the attachment. See also the example below.
   </p>

<a name="procdimesoap" />
    <div class="example">
      <div class="exampletitle">Using DIME encapsulation</div>
<p>Suppose we need to accept a binary attachment and echo it back as string
encoded in the popular &#39;base64&#39;.</p>
<p>We first need to enable DIME encapsulation to an endpoint, with virtual directory definition:</p>
<div>
        <pre class="programlisting">
SQL&gt; VHOST_DEFINE (lpath=&gt;&#39;/r4/groupG/dime/rpc&#39;, ppath=&gt;&#39;/SOAP/&#39;, soap_user=&gt;&#39;interop4&#39;,
    soap_opts =&gt; vector (&#39;DIME-ENC&#39;, &#39;yes&#39;)) ;

</pre>
      </div>
<p>The sample PL procedure that takes a binary attachment and transforms it to
a base64 encoded string must be declared as:
</p>
<div>
        <pre class="programlisting">
create procedure
EchoAttachmentAsBase64 (in &quot;In&quot; nvarchar __soap_type &#39;http://soapinterop.org/attachments/xsd:ReferencedBinary&#39;)
returns nvarchar __soap_type &#39;base64Binary&#39;
__soap_dime_enc in
{
  -- we are getting the attachment as the 3rd element of input,
  -- do the base64 encoding for it and return it to the requestor
  return encode_base64 (cast (&quot;In&quot;[2] as varchar));
}
;
</pre>
      </div>

<p>
As we have noticed an &#39;ReferencedBinary&#39; is used to declare  &#39;In&#39; parameter.
This has a special purpose for WSDL definition, not for SOAP processing itself.
In that case clients are instructed to look at annotation/appinfo of a simple type declared as:
</p>
<div>
        <pre class="programlisting">
	&lt;complexType name=&quot;ReferencedBinary&quot;&gt;
		&lt;simpleContent&gt;
			&lt;restriction base=&quot;soap-enc:base64Binary&quot;&gt;
				&lt;annotation&gt;
					&lt;appinfo&gt;
						&lt;content:mediaType value=&quot;application/octetstream&quot;/&gt;
					&lt;/appinfo&gt;
				&lt;/annotation&gt;
				&lt;attributeGroup ref=&quot;soap-enc:commonAttributes&quot;/&gt;
			&lt;/restriction&gt;
		&lt;/simpleContent&gt;
	&lt;/complexType&gt;
</pre>
      </div>
<p>
This is a little-bit tricky, but this is how  to indicate the type of the content and how to resolve the
references to the attachments as per the WSDL Extension for SOAP in DIME&#39; proposal.
</p>

</div>

<br />

<a name="soapoptions" />
    <h3>15.1.20. SOAP Endpoint Options</h3>
  <p>The virtual directory mechanism provides a special SOAP options for
  SOAP processing.  The SOAP options are name-value pairs contained in a vector:
  i.e. vector (&#39;name1&#39;, &#39;value1&#39;, ....).  The SOAP server accepts the following
  optional parameters settable in the SOAP Options field of the
  <a href="htmlconductorbar.html#httpvirtualdirs">HTTP Virtual Directories Setup</a>
  interface, or using the
  <a href="fn_vhost_define.html">vhost_define()</a>
  function:</p>

  <ul>
      <li>
        <strong>ServiceName</strong>: name of the SOAP service, will be
  prefixed with &#39;Virtuoso&#39;.  That name is shown in WSDL description.</li>
      <li>
        <strong>Namespace</strong>: namespace URI of the SOAP:Body
  request and response.</li>
      <li>
        <strong>HeaderNS</strong>: namespace URI for SOAP:Header messages.</li>
      <li>
        <strong>FaultNS</strong>: namespace URI for SOAP:Fault messages. </li>
      <li>
        <strong>MethodInSoapAction</strong>: enable or disable appending
  of the method name in the soapAction attribute (WSDL) after namespace URI.</li>
      <li>
        <strong>CR-escape</strong>: enable or disable escaping of the
  CRs on wire as &amp;#0xd</li>
      <li>
  <strong>elementFormDefault=(unqualified|qualified);</strong>
    <p>Sets the elementFormDefault for schema specification.  if
    qualified is used the elementFormDefault attribute will be set to qualified,
    in which case elements required to be unqualified can be declared with
    value of &quot;form&quot; attribute &quot;unqualified&quot;.</p>
  </li>
      <li>
      <strong>Use=(encoded|literal)</strong>
      <p>
	  Sets the default SOAP message encoding rules for those PL procedures which have no
	  explicit encoding rule assigned (see SOAP special syntax for PL procedures).
	  The default is &#39;encoded&#39; which means to follow SOAP RPC encoding as described
	  in SOAP v1.1 specification section 5.1.
	  The &#39;literal&#39; mode forces the SOAP server to expose PL procedures
	  with  the document/literal  parameter encoding style.
      </p>
  </li>
      <li>
  <strong>MethodInSoapAction=(no|yes|empty|only);</strong>
    <p>Controls soapAction attribute manipulation.  <strong>no</strong> -
    only URL for soap requests will be printed.  <strong>yes</strong>
    (default) - the URL and soap method will be printed in form:
    &lt;url&gt;#&lt;method name&gt;.  <strong>empty</strong> - no value will
    be specified for soapAction.  <strong>only</strong> - only the method
    will be specified in form #&lt;method name&gt;.</p>
  </li>
      <li>
        <strong>DIME-ENC</strong>: Controls DIME encapsulation on particular
  SOAP endpoint, valid values are <strong>no</strong> - (default) not enabled. <strong>yes</strong> -
  DIME encapsulation is enabled on endpoint
  </li>
      <li>
        <strong>WS-SEC</strong>: WS-Security processing is enabled on the endpoint, if it&#39;s <strong>yes</strong>, otherwise disabled (default)
  </li>
      <li>
        <strong>WSS-KEY</strong>: name of PL procedure, which is supposed to return a key instance, used together with &quot;WS-SEC&quot; option.
  </li>
      <li>
        <strong>WSS-Template</strong>: path to the file for making the XML Signature in response message.
  The &quot;[key reference for signing]&quot; denotes using a default template for signing, see WS Security signing SOAP messages.
  </li>
      <li>
        <strong>WSS-Validate-Signature</strong>: This option controls the
  input behavior, i.e. how to verify the incoming message.  Possible values are
  &quot;0&quot;, &quot;1&quot; or &quot;2&quot;, where 0 does not verify signatures, 1 expects a signature to
  exist, 2 will verify signature if one exists.</li>
      <li>
        <strong>WS-RP</strong>: to enable WS-Routing protocol on particular endpoint, if it&#39;s <strong>yes</strong>, otherwise disabled (default).
  </li>
      <li>
        <strong>wsrp-from</strong>: Constant for identification of endpoint, an example is &#39;some@user.network&#39;. This will be included in &#39;form&#39; element in WS Routing header.
  </li>
    </ul>
  <br />
<table border="0" width="90%" id="navbarbottom">
    <tr>
        <td align="left" width="33%">
          <a href="webservices.html" title="Web Services">Previous</a>
          <br />Contents of Web Services</td>
     <td align="center" width="34%">
          <a href="webservices.html">Chapter Contents</a>
     </td>
        <td align="right" width="33%">
          <a href="wsdl.html" title="WSDL">Next</a>
          <br />WSDL</td>
    </tr>
    </table>
  </div>
  <div id="footer">
    <div>Copyright© 1999 - 2009 OpenLink Software All rights reserved.</div>
   <div id="validation">
    <a href="http://validator.w3.org/check/referer">
        <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" />
    </a>
    <a href="http://jigsaw.w3.org/css-validator/">
        <img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88" />
    </a>
   </div>
  </div>
 </body>
</html>