WSDL is an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information. The operations and messages are described abstractly, and then bound to a concrete network protocol and message format to define an endpoint. Related concrete endpoints are combined into abstract endpoints (services). WSDL is extensible to allow description of endpoints and their messages regardless of what message formats or network protocols are used to communicate, however, the only bindings described in this document describe how to use WSDL in conjunction with SOAP 1.1, HTTP GET/POST, and MIME.[WSDL 1.1, Abstract]
The extensibility elements of WSDL allow for a straightforward means of using DAML-S and WSDL together. This, in turn, allows service developers to take advantage of the complementary strengths of these two specification languages. This document, which is written in an informal, tutorial style, describes how this combined use of DAML-S and WSDL is accomplished, and in particular focuses on the way WSDL is used in this combination.
For ease of reference, and to be helpful to readers not already familiar with WSDL, this document includes selected quotations from the WSDL 1.1 specification, which are helpful in explaining the relevant aspects of WSDL. Each such quotation is indented, displayed in a distinct font (Arial), and immediately followed by a bracketed citation. In addition, when viewed online or in a color printout, these quotations will appear in green. Also for ease of reference, a number of the section headings of this document (for example, 2.3 Messages) correspond to section headings in the WSDL 1.1 specification.
This document does not explain the concepts
or details of DAML-S, but rather assumes a basic familiarity with selected
DAML-S constructs (particularly the atomic process), which may be
acquired from the Technical Overview and related documents in the current
release of DAML-S, available at http://www.daml.org/services/daml-s/0.7/.
Note that the Technical Overview contains a Grounding section that
gives the
conceptual background for this approach.
DAML-S allows for the description of a Web service in terms of a Profile, which tells "what the service does", a Process Model, which tells "how the service works", and a Grounding, which tells "how to access the service". The Profile and Process Model are considered to be abstract specifications, in the sense that they do not specify the details of particular message formats, protocols, and network addresses by which a Web service is instantiated. The role of the Grounding is to provide these more concrete details. The Web Services Description Language (WSDL), developed independently of DAML-S, provides a well developed means of specifying these kinds of details, and has already acquired considerable visibility within the commercial Web services community. Therefore, the authors of DAML-S have chosen to define conventions for using WSDL to ground DAML-S services. This document provides an informal explanation of these conventions.
Whereas a default WSDL specification refers to
XSD primitive data types, and composite data types defined using XSD, a
DAML-S/WSDL specification can refer to DAML classes (in addition to the
XSD primitive and defined types). The DAML classes can either
be defined within the WSDL spec, or defined in a separate document and
referred to from within the WSDL spec.
A WSDL document defines services as collections of network endpoints, or ports. In WSDL, the abstract definition of endpoints and messages is separated from their concrete network deployment or data format bindings. This allows the reuse of abstract definitions: messages, which are abstract descriptions of the data being exchanged, and port types which are abstract collections of operations. The concrete protocol and data format specifications for a particular port type constitutes a reusable binding. A port is defined by associating a network address with a reusable binding, and a collection of ports define a service. Hence, a WSDL document uses the following elements in the definition of network services:
In addition, WSDL
defines a common binding mechanism. This is used to attach a specific
protocol or data format or structure to an abstract message, operation,
or endpoint. It allows the reuse of abstract definitions.
Using DAML-S with WSDL involves DAML-S extensions to the following WSDL elements: types, message, operation and binding. In brief, in types we allow (but do not require) the inclusion of arbitrary DAML declarations In message, we allow the specification of message parts having DAML classes as their abstract types. (Actually, we indicate the correspondence of a message part with a DAML-S input or output property, and from that, the appropriate DAML range class can easily be obtained.) In operation, we propose a new attribute for the purpose of indicating a correspondence between the given operation and a DAML-S atomic process. In binding, we don't actually extended WSDL, but rather, merely provide a new encoding style for use with WSDL's SOAP binding.
These extensions are described in greater detail in the following sections.
Part 1-A gives the DAML-S code for a simple atomic
process, and the accompanying Grounding instance that relates this code
to a WSDL specification by which the service can be contacted. Part
1-B gives this WSDL specification, including constructs that relate it
back to the DAML-S code. The points of reference between the two
documents are shown in bold.
http://example.com/congo/CongoBuy.daml
!DOCTYPE uridef[ <!ENTITY process "http://www.daml.org/services/daml-s/0.7/Process.daml"> ]> <daml:Class rdf:ID="SignInData"> <!-- details omitted --> </daml:Class> <daml:Class rdf:ID="CongoBuy"> <rdfs:subClassOf rdf:resource="&process;#AtomicProcess"/> </daml:Class>
<!-- Inputs -->
<rdf:Property rdf:ID="congoBuyBookName"> <rdfs:subPropertyOf rdf:resource="&process;#input"/> <rdfs:domain rdf:resource="#CongoBuy"/> <rdfs:range rdf:resource="&xsd;#string"/> </rdf:Property>
<rdf:Property rdf:ID="congoBuySignInInfo"> <rdfs:subPropertyOf rdf:resource="&process;#input"/> <rdfs:domain rdf:resource="#CongoBuy"/> <rdfs:range rdf:resource="#SignInData"/> </rdf:Property>
<!-- Output: Confirmation No. -->
<rdf:Property rdf:ID="congoBuyConfirmation"> <rdfs:subPropertyOf rdf:resource="&process;#output"/> <rdfs:domain rdf:resource="#CongoBuy"/> <rdfs:range rdf:resource="http://www.daml.org/2001/03/daml+oil.daml#Literal"/> </rdf:Property>
<!-- Here, we relate CongoBuy to its grounding, CongoBuyGrounding. Since CongoBuy is a class, we need to say: "Every instance (i.e., invocation, or use) of this class has an instance of the hasGrounding property, with value CongoBuyGrounding". The hasGrounding property is defined in Process.daml. -->
<daml:Class rdf:about="CongoBuy"> <daml:sameClassAs> <daml:Restriction daml:cardinality="1"> <daml:onProperty rdf:resource="#hasGrounding"/> <daml:hasValue rdf:resource="#congoBuyGrounding"/> </daml:Restriction> </daml:sameClassAs> </daml:Class>
<!-- DAML-S Grounding Instance -->
<grounding:WsdlGrounding rdf:ID="CongoBuyGrounding"> <grounding:damlsProcess rdf:resource="#congoBuy"> <grounding:wsdlOperation rdf:resource="http://example.com/congo/congobuy.wsdl#BuyBook"/> <grounding:wsdlInputMessage rdf:resource="http://example.com/congo/congobuy.wsdl#CongoBuyInput"/> <grounding:wsdlInputMessageParts rdf:parseType="daml:collection"> <grounding:wsdlMessageMap> <grounding:damlsParameter rdf:resource=#congoBuyBookName> <grounding:wsdlMessagePart rdf:resource="http://example.com/congo/congobuy.wsdl#BookName"> </grounding:wsdlMessageMap> <grounding:wsdlMessageMap> <grounding:damlsParameter rdf:resource=#congoBuySignInInfo> <grounding:wsdlMessagePart rdf:resource="http://example.com/congo/congobuy.wsdl#SignInInfo"> </grounding:wsdlMessageMap> </grounding:wsdlInputMessageParts> <grounding:wsdlOutputMessage rdf:resource="http://example.com/congo/congobuy.wsdl#CongoBuyOutput"/> <grounding:wsdlOutputMessageParts rdf:parseType="daml:collection"> <grounding:wsdlMessageMap> <grounding:damlsParameter rdf:resource=#congoBuyConfirmation> <grounding:wsdlMessagePart rdf:resource="http://example.com/congo/congobuy.wsdl#Confirmation"> </grounding:wsdlMessageMap> </grounding:wsdlOutputMessageParts> <grounding:wsdlReference rdf:resource="http://www.w3.org/TR/2001/NOTE-wsdl-20010315"> <grounding:otherReference> "http://www.w3.org/TR/2001/NOTE-wsdl-20010315" "http://schemas.xmlsoap.org/wsdl/soap/" "http://schemas.xmlsoap.org/soap/http/" </grounding:otherReference> <grounding:wsdlDocument> "http://example.com/congo/congobuy.wsdl" </grounding:wsdlDocument> </grounding:WsdlGrounding>
http://example.com/congo/congobuy.wsdl
<?xml version="1.0"?> <definitions name="CongoBuy"> targetNamespace="http://example.com/congo/congobuy.wsdl" xmlns:tns="http://example.com/congo/congobuy.wsdl" xmlns:congoDaml="http://example.com/congo/CongoBuy.daml#" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="CongoBuyInput"> <part name="BookName" daml-s-parameter="congoDaml:congoBuyBookName"/> <part name="SignInInfo" daml-s-parameter="congoDaml:congoBuySignInInfo"/> </message> <message name="CongoBuyOutput"> <part name="Confirmation" daml-s-parameter="congoDaml:congoBuyConfirmation"/> </message> <portType name="CongoBuyPortType"> <operation name="BuyBook" daml-s-process="congoDaml:CongoBuy"> <input message="tns:CongoBuyInput"/> <output message="tns:CongoBuyOutput"/> </operation> </portType> <binding name="CongoBuySoapBinding" type="tns:CongoBuyPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="BuyBook"> <soap:operation soapAction="http://example.com/congo/CongoBuy.daml#BuyBook"/> <input> <soap:body parts="BookName SignInInfo" use="encoded" namespace="http://example.com/congo/" encodingStyle="http://www.daml.org/2001/03/"/> </input> <output> <soap:body parts="Confirmation" use="encoded" namespace="http://example.com/congo/" encodingStyle="http://www.daml.org/2001/03/"/> </output> </operation> </binding> <service name="CongoBuyService"> <documentation>My first DAML-S/WSDL service</documentation> <port name="CongoBuyPort" binding="tns:CongoBuySoapBinding"> <soap:address location="http://example.com/congo/"/> </port> </service> </definitions>
<wsdl:definitions name="nmtoken"? targetNamespace="uri"?> <import namespace="uri" location="uri"/>* <wsdl:documentation .... /> ? <wsdl:types> ? <wsdl:documentation .... />? <xsd:schema .... />* <-- extensibility element --> * <rdf:RDF namespace-declarations ...> .... </rdf:RDF/>* </wsdl:types> <wsdl:message name="nmtoken"> * <wsdl:documentation .... />? <!-- This spec adds attribute daml-s-parameter --> <part name="nmtoken" element="qname"? type="qname"? daml-s-parameter="qname"?/> * </wsdl:message> <wsdl:portType name="nmtoken">* <wsdl:documentation .... />? <!-- This spec proposes attribute daml-process --> <wsdl:operation name="nmtoken" daml-process="qname"?>* <wsdl:documentation .... /> ? <wsdl:input name="nmtoken"? message="qname">? <wsdl:documentation .... /> ? </wsdl:input> <wsdl:output name="nmtoken"? message="qname">? <wsdl:documentation .... /> ? </wsdl:output> <wsdl:fault name="nmtoken" message="qname"> * <wsdl:documentation .... /> ? </wsdl:fault> </wsdl:operation> </wsdl:portType> <wsdl:binding name="nmtoken" type="qname">* <wsdl:documentation .... />? <-- extensibility element --> * <wsdl:operation name="nmtoken">* <wsdl:documentation .... /> ? <-- extensibility element --> * <wsdl:input> ? <wsdl:documentation .... /> ? <-- extensibility element --> </wsdl:input> <wsdl:output> ? <wsdl:documentation .... /> ? <-- extensibility element --> * </wsdl:output> <wsdl:fault name="nmtoken"> * <wsdl:documentation .... /> ? <-- extensibility element --> * </wsdl:fault> </wsdl:operation> </wsdl:binding> <wsdl:service name="nmtoken"> * <wsdl:documentation .... />? <wsdl:port name="nmtoken" binding="qname"> * <wsdl:documentation .... /> ? <-- extensibility element --> </wsdl:port> <-- extensibility element --> </wsdl:service> <-- extensibility element --> * </wsdl:definitions>
Services are defined using six major elements:
Extensibility elements are commonly used to specify some technology specific binding. To distinguish whether the semantic of the technology specific binding is required for communication or optional, extensibility elements MAY place a wsdl:required attribute of type boolean on the element. The default value for required is false. The required attribute is defined in the namespace "http://schemas.xmlsoap.org/wsdl/".
Extensibility elements
allow innovation in the area of network and message protocols without having
to revise the base WSDL specification. WSDL recommends that specifications
defining such protocols also define any necessary WSDL extensions used
to describe those protocols or formats.
The types element encloses data type definitions that are relevant for the exchanged messages. For maximum interoperability and platform neutrality, WSDL prefers the use of XSD as the canonical type system, and treats it as the intrinsic type system.[WSDL 1.1, Section 2.2]<definitions .... > <types> <xsd:schema .... />* </types> </definitions>However, since it is unreasonable to expect a single type system grammar can be used to describe all abstract types present and future, WSDL allows type systems to be added via extensibility elements. An extensibility element may appear under the types element to identify the type definition system being used and to provide an XML container element for the type definitions. The role of this element can be compared to that of the schema element of the XML Schema language.<definitions .... > <types> <-- type-system extensibility element --> * </types> </definitions>
where the "..." within the extensibility element may be replaced by any number of DAML+OIL declarations.
Messages consist of one or more logical parts. Each part is associated with a type from some type system using a message-typing attribute. The set of message-typing attributes is extensible. WSDL defines several such message-typing attributes for use with XSD:
We create the message-typing attribute daml-s-parameter for use with DAML-S. This will normally be used to indicate a sub property of daml-s:input, or of daml-s:output.
The syntax for defining a message is as follows. The message-typing attributes (which may vary depending on the type system used) are shown in bold.[WSDL 1.1, Section 2.3]<definitions .... > <message name="nmtoken"> * <part name="nmtoken" element="qname"? type="qname"?/> * </message> </definitions>The message name attribute provides a unique name among all messages defined within the enclosing WSDL document.The part name attribute provides a unique name among all the parts of the enclosing message.
For example, to specify the input message to CongoBuy, we write this (from Example 1):
<definitions .... > <message name="CongoBuyInput"> <part name="BookName" daml-s-parameter="congoDaml:congoBuyBookName"/> <part name="SignInInfo" daml-s-parameter="congoDaml:congoBuySignInInfo"/> </message> </definitions>
A port type is a named set of abstract operations and the abstract messages involved.[WSDL 1.1, Section 2.4]<wsdl:definitions .... > <wsdl:portType name="nmtoken"> <wsdl:operation name="nmtoken" .... /> * </wsdl:portType> </wsdl:definitions>The port type name attribute provides a unique name among all port types defined within in the enclosing WSDL document.An operation is named via the name attribute.
WSDL has four transmission primitives that an endpoint can support:
WSDL refers to these primitives as operations. ....One-way. The endpoint receives a message. Request-response. The endpoint receives a message, and sends a correlated message. Solicit-response. The endpoint sends a message, and receives a correlated message. Notification. The endpoint sends a message.
<operation name="BuyBook" daml-s-process="congoDaml:CongoBuy">