Red Hat JBoss Fuse

Apache CXF Development Guide

Develop applications with Apache CXF Web services

Red Hat

Version 6.1

Legal Notice

Trademark Disclaimer

The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, MetaMatrix, Fedora, the Infinity Logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Apache, ServiceMix, Camel, CXF, and ActiveMQ are trademarks of Apache Software Foundation. Any other names contained herein may be trademarks of their respective owners.

Legal Notice

Third Party Acknowledgements

One or more products in the Red Hat JBoss Fuse release includes third party components covered by licenses that require that the following documentation notices be provided:
  • JLine (http://jline.sourceforge.net) jline:jline:jar:1.0
    License: BSD (LICENSE.txt) - Copyright (c) 2002-2006, Marc Prud'hommeaux
    All rights reserved.
    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
    • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    • Neither the name of JLine nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  • Stax2 API (http://woodstox.codehaus.org/StAX2) org.codehaus.woodstox:stax2-api:jar:3.1.1
    Copyright (c) <YEAR>, <OWNER> All rights reserved.
    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
    • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  • jibx-run - JiBX runtime (http://www.jibx.org/main-reactor/jibx-run) org.jibx:jibx-run:bundle:1.2.3
    License: BSD (http://jibx.sourceforge.net/jibx-license.html) Copyright (c) 2003-2010, Dennis M. Sosnoski.
    All rights reserved.
    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
    • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    • Neither the name of JiBX nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  • JavaAssist (http://www.jboss.org/javassist) org.jboss.javassist:com.springsource.javassist:jar:3.9.0.GA:compile
  • HAPI-OSGI-Base Module (http://hl7api.sourceforge.net/hapi-osgi-base/) ca.uhn.hapi:hapi-osgi-base:bundle:1.2
    License: Mozilla Public License 1.1 (http://www.mozilla.org/MPL/MPL-1.1.txt)
18 May 2015

Abstract

REVISIT -

Part I. Writing WSDL Contracts

Abstract

This part describes how to define a Web service interface using WSDL.

Chapter 1. Introducing WSDL Contracts

Abstract

WSDL documents define services using Web Service Description Language and a number of possible extensions. The documents have a logical part and a concrete part. The abstract part of the contract defines the service in terms of implementation neutral data types and messages. The concrete part of the document defines how an endpoint implementing a service will interact with the outside world.
The recommended approach to design services is to define your services in WSDL and XML Schema before writing any code. When hand-editing WSDL documents you must make sure that the document is valid, as well as correct. To do this you must have some familiarity with WSDL. You can find the standard on the W3C web site, www.w3.org.

1. Structure of a WSDL document

A WSDL document is, at its simplest, a collection of elements contained within a root definition element. These elements describe a service and how an endpoint implementing that service is accessed.
A WSDL document has two distinct parts:
  • A logical part that defines the service in implementation neutral terms
  • A concrete part that defines how an endpoint implementing the service is exposed on a network

The logical part

The logical part of a WSDL document contains the types, the message, and the portType elements. It describes the service’s interface and the messages exchanged by the service. Within the types element, XML Schema is used to define the structure of the data that makes up the messages. A number of message elements are used to define the structure of the messages used by the service. The portType element contains one or more operation elements that define the messages sent by the operations exposed by the service.
The concrete part of a WSDL document contains the binding and the service elements. It describes how an endpoint that implements the service connects to the outside world. The binding elements describe how the data units described by the message elements are mapped into a concrete, on-the-wire data format, such as SOAP. The service elements contain one or more port elements which define the endpoints implementing the service.

1. Mapping data into logical data units

The interfaces used to implement a service define the data representing operation parameters as XML documents. If you are defining an interface for a service that is already implemented, you must translate the data types of the implemented operations into discreet XML elements that can be assembled into messages. If you are starting from scratch, you must determine the building blocks from which your messages are built, so that they make sense from an implementation standpoint.

Available type systems for defining service data units

According to the WSDL specification, you can use any type system you choose to define data types in a WSDL contract. However, the W3C specification states that XML Schema is the preferred canonical type system for a WSDL document. Therefore, XML Schema is the intrinsic type system in Apache CXF.

XML Schema as a type system

XML Schema is used to define how an XML document is structured. This is done by defining the elements that make up the document. These elements can use native XML Schema types, like xsd:int, or they can use types that are defined by the user. User defined types are either built up using combinations of XML elements or they are defined by restricting existing types. By combining type definitions and element definitions you can create intricate XML documents that can contain complex data.
When used in WSDL XML Schema defines the structure of the XML document that holds the data used to interact with a service. When defining the data units used by your service, you can define them as types that specify the structure of the message parts. You can also define your data units as elements that make up the message parts.

Considerations for creating your data units

You might consider simply creating logical data units that map directly to the types you envision using when implementing the service. While this approach works, and closely follows the model of building RPC-style applications, it is not necessarily ideal for building a piece of a service-oriented architecture.
The Web Services Interoperability Organization’s WS-I basic profile provides a number of guidelines for defining data units and can be accessed at http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#WSDLTYPES. In addition, the W3C also provides the following guidelines for using XML Schema to represent data types in WSDL documents:
  • Use elements, not attributes.
  • Do not use protocol-specific types as base types.

2. Adding data units to a contract

Depending on how you choose to create your WSDL contract, creating new data definitions requires varying amounts of knowledge. The Apache CXF GUI tools provide a number of aids for describing data types using XML Schema. Other XML editors offer different levels of assistance. Regardless of the editor you choose, it is a good idea to have some knowledge about what the resulting contract should look like.

Procedure

Defining the data used in a WSDL contract involves the following steps:
  1. Determine all the data units used in the interface described by the contract.
  2. Create a types element in your contract.
  3. Create a schema element, shown in Example 2.1, “Schema entry for a WSDL contract”, as a child of the type element.
    The targetNamespace attribute specifies the namespace under which new data types are defined. The remaining entries should not be changed.

    Example 2.1. Schema entry for a WSDL contract

    <schema targetNamespace="http://schemas.iona.com/bank.idl"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  4. For each complex type that is a collection of elements, define the data type using a complexType element. See Section 4.1, “Defining data structures”.
  5. For each array, define the data type using a complexType element. See Section 4.2, “Defining arrays”.
  6. For each complex type that is derived from a simple type, define the data type using a simpleType element. See Section 4.4, “Defining types by restriction”.
  7. For each enumerated type, define the data type using a simpleType element. See Section 4.5, “Defining enumerated types”.
  8. For each element, define it using an element element. See Section 5, “Defining elements”.

3. XML Schema simple types

If a message part is going to be of a simple type it is not necessary to create a type definition for it. However, the complex types used by the interfaces defined in the contract are defined using simple types.

Entering simple types

XML Schema simple types are mainly placed in the element elements used in the types section of your contract. They are also used in the base attribute of restriction elements and extension elements.
Simple types are always entered using the xsd prefix. For example, to specify that an element is of type int, you would enter xsd:int in its type attribute as shown in Example 2.2, “Defining an element with a simple type”.

Example 2.2. Defining an element with a simple type

<element name="simpleInt" type="xsd:int" />

Supported XSD simple types

Apache CXF supports the following XML Schema simple types:
  • xsd:string
  • xsd:normalizedString
  • xsd:int
  • xsd:unsignedInt
  • xsd:long
  • xsd:unsignedLong
  • xsd:short
  • xsd:unsignedShort
  • xsd:float
  • xsd:double
  • xsd:boolean
  • xsd:byte
  • xsd:unsignedByte
  • xsd:integer
  • xsd:positiveInteger
  • xsd:negativeInteger
  • xsd:nonPositiveInteger
  • xsd:nonNegativeInteger
  • xsd:decimal
  • xsd:dateTime
  • xsd:time
  • xsd:date
  • xsd:QName
  • xsd:base64Binary
  • xsd:hexBinary
  • xsd:ID
  • xsd:token
  • xsd:language
  • xsd:Name
  • xsd:NCName
  • xsd:NMTOKEN
  • xsd:anySimpleType
  • xsd:anyURI
  • xsd:gYear
  • xsd:gMonth
  • xsd:gDay
  • xsd:gYearMonth
  • xsd:gMonthDay

4. Defining complex data types

XML Schema provides a flexible and powerful mechanism for building complex data structures from its simple data types. You can create data structures by creating a sequence of elements and attributes. You can also extend your defined types to create even more complex types.
In addition to building complex data structures, you can also describe specialized types such as enumerated types, data types that have a specific range of values, or data types that need to follow certain patterns by either extending or restricting the primitive types.

4.1. Defining data structures

In XML Schema, data units that are a collection of data fields are defined using complexType elements. Specifying a complex type requires three pieces of information:
For example, the structure shown in Example 2.3, “Simple Structure” is be defined in XML Schema as a complex type with two elements.

Example 2.3. Simple Structure

struct personalInfo
{
  string name;
  int age;
};
Example 2.4, “A complex type” shows one possible XML Schema mapping for the structure shown in Example 2.3, “Simple Structure”.

Example 2.4. A complex type

<complexType name="personalInfo">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="age" type="xsd:int" />
  </sequence>
</complexType>

Complex type varieties

XML Schema has three ways of describing how the fields of a complex type are organized when represented as an XML document and passed on the wire. The first child element of the complexType element determines which variety of complex type is being used. Table 2.1, “Complex type descriptor elements” shows the elements used to define complex type behavior.

Table 2.1. Complex type descriptor elements

ElementComplex Type Behavior
sequence All the complex type’s fields must be present and they must be in the exact order they are specified in the type definition.
all All of the complex type’s fields must be present but they can be in any order.
choice Only one of the elements in the structure can be placed in the message.
If a sequence element, an all element, or a choice is not specified, then a sequence is assumed. For example, the structure defined in Example 2.4, “A complex type” generates a message containing two elements: name and age.
If the structure is defined using a choice element, as shown in Example 2.5, “Simple complex choice type”, it generates a message with either a name element or an age element.

Example 2.5. Simple complex choice type

<complexType name="personalInfo">
  <choice>
    <element name="name" type="xsd:string"/>
    <element name="age" type="xsd:int"/>
  </choice>
</complexType>

Defining the parts of a structure

You define the data fields that make up a structure using element elements. Every complexType element should contain at least one element element. Each element element in the complexType element represents a field in the defined data structure.
To fully describe a field in a data structure, element elements have two required attributes:

Example 2.6. Simple complex type with occurrence constraints

<complexType name="personalInfo>
  <all>
    <element name="name" type="xsd:string"/>
    <element name="age" type="xsd:int"/>
    <element name="previousJobs" type="xsd:string:
             minOccurs="3" maxOccurs="7"/>
  </all>
</complexType>
You can also use the minOccurs to make the age field optional by setting the minOccurs to zero as shown in Example 2.7, “Simple complex type with minOccurs set to zero”. In this case age can be omitted and the data will still be valid.

Example 2.7. Simple complex type with minOccurs set to zero

<complexType name="personalInfo>
  <choice>
    <element name="name" type="xsd:string"/>
    <element name="age" type="xsd:int" minOccurs="0"/>
  </choice>
</complexType>

Defining attributes

Example 2.8. Complex type with an attribute

<complexType name="personalInfo>
  <all>
    <element name="name" type="xsd:string"/>
    <element name="previousJobs" type="xsd:string"
             minOccurs="3" maxOccurs="7"/>
  </all>
  <attribute name="age" type="xsd:int" use="optional" />
</complexType>
The attribute element has three attributes:

Example 2.9. Complex type array

<complexType name="personalInfo">
  <element name="averages" type="xsd:float" maxOccurs="20"/>
</complexType>
You can also specify a value for the minOccurs attribute.

SOAP arrays

SOAP arrays are defined by deriving from the SOAP-ENC:Array base type using the wsdl:arrayType element. The syntax for this is shown in Example 2.10, “Syntax for a SOAP array derived using wsdl:arrayType”.

Example 2.10. Syntax for a SOAP array derived using wsdl:arrayType

<complexType name="TypeName">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <attribute ref="SOAP-ENC:arrayType" 
                 wsdl:arrayType="ElementType<ArrayBounds>"/>
    </restriction>
  </complexContent>
</complexType>
Using this syntax, TypeName specifies the name of the newly-defined array type. ElementType specifies the type of the elements in the array. ArrayBounds specifies the number of dimensions in the array. To specify a single dimension array use []; to specify a two-dimensional array use either [][] or [,].
For example, the SOAP Array, SOAPStrings, shown in Example 2.11, “Definition of a SOAP array”, defines a one-dimensional array of strings. The wsdl:arrayType attribute specifies the type of the array elements, xsd:string, and the number of dimensions, with [] implying one dimension.

Example 2.11. Definition of a SOAP array

<complexType name="SOAPStrings">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <attribute ref="SOAP-ENC:arrayType"
                 wsdl:arrayType="xsd:string[]"/>
    </restriction>
  </complexContent>
</complexType>
You can also describe a SOAP Array using a simple element as described in the SOAP 1.1 specification. The syntax for this is shown in Example 2.12, “Syntax for a SOAP array derived using an element”.

Example 2.12. Syntax for a SOAP array derived using an element

<complexType name="TypeName">
  <complexContent>
    <restriction base="SOAP-ENC:Array">
      <sequence>
        <element name="ElementName" type="ElementType"
                 maxOccurs="unbounded"/>
      </sequence>
    </restriction>
  </complexContent>
</complexType>
When using this syntax, the element's maxOccurs attribute must always be set to unbounded.

4.3. Defining types by extension

Like most major coding languages, XML Schema allows you to create data types that inherit some of their elements from other data types. This is called defining a type by extension. For example, you could create a new type called alienInfo, that extends the personalInfo structure defined in Example 2.4, “A complex type” by adding a new element called planet.
Types defined by extension have four parts:
  1. The name of the type is defined by the name attribute of the complexType element.
  2. The complexContent element specifies that the new type will have more than one element.
    Note
    If you are only adding new attributes to the complex type, you can use a simpleContent element.
  3. The type from which the new type is derived, called the base type, is specified in the base attribute of the extension element.
  4. The new type’s elements and attributes are defined in the extension element, the same as they are for a regular complex type.
For example, alienInfo is defined as shown in Example 2.13, “Type defined by extension”.

Example 2.13. Type defined by extension

<complexType name="alienInfo">
  <complexContent>
    <extension base="personalInfo">
      <sequence>
        <element name="planet" type="xsd:string"/>
      </sequence>
    </extension>
  </complexContent>
</complexType>

4.4. Defining types by restriction

XML Schema allows you to create new types by restricting the possible values of an XML Schema simple type. For example, you can define a simple type, SSN, which is a string of exactly nine characters. New types defined by restricting simple types are defined using a simpleType element.
The definition of a type by restriction requires three things:
  1. The name of the new type is specified by the name attribute of the simpleType element.
  2. The simple type from which the new type is derived, called the base type, is specified in the restriction element. See the section called “Specifying the base type”.
  3. The rules, called facets, defining the restrictions placed on the base type are defined as children of the restriction element. See the section called “Defining the restrictions”.

Specifying the base type

The base type is the type that is being restricted to define the new type. It is specified using a restriction element. The restriction element is the only child of a simpleType element and has one attribute, base, that specifies the base type. The base type can be any of the XML Schema simple types.
For example, to define a new type by restricting the values of an xsd:int you use a definition like the one shown in Example 2.14, “Using int as the base type”.

Example 2.14. Using int as the base type

<simpleType name="restrictedInt">
  <restriction base="xsd:int">
    ...
  </restriction>
</simpleType>

Defining the restrictions

The rules defining the restrictions placed on the base type are called facets. Facets are elements with one attribute, value, that defines how the facet is enforced. The available facets and their valid value settings depend on the base type. For example, xsd:string supports six facets, including:
  • length
  • minLength
  • maxLength
  • pattern
  • whitespace
  • enumeration
Each facet element is a child of the restriction element.

Example

Example 2.15, “SSN simple type description” shows an example of a simple type, SSN, which represents a social security number. The resulting type is a string of the form xxx-xx-xxxx. <SSN>032-43-9876<SSN> is a valid value for an element of this type, but <SSN>032439876</SSN> is not.

Example 2.15. SSN simple type description

<simpleType name="SSN">
  <restriction base="xsd:string">
    <pattern value="\d{3}-\d{2}-\d{4}"/>
  </restriction>
</simpleType>

4.5. Defining enumerated types

Enumerated types in XML Schema are a special case of definition by restriction. They are described by using the enumeration facet which is supported by all XML Schema primitive types. As with enumerated types in most modern programming languages, a variable of this type can only have one of the specified values.

Defining an enumeration in XML Schema

The syntax for defining an enumeration is shown in Example 2.16, “Syntax for an enumeration”.

Example 2.16. Syntax for an enumeration

<simpleType name="EnumName">
  <restriction base="EnumType">
    <enumeration value="Case1Value"/>
    <enumeration value="Case2Value"/>
    ...
    <enumeration value="CaseNValue"/>
  </restriction>
</simpleType>
EnumName specifies the name of the enumeration type. EnumType specifies the type of the case values. CaseNValue, where N is any number one or greater, specifies the value for each specific case of the enumeration. An enumerated type can have any number of case values, but because it is derived from a simple type, only one of the case values is valid at a time.

Example

For example, an XML document with an element defined by the enumeration widgetSize, shown in Example 2.17, “widgetSize enumeration”, would be valid if it contained <widgetSize>big</widgetSize>, but it would not be valid if it contained <widgetSize>big,mungo</widgetSize>.

Example 2.17. widgetSize enumeration

<simpleType name="widgetSize">
  <restriction base="xsd:string">
    <enumeration value="big"/>
    <enumeration value="large"/>
    <enumeration value="mungo"/>
  </restriction>
</simpleType>

5. Defining elements

Elements in XML Schema represent an instance of an element in an XML document generated from the schema. The most basic element consists of a single element element. Like the element element used to define the members of a complex type, they have three attributes:
  • name — A required attribute that specifies the name of the element as it appears in an XML document.
  • type — Specifies the type of the element. The type can be any XML Schema primitive type or any named complex type defined in the contract. This attribute can be omitted if the type has an in-line definition.
  • nillable — Specifies whether an element can be omitted from a document entirely. If nillable is set to true, the element can be omitted from any document generated using the schema.
An element can also have an in-line type definition. In-line types are specified using either a complexType element or a simpleType element. Once you specify if the type of data is complex or simple, you can define any type of data needed using the tools available for each type of data. In-line type definitions are discouraged because they are not reusable.

Chapter 3. Defining Logical Messages Used by a Service

Abstract

A service is defined by the messages exchanged when its operations are invoked. In a WSDL contract these messages are defined using message element. The messages are made up of one or more parts that are defined using part elements.
A service’s operations are defined by specifying the logical messages that are exchanged when an operation is invoked. These logical messages define the data that is passed over a network as an XML document. They contain all of the parameters that are a part of a method invocation.
Logical messages are defined using the message element in your contracts. Each logical message consists of one or more parts, defined in part elements.
Tip
While your messages can list each parameter as a separate part, the recommended practice is to use only a single part that encapsulates the data needed for the operation.

Messages and parameter lists

Each operation exposed by a service can have only one input message and one output message. The input message defines all of the information the service receives when the operation is invoked. The output message defines all of the data that the service returns when the operation is completed. Fault messages define the data that the service returns when an error occurs.
In addition, each operation can have any number of fault messages. The fault messages define the data that is returned when the service encounters an error. These messages usually have only one part that provides enough information for the consumer to understand the error.

Message design for integrating with legacy systems

If you are defining an existing application as a service, you must ensure that each parameter used by the method implementing the operation is represented in a message. You must also ensure that the return value is included in the operation’s output message.
One approach to defining your messages is RPC style. When using RPC style, you define the messages using one part for each parameter in the method’s parameter list. Each message part is based on a type defined in the types element of the contract. Your input message contains one part for each input parameter in the method. Your output message contains one part for each output parameter, plus a part to represent the return value, if needed. If a parameter is both an input and an output parameter, it is listed as a part for both the input message and the output message.
RPC style message definition is useful when service enabling legacy systems that use transports such as Tibco or CORBA. These systems are designed around procedures and methods. As such, they are easiest to model using messages that resemble the parameter lists for the operation being invoked. RPC style also makes a cleaner mapping between the service and the application it is exposing.
While RPC style is useful for modeling existing systems, the service’s community strongly favors the wrapped document style. In wrapped document style, each message has a single part. The message’s part references a wrapper element defined in the types element of the contract. The wrapper element has the following characteristics:
  • If it is a wrapper for an input message:
    • It has one element for each of the method’s input parameters.
    • Its name is the same as the name of the operation with which it is associated.
  • If it is a wrapper for an output message:
    • It has one element for each of the method’s output parameters and one element for each of the method’s inout parameters.
    • Its first element represents the method’s return parameter.
    • Its name would be generated by appending Response to the name of the operation with which the wrapper is associated.

Message naming

Each message in a contract must have a unique name within its namespace. It is recommended that you use the following naming conventions:
  • Messages should only be used by a single operation.
  • Input message names are formed by appending Request to the name of the operation.
  • Output message names are formed by appending Response to the name of the operation.
  • Fault message names should represent the reason for the fault.

Message parts

Table 3.1. Part data type attributes

AttributeDescription
element="elem_name"
The data type of the part is defined by an element called elem_name.
type="type_name"
The data type of the part is defined by a type called type_name.
Messages are allowed to reuse part names. For instance, if a method has a parameter, foo, that is passed by reference or is an in/out, it can be a part in both the request message and the response message, as shown in Example 3.1, “Reused part”.

Example 3.1. Reused part

<message name="fooRequest">
  <part name="foo" type="xsd:int"/>
<message>
<message name="fooReply">
  <part name="foo" type="xsd:int"/>
<message>

Example

For example, imagine you had a server that stored personal information and provided a method that returned an employee’s data based on the employee's ID number. The method signature for looking up the data is similar to Example 3.2, “personalInfo lookup method”.

Example 3.2. personalInfo lookup method

personalInfo lookup(long empId)
This method signature can be mapped to the RPC style WSDL fragment shown in Example 3.3, “RPC WSDL message definitions”.

Example 3.3. RPC WSDL message definitions

<message name="personalLookupRequest">
  <part name="empId" type="xsd:int"/>
<message/>
<message name="personalLookupResponse>
  <part name="return" element="xsd1:personalInfo"/>
<message/>
It can also be mapped to the wrapped document style WSDL fragment shown in Example 3.4, “Wrapped document WSDL message definitions”.

Example 3.4. Wrapped document WSDL message definitions

<types>
  <schema ... >
  ...
  <element name="personalLookup">
    <complexType>
      <sequence>
        <element name="empID" type="xsd:int" />
      </sequence>
    </complexType>
  </element>
  <element name="personalLookupResponse">
    <complexType>
      <sequence>
        <element name="return" type="personalInfo" />
      </sequence>
    </complexType>
  </element>
  </schema>
</types>
<message name="personalLookupRequest">
  <part name="empId" element="xsd1:personalLookup"/>
<message/>
<message name="personalLookupResponse">
  <part name="return" element="xsd1:personalLookupResponse"/>
<message/>

Chapter 4. Defining Your Logical Interfaces

Abstract

Logical service interfaces are defined using the portType element.
Logical service interfaces are defined using the WSDL portType element. The portType element is a collection of abstract operation definitions. Each operation is defined by the input, output, and fault messages used to complete the transaction the operation represents. When code is generated to implement the service interface defined by a portType element, each operation is converted into a method containing the parameters defined by the input, output, and fault messages specified in the contract.

Process

To define a logical interface in a WSDL contract you must do the following:
  1. Create a portType element to contain the interface definition and give it a unique name. See the section called “Port types”.
  2. Create an operation element for each operation defined in the interface. See the section called “Operations”.
  3. For each operation, specify the messages used to represent the operation’s parameter list, return type, and exceptions. See the section called “Operation messages”.

Port types

A WSDL portType element is the root element in a logical interface definition. While many Web service implementations map portType elements directly to generated implementation objects, a logical interface definition does not specify the exact functionality provided by the the implemented service. For example, a logical interface named ticketSystem can result in an implementation that either sells concert tickets or issues parking tickets.
The portType element is the unit of a WSDL document that is mapped into a binding to define the physical data used by an endpoint exposing the defined service.
Each portType element in a WSDL document must have a unique name, which is specified using the name attribute, and is made up of a collection of operations, which are described in operation elements. A WSDL document can describe any number of port types.

Table 4.1. Operation message elements

ElementDescription
inputSpecifies the message the client endpoint sends to the service provider when a request is made. The parts of this message correspond to the input parameters of the operation.
outputSpecifies the message that the service provider sends to the client endpoint in response to a request. The parts of this message correspond to any operation parameters that can be changed by the service provider, such as values passed by reference. This includes the return value of the operation.
faultSpecifies a message used to communicate an error condition between the endpoints.
An operation is required to have at least one input or one output element. An operation can have both input and output elements, but it can only have one of each. Operations are not required to have any fault elements, but can, if required, have any number of fault elements.
The elements have the two attributes listed in Table 4.2, “Attributes of the input and output elements”.

Table 4.2. Attributes of the input and output elements

AttributeDescription
nameIdentifies the message so it can be referenced when mapping the operation to a concrete data format. The name must be unique within the enclosing port type.
messageSpecifies the abstract message that describes the data being sent or received. The value of the message attribute must correspond to the name attribute of one of the abstract messages defined in the WSDL document.
It is not necessary to specify the name attribute for all input and output elements; WSDL provides a default naming scheme based on the enclosing operation’s name. If only one element is used in the operation, the element name defaults to the name of the operation. If both an input and an output element are used, the element name defaults to the name of the operation with either Request or Response respectively appended to the name.

Return values

Because the operation element is an abstract definition of the data passed during an operation, WSDL does not provide for return values to be specified for an operation. If a method returns a value it will be mapped into the output element as the last part of that message.

Example

For example, you might have an interface similar to the one shown in Example 4.1, “personalInfo lookup interface”.

Example 4.1. personalInfo lookup interface

interface personalInfoLookup
{
  personalInfo lookup(in int empID)
  raises(idNotFound);
}
This interface can be mapped to the port type in Example 4.2, “personalInfo lookup port type”.

Example 4.2. personalInfo lookup port type

<message name="personalLookupRequest">
  <part name="empId" element="xsd1:personalLookup"/>
<message/>
<message name="personalLookupResponse">
  <part name="return" element="xsd1:personalLookupResponse"/>
<message/>
<message name="idNotFoundException">
  <part name="exception" element="xsd1:idNotFound"/>
<message/>
<portType name="personalInfoLookup">
  <operation name="lookup">
    <input name="empID" message="personalLookupRequest"/>
    <output name="return" message="personalLookupResponse"/>
    <fault name="exception" message="idNotFoundException"/>
  </operation>
</portType>

Part II. Web Services Bindings

Abstract

This part describes how to add Apache CXF bindings to a WSDL document.

Chapter 5. Understanding Bindings in WSDL

Abstract

Bindings map the logical messages used to define a service into a concrete payload format that can be transmitted and received by an endpoint.

Overview

Bindings provide a bridge between the logical messages used by a service to a concrete data format that an endpoint uses in the physical world. They describe how the logical messages are mapped into a payload format that is used on the wire by an endpoint. It is within the bindings that details such as parameter order, concrete data types, and return values are specified. For example, the parts of a message can be reordered in a binding to reflect the order required by an RPC call. Depending on the binding type, you can also identify which of the message parts, if any, represent the return type of a method.

Port types and bindings

Port types and bindings are directly related. A port type is an abstract definition of a set of interactions between two logical services. A binding is a concrete definition of how the messages used to implement the logical services will be instantiated in the physical world. Each binding is then associated with a set of network details that finish the definition of one endpoint that exposes the logical service defined by the port type.
To ensure that an endpoint defines only a single service, WSDL requires that a binding can only represent a single port type. For example, if you had a contract with two port types, you could not write a single binding that mapped both of them into a concrete data format. You would need two bindings.
However, WSDL allows for a port type to be mapped to several bindings. For example, if your contract had a single port type, you could map it into two or more bindings. Each binding could alter how the parts of the message are mapped or they could specify entirely different payload formats for the message.

The WSDL elements

The actual mappings are defined in the children of the binding element. These elements vary depending on the type of payload format you decide to use. The different payload formats and the elements used to specify their mappings are discussed in the following chapters.

Adding to a contract

Apache CXF provides command line tools that can generate bindings for predefined service interfaces.
The tools will add the proper elements to your contract for you. However, it is recommended that you have some knowledge of how the different types of bindings work.
You can also add a binding to a contract using any text editor. When hand editing a contract, you are responsible for ensuring that the contract is valid.

Supported bindings

Apache CXF supports the following bindings:
  • SOAP 1.1
  • SOAP 1.2
  • CORBA
  • Pure XML

Chapter 6. Using SOAP 1.1 Messages

Abstract

Apache CXF provides a tool to generate a SOAP 1.1 binding which does not use any SOAP headers. However, you can add SOAP headers to your binding using any text or XML editor.

1. Adding a SOAP 1.1 Binding

Note
To use wsdl2soap you will need to download the Apache CXF distribution.

Using wsdl2soap

To generate a SOAP 1.1 binding using wsdl2soap use the following command:

wsdl2soap { -i port-type-name } [ -b binding-name ] [ -d output-directory ] [ -o output-file ] [ -n soap-body-namespace ] [ -style (document/rpc) ] [ -use (literal/encoded) ] [ -v ] [[ -verbose ] | [ -quiet ]] wsdlurl

The command has the following options:
OptionInterpretation
-i port-type-name
Specifies the portType element for which a binding is generated.
wsdlurlThe path and name of the WSDL file containing the portType element definition.
The tool has the following optional arguments:
OptionInterpretation
-b binding-nameSpecifies the name of the generated SOAP binding.
-d output-directorySpecifies the directory to place the generated WSDL file.
-o output-fileSpecifies the name of the generated WSDL file.
-n soap-body-namespaceSpecifies the SOAP body namespace when the style is RPC.
-style (document/rpc)Specifies the encoding style (document or RPC) to use in the SOAP binding. The default is document.
-use (literal/encoded)Specifies the binding use (encoded or literal) to use in the SOAP binding. The default is literal.
-vDisplays the version number for the tool.
-verboseDisplays comments during the code generation process.
-quietSuppresses comments during the code generation process.
The -i port-type-name and wsdlurl arguments are required. If the -style rpc argument is specified, the -n soap-body-namspace argument is also required. All other arguments are optional and may be listed in any order.
Important
wsdl2soap does not support the generation of document/encoded SOAP bindings.

Example 6.1. Ordering System Interface

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>
...
</definitions>
The SOAP binding generated for orderWidgets is shown in Example 6.2, “SOAP 1.1 Binding for orderWidgets.

Example 6.2. SOAP 1.1 Binding for orderWidgets

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap:operation soapAction="" style="document"/>
      <input name="order">
        <soap:body use="literal"/>
      </input>
      <output name="bill">
        <soap:body use="literal"/>
      </output>
      <fault name="sizeFault">
        <soap:body use="literal"/>
      </fault>
  </operation>
</binding>
This binding specifies that messages are sent using the document/literal message style.

2. Adding SOAP Headers to a SOAP 1.1 Binding

Overview

SOAP headers are defined by adding soap:header elements to your default SOAP 1.1 binding. The soap:header element is an optional child of the input, output, and fault elements of the binding. The SOAP header becomes part of the parent message. A SOAP header is defined by specifying a message and a message part. Each SOAP header can only contain one message part, but you can insert as many SOAP headers as needed.
The syntax for defining a SOAP header is shown in Example 6.3, “SOAP Header Syntax”. The message attribute of soap:header is the qualified name of the message from which the part being inserted into the header is taken. The part attribute is the name of the message part inserted into the SOAP header. Because SOAP headers are always document style, the WSDL message part inserted into the SOAP header must be defined using an element. Together the message and the part attributes fully describe the data to insert into the SOAP header.

Example 6.3. SOAP Header Syntax

<binding name="headwig">
  <soap:binding style="document"
                transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="weave">
      <soap:operation soapAction="" style="document"/>
      <input name="grain">
        <soap:body ... />
        <soap:header message="QName" part="partName"/>
      </input>
...
</binding>
As well as the mandatory message and part attributes, soap:header also supports the namespace, the use, and the encodingStyle attributes. These optional attributes function the same for soap:header as they do for soap:body.

Splitting messages between body and header

The message part inserted into the SOAP header can be any valid message part from the contract. It can even be a part from the parent message which is being used as the SOAP body. Because it is unlikely that you would want to send information twice in the same message, the SOAP binding provides a means for specifying the message parts that are inserted into the SOAP body.
The soap:body element has an optional attribute, parts, that takes a space delimited list of part names. When parts is defined, only the message parts listed are inserted into the SOAP body. You can then insert the remaining parts into the SOAP header.
Note
When you define a SOAP header using parts of the parent message, Apache CXF automatically fills in the SOAP headers for you.
Example 6.4, “SOAP 1.1 Binding with a SOAP Header” shows a modified version of the orderWidgets service shown in Example 6.1, “Ordering System Interface”. This version has been modified so that each order has an xsd:base64binary value placed in the SOAP header of the request and response. The SOAP header is defined as being the keyVal part from the widgetKey message. In this case you are responsible for adding the SOAP header to your application logic because it is not part of the input or output message.

Example 6.4. SOAP 1.1 Binding with a SOAP Header

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>
<message name="widgetKey">
  <part name="keyVal" element="xsd1:keyElem"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap:operation soapAction="" style="document"/>
      <input name="order">
        <soap:body use="literal"/>
        <soap:header message="tns:widgetKey" part="keyVal"/>
      </input>
      <output name="bill">
        <soap:body use="literal"/>
        <soap:header message="tns:widgetKey" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>
You can modify Example 6.4, “SOAP 1.1 Binding with a SOAP Header” so that the header value is a part of the input and output messages as shown in Example 6.5, “SOAP 1.1 Binding for orderWidgets with a SOAP Header”. In this case keyVal is a part of the input and output messages. In the soap:body element's parts attribute specifies that keyVal cannot be inserted into the body. However, it is inserted into the SOAP header.

Example 6.5. SOAP 1.1 Binding for orderWidgets with a SOAP Header

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
  <part name="keyVal" element="xsd1:keyElem"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
  <part name="keyVal" element="xsd1:keyElem"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap:operation soapAction="" style="document"/>
      <input name="order">
        <soap:body use="literal" parts="numOrdered"/>
        <soap:header message="tns:widgetOrder" part="keyVal"/>
      </input>
      <output name="bill">
        <soap:body use="literal" parts="bill"/>
        <soap:header message="tns:widgetOrderBill" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>

Chapter 7. Using SOAP 1.2 Messages

Abstract

Apache CXF provides tools to generate a SOAP 1.2 binding which does not use any SOAP headers. You can add SOAP headers to your binding using any text or XML editor.

1. Adding a SOAP 1.2 Binding to a WSDL Document

Using wsdl2soap

Note
To use wsdl2soap you will need to download the Apache CXF distribution.
To generate a SOAP 1.2 binding using wsdl2soap use the following command:

wsdl2soap { -i port-type-name } [ -b binding-name ] { -soap12 } [ -d output-directory ] [ -o output-file ] [ -n soap-body-namespace ] [ -style (document/rpc) ] [ -use (literal/encoded) ] [ -v ] [[ -verbose ] | [ -quiet ]] wsdlurl

The tool has the following required arguments:
OptionInterpretation
-i port-type-name
Specifies the portType element for which a binding is generated.
-soap12Specifies that the generated binding uses SOAP 1.2.
wsdlurlThe path and name of the WSDL file containing the portType element definition.
The tool has the following optional arguments:
OptionInterpretation
-b binding-nameSpecifies the name of the generated SOAP binding.
-soap12Specifies that the generated binding will use SOAP 1.2.
-d output-directorySpecifies the directory to place the generated WSDL file.
-o output-fileSpecifies the name of the generated WSDL file.
-n soap-body-namespaceSpecifies the SOAP body namespace when the style is RPC.
-style (document/rpc)Specifies the encoding style (document or RPC) to use in the SOAP binding. The default is document.
-use (literal/encoded)Specifies the binding use (encoded or literal) to use in the SOAP binding. The default is literal.
-vDisplays the version number for the tool.
-verboseDisplays comments during the code generation process.
-quietSuppresses comments during the code generation process.
The -i port-type-name and wsdlurl arguments are required. If the -style rpc argument is specified, the -n soap-body-namspace argument is also required. All other arguments are optional and can be listed in any order.
Important
wsdl2soap does not support the generation of document/encoded SOAP 1.2 bindings.

Example 7.1. Ordering System Interface

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>
...
</definitions>
The SOAP binding generated for orderWidgets is shown in Example 7.2, “SOAP 1.2 Binding for orderWidgets”.

Example 7.2. SOAP 1.2 Binding for orderWidgets

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap12:operation soapAction="" style="document"/>
      <input name="order">
        <soap12:body use="literal"/>
      </input>
      <output name="bill">
        <wsoap12:body use="literal"/>
      </output>
      <fault name="sizeFault">
        <soap12:body use="literal"/>
      </fault>
  </operation>
</binding>
This binding specifies that messages are sent using the document/literal message style.

2. Adding Headers to a SOAP 1.2 Message

Overview

SOAP message headers are defined by adding soap12:header elements to your SOAP 1.2 message. The soap12:header element is an optional child of the input, output, and fault elements of the binding. The SOAP header becomes part of the parent message. A SOAP header is defined by specifying a message and a message part. Each SOAP header can only contain one message part, but you can insert as many headers as needed.

Example 7.3. SOAP Header Syntax

<binding name="headwig">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="weave">
      <soap12:operation soapAction="" style="documment"/>
      <input name="grain">
        <soap12:body ... />
        <soap12:header message="QName" part="partName"
                       use="literal|encoded"
                        encodingStyle="encodingURI"
                        namespace="namespaceURI" />
      </input>
...
</binding>
The soap12:header element’s attributes are described in Table 7.1, “soap12:header Attributes”.

Table 7.1. soap12:header Attributes

AttributeDescription
message A required attribute specifying the qualified name of the message from which the part being inserted into the header is taken.
part A required attribute specifying the name of the message part inserted into the SOAP header.
use Specifies if the message parts are to be encoded using encoding rules. If set to encoded the message parts are encoded using the encoding rules specified by the value of the encodingStyle attribute. If set to literal, the message parts are defined by the schema types referenced.
encodingStyle Specifies the encoding rules used to construct the message.
namespace Defines the namespace to be assigned to the header element serialized with use="encoded".

Splitting messages between body and header

The message part inserted into the SOAP header can be any valid message part from the contract. It can even be a part from the parent message which is being used as the SOAP body. Because it is unlikely that you would send information twice in the same message, the SOAP 1.2 binding provides a means for specifying the message parts that are inserted into the SOAP body.
The soap12:body element has an optional attribute, parts, that takes a space delimited list of part names. When parts is defined, only the message parts listed are inserted into the body of the SOAP 1.2 message. You can then insert the remaining parts into the message's header.
Note
When you define a SOAP header using parts of the parent message, Apache CXF automatically fills in the SOAP headers for you.
Example 7.4, “SOAP 1.2 Binding with a SOAP Header” shows a modified version of the orderWidgets service shown in Example 7.1, “Ordering System Interface”. This version is modified so that each order has an xsd:base64binary value placed in the header of the request and the response. The header is defined as being the keyVal part from the widgetKey message. In this case you are responsible for adding the application logic to create the header because it is not part of the input or output message.

Example 7.4. SOAP 1.2 Binding with a SOAP Header

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>
<message name="widgetKey">
  <part name="keyVal" element="xsd1:keyElem"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap12:operation soapAction="" style="document"/>
      <input name="order">
        <soap12:body use="literal"/>
        <soap12:header message="tns:widgetKey" part="keyVal"/>
      </input>
      <output name="bill">
        <soap12:body use="literal"/>
        <soap12:header message="tns:widgetKey" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap12:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>
You can modify Example 7.4, “SOAP 1.2 Binding with a SOAP Header” so that the header value is a part of the input and output messages, as shown in Example 7.5, “SOAP 1.2 Binding for orderWidgets with a SOAP Header”. In this case keyVal is a part of the input and output messages. In the soap12:body elements the parts attribute specifies that keyVal should not be inserted into the body. However, it is inserted into the header.

Example 7.5. SOAP 1.2 Binding for orderWidgets with a SOAP Header

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="widgetOrderForm.wsdl"
    targetNamespace="http://widgetVendor.com/widgetOrderForm"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:tns="http://widgetVendor.com/widgetOrderForm"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsd1="http://widgetVendor.com/types/widgetTypes"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">

<types>
  <schema targetNamespace="http://widgetVendor.com/types/widgetTypes"
           xmlns="http://www.w3.org/2001/XMLSchema"
           xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
    <element name="keyElem" type="xsd:base64Binary"/>
  </schema>
</types>

<message name="widgetOrder">
  <part name="numOrdered" type="xsd:int"/>
  <part name="keyVal" element="xsd1:keyElem"/>
</message>
<message name="widgetOrderBill">
  <part name="price" type="xsd:float"/>
  <part name="keyVal" element="xsd1:keyElem"/>
</message>
<message name="badSize">
  <part name="numInventory" type="xsd:int"/>
</message>

<portType name="orderWidgets">
  <operation name="placeWidgetOrder">
    <input message="tns:widgetOrder" name="order"/>
    <output message="tns:widgetOrderBill" name="bill"/>
    <fault message="tns:badSize" name="sizeFault"/>
  </operation>
</portType>

<binding name="orderWidgetsBinding" type="tns:orderWidgets">
  <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="placeWidgetOrder">
      <soap12:operation soapAction="" style="document"/>
      <input name="order">
        <soap12:body use="literal" parts="numOrdered"/>
        <soap12:header message="tns:widgetOrder" part="keyVal"/>
      </input>
      <output name="bill">
        <soap12:body use="literal" parts="bill"/>
        <soap12:header message="tns:widgetOrderBill" part="keyVal"/>
      </output>
      <fault name="sizeFault">
        <soap12:body use="literal"/>
      </fault>
  </operation>
</binding>
...
</definitions>

Chapter 8. Sending Binary Data Using SOAP with Attachments

Abstract

SOAP attachments provide a mechanism for sending binary data as part of a SOAP message. Using SOAP with attachments requires that you define your SOAP messages as MIME multipart messages.

Overview

SOAP messages generally do not carry binary data. However, the W3C SOAP 1.1 specification allows for using MIME multipart/related messages to send binary data in SOAP messages. This technique is called using SOAP with attachments. SOAP attachments are defined in the W3C's SOAP Messages with Attachments Note.

Namespace

The WSDL extensions used to define the MIME multipart/related messages are defined in the namespace http://schemas.xmlsoap.org/wsdl/mime/.
In the discussion that follows, it is assumed that this namespace is prefixed with mime. The entry in the WSDL definitions element to set this up is shown in Example 8.1, “MIME Namespace Specification in a Contract”.

Example 8.1. MIME Namespace Specification in a Contract

xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"

Changing the message binding

In a default SOAP binding, the first child element of the input, output, and fault elements is a soap:body element describing the body of the SOAP message representing the data. When using SOAP with attachments, the soap:body element is replaced with a mime:multipartRelated element.
Note
WSDL does not support using mime:multipartRelated for fault messages.
The mime:multipartRelated element tells Apache CXF that the message body is a multipart message that potentially contains binary data. The contents of the element define the parts of the message and their contents. mime:multipartRelated elements contain one or more mime:part elements that describe the individual parts of the message.
The first mime:part element must contain the soap:body element that would normally appear in a default SOAP binding. The remaining mime:part elements define the attachments that are being sent in the message.
MIME multipart messages are described using a mime:multipartRelated element that contains a number of mime:part elements. To fully describe a MIME multipart message you must do the following:
  1. Inside the input or output message you are sending as a MIME multipart message, add a mime:mulipartRelated element as the first child element of the enclosing message.
  2. Add a mime:part child element to the mime:multipartRelated element and set its name attribute to a unique string.
  3. Add a soap:body element as the child of the mime:part element and set its attributes appropriately.
    Tip
    If the contract had a default SOAP binding, you can copy the soap:body element from the corresponding message from the default binding into the MIME multipart message.
  4. Add another mime:part child element to the mime:multipartReleated element and set its name attribute to a unique string.
  5. Add a mime:content child element to the mime:part element to describe the contents of this part of the message.
    To fully describe the contents of a MIME message part the mime:content element has the following attributes:

    Table 8.1. mime:content Attributes

    AttributeDescription
    part Specifies the name of the WSDL message part, from the parent message definition, that is used as the content of this part of the MIME multipart message being placed on the wire.
    type
    The MIME type of the data in this message part. MIME types are defined as a type and a subtype using the syntax type/subtype.
    There are a number of predefined MIME types such as image/jpeg and text/plain. The MIME types are maintained by the Internet Assigned Numbers Authority (IANA) and described in detail in Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies and Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types.

Example

Example 8.2, “Contract using SOAP with Attachments” shows a WSDL fragment defining a service that stores X-rays in JPEG format. The image data, xRay, is stored as an xsd:base64binary and is packed into the MIME multipart message's second part, imageData. The remaining two parts of the input message, patientName and patientNumber, are sent in the first part of the MIME multipart image as part of the SOAP body.

Example 8.2. Contract using SOAP with Attachments

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="XrayStorage"
    targetNamespace="http://mediStor.org/x-rays"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://mediStor.org/x-rays"
    xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <message name="storRequest">
    <part name="patientName" type="xsd:string"/>
    <part name="patientNumber" type="xsd:int"/>
    <part name="xRay" type="xsd:base64Binary"/>
  </message>
  <message name="storResponse">
    <part name="success" type="xsd:boolean"/>
  </message>

  <portType name="xRayStorage">
    <operation name="store">
      <input message="tns:storRequest" name="storRequest"/>
      <output message="tns:storResponse" name="storResponse"/>
    </operation>
  </portType>

  <binding name="xRayStorageBinding" type="tns:xRayStorage">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
      <operation name="store">
      <soap:operation soapAction="" style="document"/>
      <input name="storRequest">
        <mime:multipartRelated>
          <mime:part name="bodyPart">
            <soap:body use="literal"/>
          </mime:part>
          <mime:part name="imageData">
            <mime:content part="xRay" type="image/jpeg"/>
          </mime:part>
        </mime:multipartRelated>
      </input>
      <output name="storResponse">
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>

  <service name="xRayStorageService">
    <port binding="tns:xRayStorageBinding" name="xRayStoragePort">
      <soap:address location="http://localhost:9000"/>
    </port>
  </service>
</definitions>

Chapter 9. Sending Binary Data with SOAP MTOM

Abstract

SOAP Message Transmission Optimization Mechanism (MTOM) replaces SOAP with attachments as a mechanism for sending binary data as part of an XML message. Using MTOM with Apache CXF requires adding the correct schema types to a service's contract and enabling the MTOM optimizations.
SOAP Message Transmission Optimization Mechanism (MTOM) specifies an optimized method for sending binary data as part of a SOAP message. Unlike SOAP with Attachments, MTOM requires the use of XML-binary Optimized Packaging (XOP) packages for transmitting binary data. Using MTOM to send binary data does not require you to fully define the MIME Multipart/Related message as part of the SOAP binding. It does, however, require that you do the following:
  1. Annotate the data that you are going to send as an attachment.
    You can annotate either your WSDL or the Java class that implements your data.
  2. Enable the runtime's MTOM support.
    This can be done either programmatically or through configuration.
  3. Develop a DataHandler for the data being passed as an attachment.
    Note
    Developing DataHandlers is beyond the scope of this book.

1. Annotating Data Types to use MTOM

Overview

In WSDL, when defining a data type for passing along a block of binary data, such as an image file or a sound file, you define the element for the data to be of type xsd:base64Binary. By default, any element of type xsd:base64Binary results in the generation of a byte[] which can be serialized using MTOM. However, the default behavior of the code generators does not take full advantage of the serialization.
In order to fully take advantage of MTOM you must add annotations to either your service's WSDL document or the JAXB class that implements the binary data structure. Adding the annotations to the WSDL document forces the code generators to generate streaming data handlers for the binary data. Annotating the JAXB class involves specifying the proper content types and might also involve changing the type specification of the field containing the binary data.

WSDL first

Example 9.1, “Message for MTOM” shows a WSDL document for a Web service that uses a message which contains one string field, one integer field, and a binary field. The binary field is intended to carry a large image file, so it is not appropriate to send it as part of a normal SOAP message.

Example 9.1. Message for MTOM

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="XrayStorage"
    targetNamespace="http://mediStor.org/x-rays"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://mediStor.org/x-rays"
    xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
    xmlns:xsd1="http://mediStor.org/types/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <types>
    <schema targetNamespace="http://mediStor.org/types/"
            xmlns="http://www.w3.org/2001/XMLSchema">
      <complexType name="xRayType">
        <sequence>
          <element name="patientName" type="xsd:string" />
          <element name="patientNumber" type="xsd:int" />
          <element name="imageData" type="xsd:base64Binary" />
        </sequence>
      </complexType>
      <element name="xRay" type="xsd1:xRayType" />
    </schema>
  </types>

  <message name="storRequest">
    <part name="record" element="xsd1:xRay"/>
  </message>
  <message name="storResponse">
    <part name="success" type="xsd:boolean"/>
  </message>

  <portType name="xRayStorage">
    <operation name="store">
      <input message="tns:storRequest" name="storRequest"/>
      <output message="tns:storResponse" name="storResponse"/>
    </operation>
  </portType>

  <binding name="xRayStorageSOAPBinding" type="tns:xRayStorage">
    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="store">
      <soap12:operation soapAction="" style="document"/>
      <input name="storRequest">
        <soap12:body use="literal"/>
      </input>
      <output name="storResponse">
        <soap12:body use="literal"/>
      </output>
    </operation>
  </binding>
  ...
</definitions>
If you want to use MTOM to send the binary part of the message as an optimized attachment you must add the xmime:expectedContentTypes attribute to the element containing the binary data. This attribute is defined in the http://www.w3.org/2005/05/xmlmime namespace and specifies the MIME types that the element is expected to contain. You can specify a comma separated list of MIME types. The setting of this attribute changes how the code generators create the JAXB class for the data. For most MIME types, the code generator creates a DataHandler. Some MIME types, such as those for images, have defined mappings.
Note
The MIME types are maintained by the Internet Assigned Numbers Authority(IANA) and are described in detail in Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies and Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types.
Tip
For most uses you specify application/octet-stream.
Example 9.2, “Binary Data for MTOM” shows how you can modify xRayType from Example 9.1, “Message for MTOM” for using MTOM.

Example 9.2. Binary Data for MTOM

...
  <types>
    <schema targetNamespace="http://mediStor.org/types/"
            xmlns="http://www.w3.org/2001/XMLSchema"
            xmlns:xmime="http://www.w3.org/2005/05/xmlmime">
      <complexType name="xRayType">
        <sequence>
          <element name="patientName" type="xsd:string" />
          <element name="patientNumber" type="xsd:int" />
          <element name="imageData" type="xsd:base64Binary" 
                   xmime:expectedContentTypes="application/octet-stream"/>
        </sequence>
      </complexType>
      <element name="xRay" type="xsd1:xRayType" />
    </schema>
  </types>
...
The generated JAXB class generated for xRayType no longer contains a byte[]. Instead the code generator sees the xmime:expectedContentTypes attribute and generates a DataHandler for the imageData field.
Note
You do not need to change the binding element to use MTOM. The runtime makes the appropriate changes when the data is sent.

Java first

If you are doing Java first development you can make your JAXB class MTOM ready by doing the following:
  1. Make sure the field holding the binary data is a DataHandler.
  2. Add the @XmlMimeType() annotation to the field containing the data you want to stream as an MTOM attachment.
Example 9.3, “JAXB Class for MTOM” shows a JAXB class annotated for using MTOM.

Example 9.3. JAXB Class for MTOM

@XmlType
public class XRayType {
    protected String patientName;
    protected int patientNumber;
    @XmlMimeType("application/octet-stream")
    protected DataHandler imageData;
  ...
}

2. Enabling MTOM

By default the Apache CXF runtime does not enable MTOM support. It sends all binary data as either part of the normal SOAP message or as an unoptimized attachment. You can activate MTOM support either programmatically or through the use of configuration.

2.1. Using JAX-WS APIs

Overview

Both service providers and consumers must have the MTOM optimizations enabled. The JAX-WS APIs offer different mechanisms for each type of endpoint.

Service provider

If you published your service provider using the JAX-WS APIs you enable the runtime's MTOM support as follows:
  1. Access the Endpoint object for your published service.
  2. Get the SOAP binding from the Endpoint using its getBinding() method, as shown in Example 9.4, “Getting the SOAP Binding from an Endpoint”.

    Example 9.4. Getting the SOAP Binding from an Endpoint

    // Endpoint ep is declared previously
    SOAPBinding binding = (SOAPBinding)ep.getBinding();
    You must cast the returned binding object to a SOAPBinding object to access the MTOM property.
  3. Set the binding's MTOM enabled property to true using the binding's setMTOMEnabled() method, as shown in Example 9.5, “Setting a Service Provider's MTOM Enabled Property”.

    Example 9.5. Setting a Service Provider's MTOM Enabled Property

    binding.setMTOMEnabled(true);

Consumer

To MTOM enable a JAX-WS consumer you must do the following:
  1. Cast the consumer's proxy to a BindingProvider object.
  2. Get the SOAP binding from the BindingProvider using its getBinding() method, as shown in Example 9.6, “Getting a SOAP Binding from a BindingProvider.

    Example 9.6. Getting a SOAP Binding from a BindingProvider

    // BindingProvider bp declared previously
    SOAPBinding binding = (SOAPBinding)bp.getBinding();
  3. Set the bindings MTOM enabled property to true using the binding's setMTOMEnabled() method, as shown in Example 9.7, “Setting a Consumer's MTOM Enabled Property”.

    Example 9.7. Setting a Consumer's MTOM Enabled Property

    binding.setMTOMEnabled(true);

2.2. Using configuration

Overview

Procedure

The MTOM property is set inside the jaxws:endpoint element for your endpoint. To enable MTOM do the following:
  1. Add a jaxws:property child element to the endpoint's jaxws:endpoint element.
  2. Add a entry child element to the jaxws:property element.
  3. Set the entry element's key attribute to mtom-enabled.
  4. Set the entry element's value attribute to true.

Example

Example 9.8, “Configuration for Enabling MTOM” shows an endpoint that is MTOM enabled.

Example 9.8. Configuration for Enabling MTOM

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                           http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">

  <jaxws:endpoint id="xRayStorage" 
                  implementor="demo.spring.xRayStorImpl" 
                  address="http://localhost/xRayStorage">
    <jaxws:properties>
      <entry key="mtom-enabled" value="true"/>
    </jaxws:properties>
  </jaxws:endpoint>
</beans>

Chapter 10. Using XML Documents

Abstract

The pure XML payload format provides an alternative to the SOAP binding by allowing services to exchange data using straight XML documents without the overhead of a SOAP envelope.

XML binding namespace

The extensions used to describe XML format bindings are defined in the namespace http://cxf.apache.org/bindings/xformat. Apache CXF tools use the prefix xformat to represent the XML binding extensions. Add the following line to your contracts:
xmlns:xformat="http://cxf.apache.org/bindings/xformat"

Hand editing

To map an interface to a pure XML payload format do the following:
  1. Add a standard WSDL binding element to your contract to hold the XML binding, give the binding a unique name, and specify the name of the WSDL portType element that represents the interface being bound.
  2. Add an xformat:binding child element to the binding element to identify that the messages are being handled as pure XML documents without SOAP envelopes.
  3. For each operation defined in the bound interface, add a standard WSDL operation element to hold the binding information for the operation's messages.
  4. For each operation added to the binding, add the input, output, and fault children elements to represent the messages used by the operation.
    These elements correspond to the messages defined in the interface definition of the logical operation.
  5. Optionally add an xformat:body element with a valid rootNode attribute to the added input, output, and fault elements to override the value of rootNode set at the binding level.

Example 10.1. Valid XML Binding Message

<type ... >
  ...
  <element name="operatorID" type="xsd:int"/>
  ...
</types>
<message name="operator">
  <part name="lineNumber" element="ns1:operatorID"/>
</message>
For messages with one part, Apache CXF will always generate a valid XML document even if the rootNode attribute is not set. However, the message in Example 10.2, “Invalid XML Binding Message” would generate an invalid XML document.

Example 10.2. Invalid XML Binding Message

<types>
  ...
  <element name="pairName" type="xsd:string"/>
  <element name="entryNum" type="xsd:int"/>
  ...
</types>

<message name="matildas">
  <part name="dancing" element="ns1:pairName"/>
  <part name="number" element="ns1:entryNum"/>
</message>
Without the rootNode attribute specified in the XML binding, Apache CXF will generate an XML document similar to Example 10.3, “Invalid XML Document” for the message defined in Example 10.2, “Invalid XML Binding Message”. The generated XML document is invalid because it has two root elements: pairName and entryNum.

Example 10.3. Invalid XML Document

<pairName>
  Fred&Linda
</pairName>
<entryNum>
  123
</entryNum>
If you set the rootNode attribute, as shown in Example 10.4, “XML Binding with rootNode set” Apache CXF will wrap the elements in the specified root element. In this example, the rootNode attribute is defined for the entire binding and specifies that the root element will be named entrants.

Example 10.4. XML Binding with rootNode set

<portType name="danceParty">
  <operation name="register">
    <input message="tns:matildas" name="contestant"/>
  </operation>
</portType>

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered"/>
</binding>
An XML document generated from the input message would be similar to Example 10.5, “XML Document generated using the rootNode attribute”. Notice that the XML document now only has one root element.

Example 10.5. XML Document generated using the rootNode attribute

<entrants>
  <pairName>
    Fred&Linda
  <entryNum>
    123
  </entryNum>
</entrants>

Overriding the binding's rootNode attribute setting

You can also set the rootNode attribute for each individual message, or override the global setting for a particular message, by using the xformat:body element inside of the message binding. For example, if you wanted the output message defined in Example 10.4, “XML Binding with rootNode set” to have a different root element from the input message, you could override the binding's root element as shown in Example 10.6, “Using xformat:body.

Example 10.6. Using xformat:body

<binding name="matildaXMLBinding" type="tns:dancingMatildas">
  <xmlformat:binding rootNode="entrants"/>
  <operation name="register">
    <input name="contestant"/>
    <output name="entered">
      <xformat:body rootNode="entryStatus" />
    </output>
  </operation>
</binding>

Part III. Web Services Transports

Abstract

This part describes how to add Apache CXF transports to a WSDL document.

Chapter 11. Understanding How Endpoints are Defined in WSDL

Abstract

Endpoints represent an instantiated service. They are defined by combining a binding and the networking details used to expose the endpoint.

Overview

An endpoint can be thought of as a physical manifestation of a service. It combines a binding, which specifies the physical representation of the logical data used by a service, and a set of networking details that define the physical connection details used to make the service contactable by other endpoints.

Endpoints and services

In the same way a binding can only map a single interface, an endpoint can only map to a single service. However, a service can be manifested by any number of endpoints. For example, you could define a ticket selling service that was manifested by four different endpoints. However, you could not have a single endpoint that manifested both a ticket selling service and a widget selling service.

The WSDL elements

Endpoints are defined in a contract using a combination of the WSDL service element and the WSDL port element. The service element is a collection of related port elements. The port elements define the actual endpoints.
The WSDL service element has a single attribute, name, that specifies a unique name. The service element is used as the parent element of a collection of related port elements. WSDL makes no specification about how the port elements are related. You can associate the port elements in any manner you see fit.
The WSDL port element has a single attribute, binding, that specifies the binding used by the endpoint. The port element is the parent element of the elements that specify the actual transport details used by the endpoint. The elements used to specify the transport details are discussed in the following sections.

Alternative HTTP runtimes

Apache CXF supports the following alternative HTTP runtime implementations:

Netty HTTP URL

Normally, a HTTP endpoint uses whichever HTTP runtime is included on the classpath (either Jetty or Netty). If both the Jetty runtime and Netty runtime are included on the classpath, however, you need to specify explicitly when you want to use the Netty runtime, because the Jetty runtime will be used by default.
In the case where more than one HTTP runtime is available on the classpath, you can select the Netty runtime by specifying the endpoint URL to have the following format:
netty://http://RestOfURL

Payload types

There are three ways of specifying an HTTP endpoint’s address depending on the payload format you are using.
  • SOAP 1.1 uses the standardized soap:address element.
  • SOAP 1.2 uses the soap12:address element.
  • All other payload formats use the http:address element.

SOAP 1.1

When you are sending SOAP 1.1 messages over HTTP you must use the SOAP 1.1 address element to specify the endpoint’s address. It has one attribute, location, that specifies the endpoint’s address as a URL. The SOAP 1.1 address element is defined in the namespace http://schemas.xmlsoap.org/wsdl/soap/.
Example 12.1, “SOAP 1.1 Port Element” shows a port element used to send SOAP 1.1 messages over HTTP.

Example 12.1. SOAP 1.1 Port Element

<definitions ...
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" ...>
  ...
  <service name="SOAP11Service">
    <port binding="SOAP11Binding" name="SOAP11Port">
      <soap:address location="http://artie.com/index.xml">
    </port>
  </service>
  ...
<definitions>

SOAP 1.2

When you are sending SOAP 1.2 messages over HTTP you must use the SOAP 1.2 address element to specify the endpoint’s address. It has one attribute, location, that specifies the endpoint’s address as a URL. The SOAP 1.2 address element is defined in the namespace http://schemas.xmlsoap.org/wsdl/soap12/.
Example 12.2, “SOAP 1.2 Port Element” shows a port element used to send SOAP 1.2 messages over HTTP.

Example 12.2. SOAP 1.2 Port Element

<definitions ...
             xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" ... >
  <service name="SOAP12Service">
    <port binding="SOAP12Binding" name="SOAP12Port">
      <soap12:address location="http://artie.com/index.xml">
    </port>
  </service>
  ...
</definitions>

Other messages types

When your messages are mapped to any payload format other than SOAP you must use the HTTP address element to specify the endpoint’s address. It has one attribute, location, that specifies the endpoint’s address as a URL. The HTTP address element is defined in the namespace http://schemas.xmlsoap.org/wsdl/http/.
Example 12.3, “HTTP Port Element” shows a port element used to send an XML message.

Example 12.3. HTTP Port Element

<definitions ...
             xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" ... >
  <service name="HTTPService">
    <port binding="HTTPBinding" name="HTTPPort">
      <http:address location="http://artie.com/index.xml">
    </port>
  </service>
  ...
</definitions>

2. Configuring a Consumer

HTTP consumer endpoints can specify a number of HTTP connection attributes including whether the endpoint automatically accepts redirect responses, whether the endpoint can use chunking, whether the endpoint will request a keep-alive, and how the endpoint interacts with proxies. In addition to the HTTP connection properties, an HTTP consumer endpoint can specify how it is secured.
A consumer endpoint can be configured using two mechanisms:

2.1. Using Configuration

Namespace

Example 12.4. HTTP Consumer Configuration Namespace

<beans ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       ...
       xsi:schemaLocation="...
                           http://cxf.apache.org/transports/http/configuration
                              http://cxf.apache.org/schemas/configuration/http-conf.xsd
                          ...">

Jetty runtime or Netty runtime

You can use the elements from the http-conf namespace to configure either the Jetty runtime or the Netty runtime.

The conduit element

You configure an HTTP consumer endpoint using the http-conf:conduit element and its children. The http-conf:conduit element takes a single attribute, name, that specifies the WSDL port element corresponding to the endpoint. The value for the name attribute takes the form portQName.http-conduit. Example 12.5, “http-conf:conduit Element” shows the http-conf:conduit element that would be used to add configuration for an endpoint that is specified by the WSDL fragment <port binding="widgetSOAPBinding" name="widgetSOAPPort> when the endpoint's target namespace is http://widgets.widgetvendor.net.

Example 12.5. http-conf:conduit Element

...
  <http-conf:conduit name="{http://widgets/widgetvendor.net}widgetSOAPPort.http-conduit">
    ...
  </http-conf:conduit>
...
The http-conf:conduit element has child elements that specify configuration information. They are described in Table 12.1, “Elements Used to Configure an HTTP Consumer Endpoint”.

Table 12.1. Elements Used to Configure an HTTP Consumer Endpoint

ElementDescription
http-conf:client
Specifies the HTTP connection properties such as timeouts, keep-alive requests, content types, etc. See the section called “The client element”.
http-conf:authorization
Specifies the parameters for configuring the basic authentication method that the endpoint uses preemptively.
The preferred approach is to supply a Basic Authentication Supplier object.
http-conf:proxyAuthorization
Specifies the parameters for configuring basic authentication against outgoing HTTP proxy servers.
http-conf:tlsClientParameters
Specifies the parameters used to configure SSL/TLS.
http-conf:basicAuthSupplier
Specifies the bean reference or class name of the object that supplies the basic authentication information used by the endpoint, either preemptively or in response to a 401 HTTP challenge.
http-conf:trustDecider
Specifies the bean reference or class name of the object that checks the HTTP(S) URLConnection object to establish trust for a connection with an HTTPS service provider before any information is transmitted.

The client element

Table 12.2. HTTP Consumer Configuration Attributes

AttributeDescription
ConnectionTimeout
Specifies the amount of time, in milliseconds, that the consumer attempts to establish a connection before it times out. The default is 30000.
0 specifies that the consumer will continue to send the request indefinitely.
ReceiveTimeout
Specifies the amount of time, in milliseconds, that the consumer will wait for a response before it times out. The default is 30000.
0 specifies that the consumer will wait indefinitely.
AutoRedirect
Specifies if the consumer will automatically follow a server issued redirection. The default is false.
MaxRetransmits
Specifies the maximum number of times a consumer will retransmit a request to satisfy a redirect. The default is -1 which specifies that unlimited retransmissions are allowed.
AllowChunking
Specifies whether the consumer will send requests using chunking. The default is true which specifies that the consumer will use chunking when sending requests.
Chunking cannot be used if either of the following are true:
  • http-conf:basicAuthSupplier is configured to provide credentials preemptively.
  • AutoRedirect is set to true.
In both cases the value of AllowChunking is ignored and chunking is disallowed.
Accept
Specifies what media types the consumer is prepared to handle. The value is used as the value of the HTTP Accept property. The value of the attribute is specified using multipurpose internet mail extensions (MIME) types.
AcceptLanguage
Specifies what language (for example, American English) the consumer prefers for the purpose of receiving a response. The value is used as the value of the HTTP AcceptLanguage property.
Language tags are regulated by the International Organization for Standards (ISO) and are typically formed by combining a language code, determined by the ISO-639 standard, and country code, determined by the ISO-3166 standard, separated by a hyphen. For example, en-US represents American English.
AcceptEncoding
Specifies what content encodings the consumer is prepared to handle. Content encoding labels are regulated by the Internet Assigned Numbers Authority (IANA). The value is used as the value of the HTTP AcceptEncoding property.
ContentType
Specifies the media type of the data being sent in the body of a message. Media types are specified using multipurpose internet mail extensions (MIME) types. The value is used as the value of the HTTP ContentType property. The default is text/xml.
For web services, this should be set to text/xml. If the client is sending HTML form data to a CGI script, this should be set to application/x-www-form-urlencoded. If the HTTP POST request is bound to a fixed payload format (as opposed to SOAP), the content type is typically set to application/octet-stream.
Host
Specifies the Internet host and port number of the resource on which the request is being invoked. The value is used as the value of the HTTP Host property.
This attribute is typically not required. It is only required by certain DNS scenarios or application designs. For example, it indicates what host the client prefers for clusters (that is, for virtual servers mapping to the same Internet protocol (IP) address).
Connection
Specifies whether a particular connection is to be kept open or closed after each request/response dialog. There are two valid values:
  • Keep-Alive — Specifies that the consumer wants the connection kept open after the initial request/response sequence. If the server honors it, the connection is kept open until the consumer closes it.
  • close(default) — Specifies that the connection to the server is closed after each request/response sequence.
CacheControl
Specifies directives about the behavior that must be adhered to by caches involved in the chain comprising a request from a consumer to a service provider. See Section 2.3, “Consumer Cache Control Directives”.
Cookie
Specifies a static cookie to be sent with all requests.
BrowserType
Specifies information about the browser from which the request originates. In the HTTP specification from the World Wide Web consortium (W3C) this is also known as the user-agent. Some servers optimize based on the client that is sending the request.
Referer
Specifies the URL of the resource that directed the consumer to make requests on a particular service. The value is used as the value of the HTTP Referer property.
This HTTP property is used when a request is the result of a browser user clicking on a hyperlink rather than typing a URL. This can allow the server to optimize processing based upon previous task flow, and to generate lists of back-links to resources for the purposes of logging, optimized caching, tracing of obsolete or mistyped links, and so on. However, it is typically not used in web services applications.
If the AutoRedirect attribute is set to true and the request is redirected, any value specified in the Referer attribute is overridden. The value of the HTTP Referer property is set to the URL of the service that redirected the consumer’s original request.
DecoupledEndpoint
Specifies the URL of a decoupled endpoint for the receipt of responses over a separate provider->consumer connection. For more information on using decoupled endpoints see, Section 6, “Using the HTTP Transport in Decoupled Mode”.
You must configure both the consumer endpoint and the service provider endpoint to use WS-Addressing for the decoupled endpoint to work.
ProxyServer
Specifies the URL of the proxy server through which requests are routed.
ProxyServerPort
Specifies the port number of the proxy server through which requests are routed.
ProxyServerType
Specifies the type of proxy server used to route requests. Valid values are:
  • HTTP(default)
  • SOCKS

Example

Example 12.6, “HTTP Consumer Endpoint Configuration” shows the configuration of an HTTP consumer endpoint that wants to keep its connection to the provider open between requests, that will only retransmit requests once per invocation, and that cannot use chunking streams.

Example 12.6. HTTP Consumer Endpoint Configuration

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration
                             http://cxf.apache.org/schemas/configuration/http-conf.xsd
                           http://www.springframework.org/schema/beans
                             http://www.springframework.org/schema/beans/spring-beans.xsd">
   
  <http-conf:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit">
    <http-conf:client Connection="Keep-Alive"
                      MaxRetransmits="1"
                      AllowChunking="false" />
  </http-conf:conduit>
</beans>

More information

For more information on HTTP conduits see Appendix B, Conduits.

2.2. Using WSDL

Namespace

The WSDL extension elements used to configure an HTTP consumer endpoint are defined in the namespace http://cxf.apache.org/transports/http/configuration. It is commonly referred to using the prefix http-conf. In order to use the HTTP configuration elements you must add the line shown in Example 12.7, “HTTP Consumer WSDL Element's Namespace” to the definitions element of your endpoint's WSDL document.

Example 12.7. HTTP Consumer WSDL Element's Namespace

<definitions ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"

Jetty runtime or Netty runtime

You can use the elements from the http-conf namespace to configure either the Jetty runtime or the Netty runtime.

The client element

The http-conf:client element is used to specify the connection properties of an HTTP consumer in a WSDL document. The http-conf:client element is a child of the WSDL port element. It has the same attributes as the client element used in the configuration file. The attributes are described in Table 12.2, “HTTP Consumer Configuration Attributes”.

Example

Example 12.8, “WSDL to Configure an HTTP Consumer Endpoint” shows a WSDL fragment that configures an HTTP consumer endpoint to specify that it does not interact with caches.

Example 12.8. WSDL to Configure an HTTP Consumer Endpoint

<service ... >
  <port ... >
    <soap:address ... />
    <http-conf:client CacheControl="no-cache" />
  </port>
</service>

2.3. Consumer Cache Control Directives

Table 12.3, “http-conf:client Cache Control Directives” lists the cache control directives supported by an HTTP consumer.

Table 12.3. http-conf:client Cache Control Directives

DirectiveBehavior
no-cache
Caches cannot use a particular response to satisfy subsequent requests without first revalidating that response with the server. If specific response header fields are specified with this value, the restriction applies only to those header fields within the response. If no response header fields are specified, the restriction applies to the entire response.
no-store
Caches must not store either any part of a response or any part of the request that invoked it.
max-age
The consumer can accept a response whose age is no greater than the specified time in seconds.
max-stale
The consumer can accept a response that has exceeded its expiration time. If a value is assigned to max-stale, it represents the number of seconds beyond the expiration time of a response up to which the consumer can still accept that response. If no value is assigned, the consumer can accept a stale response of any age.
min-fresh
The consumer wants a response that is still fresh for at least the specified number of seconds indicated.
no-transform
Caches must not modify media type or location of the content in a response between a provider and a consumer.
only-if-cached
Caches should return only responses that are currently stored in the cache, and not responses that need to be reloaded or revalidated.
cache-extension
Specifies additional extensions to the other cache directives. Extensions can be informational or behavioral. An extended directive is specified in the context of a standard directive, so that applications not understanding the extended directive can adhere to the behavior mandated by the standard directive.

3. Configuring a Service Provider

HTTP service provider endpoints can specify a number of HTTP connection attributes including if it will honor keep alive requests, how it interacts with caches, and how tolerant it is of errors in communicating with a consumer.
A service provider endpoint can be configured using two mechanisms:

3.1. Using Configuration

Namespace

Example 12.9. HTTP Provider Configuration Namespace

<beans ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       ...
       xsi:schemaLocation="...
                           http://cxf.apache.org/transports/http/configuration
                              http://cxf.apache.org/schemas/configuration/http-conf.xsd
                          ...">

Jetty runtime or Netty runtime

You can use the elements from the http-conf namespace to configure either the Jetty runtime or the Netty runtime.

The destination element

You configure an HTTP service provider endpoint using the http-conf:destination element and its children. The http-conf:destination element takes a single attribute, name, that specifies the WSDL port element that corresponds to the endpoint. The value for the name attribute takes the form portQName.http-destination. Example 12.10, “http-conf:destination Element” shows the http-conf:destination element that is used to add configuration for an endpoint that is specified by the WSDL fragment <port binding="widgetSOAPBinding" name="widgetSOAPPort> when the endpoint's target namespace is http://widgets.widgetvendor.net.

Example 12.10. http-conf:destination Element

...
  <http-conf:destination name="{http://widgets/widgetvendor.net}widgetSOAPPort.http-destination">
    ...
  </http-conf:destination>
...
The http-conf:destination element has a number of child elements that specify configuration information. They are described in Table 12.4, “Elements Used to Configure an HTTP Service Provider Endpoint”.

Table 12.4. Elements Used to Configure an HTTP Service Provider Endpoint

ElementDescription
http-conf:server
Specifies the HTTP connection properties. See the section called “The server element”.
http-conf:contextMatchStrategy
Specifies the parameters that configure the context match strategy for processing HTTP requests.
http-conf:fixedParameterOrder
Specifies whether the parameter order of an HTTP request handled by this destination is fixed.

The server element

Table 12.5. HTTP Service Provider Configuration Attributes

AttributeDescription
ReceiveTimeout
Sets the length of time, in milliseconds, the service provider attempts to receive a request before the connection times out. The default is 30000.
0 specifies that the provider will not timeout.
SuppressClientSendErrors
Specifies whether exceptions are to be thrown when an error is encountered on receiving a request. The default is false; exceptions are thrown on encountering errors.
SuppressClientReceiveErrors
Specifies whether exceptions are to be thrown when an error is encountered on sending a response to a consumer. The default is false; exceptions are thrown on encountering errors.
HonorKeepAlive
Specifies whether the service provider honors requests for a connection to remain open after a response has been sent. The default is false; keep-alive requests are ignored.
RedirectURL
Specifies the URL to which the client request should be redirected if the URL specified in the client request is no longer appropriate for the requested resource. In this case, if a status code is not automatically set in the first line of the server response, the status code is set to 302 and the status description is set to Object Moved. The value is used as the value of the HTTP RedirectURL property.
CacheControl
Specifies directives about the behavior that must be adhered to by caches involved in the chain comprising a response from a service provider to a consumer. See Section 3.3, “Service Provider Cache Control Directives”.
ContentLocation
Sets the URL where the resource being sent in a response is located.
ContentType
Specifies the media type of the information being sent in a response. Media types are specified using multipurpose internet mail extensions (MIME) types. The value is used as the value of the HTTP ContentType location.
ContentEncoding
Specifies any additional content encodings that have been applied to the information being sent by the service provider. Content encoding labels are regulated by the Internet Assigned Numbers Authority (IANA). Possible content encoding values include zip, gzip, compress, deflate, and identity. This value is used as the value of the HTTP ContentEncoding property.
The primary use of content encodings is to allow documents to be compressed using some encoding mechanism, such as zip or gzip. Apache CXF performs no validation on content codings. It is the user’s responsibility to ensure that a specified content coding is supported at application level.
ServerType
Specifies what type of server is sending the response. Values take the form program-name/version; for example, Apache/1.2.5.

Example

Example 12.11, “HTTP Service Provider Endpoint Configuration” shows the configuration for an HTTP service provider endpoint that honors keep-alive requests and suppresses all communication errors.

Example 12.11. HTTP Service Provider Endpoint Configuration

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration
                             http://cxf.apache.org/schemas/configuration/http-conf.xsd
                           http://www.springframework.org/schema/beans
                             http://www.springframework.org/schema/beans/spring-beans.xsd">
   
  <http-conf:destination name="{http://apache.org/hello_world_soap_http}SoapPort.http-destination">
    <http-conf:server SuppressClientSendErrors="true"
                      SuppressClientReceiveErrors="true"
                      HonorKeepAlive="true" />
  </http-conf:destination>
</beans>

3.2. Using WSDL

Namespace

The WSDL extension elements used to configure an HTTP provider endpoint are defined in the namespace http://cxf.apache.org/transports/http/configuration. It is commonly referred to using the prefix http-conf. To use the HTTP configuration elements you must add the line shown in Example 12.12, “HTTP Provider WSDL Element's Namespace” to the definitions element of your endpoint's WSDL document.

Example 12.12. HTTP Provider WSDL Element's Namespace

<definitions ...
       xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"

Jetty runtime or Netty runtime

You can use the elements from the http-conf namespace to configure either the Jetty runtime or the Netty runtime.

The server element

The http-conf:server element is used to specify the connection properties of an HTTP service provider in a WSDL document. The http-conf:server element is a child of the WSDL port element. It has the same attributes as the server element used in the configuration file. The attributes are described in Table 12.5, “HTTP Service Provider Configuration Attributes”.

Example

Example 12.13, “WSDL to Configure an HTTP Service Provider Endpoint” shows a WSDL fragment that configures an HTTP service provider endpoint specifying that it will not interact with caches.

Example 12.13. WSDL to Configure an HTTP Service Provider Endpoint

<service ... >
  <port ... >
    <soap:address ... />
    <http-conf:server CacheControl="no-cache" />
  </port>
</service>

3.3. Service Provider Cache Control Directives

Table 12.6, “http-conf:server Cache Control Directives” lists the cache control directives supported by an HTTP service provider.

Table 12.6. http-conf:server Cache Control Directives

DirectiveBehavior
no-cache
Caches cannot use a particular response to satisfy subsequent requests without first revalidating that response with the server. If specific response header fields are specified with this value, the restriction applies only to those header fields within the response. If no response header fields are specified, the restriction applies to the entire response.
public
Any cache can store the response.
private
Public (shared) caches cannot store the response because the response is intended for a single user. If specific response header fields are specified with this value, the restriction applies only to those header fields within the response. If no response header fields are specified, the restriction applies to the entire response.
no-store
Caches must not store any part of the response or any part of the request that invoked it.
no-transform
Caches must not modify the media type or location of the content in a response between a server and a client.
must-revalidate
Caches must revalidate expired entries that relate to a response before that entry can be used in a subsequent response.
proxy-revalidate
Does the same as must-revalidate, except that it can only be enforced on shared caches and is ignored by private unshared caches. When using this directive, the public cache directive must also be used.
max-age
Clients can accept a response whose age is no greater that the specified number of seconds.
s-max-age
Does the same as max-age, except that it can only be enforced on shared caches and is ignored by private unshared caches. The age specified by s-max-age overrides the age specified by max-age. When using this directive, the proxy-revalidate directive must also be used.
cache-extension
Specifies additional extensions to the other cache directives. Extensions can be informational or behavioral. An extended directive is specified in the context of a standard directive, so that applications not understanding the extended directive can adhere to the behavior mandated by the standard directive.

4. Configuring the Jetty Runtime

Overview

The Jetty runtime is used by HTTP service providers and HTTP consumers using a decoupled endpoint. The runtime's thread pool can be configured, and you can also set a number of the security settings for an HTTP service provider through the Jetty runtime.

Maven dependency

If you use Apache Maven as your build system, you can add the Jetty runtime to your project by including the following dependency in your project's pom.xml file:
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-jetty</artifactId>
    <version>${cxf-version}</version>
</dependency>

Namespace

The elements used to configure the Jetty runtime are defined in the namespace http://cxf.apache.org/transports/http-jetty/configuration. It is commonly referred to using the prefix httpj. In order to use the Jetty configuration elements you must add the lines shown in Example 12.14, “Jetty Runtime Configuration Namespace” to the beans element of your endpoint's configuration file. In addition, you must add the configuration elements' namespace to the xsi:schemaLocation attribute.

Example 12.14. Jetty Runtime Configuration Namespace

<beans ...
       xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
       ...
       xsi:schemaLocation="...
                           http://cxf.apache.org/transports/http-jetty/configuration
                              http://cxf.apache.org/schemas/configuration/http-jetty.xsd
                          ...">

The engine-factory element

The httpj:engine-factory element is the root element used to configure the Jetty runtime used by an application. It has a single required attribute, bus, whose value is the name of the Bus that manages the Jetty instances being configured.
Tip
The value is typically cxf which is the name of the default Bus instance.

Table 12.7. Elements for Configuring a Jetty Runtime Factory

ElementDescription
httpj:engine
Specifies the configuration for a particular Jetty runtime instance. See the section called “The engine element”.
httpj:identifiedTLSServerParameters
Specifies a reusable set of properties for securing an HTTP service provider. It has a single attribute, id, that specifies a unique identifier by which the property set can be referred.
httpj:identifiedThreadingParameters
Specifies a reusable set of properties for controlling a Jetty instance's thread pool. It has a single attribute, id, that specifies a unique identifier by which the property set can be referred.

The engine element

The httpj:engine element is used to configure specific instances of the Jetty runtime. It has a single attribute, port, that specifies the number of the port being managed by the Jetty instance.
Tip
You can specify a value of 0 for the port attribute. Any threading properties specified in an httpj:engine element with its port attribute set to 0 are used as the configuration for all Jetty listeners that are not explicitly configured.
Each httpj:engine element can have two children: one for configuring security properties and one for configuring the Jetty instance's thread pool. For each type of configuration you can either directly provide the configuration information or you can provide a reference to a set of configuration properties defined in the parent httpj:engine-factory element.

Table 12.8. Elements for Configuring a Jetty Runtime Instance

ElementDescription
httpj:tlsServerParameters
Specifies a set of properties for configuring the security used for the specific Jetty instance.
httpj:tlsServerParametersRef
Refers to a set of security properties defined by a identifiedTLSServerParameters element. The id attribute provides the id of the referred identifiedTLSServerParameters element.
httpj:threadingParameters
Specifies the size of the thread pool used by the specific Jetty instance. See the section called “Configuring the thread pool”.
httpj:threadingParametersRef
Refers to a set of properties defined by a identifiedThreadingParameters element. The id attribute provides the id of the referred identifiedThreadingParameters element.

Configuring the thread pool

You can configure the size of a Jetty instance's thread pool by either:
  • Specifying the size of the thread pool using a identifiedThreadingParameters element in the engine-factory element. You then refer to the element using a threadingParametersRef element.
  • Specifying the size of the of the thread pool directly using a threadingParameters element.
Note
The httpj:identifiedThreadingParameters element has a single child threadingParameters element.

Table 12.9. Attributes for Configuring a Jetty Thread Pool

AttributeDescription
minThreads
Specifies the minimum number of threads available to the Jetty instance for processing requests.
maxThreads
Specifies the maximum number of threads available to the Jetty instance for processing requests.

Example

Example 12.15, “Configuring a Jetty Instance” shows a configuration fragment that configures a Jetty instance on port number 9001.

Example 12.15. Configuring a Jetty Instance

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:sec="http://cxf.apache.org/configuration/security"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
  xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
  xsi:schemaLocation="http://cxf.apache.org/configuration/security
  		      http://cxf.apache.org/schemas/configuration/security.xsd
            http://cxf.apache.org/transports/http/configuration
            http://cxf.apache.org/schemas/configuration/http-conf.xsd
            http://cxf.apache.org/transports/http-jetty/configuration
            http://cxf.apache.org/schemas/configuration/http-jetty.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  ...

  <httpj:engine-factory bus="cxf">
    <httpj:identifiedTLSServerParameters id="secure">
      <sec:keyManagers keyPassword="password">
        <sec:keyStore type="JKS" password="password" 
                      file="certs/cherry.jks"/>
      </sec:keyManagers>
    </httpj:identifiedTLSServerParameters>

    <httpj:engine port="9001">
      <httpj:tlsServerParametersRef id="secure" />
      <httpj:threadingParameters minThreads="5"
                                 maxThreads="15" />
    </httpj:engine>
  </httpj:engine-factory>
 </beans>

5. Configuring the Netty Runtime

Overview

The Netty runtime is used by HTTP service providers and HTTP consumers using a decoupled endpoint. The runtime's thread pool can be configured, and you can also set a number of the security settings for an HTTP service provider through the Netty runtime.

Maven dependencies

If you use Apache Maven as your build system, you can add the server-side implementation of the Netty runtime (for defining Web service endpoints) to your project by including the following dependency in your project's pom.xml file:
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-netty-server</artifactId>
    <version>${cxf-version}</version>
</dependency>
You can add the client-side implementation of the Netty runtime (for defining Web service clients) to your project by including the following dependency in your project's pom.xml file:
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-netty-client</artifactId>
    <version>${cxf-version}</version>
</dependency>

Namespace

The elements used to configure the Netty runtime are defined in the namespace http://cxf.apache.org/transports/http-netty-server/configuration. It is commonly referred to using the prefix httpn. In order to use the Netty configuration elements you must add the lines shown in Example 12.16, “Netty Runtime Configuration Namespace” to the beans element of your endpoint's configuration file. In addition, you must add the configuration elements' namespace to the xsi:schemaLocation attribute.

Example 12.16. Netty Runtime Configuration Namespace

<beans ...
       xmlns:httpn="http://cxf.apache.org/transports/http-netty-server/configuration"
       ...
       xsi:schemaLocation="...
               http://cxf.apache.org/transports/http-netty-server/configuration 
            http://cxf.apache.org/schemas/configuration/http-netty-server.xsd
               ...">

The engine-factory element

The httpn:engine-factory element is the root element used to configure the Netty runtime used by an application. It has a single required attribute, bus, whose value is the name of the Bus that manages the Netty instances being configured.
Tip
The value is typically cxf, which is the name of the default Bus instance.

Table 12.10. Elements for Configuring a Netty Runtime Factory

ElementDescription
httpn:engine
Specifies the configuration for a particular Netty runtime instance. See the section called “The engine element”.
httpn:identifiedTLSServerParameters
Specifies a reusable set of properties for securing an HTTP service provider. It has a single attribute, id, that specifies a unique identifier by which the property set can be referred.
httpn:identifiedThreadingParameters
Specifies a reusable set of properties for controlling a Netty instance's thread pool. It has a single attribute, id, that specifies a unique identifier by which the property set can be referred.

The engine element

Table 12.11. Attributes for Configuring a Netty Runtime Instance

AttributeDescription
portSpecifies the port used by the Netty HTTP server instance. You can specify a value of 0 for the port attribute. Any threading properties specified in an engine element with its port attribute set to 0 are used as the configuration for all Netty listeners that are not explicitly configured.
hostSpecifies the listen address used by the Netty HTTP server instance. The value can be a hostname or an IP address. If not specified, Netty HTTP server will listen on all local addresses.
readIdleTimeSpecifies the maximum read idle time for a Netty connection. The timer is reset whenever there are any read actions on the underlying stream.
writeIdleTimeSpecifies the maximum write idle time for a Netty connection. The timer is reset whenever there are any write actions on the underlying stream.
maxChunkContentSizeSpecifies the maximum aggregated content size for a Netty connection. The default value is 10MB.
A httpn:engine element has one child element for configuring security properties and one child element for configuring the Netty instance's thread pool. For each type of configuration you can either directly provide the configuration information or you can provide a reference to a set of configuration properties defined in the parent httpn:engine-factory element.
The supported child elements of httpn:engine are shown in Table 12.12, “Elements for Configuring a Netty Runtime Instance”.

Table 12.12. Elements for Configuring a Netty Runtime Instance

ElementDescription
httpn:tlsServerParameters
Specifies a set of properties for configuring the security used for the specific Netty instance.
httpn:tlsServerParametersRef
Refers to a set of security properties defined by a identifiedTLSServerParameters element. The id attribute provides the id of the referred identifiedTLSServerParameters element.
httpn:threadingParameters
Specifies the size of the thread pool used by the specific Netty instance. See the section called “Configuring the thread pool”.
httpn:threadingParametersRef
Refers to a set of properties defined by a identifiedThreadingParameters element. The id attribute provides the id of the referred identifiedThreadingParameters element.
httpn:sessionSupportWhen true, enables support for HTTP sessions. Default is false.
httpn:reuseAddressSpecifies a boolean value to set the ReuseAddress TCP socket option. Default is false.

Configuring the thread pool

You can configure the size of a Netty instance's thread pool by either:
  • Specifying the size of the thread pool using a identifiedThreadingParameters element in the engine-factory element. You then refer to the element using a threadingParametersRef element.
  • Specifying the size of the of the thread pool directly using a threadingParameters element.
Note
The httpn:identifiedThreadingParameters element has a single child threadingParameters element.

Table 12.13. Attributes for Configuring a Netty Thread Pool

AttributeDescription
threadPoolSize
Specifies the number of threads available to the Netty instance for processing requests.

Example

Example 12.17, “Configuring a Netty Instance” shows a configuration fragment that configures a variety of Netty ports.

Example 12.17. Configuring a Netty Instance

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:beans="http://www.springframework.org/schema/beans"    
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:h="http://cxf.apache.org/transports/http/configuration"
       xmlns:httpn="http://cxf.apache.org/transports/http-netty-server/configuration"
       xmlns:sec="http://cxf.apache.org/configuration/security"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/configuration/security 
            http://cxf.apache.org/schemas/configuration/security.xsd
        http://cxf.apache.org/transports/http/configuration 
            http://cxf.apache.org/schemas/configuration/http-conf.xsd
        http://cxf.apache.org/transports/http-netty-server/configuration 
            http://cxf.apache.org/schemas/configuration/http-netty-server.xsd"
>
    ...
    <httpn:engine-factory bus="cxf">
       <httpn:identifiedTLSServerParameters id="sample1">
         <httpn:tlsServerParameters jsseProvider="SUN" secureSocketProtocol="TLS">
            <sec:clientAuthentication want="false" required="false"/>
         </httpn:tlsServerParameters>
       </httpn:identifiedTLSServerParameters>
       
       <httpn:identifiedThreadingParameters id="sampleThreading1">
          <httpn:threadingParameters threadPoolSize="120"/>
       </httpn:identifiedThreadingParameters>
       
       <httpn:engine port="9000" readIdleTime="30000" writeIdleTime="90000">
          <httpn:threadingParametersRef id="sampleThreading1"/>          
       </httpn:engine>
       
       <httpn:engine port="0">
          <httpn:threadingParameters threadPoolSize="400"/>
       </httpn:engine>
       
       <httpn:engine port="9001" readIdleTime="40000" maxChunkContentSize="10000">
         <httpn:threadingParameters threadPoolSize="99" />          
         <httpn:sessionSupport>true</httpn:sessionSupport>
       </httpn:engine> 
      
       <httpn:engine port="9002">
         <httpn:tlsServerParameters>
           <sec:clientAuthentication want="true" required="true"/>
         </httpn:tlsServerParameters>
       </httpn:engine>
      
       <httpn:engine port="9003">
          <httpn:tlsServerParametersRef id="sample1"/>
       </httpn:engine>
      
    </httpn:engine-factory>
</beans>

6. Using the HTTP Transport in Decoupled Mode

Overview

In normal HTTP request/response scenarios, the request and the response are sent using the same HTTP connection. The service provider processes the request and responds with a response containing the appropriate HTTP status code and the contents of the response. In the case of a successful request, the HTTP status code is set to 200.
In some instances, such as when using WS-RM or when requests take an extended period of time to execute, it makes sense to decouple the request and response message. In this case the service providers sends the consumer a 202 Accepted response to the consumer over the back-channel of the HTTP connection on which the request was received. It then processes the request and sends the response back to the consumer using a new decoupled server->client HTTP connection. The consumer runtime receives the incoming response and correlates it with the appropriate request before returning to the application code.

Configuring decoupled interactions

Using the HTTP transport in decoupled mode requires that you do the following:
  1. Configure the consumer to use WS-Addressing.
  2. Configure the consumer to use a decoupled endpoint.
  3. Configure any service providers that the consumer interacts with to use WS-Addressing.

Configuring an endpoint to use WS-Addressing

Specify that the consumer and any service provider with which the consumer interacts use WS-Addressing.
You can specify that an endpoint uses WS-Addressing in one of two ways:
  • Example 12.18. Activating WS-Addressing using WSDL

    ...
    <service name="WidgetSOAPService">
      <port name="WidgetSOAPPort" binding="tns:WidgetSOAPBinding">
        <soap:address="http://widgetvendor.net/widgetSeller" />
        <wswa:UsingAddressing xmlns:wswa="http://www.w3.org/2005/02/addressing/wsdl"/>
      </port>
    </service>
    ...
  • Adding the WS-Addressing policy to the endpoint's WSDL port element as shown in Example 12.19, “Activating WS-Addressing using a Policy”.

    Example 12.19. Activating WS-Addressing using a Policy

    ...
    <service name="WidgetSOAPService">
      <port name="WidgetSOAPPort" binding="tns:WidgetSOAPBinding">
        <soap:address="http://widgetvendor.net/widgetSeller" />
        <wsp:Policy xmlns:wsp="http://www.w3.org/2006/07/ws-policy">
          <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
            <wsp:Policy/>
          </wsam:Addressing>
        </wsp:Policy>
      </port>
    </service>
    ...
Note
The WS-Addressing policy supersedes the wswa:UsingAddressing WSDL element.

Configuring the consumer

Configure the consumer endpoint to use a decoupled endpoint using the DecoupledEndpoint attribute of the http-conf:conduit element.
Example 12.20, “Configuring a Consumer to Use a Decoupled HTTP Endpoint” shows the configuration for setting up the endpoint defined in Example 12.18, “Activating WS-Addressing using WSDL” to use use a decoupled endpoint. The consumer now receives all responses at http://widgetvendor.net/widgetSellerInbox.

Example 12.20. Configuring a Consumer to Use a Decoupled HTTP Endpoint

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="http://cxf.apache.org/transports/http/configuration
                             http://cxf.apache.org/schemas/configuration/http-conf.xsd
                           http://www.springframework.org/schema/beans
                             http://www.springframework.org/schema/beans/spring-beans.xsd">
  
  <http:conduit name="{http://widgetvendor.net/services}WidgetSOAPPort.http-conduit">
    <http:client DecoupledEndpoint="http://widgetvendor.net:9999/decoupled_endpoint" />
  </http:conduit>
</beans>

How messages are processed

Using the HTTP transport in decoupled mode adds extra layers of complexity to the processing of HTTP messages. While the added complexity is transparent to the implementation level code in an application, it might be important to understand what happens for debugging reasons.
Figure 12.1, “Message Flow in for a Decoupled HTTP Transport” shows the flow of messages when using HTTP in decoupled mode.

Figure 12.1. Message Flow in for a Decoupled HTTP Transport

There are fifteen steps in a decoupled message exchange.
A request starts the following process:
  1. The consumer implementation invokes an operation and a request message is generated.
  2. The WS-Addressing layer adds the WS-A headers to the message.
    When a decoupled endpoint is specified in the consumer's configuration, the address of the decoupled endpoint is placed in the WS-A ReplyTo header.
  3. The message is sent to the service provider.
  4. The service provider receives the message.
  5. The request message from the consumer is dispatched to the provider's WS-A layer.
  6. Because the WS-A ReplyTo header is not set to anonymous, the provider sends back a message with the HTTP status code set to 202, acknowledging that the request has been received.
  7. The HTTP layer sends a 202 Accepted message back to the consumer using the original connection's back-channel.
  8. The consumer receives the 202 Accepted reply on the back-channel of the HTTP connection used to send the original message.
    When the consumer receives the 202 Accepted reply, the HTTP connection closes.
  9. The request is passed to the service provider's implementation where the request is processed.
  10. When the response is ready, it is dispatched to the WS-A layer.
  11. The WS-A layer adds the WS-Addressing headers to the response message.
  12. The HTTP transport sends the response to the consumer's decoupled endpoint.
  13. The consumer's decoupled endpoint receives the response from the service provider.
  14. The response is dispatched to the consumer's WS-A layer where it is correlated to the proper request using the WS-A RelatesTo header.
  15. The correlated response is returned to the client implementation and the invoking call is unblocked.

Chapter 13. Using SOAP Over JMS

Abstract

Apache CXF implements the W3C standard SOAP/JMS transport. This standard is intended to provide a more robust alternative to SOAP/HTTP services. Apache CXF applications using this transport should be able to interoperate with applications that also implement the SOAP/JMS standard. The transport is configured directly in an endpoint's WSDL.

1. Basic configuration

Overview

The SOAP over JMS protocol is defined by the World Wide Web Consortium(W3C) as a way of providing a more reliable transport layer to the customary SOAP/HTTP protocol used by most services. The Apache CXF implementation is fully compliant with the specification and should be compatible with any framework that is also compliant.
This transport uses JNDI to find the JMS destinations. When an operation is invoked, the request is packaged as a SOAP message and sent in the body of a JMS message to the specified destination.
To use the SOAP/JMS transport:
  1. Specify that the transport type is SOAP/JMS.
  2. Specify the target destination using a JMS URI.
  3. Optionally, configure the JNDI connection.
  4. Optionally, add additional JMS configuration.

Specifying the JMS transport type

You configure a SOAP binding to use the JMS transport when specifying the WSDL binding. You set the soap:binding element's transport attribute to http://www.w3.org/2010/soapjms/. Example 13.1, “SOAP over JMS binding specification” shows a WSDL binding that uses SOAP/JMS.

Example 13.1. SOAP over JMS binding specification

<wsdl:binding ... >
  <soap:binding style="document"
                transport="http://www.w3.org/2010/soapjms/" />
  ...
</wsdl:binding>

Specifying the target destination

You specify the address of the JMS target destination when specifying the WSDL port for the endpoint. The address specification for a SOAP/JMS endpoint uses the same soap:address element and attribute as a SOAP/HTTP endpoint. The difference is the address specification. JMS endpoints use a JMS URI as defined in the URI Scheme for JMS 1.0. Example 13.2, “JMS URI syntax” shows the syntax for a JMS URI.

Example 13.2. JMS URI syntax

jms:variant:destination?options
Table 13.1, “JMS URI variants” describes the available variants for the JMS URI.

Table 13.1. JMS URI variants

VariantDescription
jndiSpecifies that the destination is a JNDI name for the target destination. When using this variant, you must provide the configuration for accessing the JNDI provider.
topicSpecifies that the destination is the name of the topic to be used as the target destination. The string provided is passed into Session.createTopic() to create a representation of the destination.
queueSpecifies that the destination is the name of the queue to be used as the target destination. The string provided is passed into Session.createQueue() to create a representation of the destination.
The options portion of a JMS URI are used to configure the transport and are discussed in Section 2, “JMS URIs”.
Example 13.3, “SOAP/JMS endpoint address” shows the WSDL port entry for a SOAP/JMS endpoint whose target destination is looked up using JNDI.

Example 13.3. SOAP/JMS endpoint address

<wsdl:port ... >
  ...
  <soap:address location="jms:jndi:dynamicQueues/test.cxf.jmstransport.queue" />
</wsdl:port>
For working with SOAP/JMS services in Java see Chapter 39, Using SOAP over JMS.

Configuring JNDI and the JMS transport

The SOAP/JMS provides several ways to configure the JNDI connection and the JMS transport:

2. JMS URIs

Overview

When using SOAP/JMS, a JMS URI is used to specify the endpoint's target destination. The JMS URI can also be used to configure JMS connection by appending one or more options to the URI. These options are detailed in the IETF standard, URI Scheme for Java Message Service 1.0. They can be used to configure the JNDI system, the reply destination, the delivery mode to use, and other JMS properties.

Syntax

As shown in Example 13.2, “JMS URI syntax”, you can append one or more options to the end of a JMS URI by separating them from the destination's address with a question mark(?). Multiple options are separated by an ampersand(&). Example 13.4, “Syntax for JMS URI options” shows the syntax for using multiple options in a JMS URI.

Example 13.4. Syntax for JMS URI options

jmsAddress?option1=value1&option2=value2&...optionN=valueN

JMS properties

Table 13.2, “JMS properties settable as URI options” shows the URI options that affect the JMS transport layer.

Table 13.2. JMS properties settable as URI options

PropertyDefaultDescription
deliveryModePERSISTENTSpecifies whether to use JMS PERSISTENT or NON_PERSISTENT message semantics. In the case of PERSISTENT delivery mode, the JMS broker stores messages in persistent storage before acknowledging them; whereas NON_PERSISTENT messages are kept in memory only.
replyToName 
Explicitly specifies the reply destination to appear in the JMSReplyTo header. Setting this property is recommended for applications that have request-reply semantics because the JMS provider will assign a temporary reply queue if one is not explicitly set.
The value of this property has an interpretation that depends on the variant specified in the JMS URI:
  • jndi variant—the JNDI name of the destination
  • queue or topic variants—the actual name of the destination
priority4Specifies the JMS message priority, which ranges from 0 (lowest) to 9 (highest).
timeToLive0Time (in milliseconds) after which the message will be discarded by the JMS provider. A value of 0 represents an infinite lifetime (the default).

JNDI properties

Table 13.3, “JNDI properties settable as URI options” shows the URI options that can be used to configure JNDI for this endpoint.

Table 13.3. JNDI properties settable as URI options

PropertyDescription
jndiConnectionFactoryNameSpecifies the JNDI name of the JMS connection factory.
jndiInitialContextFactorySpecifies the fully qualified Java class name of the JNDI provider (which must be of javax.jms.InitialContextFactory type). Equivalent to setting the java.naming.factory.initial Java system property.
jndiURLSpecifies the URL that initializes the JNDI provider. Equivalent to setting the java.naming.provider.url Java system property.

Additional JNDI properties

The properties, java.naming.factory.initial and java.naming.provider.url, are standard properties, which are required to initialize any JNDI provider. Sometimes, however, a JNDI provider might support custom properties in addition to the standard ones. In this case, you can set an arbitrary JNDI property by setting a URI option of the form jndi-PropertyName.
For example, if you were using SUN's LDAP implementation of JNDI, you could set the JNDI property, java.naming.factory.control, in a JMS URI as shown in Example 13.5, “Setting a JNDI property in a JMS URI”.

Example 13.5. Setting a JNDI property in a JMS URI

jms:queue:FOO.BAR?jndi-java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory

Example

If the JMS provider is not already configured, it is possible to provide the requisite JNDI configuration details in the URI using options (see Table 13.3, “JNDI properties settable as URI options”). For example, to configure an endpoint to use the Apache ActiveMQ JMS provider and connect to the queue called test.cxf.jmstransport.queue, use the URI shown in Example 13.6, “JMS URI that configures a JNDI connection”.

Example 13.6. JMS URI that configures a JNDI connection

jms:jndi:dynamicQueues/test.cxf.jmstransport.queue
?jndiInitialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory
&jndiConnectionFactoryName=ConnectionFactory
&jndiURL=tcp://localhost:61616

3. WSDL extensions

Overview

You can specify the basic configuration of the JMS transport by inserting WSDL extension elements into the contract, either at binding scope, service scope, or port scope. The WSDL extensions enable you to specify the properties for bootstrapping a JNDI InitialContext, which can then be used to look up JMS destinations. You can also set some properties that affect the behavior of the JMS transport layer.

SOAP/JMS namespace

the SOAP/JMS WSDL extensions are defined in the http://www.w3.org/2010/soapjms/ namespace. To use them in your WSDL contracts add the following setting to the wsdl:definitions element:
<wsdl:definitions ...
    xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  ... >

WSDL extension elements

Table 13.4, “SOAP/JMS WSDL extension elements” shows all of the WSDL extension elements you can use to configure the JMS transport.

Table 13.4. SOAP/JMS WSDL extension elements

ElementDefaultDescription
soapjms:jndiInitialContextFactory Specifies the fully qualified Java class name of the JNDI provider. Equivalent to setting the java.naming.factory.initial Java system property.
soapjms:jndiURL Specifies the URL that initializes the JNDI provider. Equivalent to setting the java.naming.provider.url Java system property.
soapjms:jndiContextParameter Enables you to specify an additional property for creating the JNDI InitialContext. Use the name and value attributes to specify the property.
soapjms:jndiConnectionFactoryName Specifies the JNDI name of the JMS connection factory.
soapjms:deliveryModePERSISTENTSpecifies whether to use JMS PERSISTENT or NON_PERSISTENT message semantics. In the case of PERSISTENT delivery mode, the JMS broker stores messages in persistent storage before acknowledging them; whereas NON_PERSISTENT messages are kept in memory only.
soapjms:replyToName 
Explicitly specifies the reply destination to appear in the JMSReplyTo header. Setting this property is recommended for SOAP invocations that have request-reply semantics. If this property is not set the JMS provider allocates a temporary queue with an automatically generated name.
The value of this property has an interpretation that depends on the variant specified in the JMS URI, as follows:
  • jndi variant—the JNDI name of the destination.
  • queue or topic variants—the actual name of the destination.
soapjms:priority4Specifies the JMS message priority, which ranges from 0 (lowest) to 9 (highest).
soapjms:timeToLive0Time, in milliseconds, after which the message will be discarded by the JMS provider. A value of 0 represents an infinite lifetime.

Configuration scopes

The WSDL elements placement in the WSDL contract effect the scope of the configuration changes on the endpoints defined in the contract. The SOAP/JMS WSDL elements can be placed as children of either the wsdl:binding element, the wsdl:service element, or the wsdl:port element. The parent of the SOAP/JMS elements determine which of the following scopes the configuration is placed into.
Binding scope
You can configure the JMS transport at the binding scope by placing extension elements inside the wsdl:binding element. Elements in this scope define the default configuration for all endpoints that use this binding. Any settings in the binding scope can be overridden at the service scope or the port scope.
Service scope
You can configure the JMS transport at the service scope by placing extension elements inside a wsdl:service element. Elements in this scope define the default configuration for all endpoints in this service. Any settings in the service scope can be overridden at the port scope.
Port scope
You can configure the JMS transport at the port scope by placing extension elements inside a wsdl:port element. Elements in the port scope define the configuration for this port. They override any defaults defined at the service scope or at the binding scope.

Example

Example 13.7, “WSDL contract with SOAP/JMS configuration” shows a WSDL contract for a SOAP/JMS service. It configures the JNDI layer in the binding scope, the message delivery details in the service scope, and the reply destination in the port scope.

Example 13.7. WSDL contract with SOAP/JMS configuration

<wsd;definitions ...
1    xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  ... >
  ...
  <wsdl:binding name="JMSGreeterPortBinding" type="tns:JMSGreeterPortType">
    ...
2    <soapjms:jndiInitialContextFactory>
      org.apache.activemq.jndi.ActiveMQInitialContextFactory
    </soapjms:jndiInitialContextFactory>
    <soapjms:jndiURL>tcp://localhost:61616</soapjms:jndiURL>
    <soapjms:jndiConnectionFactoryName>
      ConnectionFactory
    </soapjms:jndiConnectionFactoryName>
    ...
  </wsdl:binding>
  ...
  <wsdl:service name="JMSGreeterService">
    ...
3    <soapjms:deliveryMode>NON_PERSISTENT</soapjms:deliveryMode>
    <soapjms:timeToLive>60000</soapjms:timeToLive>
    ...
    <wsdl:port binding="tns:JMSGreeterPortBinding" name="GreeterPort">
4      <soap:address location="jms:jndi:dynamicQueues/test.cxf.jmstransport.queue" />
5      <soapjms:replyToName>
        dynamicQueues/greeterReply.queue
      </soapjms:replyToName>
      ...
    </wsdl:port>
    ...
  </wsdl:service>
  ...
</wsdl:definitions>
1
Declare the namespace for the SOAP/JMS extensions.
2
Configure the JNDI connections in the binding scope.
3
Configure the JMS delivery style to non-persistent and each message to live for one minute.
4
Specify the target destination.
5
Configure the JMS transport so that reply messages are delivered on the greeterReply.queue queue.

Chapter 14. Using Generic JMS

Abstract

Apache CXF provides a generic implementation of a JMS transport. The generic JMS transport is not restricted to using SOAP messages and allows for connecting to any application that uses JMS.
The Apache CXF generic JMS transport can connect to any JMS provider and work with applications that exchange JMS messages with bodies of either TextMessage or ByteMessage.
There are two ways to enable and configure the JMS transport:

1. Using the JMS configuration bean

Overview

To simplify JMS configuration and make it more powerful, Apache CXF uses a single JMS configuration bean to configure JMS endpoints. The bean is implemented by the org.apache.cxf.transport.jms.JMSConfiguration class. It can be used to either configure endpoint's directly or to configure the JMS conduits and destinations.

Configuration namespace

The JMS configuration bean uses the Spring p-namespace to make the configuration as simple as possible. To use this namespace you need to declare it in the configuration's root element as shown in Example 14.1, “Declaring the Spring p-namespace”.

Example 14.1. Declaring the Spring p-namespace

<beans ...
  xmlns:p="http://www.springframework.org/schema/p"
  ... >
  ...
</beans>

Specifying the configuration

You specify the JMS configuration by defining a bean of class org.apache.cxf.transport.jms.JMSConfiguration. The properties of the bean provide the configuration settings for the transport.
Table 14.1, “General JMS Configuration Properties” lists properties that are common to both providers and consumers.

Table 14.1. General JMS Configuration Properties

PropertyDefaultDescription
connectionFactory-ref Specifies a reference to a bean that defines a JMS ConnectionFactory.
wrapInSingleConnectionFactorytrueSpecifies whether to wrap the ConnectionFactory with a Spring SingleConnectionFactory. Doing so can improve the performance of the JMS transport when the specified connection factory does not pool connections.
reconnectOnExceptionfalseSpecifies whether to create a new connection in the case of an exception. This property is only used when wrapping the connection factory with a Spring SingleConnectionFactory.
targetDestination Specifies the JNDI name or provider specific name of a destination.
replyDestination Specifies the JMS name of the JMS destinations where replies are sent. This attribute allows you to use a user defined destination for replies. For more details see Section 3, “Using a Named Reply Destination”.
destinationResolver Specifies a reference to a Spring DestinationResolver. This allows you to define how destination names are resolved. By default a DynamicDestinationResolver is used. It resolves destinations using the JMS providers features. If you reference a JndiDestinationResolver you can resolve the destination names using JNDI.
transactionManager Specifies a reference to a Spring transaction manager. This allows the service to participate in JTA Transactions.
taskExecutor Specifies a reference to a Spring TaskExecutor. This is used in listeners to decide how to handle incoming messages. By default the transport uses the Spring SimpleAsyncTaskExecutor.
useJms11falseSpecifies whether JMS 1.1 features are available.
messageIdEnabledtrueSpecifies whether the JMS transport wants the JMS broker to provide message IDs. Setting this to false causes the endpoint to call its message producer's setDisableMessageID() method with a value of true. The JMS broker is then given a hint that it does not need to generate message IDs or add them to the messages from the endpoint. The JMS broker can choose to accept the hint or ignore it.
messageTimestampEnabledtrueSpecifies whether the JMS transport wants the JMS broker to provide message time stamps. Setting this to false causes the endpoint to call its message producer's setDisableMessageTimestamp() method with a value of true. The JMS broker is then given a hint that it does not need to generate time stamps or add them to the messages from the endpoint. The JMS broker can choose to accept the hint or ignore it.
cacheLevel3Specifies the level of caching allowed by the listener. Valid values are 0(CACHE_NONE), 1(CACHE_CONNECTION), 2(CACHE_SESSION), 3(CACHE_CONSUMER), 4(CACHE_AUTO).
pubSubNoLocalfalseSpecifies whether to receive messages produced from the same connection.
receiveTimeout0Specifies, in milliseconds, the amount of time to wait for response messages. 0 means wait indefinitely.
explicitQosEnabledfalseSpecifies whether the QoS settings like priority, persistence, and time to live are explicitly set for each message or if they are allowed to use default values.
deliveryMode1
Specifies if a message is persistent. The two values are:
  • 1(NON_PERSISTENT)—messages will be kept memory
  • 2(PERSISTENT)—messages will be persisted to disk
priority4Specifies the message's priority for the messages. JMS priority values can range from 0 to 9. The lowest priority is 0 and the highest priority is 9.
timeToLive0Specifies, in milliseconds, the message will be available after it is sent. 0 specifies an infinite time to live.
sessionTransactedfalseSpecifies if JMS transactions are used.
concurrentConsumers1Specifies the minimum number of concurrent consumers created by the listener.
maxConcurrentConsumers1Specifies the maximum number of concurrent consumers by listener.
messageSelector Specifies the string value of the selector. For more information on the syntax used to specify message selectors, see the JMS 1.1 specification.
subscriptionDurablefalseSpecifies whether the server uses durrable subscriptions.
durableSubscriptionName Specifies the string used to register the durable subscription.
messageTypetextSpecifies how the message data will be packaged as a JMS message. text specifies that the data will be packaged as a TextMessage. binary specifies that the data will be packaged as an ByteMessage.
pubSubDomainfalseSpecifies whether the target destination is a topic.
jmsProviderTibcoEmsfalseSpecifies if your JMS provider is Tibco EMS. This causes the principal in the security context to be populated from the JMS_TIBCO_SENDER header.
useMessageIDAsCorrelationIDfalseSpecifies whether JMS will use the message ID to correlate messages. If not, the client will set a generated correlation ID.
As shown in Example 14.2, “JMS configuration bean”, the bean's properties are specified as attributes to the bean element. They are all declared in the Spring p namespace.

Example 14.2. JMS configuration bean

<bean id="jmsConfig"
      class="org.apache.cxf.transport.jms.JMSConfiguration"
      p:connectionFactory-ref="connectionFactory"
      p:targetDestination="dynamicQueues/greeter.request.queue"
      p:pubSubDomain="false" />

Applying the configuration to an endpoint

The JMSConfiguration bean can be applied directly to both server and client endpoints using the Apache CXF features mechanism. To do so:
  1. Set the endpoint's address attribute to jms://.
  2. Add a jaxws:feature element to the endpoint's configuration.
  3. Add a bean of type org.apache.cxf.transport.jms.JMSConfigFeature to the feature.
  4. Set the bean element's p:jmsConfig-ref attribute to the ID of the JMSConfiguration bean.

Example 14.3. Adding JMS configuration to a JAX-WS client

<jaxws:client id="CustomerService"
              xmlns:customer="http://customerservice.example.com/"
              serviceName="customer:CustomerServiceService"
              endpointName="customer:CustomerServiceEndpoint"
              address="jms://"
              serviceClass="com.example.customerservice.CustomerService">
  <jaxws:features>
    <bean class="org.apache.cxf.transport.jms.JMSConfigFeature"
          p:jmsConfig-ref="jmsConfig"/>
  </jaxws:features>
</jaxws:client>

Applying the configuration to the transport

The JMSConfiguration bean can be applied to JMS conduits and JMS destinations using the jms:jmsConfig-ref element. The jms:jmsConfig-ref element's value is the ID of the JMSConfiguration bean.

Example 14.4. Adding JMS configuration to a JMS conduit

<jms:conduit name="{http://cxf.apache.org/jms_conf_test}HelloWorldQueueBinMsgPort.jms-conduit">
  ...
  <jms:jmsConfig-ref>jmsConf</jms:jmsConfig-ref>
</jms:conduit>

2. Using WSDL to configure JMS

The WSDL extensions for defining a JMS endpoint are defined in the namespace http://cxf.apache.org/transports/jms. In order to use the JMS extensions you will need to add the line shown in Example 14.5, “JMS WSDL extension namespace” to the definitions element of your contract.

Example 14.5. JMS WSDL extension namespace

xmlns:jms="http://cxf.apache.org/transports/jms"

2.1. Basic JMS configuration

Overview

The JMS address information is provided using the jms:address element and its child, the jms:JMSNamingProperties element. The jms:address element’s attributes specify the information needed to identify the JMS broker and the destination. The jms:JMSNamingProperties element specifies the Java properties used to connect to the JNDI service.
Important
Information specified using the JMS feature will override the information in the endpoint's WSDL file.

Specifying the JMS address

Table 14.2. JMS endpoint attributes

AttributeDescription
destinationStyle Specifies if the JMS destination is a JMS queue or a JMS topic.
jndiConnectionFactoryName Specifies the JNDI name bound to the JMS connection factory to use when connecting to the JMS destination.
jmsDestinationName Specifies the JMS name of the JMS destination to which requests are sent.
jmsReplyDestinationName Specifies the JMS name of the JMS destinations where replies are sent. This attribute allows you to use a user defined destination for replies. For more details see Section 3, “Using a Named Reply Destination”.
jndiDestinationName Specifies the JNDI name bound to the JMS destination to which requests are sent.
jndiReplyDestinationName Specifies the JNDI name bound to the JMS destinations where replies are sent. This attribute allows you to use a user defined destination for replies. For more details see Section 3, “Using a Named Reply Destination”.
connectionUserName Specifies the user name to use when connecting to a JMS broker.
connectionPassword Specifies the password to use when connecting to a JMS broker.
The jms:address WSDL element uses a jms:JMSNamingProperties child element to specify additional information needed to connect to a JNDI provider.

Specifying JNDI properties

To increase interoperability with JMS and JNDI providers, the jms:address element has a child element, jms:JMSNamingProperties, that allows you to specify the values used to populate the properties used when connecting to the JNDI provider. The jms:JMSNamingProperties element has two attributes: name and value. name specifies the name of the property to set. value attribute specifies the value for the specified property. jms:JMSNamingProperties element can also be used for specification of provider specific properties.
The following is a list of common JNDI properties that can be set:
  1. java.naming.factory.initial
  2. java.naming.provider.url
  3. java.naming.factory.object
  4. java.naming.factory.state
  5. java.naming.factory.url.pkgs
  6. java.naming.dns.url
  7. java.naming.authoritative
  8. java.naming.batchsize
  9. java.naming.referral
  10. java.naming.security.protocol
  11. java.naming.security.authentication
  12. java.naming.security.principal
  13. java.naming.security.credentials
  14. java.naming.language
  15. java.naming.applet
For more details on what information to use in these attributes, check your JNDI provider’s documentation and consult the Java API reference material.
Example 14.6, “JMS WSDL port specification” shows an example of a JMS WSDL port specification.

Example 14.6. JMS WSDL port specification

<service name="JMSService">
  <port binding="tns:Greeter_SOAPBinding" name="SoapPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/test.Celtix.jmstransport" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
  </port>
</service>

2.2. JMS client configuration

Overview

JMS consumer endpoints specify the type of messages they use. JMS consumer endpoint can use either a JMS ByteMessage or a JMS TextMessage.
When using an ByteMessage the consumer endpoint uses a byte[] as the method for storing data into and retrieving data from the JMS message body. When messages are sent, the message data, including any formating information, is packaged into a byte[] and placed into the message body before it is placed on the wire. When messages are received, the consumer endpoint will attempt to unmarshall the data stored in the message body as if it were packed in a byte[].
When using a TextMessage, the consumer endpoint uses a string as the method for storing and retrieving data from the message body. When messages are sent, the message information, including any format-specific information, is converted into a string and placed into the JMS message body. When messages are received the consumer endpoint will attempt to unmarshall the data stored in the JMS message body as if it were packed into a string.
When native JMS applications interact with Apache CXF consumers, the JMS application is responsible for interpreting the message and the formatting information. For example, if the Apache CXF contract specifies that the binding used for a JMS endpoint is SOAP, and the messages are packaged as TextMessage, the receiving JMS application will get a text message containing all of the SOAP envelope information.

Specifying the message type

The type of messages accepted by a JMS consumer endpoint is configured using the optional jms:client element. The jms:client element is a child of the WSDL port element and has one attribute:

Table 14.3. JMS Client WSDL Extensions

messageType Specifies how the message data will be packaged as a JMS message. text specifies that the data will be packaged as a TextMessage. binary specifies that the data will be packaged as an ByteMessage.
Example 14.7, “WSDL for a JMS consumer endpoint” shows the WSDL for configuring a JMS consumer endpoint.

Example 14.7. WSDL for a JMS consumer endpoint

<service name="JMSService">
  <port binding="tns:Greeter_SOAPBinding" name="SoapPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/test.Celtix.jmstransport" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
    <jms:client messageType="binary" />
  </port>
</service>

2.3. JMS provider configuration

Overview

JMS provider endpoints have a number of behaviors that are configurable. These include:
  • how messages are correlated
  • the use of durable subscriptions
  • if the service uses local JMS transactions
  • the message selectors used by the endpoint

Specifying the configuration

Provider endpoint behaviors are configured using the optional jms:server element. The jms:server element is a child of the WSDL wsdl:port element and has the following attributes:

Table 14.4. JMS provider endpoint WSDL extensions

AttributeDescription
useMessageIDAsCorrealationID Specifies whether JMS will use the message ID to correlate messages. The default is false.
durableSubscriberName Specifies the name used to register a durable subscription.
messageSelector Specifies the string value of a message selector to use. For more information on the syntax used to specify message selectors, see the JMS 1.1 specification.
transactional Specifies whether the local JMS broker will create transactions around message processing. The default is false. [a]
[a] Currently, setting the transactional attribute to true is not supported by the runtime.
Example 14.8, “WSDL for a JMS provider endpoint” shows the WSDL for configuring a JMS provider endpoint.

Example 14.8. WSDL for a JMS provider endpoint

<service name="JMSService">
  <port binding="tns:Greeter_SOAPBinding" name="SoapPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/test.Celtix.jmstransport" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
    <jms:server messageSelector="cxf_message_selector"
                useMessageIDAsCorrelationID="true"
                transactional="true"
                durableSubscriberName="cxf_subscriber" />
  </port>
</service>

3. Using a Named Reply Destination

Overview

By default, Apache CXF endpoints using JMS create a temporary queue for sending replies back and forth. If you prefer to use named queues, you can configure the queue used to send replies as part of an endpoint's JMS configuration.

Setting the reply destination name

You specify the reply destination using either the jmsReplyDestinationName attribute or the jndiReplyDestinationName attribute in the endpoint's JMS configuration. A client endpoint will listen for replies on the specified destination and it will specify the value of the attribute in the ReplyTo field of all outgoing requests. A service endpoint will use the value of the jndiReplyDestinationName attribute as the location for placing replies if there is no destination specified in the request’s ReplyTo field.

Example

Example 14.9, “JMS Consumer Specification Using a Named Reply Queue” shows the configuration for a JMS client endpoint.

Example 14.9. JMS Consumer Specification Using a Named Reply Queue

<jms:conduit name="{http://cxf.apache.org/jms_endpt}HelloWorldJMSPort.jms-conduit">
    <jms:address destinationStyle="queue"
                 jndiConnectionFactoryName="myConnectionFactory"
                 jndiDestinationName="myDestination"
                 jndiReplyDestinationName="myReplyDestination" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.apache.cxf.transport.jms.MyInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
  </jms:conduit>

Appendix A. Integrating with Apache ActiveMQ

Overview

If you are using Apache ActiveMQ as your JMS provider, the JNDI name of your destinations can be specified in a special format that dynamically creates JNDI bindings for queues or topics. This means that it is not necessary to configure the JMS provider in advance with the JNDI bindings for your queues or topics.

The initial context factory

The key to integrating Apache ActiveMQ with JNDI is the ActiveMQInitialContextFactory class. This class is used to create a JNDI InitialContext instance, which you can then use to access JMS destinations in the JMS broker.
Example A.1, “SOAP/JMS WSDL to connect to Apache ActiveMQ” shows SOAP/JMS WSDL extensions to create a JNDI InitialContext that is integrated with Apache ActiveMQ.

Example A.1. SOAP/JMS WSDL to connect to Apache ActiveMQ

<soapjms:jndiInitialContextFactory>
  org.apache.activemq.jndi.ActiveMQInitialContextFactory
</soapjms:jndiInitialContextFactory>
<soapjms:jndiURL>tcp://localhost:61616</soapjms:jndiURL>
In Example A.1, “SOAP/JMS WSDL to connect to Apache ActiveMQ”, the Apache ActiveMQ client connects to the broker port located at tcp://localhost:61616.

Looking up the connection factory

As well as creating a JNDI InitialContext instance, you must specify the JNDI name that is bound to a javax.jms.ConnectionFactory instance. In the case of Apache ActiveMQ, there is a predefined binding in the InitialContext instance, which maps the JNDI name ConnectionFactory to an ActiveMQConnectionFactory instance. Example A.2, “SOAP/JMS WSDL for specifying the Apache ActiveMQ connection factory” shaows the SOAP/JMS extension element for specifying the Apache ActiveMQ connection factory.

Example A.2. SOAP/JMS WSDL for specifying the Apache ActiveMQ connection factory

<soapjms:jndiConnectionFactoryName>
  ConnectionFactory
</soapjms:jndiConnectionFactoryName>

Syntax for dynamic destinations

To access queues or topics dynamically, specify the destination's JNDI name as a JNDI composite name in either of the following formats:
dynamicQueues/QueueName
dynamicTopics/TopicName
QueueName and TopicName are the names that the Apache ActiveMQ broker uses. They are not abstract JNDI names.
Example A.3, “WSDL port specification with a dynamically created queue” shows a WSDL port that uses a dynamically created queue.

Example A.3. WSDL port specification with a dynamically created queue

<service name="JMSService">
  <port binding="tns:GreeterBinding" name="JMSPort">
    <jms:address jndiConnectionFactoryName="ConnectionFactory"
                 jndiDestinationName="dynamicQueues/greeter.request.queue" >
      <jms:JMSNamingProperty name="java.naming.factory.initial"
                             value="org.activemq.jndi.ActiveMQInitialContextFactory" />
      <jms:JMSNamingProperty name="java.naming.provider.url"
                             value="tcp://localhost:61616" />
    </jms:address>
  </port>
</service>
When the application attempts to open the JMS connection, Apache ActiveMQ will check to see if a queue with the JNDI name greeter.request.queue exists. If it does not exist, it will create a new queue and bind it to the JNDI name greeter.request.queue.

Appendix B. Conduits

Abstract

Conduits are a low-level piece of the transport architecture that are used to implement outbound connections. Their behavior and life-cycle can effect system performance and processing load.

Overview

Conduits manage the client-side, or outbound, transport details in the Apache CXF runtime. They are responsible for opening ports, establishing outbound connections, sending messages, and listening for any responses between an application and a single external endpoint. If an application connects to multiple endpoints, it will have one conduit instance for each endpoint.
Each transport type implements its own conduit using the Conduit interface. This allows for a standardized interface between the application level functionality and the transports.
In general, you only need to worry about the conduits being used by your application when configuring the client-side transport details. The underlying semantics of how the runtime handles conduits is, generally, not something a developer needs to worry about.
However, there are cases when an understanding of conduit's can prove helpful:
  • Implementing a custom transport
  • Advanced application tuning to manage limited resources

Conduit life-cycle

Conduits are managed by the client implementation object. Once created, a conduit lives for the duration of the client implementation object. The conduit's life-cycle is:
  1. When the client implementation object is created, it is given a reference to a ConduitSelector object.
  2. When the client needs to send a message is request's a reference to a conduit from the conduit selector.
    If the message is for a new endpoint, the conduit selector creates a new conduit and passes it to the client implementation. Otherwise, it passes the client a reference to the conduit for the target endpoint.
  3. The conduit sends messages when needed.
  4. When the client implementation object is destroyed, all of the conduits associated with it are destroyed.

Conduit weight

The weight of a conduit object depends on the transport implementation. HTTP conduits are extremely light weight. JMS conduits are heavy because they are associated with the JMS Session object and one or more JMSListenerContainer objects.

Part IV. Configuring Web Service Endpoints

Abstract

This guide describes how to create Apache CXF endpoints in Red Hat JBoss Fuse.

Chapter 15. Configuring JAX-WS Endpoints

Abstract

JAX-WS endpoints are configured using one of three Spring configuration elements. The correct element depends on what type of endpoint you are configuring and which features you wish to use. For consumers you use the jaxws:client element. For service providers you can use either the jaxws:endpoint element or the jaxws:server element.
The information used to define an endpoint is typically defined in the endpoint's contract. You can use the configuration element's to override the information in the contract. You can also use the configuration elements to provide information that is not provided in the contract.
Note
When dealing with endpoints developed using a Java-first approach it is likely that the SEI serving as the endpoint's contract is lacking information about the type of binding and transport to use.
You must use the configuration elements to activate advanced features such as WS-RM. This is done by providing child elements to the endpoint's configuration element.

1. Configuring Service Providers

Apache CXF has two elements that can be used to configure a service provider:
The differences between the two elements are largely internal to the runtime. The jaxws:endpoint element injects properties into the org.apache.cxf.jaxws.EndpointImpl object created to support a service endpoint. The jaxws:server element injects properties into the org.apache.cxf.jaxws.support.JaxWsServerFactoryBean object created to support the endpoint. The EndpointImpl object passes the configuration data to the JaxWsServerFactoryBean object. The JaxWsServerFactoryBean object is used to create the actual service object. Because either configuration element will configure a service endpoint, you can choose based on the syntax you prefer.

1.1. Using the jaxws:endpoint Element

Overview

The jaxws:endpoint element is the default element for configuring JAX-WS service providers. Its attributes and children specify all of the information needed to instantiate a service provider. Many of the attributes map to information in the service's contract. The children are used to configure interceptors and other advanced features.

Identifying the endpoint being configured

For the runtime to apply the configuration to the proper service provider, it must be able to identify it. The basic means for identifying a service provider is to specify the class that implements the endpoint. This is done using the jaxws:endpoint element's implementor attribute.
For instances where different endpoint's share a common implementation, it is possible to provide different configuration for each endpoint. There are two approaches for distinguishing a specific endpoint in configuration:
  • a combination of the serviceName attribute and the endpointName attribute
    The serviceName attribute specifies the wsdl:service element defining the service's endpoint. The endpointName attribute specifies the specific wsdl:port element defining the service's endpoint. Both attributes are specified as QNames using the format ns:name. ns is the namespace of the element and name is the value of the element's name attribute.
    Tip
    If the wsdl:service element only has one wsdl:port element, the endpointName attribute can be omitted.
  • the name attribute
    The name attribute specifies the QName of the specific wsdl:port element defining the service's endpoint. The QName is provided in the format {ns}localPart. ns is the namespace of the wsdl:port element and localPart is the value of the wsdl:port element's name attribute.

Attributes

The attributes of the jaxws:endpoint element configure the basic properties of the endpoint. These properties include the address of the endpoint, the class that implements the endpoint, and the bus that hosts the endpoint.

Table 15.1. Attributes for Configuring a JAX-WS Service Provider Using the jaxws:endpoint Element

AttributeDescription
id Specifies a unique identifier that other configuration elements can use to refer to the endpoint.
implementor Specifies the class implementing the service. You can specify the implementation class using either the class name or an ID reference to a Spring bean configuring the implementation class. This class must be on the classpath.
implementorClass Specifies the class implementing the service. This attribute is useful when the value provided to the implementor attribute is a reference to a bean that is wrapped using Spring AOP.
address Specifies the address of an HTTP endpoint. This value overrides the value specified in the services contract.
wsdlLocation Specifies the location of the endpoint's WSDL contract. The WSDL contract's location is relative to the folder from which the service is deployed.
endpointName Specifies the value of the service's wsdl:port element's name attribute. It is specified as a QName using the format ns:name where ns is the namespace of the wsdl:port element.
serviceName Specifies the value of the service's wsdl:service element's name attribute. It is specified as a QName using the format ns:name where ns is the namespace of the wsdl:service element.
publish Specifies if the service should be automatically published. If this is set to false, the developer must explicitly publish the endpoint.
bus Specifies the ID of the Spring bean configuring the bus used to manage the service endpoint. This is useful when configuring several endpoints to use a common set of features.
bindingUri Specifies the ID of the message binding the service uses. A list of valid binding IDs is provided in Appendix C, Apache CXF Binding IDs.
name Specifies the stringified QName of the service's wsdl:port element. It is specified as a QName using the format {ns}localPart. ns is the namespace of the wsdl:port element and localPart is the value of the wsdl:port element's name attribute.
abstract Specifies if the bean is an abstract bean. Abstract beans act as parents for concrete bean definitions and are not instantiated. The default is false. Setting this to true instructs the bean factory not to instantiate the bean.
depends-on Specifies a list of beans that the endpoint depends on being instantiated before it can be instantiated.
createdFromAPI
Specifies that the user created that bean using Apache CXF APIs, such as Endpoint.publish() or Service.getPort().
The default is false.
Setting this to true does the following:
  • Changes the internal name of the bean by appending .jaxws-endpoint to its id
  • Makes the bean abstract
publishedEndpointUrl The URL that is placed in the address element of the generated WSDL. If this value is not specified, the value of the address attribute is used. This attribute is useful when the "public" URL is not be the same as the URL on which the service is deployed.
In addition to the attributes listed in Table 15.1, “Attributes for Configuring a JAX-WS Service Provider Using the jaxws:endpoint Element”, you might need to use multiple xmlns:shortName attributes to declare the namespaces used by the endpointName and serviceName attributes.

Example

Example 15.1, “Simple JAX-WS Endpoint Configuration” shows the configuration for a JAX-WS endpoint that specifies the address where the endpoint is published. The example assumes that you want to use the defaults for all other values or that the implementation has specified values in the annotations.

Example 15.1. Simple JAX-WS Endpoint Configuration

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:endpoint id="example"
                  implementor="org.apache.cxf.example.DemoImpl"
                  address="http://localhost:8080/demo" />
</beans>
Example 15.2, “JAX-WS Endpoint Configuration with a Service Name” shows the configuration for a JAX-WS endpoint whose contract contains two service definitions. In this case, you must specify which service definition to instantiate using the serviceName attribute.

Example 15.2. JAX-WS Endpoint Configuration with a Service Name

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">

  <jaxws:endpoint id="example2"
                  implementor="org.apache.cxf.example.DemoImpl"
                  serviceName="samp:demoService2"
                  xmlns:samp="http://org.apache.cxf/wsdl/example" />

</beans>
The xmlns:samp attribute specifies the namespace in which the WSDL service element is defined.

1.2. Using the jaxws:server Element

Overview

The jaxws:server element is an element for configuring JAX-WS service providers. It injects the configuration information into the org.apache.cxf.jaxws.support.JaxWsServerFactoryBean. This is a Apache CXF specific object. If you are using a pure Spring approach to building your services, you will not be forced to use Apache CXF specific APIs to interact with the service.
The attributes and children of the jaxws:server element specify all of the information needed to instantiate a service provider. The attributes specify the information that is required to instantiate an endpoint. The children are used to configure interceptors and other advanced features.

Identifying the endpoint being configured

In order for the runtime to apply the configuration to the proper service provider, it must be able to identify it. The basic means for identifying a service provider is to specify the class that implements the endpoint. This is done using the jaxws:server element's serviceBean attribute.
For instances where different endpoint's share a common implementation, it is possible to provide different configuration for each endpoint. There are two approaches for distinguishing a specific endpoint in configuration:
  • a combination of the serviceName attribute and the endpointName attribute
    The serviceName attribute specifies the wsdl:service element defining the service's endpoint. The endpointName attribute specifies the specific wsdl:port element defining the service's endpoint. Both attributes are specified as QNames using the format ns:name. ns is the namespace of the element and name is the value of the element's name attribute.
    Tip
    If the wsdl:service element only has one wsdl:port element, the endpointName attribute can be omitted.
  • the name attribute
    The name attribute specifies the QName of the specific wsdl:port element defining the service's endpoint. The QName is provided in the format {ns}localPart. ns is the namespace of the wsdl:port element and localPart is the value of the wsdl:port element's name attribute.

Attributes

The attributes of the jaxws:server element configure the basic properties of the endpoint. These properties include the address of the endpoint, the class that implements the endpoint, and the bus that hosts the endpoint.

Table 15.2. Attributes for Configuring a JAX-WS Service Provider Using the jaxws:server Element

AttributeDescription
id Specifies a unique identifier that other configuration elements can use to refer to the endpoint.
serviceBean Specifies the class implementing the service. You can specify the implementation class using either the class name or an ID reference to a Spring bean configuring the implementation class. This class must be on the classpath.
serviceClass Specifies the class implementing the service. This attribute is useful when the value provided to the implementor attribute is a reference to a bean that is wrapped using Spring AOP.
address Specifies the address of an HTTP endpoint. This value will override the value specified in the services contract.
wsdlLocation Specifies the location of the endpoint's WSDL contract. The WSDL contract's location is relative to the folder from which the service is deployed.
endpointName Specifies the value of the service's wsdl:port element's name attribute. It is specified as a QName using the format ns:name, where ns is the namespace of the wsdl:port element.
serviceName Specifies the value of the service's wsdl:service element's name attribute. It is specified as a QName using the format ns:name, where ns is the namespace of the wsdl:service element.
start Specifies if the service should be automatically published. If this is set to false, the developer must explicitly publish the endpoint.
bus Specifies the ID of the Spring bean configuring the bus used to manage the service endpoint. This is useful when configuring several endpoints to use a common set of features.
bindingId Specifies the ID of the message binding the service uses. A list of valid binding IDs is provided in Appendix C, Apache CXF Binding IDs.
name Specifies the stringified QName of the service's wsdl:port element. It is specified as a QName using the format {ns}localPart, where ns is the namespace of the wsdl:port element and localPart is the value of the wsdl:port element's name attribute.
abstract Specifies if the bean is an abstract bean. Abstract beans act as parents for concrete bean definitions and are not instantiated. The default is false. Setting this to true instructs the bean factory not to instantiate the bean.
depends-on Specifies a list of beans that the endpoint depends on being instantiated before the endpoint can be instantiated.
createdFromAPI
Specifies that the user created that bean using Apache CXF APIs, such as Endpoint.publish() or Service.getPort().
The default is false.
Setting this to true does the following:
  • Changes the internal name of the bean by appending .jaxws-endpoint to its id
  • Makes the bean abstract
In addition to the attributes listed in Table 15.2, “Attributes for Configuring a JAX-WS Service Provider Using the jaxws:server Element”, you might need to use multiple xmlns:shortName attributes to declare the namespaces used by the endpointName and serviceName attributes.

Example

Example 15.3, “Simple JAX-WS Server Configuration” shows the configuration for a JAX-WS endpoint that specifies the address where the endpoint is published.

Example 15.3. Simple JAX-WS Server Configuration

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:server id="exampleServer"
                  serviceBean="org.apache.cxf.example.DemoImpl"
                  address="http://localhost:8080/demo" />
</beans>

1.3. Adding Functionality to Service Providers

Overview

The jaxws:endpoint and the jaxws:server elements provide the basic configuration information needed to instantiate a service provider. To add functionality to your service provider or to perform advanced configuration you must add child elements to the configuration.
Child elements allow you to do the following:

Elements

Table 15.3, “Elements Used to Configure JAX-WS Service Providers” describes the child elements that jaxws:endpoint supports.

Table 15.3. Elements Used to Configure JAX-WS Service Providers

ElementDescription
jaxws:handlers Specifies a list of JAX-WS Handler implementations for processing messages.
jaxws:inInterceptors Specifies a list of interceptors that process inbound requests. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:inFaultInterceptors Specifies a list of interceptors that process inbound fault messages. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:outInterceptors Specifies a list of interceptors that process outbound replies. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:outFaultInterceptors Specifies a list of interceptors that process outbound fault messages. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:binding Specifies a bean configuring the message binding used by the endpoint. Message bindings are configured using implementations of the org.apache.cxf.binding.BindingFactory interface.[a]
jaxws:dataBinding [b] Specifies the class implementing the data binding used by the endpoint. This is specified using an embedded bean definition.
jaxws:executor Specifies a Java executor that is used for the service. This is specified using an embedded bean definition.
jaxws:features Specifies a list of beans that configure advanced features of Apache CXF. You can provide either a list of bean references or a list of embedded beans.
jaxws:invoker Specifies an implementation of the org.apache.cxf.service.Invoker interface used by the service. [c]
jaxws:properties Specifies a Spring map of properties that are passed along to the endpoint. These properties can be used to control features like enabling MTOM support.
jaxws:serviceFactory Specifies a bean configuring the JaxWsServiceFactoryBean object used to instantiate the service.
[a] The SOAP binding is configured using the soap:soapBinding bean.
[b] The jaxws:endpoint element does not support the jaxws:dataBinding element.
[c] The Invoker implementation controls how a service is invoked. For example, it controls whether each request is handled by a new instance of the service implementation or if state is preserved across invocations.

2. Configuring Consumer Endpoints

Overview

JAX-WS consumer endpoints are configured using the jaxws:client element. The element's attributes provide the basic information necessary to create a consumer.
To add other functionality, like WS-RM, to the consumer you add children to the jaxws:client element. Child elements are also used to configure the endpoint's logging behavior and to inject other properties into the endpoint's implementation.

Basic Configuration Properties

The attributes described in Table 15.4, “Attributes Used to Configure a JAX-WS Consumer” provide the basic information necessary to configure a JAX-WS consumer. You only need to provide values for the specific properties you want to configure. Most of the properties have sensible defaults, or they rely on information provided by the endpoint's contract.

Table 15.4. Attributes Used to Configure a JAX-WS Consumer

AttributeDescription
address Specifies the HTTP address of the endpoint where the consumer will make requests. This value overrides the value set in the contract.
bindingId Specifies the ID of the message binding the consumer uses. A list of valid binding IDs is provided in Appendix C, Apache CXF Binding IDs.
bus Specifies the ID of the Spring bean configuring the bus managing the endpoint.
endpointName Specifies the value of the wsdl:port element's name attribute for the service on which the consumer is making requests. It is specified as a QName using the format ns:name, where ns is the namespace of the wsdl:port element.
serviceName Specifies the value of the wsdl:service element's name attribute for the service on which the consumer is making requests. It is specified as a QName using the format ns:name where ns is the namespace of the wsdl:service element.
username Specifies the username used for simple username/password authentication.
password Specifies the password used for simple username/password authentication.
serviceClass Specifies the name of the service endpoint interface(SEI).
wsdlLocation Specifies the location of the endpoint's WSDL contract. The WSDL contract's location is relative to the folder from which the client is deployed.
name Specifies the stringified QName of the wsdl:port element for the service on which the consumer is making requests. It is specified as a QName using the format {ns}localPart, where ns is the namespace of the wsdl:port element and localPart is the value of the wsdl:port element's name attribute.
abstract Specifies if the bean is an abstract bean. Abstract beans act as parents for concrete bean definitions and are not instantiated. The default is false. Setting this to true instructs the bean factory not to instantiate the bean.
depends-on Specifies a list of beans that the endpoint depends on being instantiated before it can be instantiated.
createdFromAPI
Specifies that the user created that bean using Apache CXF APIs like Service.getPort().
The default is false.
Setting this to true does the following:
  • Changes the internal name of the bean by appending .jaxws-client to its id
  • Makes the bean abstract
In addition to the attributes listed in Table 15.4, “Attributes Used to Configure a JAX-WS Consumer”, it might be necessary to use multiple xmlns:shortName attributes to declare the namespaces used by the endpointName and the serviceName attributes.

Adding functionality

To add functionality to your consumer or to perform advanced configuration, you must add child elements to the configuration.
Child elements allow you to do the following:
Table 15.5, “Elements For Configuring a Consumer Endpoint” describes the child element's you can use to configure a JAX-WS consumer.

Table 15.5. Elements For Configuring a Consumer Endpoint

ElementDescription
jaxws:binding Specifies a bean configuring the message binding used by the endpoint. Message bindings are configured using implementations of the org.apache.cxf.binding.BindingFactory interface.[a]
jaxws:dataBinding Specifies the class implementing the data binding used by the endpoint. You specify this using an embedded bean definition. The class implementing the JAXB data binding is org.apache.cxf.jaxb.JAXBDataBinding.
jaxws:features Specifies a list of beans that configure advanced features of Apache CXF. You can provide either a list of bean references or a list of embedded beans.
jaxws:handlers Specifies a list of JAX-WS Handler implementations for processing messages.
jaxws:inInterceptors Specifies a list of interceptors that process inbound responses. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:inFaultInterceptors Specifies a list of interceptors that process inbound fault messages. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:outInterceptors Specifies a list of interceptors that process outbound requests. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:outFaultInterceptors Specifies a list of interceptors that process outbound fault messages. For more information see Part VII, “Developing Apache CXF Interceptors”.
jaxws:properties Specifies a map of properties that are passed to the endpoint.
jaxws:conduitSelector Specifies an org.apache.cxf.endpoint.ConduitSelector implementation for the client to use. A ConduitSelector implementation will override the default process used to select the Conduit object that is used to process outbound requests.
[a] The SOAP binding is configured using the soap:soapBinding bean.

Example

Example 15.4, “Simple Consumer Configuration” shows a simple consumer configuration.

Example 15.4. Simple Consumer Configuration

<beans ...
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  ...
  schemaLocation="...
    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
    ...">
  <jaxws:client id="bookClient" 
                serviceClass="org.apache.cxf.demo.BookClientImpl"
                address="http://localhost:8080/books"/>
  ...
</beans>

Chapter 16. Apache CXF Logging

Abstract

This chapter describes how to configure logging in the Apache CXF runtime.

1. Overview of Apache CXF Logging

Overview

Apache CXF uses the Java logging utility, java.util.logging. Logging is configured in a logging configuration file that is written using the standard java.util.Properties format. To run logging on an application, you can specify logging programmatically or by defining a property at the command that points to the logging configuration file when you start the application.

Default logging.properties file

Apache CXF comes with a default logging.properties file, which is located in your InstallDir/etc directory. This file configures both the output destination for the log messages and the message level that is published. The default configuration sets the loggers to print message flagged with the WARNING level to the console. You can either use the default file without changing any of the configuration settings or you can change the configuration settings to suit your specific application.

Logging feature

Apache CXF includes a logging feature that can be plugged into your client or your service to enable logging. Example 16.1, “Configuration for Enabling Logging” shows the configuration to enable the logging feature.

Example 16.1. Configuration for Enabling Logging

<jaxws:endpoint...>
  <jaxws:features>
    <bean class="org.apache.cxf.feature.LoggingFeature"/>
  </jaxws:features>
</jaxws:endpoint>
For more information, see Section 6, “Logging Message Content”.

Where to begin?

To run a simple example of logging follow the instructions outlined in a Section 2, “Simple Example of Using Logging”.
For more information on how logging works in Apache CXF, read this entire chapter.

More information on java.util.logging

The java.util.logging utility is one of the most widely used Java logging frameworks. There is a lot of information available online that describes how to use and extend this framework. As a starting point, however, the following documents gives a good overview of java.util.logging:

2. Simple Example of Using Logging

Changing the log levels and output destination

To change the log level and output destination of the log messages in the wsdl_first sample application, complete the following steps:
  1. Run the sample server as described in the Running the demo using java section of the README.txt file in the InstallDir/samples/wsdl_first directory. Note that the server start command specifies the default logging.properties file, as follows:
    PlatformCommand
    Windows start java -Djava.util.logging.config.file=%CXF_HOME%\etc\logging.properties demo.hw.server.Server
    UNIX java -Djava.util.logging.config.file=$CXF_HOME/etc/logging.properties demo.hw.server.Server &
    The default logging.properties file is located in the InstallDir/etc directory. It configures the Apache CXF loggers to print WARNING level log messages to the console. As a result, you see very little printed to the console.
  2. Stop the server as described in the README.txt file.
  3. Make a copy of the default logging.properties file, name it mylogging.properties file, and save it in the same directory as the default logging.properties file.
  4. Change the global logging level and the console logging levels in your mylogging.properties file to INFO by editing the following lines of configuration:
    .level= INFO
    java.util.logging.ConsoleHandler.level = INFO
  5. Restart the server using the following command:
    PlatformCommand
    Windows start java -Djava.util.logging.config.file=%CXF_HOME%\etc\mylogging.properties demo.hw.server.Server
    UNIX java -Djava.util.logging.config.file=$CXF_HOME/etc/mylogging.properties demo.hw.server.Server &
    Because you configured the global logging and the console logger to log messages of level INFO, you see a lot more log messages printed to the console.

3. Default logging configuration file

The default logging configuration file, logging.properties, is located in the InstallDir/etc directory. It configures the Apache CXF loggers to print WARNING level messages to the console. If this level of logging is suitable for your application, you do not have to make any changes to the file before using it. You can, however, change the level of detail in the log messages. For example, you can change whether log messages are sent to the console, to a file or to both. In addition, you can specify logging at the level of individual packages.
Note
This section discusses the configuration properties that appear in the default logging.properties file. There are, however, many other java.util.logging configuration properties that you can set. For more information on the java.util.logging API, see the java.util.logging javadoc at: http://java.sun.com/j2se/1.5/docs/api/java/util/logging/package-summary.html.

3.1. Configuring Logging Output

The Java logging utility, java.util.logging, uses handler classes to output log messages. Table 16.1, “Java.util.logging Handler Classes” shows the handlers that are configured in the default logging.properties file.

Table 16.1. Java.util.logging Handler Classes

Handler ClassOutputs to
ConsoleHandler Outputs log messages to the console
FileHandler Outputs log messages to a file
Important
The handler classes must be on the system classpath in order to be installed by the Java VM when it starts. This is done when you set the Apache CXF environment.

Configuring the console handler

Example 16.2, “Configuring the Console Handler” shows the code for configuring the console logger.

Example 16.2. Configuring the Console Handler

handlers= java.util.logging.ConsoleHandler
The console handler also supports the configuration properties shown in Example 16.3, “Console Handler Properties”.

Example 16.3. Console Handler Properties

java.util.logging.ConsoleHandler.level = WARNING 1
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 2
The configuration properties shown in Example 16.3, “Console Handler Properties” can be explained as follows:
1
The console handler supports a separate log level configuration property. This allows you to limit the log messages printed to the console while the global logging setting can be different (see Section 3.2, “Configuring Logging Levels”). The default setting is WARNING.
2
Specifies the java.util.logging formatter class that the console handler class uses to format the log messages. The default setting is the java.util.logging.SimpleFormatter.

Configuring the file handler

Example 16.4, “Configuring the File Handler” shows code that configures the file handler.

Example 16.4. Configuring the File Handler

handlers= java.util.logging.FileHandler
The file handler also supports the configuration properties shown in Example 16.5, “File Handler Configuration Properties”.

Example 16.5. File Handler Configuration Properties

java.util.logging.FileHandler.pattern = %h/java%u.log 1
java.util.logging.FileHandler.limit = 50000 2
java.util.logging.FileHandler.count = 1 3
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter 4
The configuration properties shown in Example 16.5, “File Handler Configuration Properties” can be explained as follows:
1
Specifies the location and pattern of the output file. The default setting is your home directory.
2
Specifies, in bytes, the maximum amount that the logger writes to any one file. The default setting is 50000. If you set it to zero, there is no limit on the amount that the logger writes to any one file.
3
Specifies how many output files to cycle through. The default setting is 1.
4
Specifies the java.util.logging formatter class that the file handler class uses to format the log messages. The default setting is the java.util.logging.XMLFormatter.

Configuring both the console handler and the file handler

You can set the logging utility to output log messages to both the console and to a file by specifying the console handler and the file handler, separated by a comma, as shown in Example 16.6, “Configuring Both Console Logging and File Logging”.

Example 16.6. Configuring Both Console Logging and File Logging

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

3.2. Configuring Logging Levels

Logging levels

The java.util.logging framework supports the following levels of logging, from the least verbose to the most verbose:
  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST

Configuring the global logging level

To configure the types of event that are logged across all loggers, configure the global logging level as shown in Example 16.7, “Configuring Global Logging Levels”.

Example 16.7. Configuring Global Logging Levels

.level= WARNING

Configuring logging at an individual package level

The java.util.logging framework supports configuring logging at the level of an individual package. For example, the line of code shown in Example 16.8, “Configuring Logging at the Package Level” configures logging at a SEVERE level on classes in the com.xyz.foo package.

Example 16.8. Configuring Logging at the Package Level

com.xyz.foo.level = SEVERE

4. Enabling Logging at the Command Line

Overview

You can run the logging utility on an application by defining a java.util.logging.config.file property when you start the application. You can either specify the default logging.properties file or a logging.properties file that is unique to that application.

Specifying the log configuration file on application start-up

To specify logging on application start-up add the flag shown in Example 16.9, “Flag to Start Logging on the Command Line” when starting the application.

Example 16.9. Flag to Start Logging on the Command Line

-Djava.util.logging.config.file=myfile

5. Logging for Subsystems and Services

You can use the com.xyz.foo.level configuration property described in the section called “Configuring logging at an individual package level” to set fine-grained logging for specified Apache CXF logging subsystems.

Apache CXF logging subsystems

Table 16.2, “Apache CXF Logging Subsystems” shows a list of available Apache CXF logging subsystems.

Table 16.2. Apache CXF Logging Subsystems

SubsystemDescription
org.apache.cxf.aegis Aegis binding
org.apache.cxf.binding.coloc colocated binding
org.apache.cxf.binding.http HTTP binding
org.apache.cxf.binding.jbi JBI binding
org.apache.cxf.binding.object Java Object binding
org.apache.cxf.binding.soap SOAP binding
org.apache.cxf.binding.xml XML binding
org.apache.cxf.bus Apache CXF bus
org.apache.cxf.configuration configuration framework
org.apache.cxf.endpoint server and client endpoints
org.apache.cxf.interceptor interceptors
org.apache.cxf.jaxws Front-end for JAX-WS style message exchange, JAX-WS handler processing, and interceptors relating to JAX-WS and configuration
org.apache.cxf.jbi JBI container integration classes
org.apache.cxf.jca JCA container integration classes
org.apache.cxf.js JavaScript front-end
org.apache.cxf.transport.http HTTP transport
org.apache.cxf.transport.https secure version of HTTP transport, using HTTPS
org.apache.cxf.transport.jbi JBI transport
org.apache.cxf.transport.jms JMS transport
org.apache.cxf.transport.local transport implementation using local file system
org.apache.cxf.transport.servlet HTTP transport and servlet implementation for loading JAX-WS endpoints into a servlet container
org.apache.cxf.ws.addressing WS-Addressing implementation
org.apache.cxf.ws.policy WS-Policy implementation
org.apache.cxf.ws.rm WS-ReliableMessaging (WS-RM) implementation
org.apache.cxf.ws.security.wss4j WSS4J security implementation

Example

The WS-Addressing sample is contained in the InstallDir/samples/ws_addressing directory. Logging is configured in the logging.properties file located in that directory. The relevant lines of configuration are shown in Example 16.10, “Configuring Logging for WS-Addressing”.

Example 16.10. Configuring Logging for WS-Addressing

java.util.logging.ConsoleHandler.formatter = demos.ws_addressing.common.ConciseFormatter
...
org.apache.cxf.ws.addressing.soap.MAPCodec.level = INFO
The configuration in Example 16.10, “Configuring Logging for WS-Addressing” enables the snooping of log messages relating to WS-Addressing headers, and displays them to the console in a concise form.
For information on running this sample, see the README.txt file located in the InstallDir/samples/ws_addressing directory.

6. Logging Message Content

You can log the content of the messages that are sent between a service and a consumer. For example, you might want to log the contents of SOAP messages that are being sent between a service and a consumer.

Configuring message content logging

To log the messages that are sent between a service and a consumer, and vice versa, complete the following steps:

Adding the logging feature to an endpoint

Add the logging feature your endpoint's configuration as shown in Example 16.11, “Adding Logging to Endpoint Configuration”.

Example 16.11. Adding Logging to Endpoint Configuration

<jaxws:endpoint ...>
  <jaxws:features>
    <bean class="org.apache.cxf.feature.LoggingFeature"/>
  </jaxws:features>
</jaxws:endpoint>
The example XML shown in Example 16.11, “Adding Logging to Endpoint Configuration” enables the logging of SOAP messages.

Adding the logging feature to a consumer

Add the logging feature your client's configuration as shown in Example 16.12, “Adding Logging to Client Configuration”.

Example 16.12. Adding Logging to Client Configuration

<jaxws:client ...>
   <jaxws:features>
      <bean class="org.apache.cxf.feature.LoggingFeature"/>
    </jaxws:features>
</jaxws:client>
The example XML shown in Example 16.12, “Adding Logging to Client Configuration” enables the logging of SOAP messages.

Set logging to log INFO level messages

Ensure that the logging.properties file associated with your service is configured to log INFO level messages, as shown in Example 16.13, “Setting the Logging Level to INFO”.

Example 16.13. Setting the Logging Level to INFO

.level= INFO
java.util.logging.ConsoleHandler.level = INFO

Logging SOAP messages

To see the logging of SOAP messages modify the wsdl_first sample application located in the InstallDir/samples/wsdl_first directory, as follows:
  1. Add the jaxws:features element shown in Example 16.14, “Endpoint Configuration for Logging SOAP Messages” to the cxf.xml configuration file located in the wsdl_first sample's directory:

    Example 16.14. Endpoint Configuration for Logging SOAP Messages

    <jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
                    createdFromAPI="true">
      <jaxws:properties>
        <entry key="schema-validation-enabled" value="true" />
      </jaxws:properties>
      <jaxws:features>
        <bean class="org.apache.cxf.feature.LoggingFeature"/>
      </jaxws:features>
    </jaxws:endpoint>
  2. The sample uses the default logging.properties file, which is located in the InstallDir/etc directory. Make a copy of this file and name it mylogging.properties.
  3. In the mylogging.properties file, change the logging levels to INFO by editing the .level and the java.util.logging.ConsoleHandler.level configuration properties as follows:
    .level= INFO
    java.util.logging.ConsoleHandler.level = INFO
  4. Start the server using the new configuration settings in both the cxf.xml file and the mylogging.properties file as follows:
    PlatformCommand
    Windows start java -Djava.util.logging.config.file=%CXF_HOME%\etc\mylogging.properties demo.hw.server.Server
    UNIX java -Djava.util.logging.config.file=$CXF_HOME/etc/mylogging.properties demo.hw.server.Server &
  5. Start the hello world client using the following command:
    PlatformCommand
    Windows java -Djava.util.logging.config.file=%CXF_HOME%\etc\mylogging.properties demo.hw.client.Client .\wsdl\hello_world.wsdl
    UNIX java -Djava.util.logging.config.file=$CXF_HOME/etc/mylogging.properties demo.hw.client.Client ./wsdl/hello_world.wsdl
The SOAP messages are logged to the console.

Chapter 17. Deploying WS-Addressing

Abstract

Apache CXF supports WS-Addressing for JAX-WS applications. This chapter explains how to deploy WS-Addressing in the Apache CXF runtime environment.

1. Introduction to WS-Addressing

Overview

WS-Addressing is a specification that allows services to communicate addressing information in a transport neutral way. It consists of two parts:
  • A structure for communicating a reference to a Web service endpoint
  • A set of Message Addressing Properties (MAP) that associate addressing information with a particular message

Supported specifications

Apache CXF supports both the WS-Addressing 2004/08 specification and the WS-Addressing 2005/03 specification.

Further information

For detailed information on WS-Addressing, see the 2004/08 submission at http://www.w3.org/Submission/ws-addressing/.

2. WS-Addressing Interceptors

Overview

In Apache CXF, WS-Addressing functionality is implemented as interceptors. The Apache CXF runtime uses interceptors to intercept and work with the raw messages that are being sent and received. When a transport receives a message, it creates a message object and sends that message through an interceptor chain. If the WS-Addressing interceptors are added to the application's interceptor chain, any WS-Addressing information included with a message is processed.

WS-Addressing Interceptors

The WS-Addressing implementation consists of two interceptors, as described in Table 17.1, “WS-Addressing Interceptors”.

Table 17.1. WS-Addressing Interceptors

InterceptorDescription
org.apache.cxf.ws.addressing.MAPAggregator A logical interceptor responsible for aggregating the Message Addressing Properties (MAPs) for outgoing messages.
org.apache.cxf.ws.addressing.soap.MAPCodec A protocol-specific interceptor responsible for encoding and decoding the Message Addressing Properties (MAPs) as SOAP headers.

3. Enabling WS-Addressing

Overview

To enable WS-Addressing the WS-Addressing interceptors must be added to the inbound and outbound interceptor chains. This is done in one of the following ways:
  • RMAssertion and WS-Policy Framework
  • Using Policy Assertion in a WS-Addressing Feature

Adding WS-Addressing as a Feature

WS-Addressing can be enabled by adding the WS-Addressing feature to the client and the server configuration as shown in Example 17.1, “client.xml—Adding WS-Addressing Feature to Client Configuration” and Example 17.2, “server.xml—Adding WS-Addressing Feature to Server Configuration” respectively.

Example 17.1. client.xml—Adding WS-Addressing Feature to Client Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:wsa="http://cxf.apache.org/ws/addressing"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <jaxws:client ...>
        <jaxws:features>
            <wsa:addressing/>
        </jaxws:features>
    </jaxws:client>
</beans>

Example 17.2. server.xml—Adding WS-Addressing Feature to Server Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:wsa="http://cxf.apache.org/ws/addressing"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <jaxws:endpoint ...>
        <jaxws:features>
            <wsa:addressing/>
        </jaxws:features>
    </jaxws:endpoint>
</beans>

4. Configuring WS-Addressing Attributes

Overview

The Apache CXF WS-Addressing feature element is defined in the namespace http://cxf.apache.org/ws/addressing. It supports the two attributes described in Table 17.2, “WS-Addressing Attributes”.

Table 17.2. WS-Addressing Attributes

Attribute NameValue
allowDuplicates A boolean that determines if duplicate MessageIDs are tolerated. The default setting is true.
usingAddressingAdvisory A boolean that indicates if the presence of the UsingAddressing element in the WSDL is advisory only; that is, its absence does not prevent the encoding of WS-Addressing headers.

Configuring WS-Addressing attributes

Configure WS-Addressing attributes by adding the attribute and the value you want to set it to the WS-Addressing feature in your server or client configuration file. For example, the following configuration extract sets the allowDublicates attribute to false on the server endpoint:
<beans ... xmlns:wsa="http://cxf.apache.org/ws/addressing" ...>
    <jaxws:endpoint ...>
        <jaxws:features>
            <wsa:addressing allowDuplicates="false"/>
        </jaxws:features>
    </jaxws:endpoint>
</beans>

Using a WS-Policy assertion embedded in a feature

In Example 17.3, “Using the Policies to Configure WS-Addressing” an addressing policy assertion to enable non-anonymous responses is embedded in the policies element.

Example 17.3. Using the Policies to Configure WS-Addressing

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:wsa="http://cxf.apache.org/ws/addressing"
        xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
        xmlns:policy="http://cxf.apache.org/policy-config"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
http://www.w3.org/2006/07/ws-policy http://www.w3.org/2006/07/ws-policy.xsd
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schema/ws/addressing.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <jaxws:endpoint name="{http://cxf.apache.org/greeter_control}GreeterPort"
                    createdFromAPI="true">
        <jaxws:features>
            <policy:policies>
                <wsp:Policy xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                    <wsam:Addressing>
                        <wsp:Policy>
                            <wsam:NonAnonymousResponses/>
                        </wsp:Policy>
                    </wsam:Addressing>
                </wsp:Policy>
            <policy:policies>
        </jaxws:features>
    </jaxws:endpoint>
</beans>

Chapter 18. Enabling Reliable Messaging

Abstract

Apache CXF supports WS-Reliable Messaging(WS-RM). This chapter explains how to enable and configure WS-RM in Apache CXF.

1. Introduction to WS-RM

Overview

WS-ReliableMessaging (WS-RM) is a protocol that ensures the reliable delivery of messages in a distributed environment. It enables messages to be delivered reliably between distributed applications in the presence of software, system, or network failures.
For example, WS-RM can be used to ensure that the correct messages have been delivered across a network exactly once, and in the correct order.

How WS-RM works

Figure 18.1. Web Services Reliable Messaging

reliable message exchange
The flow of WS-RM messages can be described as follows:
This entire process occurs symmetrically for both the request and the response message; that is, in the case of the response message, the server acts as the RM source and the client acts as the RM destination.

WS-RM delivery assurances

WS-RM guarantees reliable message delivery in a distributed environment, regardless of the transport protocol used. Either the source or the destination endpoint logs an error if reliable delivery can not be assured.

Supported specifications

Apache CXF supports the 2005/02 version of the WS-RM specification, which is based on the WS-Addressing 2004/08 specification.

Further information

For detailed information on WS-RM, see the specification at http://specs.xmlsoap.org/ws/2005/02/rm/ws-reliablemessaging.pdf.

2. WS-RM Interceptors

Overview

In Apache CXF, WS-RM functionality is implemented as interceptors. The Apache CXF runtime uses interceptors to intercept and work with the raw messages that are being sent and received. When a transport receives a message, it creates a message object and sends that message through an interceptor chain. If the application's interceptor chain includes the WS-RM interceptors, the application can participate in reliable messaging sessions. The WS-RM interceptors handle the collection and aggregation of the message chunks. They also handle all of the acknowledgement and retransmission logic.

Apache CXF WS-RM Interceptors

Table 18.1. Apache CXF WS-ReliableMessaging Interceptors

InterceptorDescription
org.apache.cxf.ws.rm.RMOutInterceptor
Deals with the logical aspects of providing reliability guarantees for outgoing messages.
Responsible for sending the CreateSequence requests and waiting for their CreateSequenceResponse responses.
Also responsible for aggregating the sequence properties—ID and message number—for an application message.
org.apache.cxf.ws.rm.RMInInterceptorResponsible for intercepting and processing RM protocol messages and SequenceAcknowledgement messages that are piggybacked on application messages.
org.apache.cxf.ws.rm.soap.RMSoapInterceptorResponsible for encoding and decoding the reliability properties as SOAP headers.
org.apache.cxf.ws.rm.RetransmissionInterceptorResponsible for creating copies of application messages for future resending.

Enabling WS-RM

The presence of the WS-RM interceptors on the interceptor chains ensures that WS-RM protocol messages are exchanged when necessary. For example, when intercepting the first application message on the outbound interceptor chain, the RMOutInterceptor sends a CreateSequence request and waits to process the original application message until it receives the CreateSequenceResponse response. In addition, the WS-RM interceptors add the sequence headers to the application messages and, on the destination side, extract them from the messages. It is not necessary to make any changes to your application code to make the exchange of messages reliable.
For more information on how to enable WS-RM, see Section 3, “Enabling WS-RM”.

Configuring WS-RM Attributes

You control sequence demarcation and other aspects of the reliable exchange through configuration. For example, by default Apache CXF attempts to maximize the lifetime of a sequence, thus reducing the overhead incurred by the out-of-band WS-RM protocol messages. To enforce the use of a separate sequence per application message configure the WS-RM source’s sequence termination policy (setting the maximum sequence length to 1).
For more information on configuring WS-RM behavior, see Section 4, “Configuring WS-RM”.

3. Enabling WS-RM

Overview

To enable reliable messaging, the WS-RM interceptors must be added to the interceptor chains for both inbound and outbound messages and faults. Because the WS-RM interceptors use WS-Addressing, the WS-Addressing interceptors must also be present on the interceptor chains.
You can ensure the presence of these interceptors in one of two ways:
  • Explicitly, by adding them to the dispatch chains using Spring beans
  • Implicitly, using WS-Policy assertions, which cause the Apache CXF runtime to transparently add the interceptors on your behalf.

Spring beans—explicitly adding interceptors

To enable WS-RM add the WS-RM and WS-Addressing interceptors to the Apache CXF bus, or to a consumer or service endpoint using Spring bean configuration. This is the approach taken in the WS-RM sample that is found in the InstallDir/samples/ws_rm directory. The configuration file, ws-rm.cxf, shows the WS-RM and WS-Addressing interceptors being added one-by-one as Spring beans (see Example 18.1, “Enabling WS-RM Using Spring Beans”).

Example 18.1. Enabling WS-RM Using Spring Beans

<?xml version="1.0" encoding="UTF-8"?>
1<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/
   beans http://www.springframework.org/schema/beans/spring-beans.xsd">
2   <bean id="mapAggregator" class="org.apache.cxf.ws.addressing.MAPAggregator"/>
   <bean id="mapCodec" class="org.apache.cxf.ws.addressing.soap.MAPCodec"/>
3   <bean id="rmLogicalOut" class="org.apache.cxf.ws.rm.RMOutInterceptor">
        <property name="bus" ref="cxf"/>
   </bean>
   <bean id="rmLogicalIn" class="org.apache.cxf.ws.rm.RMInInterceptor">
        <property name="bus" ref="cxf"/>
   </bean>
   <bean id="rmCodec" class="org.apache.cxf.ws.rm.soap.RMSoapInterceptor"/>
   <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl">
4        <property name="inInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalIn"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
5        <property name="inFaultInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalIn"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
6        <property name="outInterceptors">
            <list>
                <ref bean="mapAggregator"/>
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalOut"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
7        <property name="outFaultInterceptors">
            <list>
                <ref bean="mapAggregator">
                <ref bean="mapCodec"/>
                <ref bean="rmLogicalOut"/>
                <ref bean="rmCodec"/>
            </list>
        </property>
    </bean>
</beans>
The code shown in Example 18.1, “Enabling WS-RM Using Spring Beans” can be explained as follows:
1
A Apache CXF configuration file is a Spring XML file. You must include an opening Spring beans element that declares the namespaces and schema files for the child elements that are encapsulated by the beans element.
2
Configures each of the WS-Addressing interceptors—MAPAggregator and MAPCodec. For more information on WS-Addressing, see Chapter 17, Deploying WS-Addressing.
3
Configures each of the WS-RM interceptors—RMOutInterceptor, RMInInterceptor, and RMSoapInterceptor.
4
Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for inbound messages.
5
Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for inbound faults.
6
Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for outbound messages.
7
Adds the WS-Addressing and WS-RM interceptors to the interceptor chain for outbound faults.

WS-Policy framework—implicitly adding interceptors

The WS-Policy framework provides the infrastructure and APIs that allow you to use WS-Policy. It is compliant with the November 2006 draft publications of the Web Services Policy 1.5—Framework and Web Services Policy 1.5—Attachment specifications.
To enable WS-RM using the Apache CXF WS-Policy framework, do the following:
  1. Add the policy feature to your client and server endpoint. Example 18.2, “Configuring WS-RM using WS-Policy” shows a reference bean nested within a jaxws:feature element. The reference bean specifies the AddressingPolicy, which is defined as a separate element within the same configuration file.

    Example 18.2. Configuring WS-RM using WS-Policy

    <jaxws:client>
        <jaxws:features>
          <ref bean="AddressingPolicy"/>
        </jaxws:features>
    </jaxws:client>
    <wsp:Policy wsu:Id="AddressingPolicy" xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
        <wsam:Addressing>
          <wsp:Policy>
            <wsam:NonAnonymousResponses/>
          </wsp:Policy>
        </wsam:Addressing>
    </wsp:Policy>
  2. Add a reliable messaging policy to the wsdl:service element—or any other WSDL element that can be used as an attachment point for policy or policy reference elements—to your WSDL file, as shown in Example 18.3, “Adding an RM Policy to Your WSDL File”.

    Example 18.3. Adding an RM Policy to Your WSDL File

    <wsp:Policy wsu:Id="RM"
       xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
            <wsp:Policy/>
        </wsam:Addressing>
        <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
            <wsrmp:BaseRetransmissionInterval Milliseconds="10000"/>
        </wsrmp:RMAssertion>
    </wsp:Policy>
    ...
    <wsdl:service name="ReliableGreeterService">
        <wsdl:port binding="tns:GreeterSOAPBinding" name="GreeterPort">
            <soap:address location="http://localhost:9020/SoapContext/GreeterPort"/>
            <wsp:PolicyReference URI="#RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"/>
        </wsdl:port>
    </wsdl:service>

4. Configuring WS-RM

You can configure WS-RM by:
  • Setting Apache CXF-specific attributes that are defined in the Apache CXF WS-RM manager namespace, http://cxf.apache.org/ws/rm/manager.
  • Setting standard WS-RM policy attributes that are defined in the http://schemas.xmlsoap.org/ws/2005/02/rm/policy namespace.

4.1. Configuring Apache CXF-Specific WS-RM Attributes

Overview

To configure the Apache CXF-specific attributes, use the rmManager Spring bean. Add the following to your configuration file:
  • The http://cxf.apache.org/ws/rm/manager namespace to your list of namespaces.
  • An rmManager Spring bean for the specific attribute that your want to configure.

Example 18.4. Configuring Apache CXF-Specific WS-RM Attributes

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://cxf.apache.org/ws/rm/manager http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd">
...
<wsrm-mgr:rmManager>
<!--
  ...Your configuration goes here
-->
</wsrm-mgr:rmManager>

Children of the rmManager Spring bean

Table 18.2, “Children of the rmManager Spring Bean” shows the child elements of the rmManager Spring bean, defined in the http://cxf.apache.org/ws/rm/manager namespace.

Table 18.2. Children of the rmManager Spring Bean

ElementDescription
RMAssertionAn element of type RMAssertion
deliveryAssuranceAn element of type DeliveryAssuranceType that describes the delivery assurance that should apply
sourcePolicyAn element of type SourcePolicyType that allows you to configure details of the RM source
destinationPolicyAn element of type DestinationPolicyType that allows you to configure details of the RM destination

Example

4.2. Configuring Standard WS-RM Policy Attributes

Overview

You can configure standard WS-RM policy attributes in one of the following ways:

WS-Policy RMAssertion Children

Table 18.3, “Children of the WS-Policy RMAssertion Element” shows the elements defined in the http://schemas.xmlsoap.org/ws/2005/02/rm/policy namespace:

Table 18.3. Children of the WS-Policy RMAssertion Element

NameDescription
InactivityTimeout Specifies the amount of time that must pass without receiving a message before an endpoint can consider an RM sequence to have been terminated due to inactivity.
BaseRetransmissionInterval Sets the interval within which an acknowledgement must be received by the RM Source for a given message. If an acknowledgement is not received within the time set by the BaseRetransmissionInterval, the RM Source will retransmit the message.
ExponentialBackoff
Indicates the retransmission interval will be adjusted using the commonly known exponential backoff algorithm (Tanenbaum).
For more information, see Computer Networks, Andrew S. Tanenbaum, Prentice Hall PTR, 2003.
AcknowledgementInterval In WS-RM, acknowledgements are sent on return messages or sent stand-alone. If a return message is not available to send an acknowledgement, an RM Destination can wait for up to the acknowledgement interval before sending a stand-alone acknowledgement. If there are no unacknowledged messages, the RM Destination can choose not to send an acknowledgement.

More detailed reference information

For more detailed reference information, including descriptions of each element’s sub-elements and attributes, please refer to http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd.

RMAssertion in rmManager Spring bean

You can configure standard WS-RM policy attributes by adding an RMAssertion within a Apache CXF rmManager Spring bean. This is the best approach if you want to keep all of your WS-RM configuration in the same configuration file; that is, if you want to configure Apache CXF-specific attributes and standard WS-RM policy attributes in the same file.
  • A standard WS-RM policy attribute, BaseRetransmissionInterval, configured using an RMAssertion within an rmManager Spring bean.
  • An Apache CXF-specific RM attribute, intraMessageThreshold, configured in the same configuration file.

Example 18.5. Configuring WS-RM Attributes Using an RMAssertion in an rmManager Spring Bean

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
       xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
    </wsrm-policy:RMAssertion>
    <wsrm-mgr:destinationPolicy>
        <wsrm-mgr:acksPolicy intraMessageThreshold="0" />
    </wsrm-mgr:destinationPolicy>
</wsrm-mgr:rmManager>
</beans>

Policy within a feature

You can configure standard WS-RM policy attributes within features, as shown in Example 18.6, “Configuring WS-RM Attributes as a Policy within a Feature”.

Example 18.6. Configuring WS-RM Attributes as a Policy within a Feature

<xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:wsa="http://cxf.apache.org/ws/addressing"
        xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="
http://www.w3.org/2006/07/ws-policy http://www.w3.org/2006/07/ws-policy.xsd
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schema/ws/addressing.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <jaxws:endpoint name="{http://cxf.apache.org/greeter_control}GreeterPort" createdFromAPI="true">
        <jaxws:features>
               <wsp:Policy>
                   <wsrm:RMAssertion xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
                     <wsrm:AcknowledgementInterval Milliseconds="200" />
                   </wsrm:RMAssertion>
                   <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                       <wsp:Policy>
                            <wsam:NonAnonymousResponses/>
                       </wsp:Policy>
                   </wsam:Addressing>
              </wsp:Policy>
        </jaxws:features>
    </jaxws:endpoint>
</beans>

WSDL file

If you use the WS-Policy framework to enable WS-RM, you can configure standard WS-RM policy attributes in a WSDL file. This is a good approach if you want your service to interoperate and use WS-RM seamlessly with consumers deployed to other policy-aware Web services stacks.
For an example, see the section called “WS-Policy framework—implicitly adding interceptors” where the base retransmission interval is configured in the WSDL file.

External attachment

You can configure standard WS-RM policy attributes in an external attachment file. This is a good approach if you cannot, or do not want to, change your WSDL file.
Example 18.7, “Configuring WS-RM in an External Attachment” shows an external attachment that enables both WS-A and WS-RM (base retransmission interval of 30 seconds) for a specific EPR.

Example 18.7. Configuring WS-RM in an External Attachment

<attachments xmlns:wsp="http://www.w3.org/2006/07/ws-policy" xmlns:wsa="http://www.w3.org/2005/08/addressing">
    <wsp:PolicyAttachment>
        <wsp:AppliesTo>
           <wsa:EndpointReference>
                <wsa:Address>http://localhost:9020/SoapContext/GreeterPort</wsa:Address>
            </wsa:EndpointReference>
        </wsp:AppliesTo>
        <wsp:Policy>
            <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
                <wsp:Policy/>
            </wsam:Addressing>
            <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
                <wsrmp:BaseRetransmissionInterval Milliseconds="30000"/>
            </wsrmp:RMAssertion>
        </wsp:Policy>
    </wsp:PolicyAttachment>
</attachments>/

4.3. WS-RM Configuration Use Cases

Overview

This subsection focuses on configuring WS-RM attributes from a use case point of view. Where an attribute is a standard WS-RM policy attribute, defined in the http://schemas.xmlsoap.org/ws/2005/02/rm/policy namespace, only the example of setting it in an RMAssertion within an rmManager Spring bean is shown. For details of how to set such attributes as a policy within a feature; in a WSDL file, or in an external attachment, see Section 4.2, “Configuring Standard WS-RM Policy Attributes”.
The following use cases are covered:

Base retransmission interval

Example 18.8, “Setting the WS-RM Base Retransmission Interval” shows how to set the WS-RM base retransmission interval.

Example 18.8. Setting the WS-RM Base Retransmission Interval

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>

Exponential backoff for retransmission

The ExponentialBackoff element determines if successive retransmission attempts for an unacknowledged message are performed at exponential intervals.
The presence of the ExponentialBackoff element enables this feature. An exponential backoff ratio of 2 is used by default.
Example 18.9, “Setting the WS-RM Exponential Backoff Property” shows how to set the WS-RM exponential backoff for retransmission.

Example 18.9. Setting the WS-RM Exponential Backoff Property

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:ExponentialBackoff="4"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>

Acknowledgement interval

The AcknowledgementInterval element specifies the interval at which the WS-RM destination sends asynchronous acknowledgements. These are in addition to the synchronous acknowledgements that it sends on receipt of an incoming message. The default asynchronous acknowledgement interval is 0 milliseconds. This means that if the AcknowledgementInterval is not configured to a specific value, acknowledgements are sent immediately (that is, at the first available opportunity).
Asynchronous acknowledgements are sent by the RM destination only if both of the following conditions are met:
  • The RM destination is using a non-anonymous wsrm:acksTo endpoint.
  • The opportunity to piggyback an acknowledgement on a response message does not occur before the expiry of the acknowledgement interval.
Example 18.10, “Setting the WS-RM Acknowledgement Interval” shows how to set the WS-RM acknowledgement interval.

Example 18.10. Setting the WS-RM Acknowledgement Interval

<beans xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy
...>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <wsrm-policy:RMAssertion>
        <wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>
    </wsrm-policy:RMAssertion>
</wsrm-mgr:rmManager>
</beans>

Maximum unacknowledged messages threshold

The maxUnacknowledged attribute sets the maximum number of unacknowledged messages that can accrue per sequence before the sequence is terminated.
Example 18.11, “Setting the WS-RM Maximum Unacknowledged Message Threshold” shows how to set the WS-RM maximum unacknowledged messages threshold.

Example 18.11. Setting the WS-RM Maximum Unacknowledged Message Threshold

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxUnacknowledged="20" />
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:reliableMessaging>
</beans>

Maximum length of an RM sequence

The maxLength attribute sets the maximum length of a WS-RM sequence. The default value is 0, which means that the length of a WS-RM sequence is unbound.
When this attribute is set, the RM endpoint creates a new RM sequence when the limit is reached, and after receiving all of the acknowledgements for the previously sent messages. The new message is sent using a newsequence.
Example 18.12, “Setting the Maximum Length of a WS-RM Message Sequence” shows how to set the maximum length of an RM sequence.

Example 18.12. Setting the Maximum Length of a WS-RM Message Sequence

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxLength="100" />
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:reliableMessaging>
</beans>

Message delivery assurance policies

You can configure the RM destination to use the following delivery assurance policies:
Example 18.13, “Setting the WS-RM Message Delivery Assurance Policy” shows how to set the WS-RM message delivery assurance.

Example 18.13. Setting the WS-RM Message Delivery Assurance Policy

<beans xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager
...>
<wsrm-mgr:reliableMessaging>
    <wsrm-mgr:deliveryAssurance>
        <wsrm-mgr:AtLeastOnce />
    </wsrm-mgr:deliveryAssurance>
</wsrm-mgr:reliableMessaging>
</beans>

5. Configuring WS-RM Persistence

Overview

The Apache CXF WS-RM features already described in this chapter provide reliability for cases such as network failures. WS-RM persistence provides reliability across other types of failure such as an RM source or an RM destination crash.
WS-RM persistence involves storing the state of the various RM endpoints in persistent storage. This enables the endpoints to continue sending and receiving messages when they are reincarnated.
Apache CXF enables WS-RM persistence in a configuration file. The default WS-RM persistence store is JDBC-based. For convenience, Apache CXF includes Derby for out-of-the-box deployment. In addition, the persistent store is also exposed using a Java API.
Important
WS-RM persistence is supported for oneway calls only, and it is disabled by default.

How it works

Apache CXF WS-RM persistence works as follows:
  • At the RM source endpoint, an outgoing message is persisted before transmission. It is evicted from the persistent store after the acknowledgement is received.
  • After a recovery from crash, it recovers the persisted messages and retransmits until all the messages have been acknowledged. At that point, the RM sequence is closed.
  • At the RM destination endpoint, an incoming message is persisted, and upon a successful store, the acknowledgement is sent. When a message is successfully dispatched, it is evicted from the persistent store.
  • After a recovery from a crash, it recovers the persisted messages and dispatches them. It also brings the RM sequence to a state where new messages are accepted, acknowledged, and delivered.

Enabling WS-persistence

To enable WS-RM persistence, you must specify the object implementing the persistent store for WS-RM. You can develop your own or you can use the JDBC based store that comes with Apache CXF.
The configuration shown in Example 18.14, “Configuration for the Default WS-RM Persistence Store” enables the JDBC-based store that comes with Apache CXF.

Example 18.14. Configuration for the Default WS-RM Persistence Store

<bean id="RMTxStore" class="org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore"/>
<wsrm-mgr:rmManager id="org.apache.cxf.ws.rm.RMManager">
    <property name="store" ref="RMTxStore"/>
</wsrm-mgr:rmManager>

Configuring WS-persistence

The JDBC-based store that comes with Apache CXF supports the properties shown in Table 18.4, “JDBC Store Properties”.

Table 18.4. JDBC Store Properties

Attribute NameTypeDefault Setting
driverClassName Stringorg.apache.derby.jdbc.EmbeddedDriver
userName Stringnull
passWord Stringnull
url Stringjdbc:derby:rmdb;create=true
The configuration shown in Example 18.15, “Configuring the JDBC Store for WS-RM Persistence” enables the JDBC-based store that comes with Apache CXF, while setting the driverClassName and url to non-default values.

Example 18.15. Configuring the JDBC Store for WS-RM Persistence

<bean id="RMTxStore" class="org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore">
    <property name="driverClassName" value="com.acme.jdbc.Driver"/>
    <property name="url" value="jdbc:acme:rmdb;create=true"/>
</bean>

Chapter 19. Enabling High Availability

Abstract

This chapter explains how to enable and configure high availability in the Apache CXF runtime.

1. Introduction to High Availability

Overview

Scalable and reliable applications require high availability to avoid any single point of failure in a distributed system. You can protect your system from single points of failure using replicated services.
Apache CXF supports high availability (HA) with static failover in which replica details are encoded in the service WSDL file. The WSDL file contains multiple ports, and can contain multiple hosts, for the same service. The number of replicas in the cluster remains static as long as the WSDL file remains unchanged. Changing the cluster size involves editing the WSDL file.
To enable HA with static failover, you must do the following:

Encode replica details in your service WSDL file

You must encode the details of the replicas in your cluster in your service WSDL file. Example 19.1, “Enabling HA with Static Failover—WSDL File” shows a WSDL file extract that defines a service cluster of three replicas.

Example 19.1. Enabling HA with Static Failover—WSDL File

1<wsdl:service name="ClusteredService">
2    <wsdl:port binding="tns:Greeter_SOAPBinding" name="Replica1">
        <soap:address location="http://localhost:9001/SoapContext/Replica1"/>
    </wsdl:port>

3    <wsdl:port binding="tns:Greeter_SOAPBinding" name="Replica2">
        <soap:address location="http://localhost:9002/SoapContext/Replica2"/>
    </wsdl:port>

4    <wsdl:port binding="tns:Greeter_SOAPBinding" name="Replica3">
        <soap:address location="http://localhost:9003/SoapContext/Replica3"/>
    </wsdl:port>

</wsdl:service>
The WSDL extract shown in Example 19.1, “Enabling HA with Static Failover—WSDL File” can be explained as follows:
1
Defines a service, ClusterService, which is exposed on three ports:
  1. Replica1
  2. Replica2
  3. Replica3
2
Defines Replica1 to expose the ClusterService as a SOAP over HTTP endpoint on port 9001.
3
Defines Replica2 to expose the ClusterService as a SOAP over HTTP endpoint on port 9002.
4
Defines Replica3 to expose the ClusterService as a SOAP over HTTP endpoint on port 9003.

Add the clustering feature to your client configuration

Example 19.2. Enabling HA with Static Failover—Client Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:clustering="http://cxf.apache.org/clustering"
         xsi:schemaLocation="http://cxf.apache.org/jaxws
         http://cxf.apache.org/schemas/jaxws.xsd
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica1"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover/>
        </jaxws:features>
    </jaxws:client>

    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica2"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover/>
        </jaxws:features>
    </jaxws:client>

    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica3"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover/>
        </jaxws:features>
    </jaxws:client>
    
</beans>

3. Configuring HA with Static Failover

Overview

By default, HA with static failover uses a sequential strategy when selecting a replica service if the original service with which a client is communicating becomes unavailable, or fails. The sequential strategy selects a replica service in the same sequential order every time it is used. Selection is determined by Apache CXF’s internal service model and results in a deterministic failover pattern.
You can configure HA with static failover to use a random strategy instead of the sequential strategy when selecting a replica. The random strategy selects a random replica service each time a service becomes unavailable, or fails. The choice of failover target from the surviving members in a cluster is entirely random.

Example 19.3. Configuring a Random Strategy for Static Failover

<beans ...>
1    <bean id="Random" class="org.apache.cxf.clustering.RandomStrategy"/>
    
    <jaxws:client name="{http://apache.org/hello_world_soap_http}Replica3"
                  createdFromAPI="true">
        <jaxws:features>
            <clustering:failover>
2                <clustering:strategy>
                    <ref bean="Random"/>
                </clustering:strategy>
            </clustering:failover>
        </jaxws:features>
    </jaxws:client>
</beans>
The configuration shown in Example 19.3, “Configuring a Random Strategy for Static Failover” can be explained as follows:
1
Defines a Random bean and implementation class that implements the random strategy.
2
Specifies that the random strategy is used when selecting a replica.

Chapter 20. Enabling High Availability in Fuse Fabric

Abstract

When all of your servers and clients are deployed within the same fabric, you can use an alternative mechanism for implementing high availability cluster, which works by exploiting the fabric registry. Because all the parts of the application must be deployed on the same fabric, this mechanism is suitable for deployment on a LAN.

1. Load Balancing Cluster

1.1. Introduction to Load Balancing

Overview

The fabric load balancing mechanism exploits the fact that fabric provides a distributed fabric registry, which is accessible to all of the container in the fabric. This makes it possible to use the fabric registry as a discovery mechanism for locating WS endpoints in the fabric. By storing all of the endpoint addresses belonging to a particular cluster under the same registry node, any WS clients in the fabric can easily discover the location of the endpoints in the cluster.

Fuse Fabric

A fabric is a distributed collection of containers that share a common database of configuration settings (the fabric registry). Every container in the fabric has a fabric agent deployed in it, which manages the container and redeploys applications to the container whenever a new profile is assigned to the container (a profile is the basic deployment unit in a fabric).

Load-balancing cluster

Figure 20.1, “Fabric Load Balancing for Apache CXF” gives an overview of the fabric load balancing mechanism for Apache CXF endpoints.

Figure 20.1. Fabric Load Balancing for Apache CXF

Fabric Load Balancing for Apache CXF
In this example, two WS servers are created, with the URIs, http://localhost:8185/Foo and http://localhost:8186/Foo. For both of these servers, the load balancer feature is configured to store the cluster endpoints under the path, demo/lb, in the fabric registry.
Now, when the WS client starts, it is configured to look up the cluster path, demo/lb, in the fabric registry. Because the demo/lb path is associated with multiple endpoint addresses, fabric implements a random load balancing algorithm to choose one of the available URIs to connect to.

FabricLoadBalancerFeature

The fabric load balancer feature is implemented by the following class:
io.fabric8.cxf.FabricLoadBalancerFeature
The FabricLoadBalancerFeature class exposes the following bean properties:
fabricPath
This property specifies a node in the fabric registry (specified relative to the base node, /fabric/cxf/endpoints) that is used to store the data for a particular endpoint cluster.
curator
A proxy reference to the OSGi service exposed by the fabric agent (of type, org.apache.curator.framework.CuratorFramework).
maximumConnectionTimeout
The maximum length of time to attempt to connect to the fabric agent, specified in milliseconds. The default is 10000 (10 seconds).
connectionRetryTime
How long to wait between connection attempts, specified in milliseconds. The default is 100.
loadBalanceStrategy
By implementing a bean of type io.fabric8.cxf.LoadBalanceStrategy and setting this property, you can customise the load balancing algorithm used by the load balancing feature.

Prerequisites

To use the fabric load balancer feature in your application, your project must satisfy the following prerequisites:

Maven dependency

The fabric load balancer feature requires the fabric-cxf Maven artifact. Add the following dependency to your project's POM file:
<dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>fabric-cxf</artifactId>
    <version>6.1.0.redhat-379</version>
</dependency>

OSGi package import

If you are packaging your project as an OSGi bundle, you must add io.fabric8.cxf to the list of imported packages. For example, using the Maven bundle plug-in, you can specify this package import by adding io.fabric8.cxf to the comma-separated list in the Import-Package element, as follows:
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>2.2.0</version>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            <Import-Package>
                ...
 io.fabric8.cxf,
                *
            </Import-Package>
            ...
        </instructions>
    </configuration>
</plugin>

Fabric deployment

When you come to deploy your application into a Red Hat JBoss Fuse container, you must deploy it into a fabric. The fabric load balancer feature is not supported in a standalone container.

Required feature

The fabric load balancer requires the fabric-cxf Apache Karaf feature to be installed in the container. In the context of a fabric, this means you must add the fabric-cxf feature to the relevant deployment profile. For example, if you are using the cxf-lb-server profile to deploy a load-balancing WS server, you can add the fabric-cxf feature by entering the following console command:
JBossFuse:karaf@root> profile-edit -f fabric-cxf cxf-lb-server

1.2. Configure the Server

Overview

To configure a WS server to use fabric load balancing, you must configure a fabric load balancer feature and install it in the default Apache CXF bus instance. This section describes how to configure the load balancer feature in Spring XML and in blueprint XML.

Prerequisites

For the basic prerequisites to build a fabric load-balancing WS server, see the section called “Prerequisites”.

Blueprint XML

The following fragment from a blueprint XML file shows how to add the fabric load balancer feature, FabricLoadBalancerFeature, to an Apache CXF bus. Any Apache CXF endpoints subsequently created on this bus will automatically have the load-balancer feature enabled.
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           ...
           xmlns:cxf="http://cxf.apache.org/blueprint/core"
           ...
>
    ...
    <reference id="curator"
               interface="org.apache.curator.framework.CuratorFramework" />

    <!-- The FabricFailOverFeature will try to access other service endpoint with round rad -->
    <bean id="fabricLoadBalancerFeature" class="io.fabric8.cxf.FabricLoadBalancerFeature">
        <property name="curator" ref="curator" />
        <property name="fabricPath" value="cxf/demo" />
    </bean>

    <!-- setup the feature on the bus to help publish the services to the fabric-->
    <cxf:bus bus="cxf">
        <cxf:features>
            <ref component-id="fabricLoadBalancerFeature"/>
        </cxf:features>
    </cxf:bus>
    ...
</blueprint>
The following beans are used to install the fabric load-balancer feature:
curator reference
The curator reference is a proxy of the local fabric agent, which it accesses through the org.apache.curator.framework.CuratorFramework interface. This reference is needed in order to integrate the load balancer feature with the underlying fabric.
FabricLoadBalancerFeature bean
The FabricLoadBalancerFeature bean is initialized with the following properties:
curator
A reference to the Apache Curator client, CuratorFramework.
fabricPath
The path of a node in the fabric registry, where the cluster data is stored (for example, the addresses of the endpoints in the load-balancing cluster). The node path is specified relative to the base node, /fabric/cxf/endpoints.
Apache CXF bus
The cxf:bus element installs the fabric load balancer feature in the default bus instance.

Example using Blueprint XML

Example 20.1, “WS Server with Fabric Load Balancer Feature” shows a complete Blueprint XML example of a WS endpoint configured to use the fabric load balancing feature.

Example 20.1. WS Server with Fabric Load Balancer Feature

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:cxf="http://cxf.apache.org/blueprint/core"
           xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
           xsi:schemaLocation="
           http://www.osgi.org/xmlns/blueprint/v1.0.0
           http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
           http://cxf.apache.org/schemas/blueprint/core
           http://cxf.apache.org/schemas/blueprint/core.xsd
           http://cxf.apache.org/blueprint/jaxws
           http://cxf.apache.org/blueprint/jaxws.xsd
           ">

    <reference id="curator" interface="org.apache.curator.framework.CuratorFramework" />

    <!-- The FabricFailOverFeature will try to access other service endpoint with round rad -->
    <bean id="fabicLoadBalancerFeature" class="io.fabric8.cxf.FabricLoadBalancerFeature">
        <property name="curator" ref="curator" />
        <property name="fabricPath" value="cxf/demo" />
    </bean>

    <!-- setup the feature on the bus to help publish the services to the fabric-->
    <cxf:bus bus="cxf">
        <cxf:features>
            <ref component-id="fabicLoadBalancerFeature"/>
        </cxf:features>
    </cxf:bus>

    <bean id="hello1" class="io.fabric8.demo.cxf.server.HelloImpl">
        <property name="hello" value="Hi"/>
    </bean>

    <bean id="hello2" class="io.fabric8.demo.cxf.server.HelloImpl">
        <property name="hello" value="Hello"/>
    </bean>

    <!--
    TODO: We should use address in the form of http://$[bind.address]:$[app1.port]/server/server1, but currently only fuseenterprise
    has appX.port system properties defined
    -->

    <!-- publish the service with the address of fail, cxf client will get the simulated IOException -->
    <jaxws:server id="service1" serviceClass="io.fabric8.demo.cxf.Hello" address="http://localhost:9000/server/server1">
        <jaxws:serviceBean>
             <ref component-id="hello1" />
        </jaxws:serviceBean>
    </jaxws:server>

    <jaxws:server id="service2" serviceClass="io.fabric8.demo.cxf.Hello" address="http://localhost:9000/server/server2">
        <jaxws:serviceBean>
            <ref component-id="hello2" />
        </jaxws:serviceBean>
    </jaxws:server>

</blueprint>
The preceding Spring XML configuration consists of the following main sections:
  • Enabling the fabric load balancing feature—the fabric load balancing feature is installed in the default bus instance, as previously described. In this example, the fabricPath property is set to the value, cxf/demo.
  • Creating the WS endpoints—create the WS endpoints in the usual way, using the jaxws:server element (this can be used as an alternative to the jaxws:endpoint element). By default, this endpoint is automatically associated with the default bus instance, which has load balancing enabled.

1.3. Configure the Client

Overview

To configure a WS client to use fabric load balancing, you must install the fabric load balancer feature directly in the client proxy instance. This section describes how to configure the load balancer feature in Blueprint XML, and by programming in Java.

Prerequisites

For the basic prerequisites to build a fabric load-balancing WS client, see the section called “Prerequisites”.

Blueprint XML

The following fragment from a blueprint XML file shows how to add the fabric load balancer feature, FabricLoadBalancerFeature, directly into a WS client proxy instance.
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           ...
           xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws"
           xmlns:cxf="http://cxf.apache.org/blueprint/core"
           ...
>
    <!-- Create a client proxy, with load balancing enabled -->
    <jaxws:client id="ClientProxyBeanID"
        address="http://dummyaddress"
        serviceClass="SEI">
        <jaxws:features>
            <ref component-id="fabricLoadBalancerFeature" />
        </jaxws:features>
    </jaxws:client>
    ...
    <reference id="curator"
               interface="org.apache.curator.framework.CuratorFramework" />

    <!-- The FabricFailOverFeature will try to access other service endpoint with round rad -->
    <bean id="fabricLoadBalancerFeature" class="io.fabric8.cxf.FabricLoadBalancerFeature">
        <property name="curator" ref="curator" />
        <property name="fabricPath" value="ZKPath" />
    </bean>
    ...
</blueprint>
The fabric load balancer feature is installed directly into the WS client proxy by inserting it as a child of the jaxws:features element (or, as in this case, by inserting a bean reference to the actual instance). The following beans are used to initialise the fabric load-balancer feature:
curator reference
The curator reference is a proxy of the local fabric agent, which it accesses through the org.apache.curator.framework.CuratorFramework interface. This reference is needed in order to integrate the load balancer feature with the underlying fabric.
FabricLoadBalancerFeature bean
The FabricLoadBalancerFeature bean is initialized with the following properties:
curator
A reference to the Apache Curator client, curator.
fabricPath
The path of a node in the fabric registry, where the cluster data is stored (for example, the addresses of the endpoints in the load-balancing cluster). The node path is specified relative to the base node, /fabric/cxf/endpoints.

Java

As an alternative to using XML configuration, you can enable the fabric load balancing feature on the client side by programming directly in Java. The following example shows how to enable fabric load balancing on a proxy for the Hello Web service.
// Java
package io.fabric8.demo.cxf.client;

import org.apache.cxf.feature.AbstractFeature;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import io.fabric8.cxf.FabricLoadBalancerFeature;
import io.fabric8.demo.cxf.Hello;

import java.util.ArrayList;
import java.util.List;

public class Client {
    
    private Hello hello;

    public void initializeHelloProxy() {
        // The feature will try to create a zookeeper client itself
        // by checking the system property of zookeeper.url
        FabricLoadBalancerFeature feature = new FabricLoadBalancerFeature();
        // Feature will use this path to locate the service
        feature.setFabricPath("demo/lb");

        ClientProxyFactoryBean clientFactory = new JaxWsProxyFactoryBean();
        clientFactory.setServiceClass(ClientProxyFactoryBean.class);
        // The address is not the actual address that the client will access
        clientFactory.setAddress("http://dummyaddress");

        List<AbstractFeature> features = new ArrayList<AbstractFeature>();
        features.add(feature);
        // we need to setup the feature on the client factory
        clientFactory.setFeatures(features);

        // Create the proxy of Hello
        hello = clientFactory.create(Hello.class);
    }
    
    public static void main(String args[]) {
        initializeHelloProxy();
        ...
    }
}
In this example, the fabricPath property is set to the value, demo/lb (which matches the example value used by the server in Example 20.1, “WS Server with Fabric Load Balancer Feature”).
The address that the client proxy accesses is set to a dummy value, http://dummyaddress, because this value is not used. When the client is initialized, the load balancer feature substitutes the address value retrieved from the demo/lb node of the fabric registry.

2. Failover Cluster

Overview

A failover cluster in Fuse Fabric is based on an ordered list of WS endpoints that are registered under a particular node in the fabric registry. A client detects the failure of a master endpoint by catching the exception that occurs when it tries to make an invocation. When that happens, the client automatically moves to the next available endpoint in the cluster.

Failover cluster

Figure 20.2, “Fabric Failover for Apache CXF” gives an overview of the fabric failover mechanism for Apache CXF endpoints.

Figure 20.2. Fabric Failover for Apache CXF

Fabric Failover for Apache CXF
In this example, two WS servers are created, with the URIs, http://localhost:8185/Foo and http://localhost:8186/Foo. In both servers, the failover feature is configured to store the cluster endpoints under the path, demo/fo, in the fabric registry. The cluster endpoints stored under demo/fo are ordered. The first endpoint in the cluster is the master and all of the other endpoints are slaves.
The failover algorithm works as follows:
  1. When the WS client starts, it is configured to look up the cluster path, demo/fo, in the fabric registry. The failover feature initially returns the first address registered under demo/fo (the master).
  2. At some point, the master server could fail. The client determines whether the master has failed by catching the exception that occurs when it tries to make an invocation: if the caught exception matches one of the exceptions in a specified list (by default, just the java.io.IOException), the master is deemed to have failed and the client now ignores the corresponding address entry under demo/fo.
  3. The client selects the next address entry under demo/fo and attempts to connect to that server. Assuming that this server is healthy, it is effectively the new master.
  4. At some point in the future, if the failed old master is restarted successfully, it creates a new address entry under demo/fo after the existing entries, and is then available to clients, in case the other server (or servers) fail.

FabricFailOverFeature

The fabric failover feature is implemented by the following class:
io.fabric8.cxf.FabricFailOverFeature
The FabricFailOverFeature class exposes the following bean properties:
fabricPath
This property specifies a node in the fabric registry (specified relative to the base node, /fabric/cxf/endpoints) that is used to store the data for a particular endpoint cluster.
curator
A proxy reference to the OSGi service (of type, org.apache.curator.framework.CuratorFramework) for the Apache Curator client, which is exposed by the fabric agent.
maximumConnectionTimeout
The maximum length of time to attempt to connect to the fabric agent, specified in milliseconds. The default is 10000 (10 seconds).
connectionRetryTime
How long to wait between connection attempts, specified in milliseconds. The default is 100.
exceptions
A semicolon-separated list of exceptions that signal to the client that a server has failed. If not set, this property defaults to java.io.IOException.
For example, you could set the exceptions property to a value like the following:
java.io.IOException;javax.xml.ws.soap.SOAPFaultException

Blueprint XML

The configuration of WS servers and WS clients in the failover case is similar to the load balancing case (see Section 1.2, “Configure the Server” and Section 1.3, “Configure the Client”), except that instead of instantiating and referencing a FabricLoadBalancerFeature bean, you must instantiate and reference a FabricFailOverFeature bean.
In blueprint XML you can create a FabricFailOverFeature bean instance as follows:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           ...
           xmlns:cxf="http://cxf.apache.org/blueprint/core"
           ...
>
    ...
    <!-- Reference the fabric agent -->
    <reference id="curator"
               interface="org.apache.curator.framework.CuratorFramework" />

    <!-- Create the Fabric load balancer feature -->
    <bean id="failoverFeature"
          class="io.fabric8.cxf.FabricFailOverFeature">
        <property name="curator" ref="curator" />
        <property name="fabricPath" value="ZKPath" />
    </bean>
    ...
</blueprint>
Remember to customise the value of the fabricPath property and to reference the appropriate bean ID (failoverFeature in the preceding example).

Chapter 21. Packaging an Application

Abstract

Applications must be packed as an OSGi bundle before they can be deployed into Red Hat JBoss Fuse. You will not need to include any Apache CXF specific packages in your bundle. The Apache CXF packages are included in JBoss Fuse. You need to ensure you import the required packages when building your bundle.

Creating a bundle

To deploy a Apache CXF application into Red Hat JBoss Fuse, you need to package it as an OSGi bundle. There are several tools available for assisting in the process. JBoss Fuse uses the Maven bundle plug-in whose use is described in Appendix D, Using the Maven OSGi Tooling.

Required bundle

The Apache CXF runtime components are included in JBoss Fuse as an OSGi bundle called org.apache.cxf.cxf-bundle. This bundle needs to be installed in the JBoss Fuse container before your application's bundle can be started.
To inform the container of this dependency, you use the OSGi manifest's Required-Bundle property.

Required packages

In order for your application to use the Apache CXF components, you need to import their packages into the application's bundle. Because of the complex nature of the dependencies in Apache CXF, you cannot rely on the Maven bundle plug-in, or the bnd tool, to automatically determine the needed imports. You will need to explicitly declare them.
You need to import the following packages into your bundle:
  • javax.jws
  • javax.wsdl
  • META-INF.cxf
  • META-INF.cxf.osgi
  • org.apache.cxf.bus
  • org.apache.cxf.bus.spring
  • org.apache.cxf.bus.resource
  • org.apache.cxf.configuration.spring
  • org.apache.cxf.resource
  • org.apache.servicemix.cxf.transport.http_osgi
  • org.springframework.beans.factory.config

Example

Example 21.1, “Apache CXF Application Manifest” shows a manifest for a Apache CXF application's OSGi bundle.

Example 21.1. Apache CXF Application Manifest

Manifest-Version: 1.0
Built-By: FinnMcCumial
Created-By: Apache Maven Bundle Plugin
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Import-Package: javax.jws,javax.wsdl,META-INF.cxf,META-INF.cxf.osgi,
org.apache.cxf.bus,org.apache.cxf.bus.spring,org.apache.bus.resource,
org.apache.cxf.configuration.spring, org.apache.cxf.resource,
org.apache.servicemix.cxf.transport.http_cxf,
org.springframework.beans.factory.config
Bnd-LastModified: 1222079507224
Bundle-Version: 4.0.0.fuse
Bundle-Name: Fuse CXF Example
Bundle-Description: This is a sample CXF manifest.
Build-Jdk: 1.5.0_08
Private-Package: org.apache.servicemix.examples.cxf
Required-Bundle: org.apache.cxf.cxf-bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: cxf-wsdl-first-osgi
Tool: Bnd-0.0.255

Chapter 22. Deploying an Application

Abstract

Red Hat JBoss Fuse will automatically install and deploy your application. You can also manually control the state of your application using the console.

Overview

There are two ways to deploy your application into Red Hat JBoss Fuse:
  1. Rely on the hot deployment mechanism.
  2. Use the console.
You can also start and stop a deployed application using the console.

Hot deployment

The easiest way to deploy an application is to place it in the hot deployment folder. By default, the hot deployment folder is InstallDir/deploy. Any bundle placed in this folder is installed into the container. If its dependencies can be resolved, the bundle is activated.
One the bundle is installed in the container, you can manage it using the console.

Deploying from the console

The easiest way to deploy an application from the console is to install it and start it in one step. This is done using the osgi install -s command. It takes the location of the bundle as a URI. So the command:
servicemix>osgi install -s file:/home/finn/ws/widgetapp.jar
Installs and attempts to start the bundle widgetapp.jar which is located in /home/finn/ws.
You can use the osgi install command without the -s flag. That will install the bundle without attempting to start it. You will then have to manually start the bundle using the osgi start command.

Refreshing an application

If you make changes to your application and want to redeploy it, you can do so by replacing the installed bundle with a new version and using the osgi refresh command. This command instructs the container to stop the running instance of your application, reload the bundle, and restart it.

Stopping an application

If you want to temporarily deactivate your application you can use the osgi stop command. The osgi stop moves your application's bundle from the active state to the resolved state. This means that it can be easily restarted using the osgi start command.

Uninstalling an application

When you want to permanently remove an application from the container you need to uninstall it. Bundles can only be installed when they are not active. This means that you have to stop your application using the osgi stop command before trying to unistall it.
Once the application's bundle is stopped, you can use the osgi uninstall command to remove the bundle from the container. This does not delete the physical bundle. It just removes the bundle from the container's list of installed bundles.


[1] You can get a list of the bundle IDs using the osgi list command.

Appendix C. Apache CXF Binding IDs

Table C.1. Binding IDs for Message Bindings

BindingID
CORBA http://cxf.apache.org/bindings/corba
HTTP/REST http://apache.org/cxf/binding/http
SOAP 1.1 http://schemas.xmlsoap.org/wsdl/soap/http
SOAP 1.1 w/ MTOM http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true
SOAP 1.2 http://www.w3.org/2003/05/soap/bindings/HTTP/
SOAP 1.2 w/ MTOM http://www.w3.org/2003/05/soap/bindings/HTTP/?mtom=true
XML http://cxf.apache.org/bindings/xformat

Appendix D. Using the Maven OSGi Tooling

Abstract

Manually creating a bundle, or a collection of bundles, for a large project can be cumbersome. The Maven bundle plug-in makes the job easier by automating the process and providing a number of shortcuts for specifying the contents of the bundle manifest.
The Red Hat JBoss Fuse OSGi tooling uses the Maven bundle plug-in from Apache Felix. The bundle plug-in is based on the bnd tool from Peter Kriens. It automates the construction of OSGi bundle manifests by introspecting the contents of the classes being packaged in the bundle. Using the knowledge of the classes contained in the bundle, the plug-in can calculate the proper values to populate the Import-Packages and the Export-Package properties in the bundle manifest. The plug-in also has default values that are used for other required properties in the bundle manifest.
To use the bundle plug-in, do the following:
  1. Add the bundle plug-in to your project's POM file.
  2. Configure the plug-in to correctly populate your bundle's manifest.

1. Setting up a Red Hat JBoss Fuse OSGi project

Overview

A Maven project for building an OSGi bundle can be a simple single level project. It does not require any sub-projects. However, it does require that you do the following:
  1. Add the bundle plug-in to your POM.
  2. Instruct Maven to package the results as an OSGi bundle.
Note
There are several Maven archetypes you can use to set up your project with the appropriate settings.

Directory structure

A project that constructs an OSGi bundle can be a single level project. It only requires that you have a top-level POM file and a src folder. As in all Maven projects, you place all Java source code in the src/java folder, and you place any non-Java resources in the src/resources folder.
Non-Java resources include Spring configuration files, JBI endpoint configuration files, and WSDL contracts.
Note
Red Hat JBoss Fuse OSGi projects that use Apache CXF, Apache Camel, or another Spring configured bean also include a beans.xml file located in the src/resources/META-INF/spring folder.

Adding a bundle plug-in

Before you can use the bundle plug-in you must add a dependency on Apache Felix. After you add the dependency, you can add the bundle plug-in to the plug-in portion of the POM.
Example D.1, “Adding an OSGi bundle plug-in to a POM” shows the POM entries required to add the bundle plug-in to your project.

Example D.1. Adding an OSGi bundle plug-in to a POM

...
<dependencies>
  <dependency> 1
    <groupId>org.apache.felix</groupId>
    <artifactId>org.osgi.core</artifactId>
    <version>1.0.0</version>
  </dependency>
...
</dependencies>
...
<build>
  <plugins>
    <plugin> 2
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <configuration>
        <instructions>
          <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> 3
          <Import-Package>*,org.apache.camel.osgi</Import-Package> 4
          <Private-Package>org.apache.servicemix.examples.camel</Private-Package> 5
        </instructions>
      </configuration> 
    </plugin>
  </plugins>
</build>
...
1
Adds the dependency on Apache Felix
2
Adds the bundle plug-in to your project
3
Configures the plug-in to use the project's artifact ID as the bundle's symbolic name
4
Configures the plug-in to include all Java packages imported by the bundled classes; also imports the org.apache.camel.osgi package
5
Configures the plug-in to bundle the listed class, but not to include them in the list of exported packages
Note
Edit the configuration to meet the requirements of your project.
For more information on configuring the bundle plug-in, see Section 2, “Configuring the Bundle Plug-In”.

Activating a bundle plug-in

To have Maven use the bundle plug-in, instruct it to package the results of the project as a bundle. Do this by setting the POM file's packaging element to bundle.

Useful Maven archetypes

There are several Maven archetypes to generate a project that is preconfigured to use the bundle plug-in:

Spring OSGi archetype

The Spring OSGi archetype creates a generic project for building an OSGi project using Spring DM, as shown:
org.springframework.osgi/spring-bundle-osgi-archetype/1.1.2
You invoke the archetype using the following command:
mvn archetype:create -DarchetypeGroupId=org.springframework.osgi -DarchetypeArtifactId=spring-osgi-bundle-archetype -DarchetypeVersion=1.12 -DgroupId=groupId -DartifactId=artifactId -Dversion=version

Apache CXF code-first archetype

The Apache CXF code-first archetype creates a project for building a service from Java, as shown:
org.apache.servicemix.tooling/servicemix-osgi-cxf-code-first-archetype/2008.01.0.3-fuse
You invoke the archetype using the following command:
mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=spring-osgi-bundle-archetype -DarchetypeVersion=2008.01.0.3-fuse -DgroupId=groupId -DartifactId=artifactId -Dversion=version

Apache CXF wsdl-first archetype

The Apache CXF wsdl-first archetype creates a project for creating a service from WSDL, as shown:
org.apache.servicemix.tooling/servicemix-osgi-cxf-wsdl-first-archetype/2008.01.0.3-fuse
You invoke the archetype using the following command:
mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-osgi-cxf-wsdl-first-archetype -DarchetypeVersion=2008.01.0.3-fuse -DgroupId=groupId -DartifactId=artifactId -Dversion=version

Apache Camel archetype

The Apache Camel archetype creates a project for building a route that is deployed into JBoss Fuse, as shown:
org.apache.servicemix.tooling/servicemix-osgi-camel-archetype/2008.01.0.3-fuse
You invoke the archetype using the following command:
mvn archetype:create -DarchetypeGroupId=org.apache.servicemix.tooling -DarchetypeArtifactId=servicemix-osgi-camel-archetype -DarchetypeVersion=2008.01.0.3-fuse -DgroupId=groupId -DartifactId=artifactId -Dversion=version 

2. Configuring the Bundle Plug-In

Overview

A bundle plug-in requires very little information to function. All of the required properties use default settings to generate a valid OSGi bundle.
While you can create a valid bundle using just the default values, you will probably want to modify some of the values. You can specify most of the properties inside the plug-in's instructions element.

Configuration properties

Some of the commonly used configuration properties are:

Setting a bundle's symbolic name

By default, the bundle plug-in sets the value for the Bundle-SymbolicName property to groupId + "." + artifactId, with the following exceptions:
  • If groupId has only one section (no dots), the first package name with classes is returned.
    For example, if the group Id is commons-logging:commons-logging, the bundle's symbolic name is org.apache.commons.logging.
  • If artifactId is equal to the last section of groupId, then groupId is used.
    For example, if the POM specifies the group ID and artifact ID as org.apache.maven:maven, the bundle's symbolic name is org.apache.maven.
  • If artifactId starts with the last section of groupId, that portion is removed.
    For example, if the POM specifies the group ID and artifact ID as org.apache.maven:maven-core, the bundle's symbolic name is org.apache.maven.core.

Example D.2. Setting a bundle's symbolic name

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
     ...
    </instructions>
  </configuration> 
</plugin>

Setting a bundle's name

By default, a bundle's name is set to ${project.name}.

Example D.3. Setting a bundle's name

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-Name>JoeFred</Bundle-Name>
     ...
    </instructions>
  </configuration> 
</plugin>

Setting a bundle's version

By default, a bundle's version is set to ${project.version}. Any dashes (-) are replaced with dots (.) and the number is padded up to four digits. For example, 4.2-SNAPSHOT becomes 4.2.0.SNAPSHOT.

Example D.4. Setting a bundle's version

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Bundle-Version>1.0.3.1</Bundle-Version>
     ...
    </instructions>
  </configuration> 
</plugin>

Specifying exported packages

By default, the OSGi manifest's Export-Package list is populated by all of the packages in your local Java source code (under src/main/java), except for the deault package, ., and any packages containing .impl or .internal.
Important
If you use a Private-Package element in your plug-in configuration and you do not specify a list of packages to export, the default behavior includes only the packages listed in the Private-Package element in the bundle. No packages are exported.
The default behavior can result in very large packages and in exporting packages that should be kept private. To change the list of exported packages you can add an Export-Package child to the plug-in's instructions element.
The Export-Package element specifies a list of packages that are to be included in the bundle and that are to be exported. The package names can be specified using the * wildcard symbol. For example, the entry com.fuse.demo.* includes all packages on the project's classpath that start with com.fuse.demo.
You can specify packages to be excluded be prefixing the entry with !. For example, the entry !com.fuse.demo.private excludes the package com.fuse.demo.private.
When excluding packages, the order of entries in the list is important. The list is processed in order from the beginning and any subsequent contradicting entries are ignored.
For example, to include all packages starting with com.fuse.demo except the package com.fuse.demo.private, list the packages using:
!com.fuse.demo.private,com.fuse.demo.*
However, if you list the packages using com.fuse.demo.*,!com.fuse.demo.private, then com.fuse.demo.private is included in the bundle because it matches the first pattern.
If you want to specify a list of packages to include in a bundle without exporting them, you can add a Private-Package instruction to the bundle plug-in configuration. By default, if you do not specify a Private-Package instruction, all packages in your local Java source are included in the bundle.
Important
If a package matches an entry in both the Private-Package element and the Export-Package element, the Export-Package element takes precedence. The package is added to the bundle and exported.
The Private-Package element works similarly to the Export-Package element in that you specify a list of packages to be included in the bundle. The bundle plug-in uses the list to find all classes on the project's classpath that are to be included in the bundle. These packages are packaged in the bundle, but not exported (unless they are also selected by the Export-Package instruction).
Example D.5 shows the configuration for including a private package in a bundle

Example D.5. Including a private package in a bundle

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Private-Package>org.apache.cxf.wsdlFirst.impl</Private-Package>
     ...
    </instructions>
  </configuration> 
</plugin>

Specifying imported packages

By default, the bundle plug-in populates the OSGi manifest's Import-Package property with a list of all the packages referred to by the contents of the bundle.
While the default behavior is typically sufficient for most projects, you might find instances where you want to import packages that are not automatically added to the list. The default behavior can also result in unwanted packages being imported.
Important
When you use the Import-Package element, the plug-in does not automatically scan the bundle's contents to determine if there are any required imports. To ensure that the contents of the bundle are scanned, you must place an * as the last entry in the package list.
Example D.6 shows the configuration for specifying the packages imported by a bundle

Example D.6. Specifying the packages imported by a bundle

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
   <instructions>
     <Import-Package>javax.jws,
         javax.wsdl,
         org.apache.cxf.bus,
         org.apache.cxf.bus.spring,
         org.apache.cxf.bus.resource,
         org.apache.cxf.configuration.spring,
         org.apache.cxf.resource,
         org.springframework.beans.factory.config,
         *
     </Import-Package>
     ...
   </instructions>
  </configuration> 
</plugin>

More information

For more information on configuring a bundle plug-in, see:

Part V. Developing Applications Using JAX-WS

Abstract

This guide describes how to develop Web services using the standard JAX-WS APIs.

Table of Contents

Chapter 23. Bottom-Up Service Development

Abstract

There are many instances where you have Java code that already implements a set of functionality that you want to expose as part of a service oriented application. You may also simply want to avoid using WSDL to define your interface. Using JAX-WS annotations, you can add the information required to service enable a Java class. You can also create a Service Endpoint Interface (SEI) that can be used in place of a WSDL contract. If you want a WSDL contract, Apache CXF provides tools to generate a contract from annotated Java code.
To create a service starting from Java you must do the following:
  1. Create a Service Endpoint Interface (SEI) that defines the methods you want to expose as a service.
    Tip
    You can work directly from a Java class, but working from an interface is the recommended approach. Interfaces are better suited for sharing with the developers who are responsible for developing the applications consuming your service. The interface is smaller and does not provide any of the service's implementation details.
  2. Add the required annotations to your code.
  3. Generate the WSDL contract for your service.
    Tip
    If you intend to use the SEI as the service's contract, it is not necessary to generate a WSDL contract.
  4. Publish the service as a service provider.

1. Creating the SEI

Overview

The service endpoint interface (SEI) is the piece of Java code that is shared between a service implementation and the consumers that make requests on that service. The SEI defines the methods implemented by the service and provides details about how the service will be exposed as an endpoint. When starting with a WSDL contract, the SEI is generated by the code generators. However, when starting from Java, it is the developer's responsibility to create the SEI.
There are two basic patterns for creating an SEI:
The SEI is a standard Java interface. It defines a set of methods that a class implements. It can also define a number of member fields and constants to which the implementing class has access.
In the case of an SEI the methods defined are intended to be mapped to operations exposed by a service. The SEI corresponds to a wsdl:portType element. The methods defined by the SEI correspond to wsdl:operation elements in the wsdl:portType element.
Tip
JAX-WS defines an annotation that allows you to specify methods that are not exposed as part of a service. However, the best practice is to leave those methods out of the SEI.
Example 23.1, “Simple SEI” shows a simple SEI for a stock updating service.

Example 23.1. Simple SEI

package com.fusesource.demo;

public interface quoteReporter
{
  public Quote getQuote(String ticker);
}

Implementing the interface

Because the SEI is a standard Java interface, the class that implements it is a standard Java class. If you start with a Java class you must modify it to implement the interface. If you start with the SEI, the implementation class implements the SEI.

Example 23.2. Simple Implementation Class

package com.fusesource.demo;

import java.util.*;

public class stockQuoteReporter implements quoteReporter
{
  ...
public Quote getQuote(String ticker)
  {
    Quote retVal = new Quote();
    retVal.setID(ticker);
    retVal.setVal(Board.check(ticker));[2]
    Date retDate = new Date();
    retVal.setTime(retDate.toString());
    return(retVal);
  }
}

2. Annotating the Code

The JAX-WS annotations specify the metadata used to map the SEI to a fully specified service definition. Among the information provided in the annotations are the following:
  • The target namespace for the service.
  • The name of the class used to hold the request message
  • The name of the class used to hold the response message
  • If an operation is a one way operation
  • The binding style the service uses
  • The name of the class used for any custom exceptions
  • The namespaces under which the types used by the service are defined
Tip
Most of the annotations have sensible defaults and it is not necessary to provide values for them. However, the more information you provide in the annotations, the better your service definition is specified. A well-specified service definition increases the likelihood that all parts of a distributed application will work together.

2.1. Required Annotations

Overview

In order to create a service from Java code you are only required to add one annotation to your code. You must add the @WebService annotation on both the SEI and the implementation class.

The @WebService annotation

Table 23.1. @WebService Properties

PropertyDescription
name Specifies the name of the service interface. This property is mapped to the name attribute of the wsdl:portType element that defines the service's interface in a WSDL contract. The default is to append PortType to the name of the implementation class. [a]
targetNamespace Specifies the target namespace where the service is defined. If this property is not specified, the target namespace is derived from the package name.
serviceName Specifies the name of the published service. This property is mapped to the name attribute of the wsdl:service element that defines the published service. The default is to use the name of the service's implementation class. [a]
wsdlLocation Specifies the URL where the service's WSDL contract is stored. This must be specified using a relative URL. The default is the URL where the service is deployed.
endpointInterface Specifies the full name of the SEI that the implementation class implements. This property is only specified when the attribute is used on a service implementation class.
portName Specifies the name of the endpoint at which the service is published. This property is mapped to the name attribute of the wsdl:port element that specifies the endpoint details for a published service. The default is the append Port to the name of the service's implementation class.[a]
[a] When you generate WSDL from an SEI the interface's name is used in place of the implementation class' name.
Tip
It is not necessary to provide values for any of the @WebService annotation's properties. However, it is recommended that you provide as much information as you can.

Annotating the SEI

The SEI requires that you add the @WebService annotation. Because the SEI is the contract that defines the service, you should specify as much detail as possible about the service in the @WebService annotation's properties.
Example 23.3, “Interface with the @WebService Annotation” shows the interface defined in Example 23.1, “Simple SEI” with the @WebService annotation.

Example 23.3. Interface with the @WebService Annotation

package com.fusesource.demo;

import javax.jws.*;

@WebService(name="quoteUpdater", 1
            targetNamespace="http:\\demos.redhat.com", 2
	        serviceName="updateQuoteService", 3
            wsdlLocation="http:\\demos.redhat.com\quoteExampleService?wsdl", 4
            portName="updateQuotePort") 5
public interface quoteReporter
{
  public Quote getQuote(String ticker);
}
The @WebService annotation in Example 23.3, “Interface with the @WebService Annotation” does the following:
1
Specifies that the value of the name attribute of the wsdl:portType element defining the service interface is quoteUpdater.
2
Specifies that the target namespace of the service is http:\\demos.redhat.com.
3
Specifies that the value of the name of the wsdl:service element defining the published service is updateQuoteService.
4
Specifies that the service will publish its WSDL contract at http:\\demos.redhat.com\quoteExampleService?wsdl.
5
Specifies that the value of the name attribute of the wsdl:port element defining the endpoint exposing the service is updateQuotePort.

Annotating the service implementation

Example 23.4. Annotated Service Implementation Class

package org.eric.demo;

import javax.jws.*;

@WebService(endpointInterface="com.fusesource.demo.quoteReporter")
public class stockQuoteReporter implements quoteReporter
{
public Quote getQuote(String ticker)
  {
  ...
  }
}

2.2. Optional Annotations

While the @WebService annotation is sufficient for service enabling a Java interface or a Java class, it does not fully describe how the service will be exposed as a service provider. The JAX-WS programming model uses a number of optional annotations for adding details about your service, such as the binding it uses, to the Java code. You add these annotations to the service's SEI.
Tip
The more details you provide in the SEI the easier it is for developers to implement applications that can use the functionality it defines. It also makes the WSDL documents generated by the tools more specific.

2.2.1. Defining the Binding Properties with Annotations

Overview
If you are using a SOAP binding for your service, you can use JAX-WS annotations to specify a number of the bindings properties. These properties correspond directly to the properties you can specify in a service's WSDL contract. Some of the settings, such as the parameter style, can restrict how you implement a method. These settings can also effect which annotations can be used when annotating method parameters.
The @SOAPBinding annotation
The @SOAPBinding annotation is defined by the javax.jws.soap.SOAPBinding interface. It provides details about the SOAP binding used by the service when it is deployed. If the @SOAPBinding annotation is not specified, a service is published using a wrapped doc/literal SOAP binding.
You can put the @SOAPBinding annotation on the SEI and any of the SEI's methods. When it is used on a method, setting of the method's @SOAPBinding annotation take precedence.
Table 23.2, “@SOAPBinding Properties” shows the properties for the @SOAPBinding annotation.

Table 23.2. @SOAPBinding Properties

PropertyValuesDescription
style
Style.DOCUMENT (default)
Style.RPC
Specifies the style of the SOAP message. If RPC style is specified, each message part within the SOAP body is a parameter or return value and appears inside a wrapper element within the soap:body element. The message parts within the wrapper element correspond to operation parameters and must appear in the same order as the parameters in the operation. If DOCUMENT style is specified, the contents of the SOAP body must be a valid XML document, but its form is not as tightly constrained.
use
Use.LITERAL (default)
Use.ENCODED[a]
Specifies how the data of the SOAP message is streamed.
parameterStyle [b]
ParameterStyle.BARE
ParameterStyle.WRAPPED (default)
Specifies how the method parameters, which correspond to message parts in a WSDL contract, are placed into the SOAP message body. If BARE is specified, each parameter is placed into the message body as a child element of the message root. If WRAPPED is specified, all of the input parameters are wrapped into a single element on a request message and all of the output parameters are wrapped into a single element in the response message.
[a] Use.ENCODED is not currently supported.
[b] If you set the style to RPC you must use the WRAPPED parameter style.
Document bare style parameters
Document bare style is the most direct mapping between Java code and the resulting XML representation of the service. When using this style, the schema types are generated directly from the input and output parameters defined in the operation's parameter list.
You specify you want to use bare document\literal style by using the @SOAPBinding annotation with its style property set to Style.DOCUMENT, and its parameterStyle property set to ParameterStyle.BARE.
To ensure that an operation does not violate the restrictions of using document style when using bare parameters, your operations must adhere to the following conditions:
  • The operation must have no more than one input or input/output parameter.
  • If the operation has a return type other than void, it must not have any output or input/output parameters.
  • If the operation has a return type of void, it must have no more than one output or input/output parameter.
Note
Any parameters that are placed in the SOAP header using the @WebParam annotation or the @WebResult annotation are not counted against the number of allowed parameters.
Document wrapped parameters
Document wrapped style allows a more RPC like mapping between the Java code and the resulting XML representation of the service. When using this style, the parameters in the method's parameter list are wrapped into a single element by the binding. The disadvantage of this is that it introduces an extra-layer of indirection between the Java implementation and how the messages are placed on the wire.
To specify that you want to use wrapped document\literal style use the @SOAPBinding annotation with its style property set to Style.DOCUMENT, and its parameterStyle property set to ParameterStyle.WRAPPED.
You have some control over how the wrappers are generated by using the the section called “The @RequestWrapper annotation” annotation and the the section called “The @ResponseWrapper annotation” annotation.
Example

Example 23.5. Specifying a Document Bare SOAP Binding with the SOAP Binding Annotation

package org.eric.demo;

import javax.jws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;

@WebService(name="quoteReporter")
@SOAPBinding(parameterStyle=ParameterStyle.BARE)
public interface quoteReporter
{
  ...
}

2.2.2. Defining Operation Properties with Annotations

Overview
When the runtime maps your Java method definitions into XML operation definitions it provides details such as:
  • What the exchanged messages look like in XML
  • If the message can be optimized as a one way message
  • The namespaces where the messages are defined
The @WebMethod annotation
The @WebMethod annotation is defined by the javax.jws.WebMethod interface. It is placed on the methods in the SEI. The @WebMethod annotation provides the information that is normally represented in the wsdl:operation element describing the operation to which the method is associated.
Table 23.3, “@WebMethod Properties” describes the properties of the @WebMethod annotation.

Table 23.3. @WebMethod Properties

PropertyDescription
operationName Specifies the value of the associated wsdl:operation element's name. The default value is the name of the method.
action Specifies the value of the soapAction attribute of the soap:operation element generated for the method. The default value is an empty string.
exclude Specifies if the method should be excluded from the service interface. The default is false.
The @RequestWrapper annotation
The @RequestWrapper annotation is defined by the javax.xml.ws.RequestWrapper interface. It is placed on the methods in the SEI. The @RequestWrapper annotation specifies the Java class implementing the wrapper bean for the method parameters of the request message starting a message exchange. It also specifies the element names, and namespaces, used by the runtime when marshalling and unmarshalling the request messages.
Table 23.4, “@RequestWrapper Properties” describes the properties of the @RequestWrapper annotation.

Table 23.4. @RequestWrapper Properties

PropertyDescription
localName Specifies the local name of the wrapper element in the XML representation of the request message. The default value is either the name of the method, or the value of the the section called “The @WebMethod annotation” annotation's operationName property.
targetNamespace Specifies the namespace under which the XML wrapper element is defined. The default value is the target namespace of the SEI.
className Specifies the full name of the Java class that implements the wrapper element.
Tip
Only the className property is required.
Important
If the method is also annotated with the @SOAPBinding annotation, and its parameterStyle property is set to ParameterStyle.BARE, this annotation is ignored.
The @ResponseWrapper annotation
The @ResponseWrapper annotation is defined by the javax.xml.ws.ResponseWrapper interface. It is placed on the methods in the SEI. The @ResponseWrapper specifies the Java class implementing the wrapper bean for the method parameters in the response message in the message exchange. It also specifies the element names, and namespaces, used by the runtime when marshaling and unmarshalling the response messages.
Table 23.5, “@ResponseWrapper Properties” describes the properties of the @ResponseWrapper annotation.

Table 23.5. @ResponseWrapper Properties

PropertyDescription
localName Specifies the local name of the wrapper element in the XML representation of the response message. The default value is either the name of the method with Response appended, or the value of the the section called “The @WebMethod annotation” annotation's operationName property with Response appended.
targetNamespace Specifies the namespace where the XML wrapper element is defined. The default value is the target namespace of the SEI.
className Specifies the full name of the Java class that implements the wrapper element.
Tip
Only the className property is required.
Important
If the method is also annotated with the @SOAPBinding annotation and its parameterStyle property is set to ParameterStyle.BARE, this annotation is ignored.
The @WebFault annotation
The @WebFault annotation is defined by the javax.xml.ws.WebFault interface. It is placed on exceptions that are thrown by your SEI. The @WebFault annotation is used to map the Java exception to a wsdl:fault element. This information is used to marshall the exceptions into a representation that can be processed by both the service and its consumers.
Table 23.6, “@WebFault Properties” describes the properties of the @WebFault annotation.

Table 23.6. @WebFault Properties

PropertyDescription
name Specifies the local name of the fault element.
targetNamespace Specifies the namespace under which the fault element is defined. The default value is the target namespace of the SEI.
faultName Specifies the full name of the Java class that implements the exception.
Important
The name property is required.
The @Oneway annotation
The @Oneway annotation is defined by the javax.jws.Oneway interface. It is placed on the methods in the SEI that will not require a response from the service. The @Oneway annotation tells the run time that it can optimize the execution of the method by not waiting for a response and by not reserving any resources to process a response.
This annotation can only be used on methods that meet the following criteria:
  • They return void
  • They have no parameters that implement the Holder interface
  • They do not throw any exceptions that can be passed back to a consumer
Example 23.6, “SEI with Annotated Methods” shows an SEI with its methods annotated.

Example 23.6. SEI with Annotated Methods

package com.fusesource.demo;

import javax.jws.*;
import javax.xml.ws.*;

@WebService(name="quoteReporter")
public interface quoteReporter
{
  @WebMethod(operationName="getStockQuote")
  @RequestWrapper(targetNamespace="http://demo.redhat.com/types", 
                  className="java.lang.String")
  @ResponseWrapper(targetNamespace="http://demo.redhat.com/types", 
                   className="org.eric.demo.Quote")
  public Quote getQuote(String ticker);
}

2.2.3. Defining Parameter Properties with Annotations

Overview
The method parameters in the SEI correspond to the wsdl:message elements and their wsdl:part elements. JAX-WS provides annotations that allow you to describe the wsdl:part elements that are generated for the method parameters.
The @WebParam annotation
The @WebParam annotation is defined by the javax.jws.WebParam interface. It is placed on the parameters of the methods defined in the SEI. The @WebParam annotation allows you to specify the direction of the parameter, if the parameter will be placed in the SOAP header, and other properties of the generated wsdl:part.
Table 23.7, “@WebParam Properties” describes the properties of the @WebParam annotation.

Table 23.7. @WebParam Properties

PropertyValuesDescription
name  Specifies the name of the parameter as it appears in the generated WSDL document. For RPC bindings, this is the name of the wsdl:part representing the parameter. For document bindings, this is the local name of the XML element representing the parameter. Per the JAX-WS specification, the default is argN, where N is replaced with the zero-based argument index (i.e., arg0, arg1, etc.).
targetNamespace  Specifies the namespace for the parameter. It is only used with document bindings where the parameter maps to an XML element. The default is to use the service's namespace.
mode
Mode.IN (default)[a]
Mode.OUT
Mode.INOUT
Specifies the direction of the parameter.
header
false (default)
true
Specifies if the parameter is passed as part of the SOAP header.
partName  Specifies the value of the name attribute of the wsdl:part element for the parameter. This property is used for document style SOAP bindings.
[a] Any parameter that implements the Holder interface is mapped to Mode.INOUT by default.
The @WebResult annotation
The @WebResult annotation is defined by the javax.jws.WebResult interface. It is placed on the methods defined in the SEI. The @WebResult annotation allows you to specify the properties of the wsdl:part that is generated for the method's return value.
Table 23.8, “@WebResult Properties” describes the properties of the @WebResult annotation.

Table 23.8. @WebResult Properties

PropertyDescription
name Specifies the name of the return value as it appears in the generated WSDL document. For RPC bindings, this is the name of the wsdl:part representing the return value. For document bindings, this is the local name of the XML element representing the return value. The default value is return.
targetNamespace Specifies the namespace for the return value. It is only used with document bindings where the return value maps to an XML element. The default is to use the service's namespace.
header Specifies if the return value is passed as part of the SOAP header.
partName Specifies the value of the name attribute of the wsdl:part element for the return value. This property is used for document style SOAP bindings.
Example
Example 23.7, “Fully Annotated SEI” shows an SEI that is fully annotated.

Example 23.7. Fully Annotated SEI

package com.fusesource.demo;

import javax.jws.*;
import javax.xml.ws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;
import javax.jws.WebParam.*;

@WebService(targetNamespace="http://demo.redhat.com", 
            name="quoteReporter")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)
public interface quoteReporter
{
  @WebMethod(operationName="getStockQuote")
  @RequestWrapper(targetNamespace="http://demo.redhat.com/types", 
                  className="java.lang.String")
  @ResponseWrapper(targetNamespace="http://demo.redhat.com/types", 
                   className="org.eric.demo.Quote")
  @WebResult(targetNamespace="http://demo.redhat.com/types", 
             name="updatedQuote")
  public Quote getQuote(
                        @WebParam(targetNamespace="http://demo.redhat.com/types", 
                                  name="stockTicker",
                                  mode=Mode.IN)
                        String ticker
  );
}

2.3. Apache CXF Annotations

2.3.1. WSDL Documentation

@WSDLDocumentation annotation
The @WSDLDocumentation annotation is defined by the org.apache.cxf.annotations.WSDLDocumentation interface. It can be placed on the SEI or the SEI methods.

Table 23.9. @WSDLDocumentation properties

PropertyDescription
value(Required) A string containing the documentation text.
placement(Optional) Specifies where in the WSDL file this documentation is to appear. For the list of possible placement values, see the section called “Placement in the WSDL contract”.
faultClass(Optional) If the placement is set to be FAULT_MESSAGE, PORT_TYPE_OPERATION_FAULT, or BINDING_OPERATION_FAULT, you must also set this property to the Java class that represents the fault.
@WSDLDocumentationCollection annotation
The @WSDLDocumentationCollection annotation is defined by the org.apache.cxf.annotations.WSDLDocumentationCollection interface. It can be placed on the SEI or the SEI methods.
This annotation is used to insert multiple documentation elements at a single placement location or at various placement locations.
Example 23.8, “Using @WSDLDocumentation” shows how to add a @WSDLDocumentation annotation to the SEI and to one of its methods.

Example 23.8. Using @WSDLDocumentation

@WebService
@WSDLDocumentation("A very simple example of an SEI")
public interface HelloWorld {
    @WSDLDocumentation("A traditional form of greeting")
    String sayHi(@WebParam(name = "text") String text);
}
When WSDL, shown in Example 23.9, “WSDL generated with documentation”, is generated from the SEI in Example 23.8, “Using @WSDLDocumentation”, the default placements of the documentation elements are, respectively, PORT_TYPE and PORT_TYPE_OPERATION.

Example 23.9. WSDL generated with documentation

<wsdl:definitions ... >
  ...
  <wsdl:portType name="HelloWorld">
 <wsdl:documentation>A very simple example of an SEI</wsdl:documentation>
    <wsdl:operation name="sayHi">
 <wsdl:documentation>A traditional form of greeting</wsdl:documentation>
      <wsdl:input name="sayHi" message="tns:sayHi">
    </wsdl:input>
      <wsdl:output name="sayHiResponse" message="tns:sayHiResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>
Example of @WSDLDocumentationCollection
Example 23.10, “Using @WSDLDocumentationCollection” shows how to add a @WSDLDocumentationCollection annotation to an SEI.

Example 23.10. Using @WSDLDocumentationCollection

@WebService
@WSDLDocumentationCollection(
    {
        @WSDLDocumentation("A very simple example of an SEI"),
        @WSDLDocumentation(value = "My top level documentation",
                           placement = WSDLDocumentation.Placement.TOP),
        @WSDLDocumentation(value = "Binding documentation",
                           placement = WSDLDocumentation.Placement.BINDING)
    }
)
public interface HelloWorld {
    @WSDLDocumentation("A traditional form of Geeky greeting")
    String sayHi(@WebParam(name = "text") String text);
}

2.3.2. Schema Validation of Messages

@SchemaValidation annotation
The @SchemaValidation annotation is defined by the org.apache.cxf.annotations.SchemaValidation interface. It is placed on the SEI.
This annotation turns on schema validation of the XML messages sent to this endpoint. This can be useful for testing purposes, when you suspect there is a problem with the format of incoming XML messages. By default, validation is disabled, because it has a significant impact on performance.
Example
Example 23.11, “Activating schema validation” shows how to enable schema validation of messages for endpoints based on the HelloWorld SEI.

Example 23.11. Activating schema validation

@WebService
@SchemaValidation
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

2.3.3. Specifying the Data Binding

@DataBinding annotation
The @DataBinding annotation is defined by the org.apache.cxf.annotations.DataBinding interface. It is placed on the SEI.
This annotation is used to associate a data binding with the SEI, replacing the default JAXB data binding. The value of the @DataBinding annotation must be the class that provides the data binding, ClassName.class.
Supported data bindings
The following data bindings are currently supported by Apache CXF:
  • org.apache.cxf.jaxb.JAXBDataBinding
  • org.apache.cxf.sdo.SDODataBinding
    The Service Data Objects (SDO) data binding is based on the Apache Tuscany SDO implementation. If you want to use this data binding in the context of a Maven build, you need to add a dependency on the cxf-rt-databinding-sdo artifact.
  • org.apache.cxf.aegis.databinding.AegisDatabinding
    If you want to use this data binding in the context of a Maven build, you need to add a dependency on the cxf-rt-databinding-aegis artifact.
  • org.apache.cxf.xmlbeans.XmlBeansDataBinding
    If you want to use this data binding in the context of a Maven build, you need to add a dependency on the cxf-rt-databinding-xmlbeans artifact.
  • org.apache.cxf.databinding.source.SourceDataBinding
    This data binding belongs to the Apache CXF core.
  • org.apache.cxf.databinding.stax.StaxDataBinding
    This data binding belongs to the Apache CXF core.
Example
Example 23.12, “Setting the data binding” shows how to associate the SDO binding with the HelloWorld SEI

Example 23.12. Setting the data binding

@WebService
@DataBinding(org.apache.cxf.sdo.SDODataBinding.class)
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

2.3.4. Compressing Messages

@GZIP annotation
The @GZIP annotation is defined by the org.apache.cxf.annotations.GZIP interface. It is placed on the SEI.
Enables GZIP compression of messages. GZIP is a negotiated enhancement. That is, an initial request from a client will not be gzipped, but an Accept header will be added and, if the server supports GZIP compression, the response will be gzipped and any subsequent requests will be also.
Table 23.10, “@GZIP Properties” shows the optional properties supported by the @GZIP annotation.

Table 23.10. @GZIP Properties

PropertyDescription
thresholdMessages smaller than the size specified by this property are not gzipped. Default is -1 (no limit).
@FastInfoset
The @FastInfoset annotation is defined by the org.apache.cxf.annotations.FastInfoset interface. It is placed on the SEI.
FastInfoset is a negotiated enhancement. That is, an initial request from a client will not be in FastInfoset format, but an Accept header will be added and, if the server supports FastInfoset, the response will be in FastInfoset and any subsequent requests will be also.
Table 23.11, “@FastInfoset Properties” shows the optional properties supported by the @FastInfoset annotation.

Table 23.11. @FastInfoset Properties

PropertyDescription
forceA boolean property that forces the use of FastInfoset format, instead of negotiating. When true, force the use of FastInfoset format; otherwise, negotiate. Default is false.
Example of @GZIP
Example 23.13, “Enabling GZIP” shows how to enable GZIP compression for the HelloWorld SEI.

Example 23.13. Enabling GZIP

@WebService
@GZIP
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Exampe of @FastInfoset
Example 23.14, “Enabling FastInfoset” shows how to enable the FastInfoset format for the HelloWorld SEI.

Example 23.14. Enabling FastInfoset

@WebService
@FastInfoset
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

2.3.5. Enable Logging on an Endpoint

@Logging annotation
The @Logging annotation is defined by the org.apache.cxf.annotations.Logging interface. It is placed on the SEI.

Table 23.12. @Logging Properties

PropertyDescription
limitSpecifies the size limit, beyond which the message is truncated in the logs. Default is 64K.
inLocationSpecifies the location to log incoming messages. Can be either <stderr>, <stdout>, <logger>, or a filename. Default is <logger>.
outLocationSpecifies the location to log outgoing messages. Can be either <stderr>, <stdout>, <logger>, or a filename. Default is <logger>.
Example
Example 23.15, “Logging configuration using annotations” shows how to enable logging for the HelloWorld SEI, where incoming messages are sent to <stdout> and outgoing messages are sent to <logger>.

Example 23.15. Logging configuration using annotations

@WebService
@Logging(limit=16000, inLocation="<stdout>")
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

2.3.6. Adding Properties and Policies to an Endpoint

Both properties and policies can be used to associate configuration data with an endpoint. The essential difference between them is that properties are a Apache CXF specific configuration mechanism whereas policies are a standard WSDL configuration mechanism. Policies typically originate from WS specifications and standards and they are normally set by defining wsdl:policy elements that appear in the WSDL contract. By contrast, properties are Apache CXF-specific and they are normally set by defining jaxws:properties elements in the Apache CXF Spring configuration file.
It is also possible, however, to define property settings and WSDL policy settings in Java using annotations, as described here.
2.3.6.1. Adding properties
@EndpointProperty annotation
The @EndpointProperty annotation is defined by the org.apache.cxf.annotations.EndpointProperty interface. It is placed on the SEI.
This annotation adds Apache CXF-specific configuration settings to an endpoint. Endpoint properties can also be specified in a Spring configuration file. For example, to configure WS-Security on an endpoint, you could add endpoint properties using the jaxws:properties element in a Spring configuration file as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jaxws="http://cxf.apache.org/jaxws"
   ... >

   <jaxws:endpoint 
      id="MyService"
      address="https://localhost:9001/MyService" 
      serviceName="interop:MyService"
      endpointName="interop:MyServiceEndpoint"
      implementor="com.foo.MyService">
        
      <jaxws:properties>
         <entry key="ws-security.callback-handler" value="interop.client.UTPasswordCallback"/>
         <entry key="ws-security.signature.properties" value="etc/keystore.properties"/>
         <entry key="ws-security.encryption.properties" value="etc/truststore.properties"/>
         <entry key="ws-security.encryption.username" value="useReqSigCert"/>
      </jaxws:properties> 
     
   </jaxws:endpoint> 
</beans>

Example 23.16. Configuring WS-Security Using @EndpointProperty Annotations

@WebService
@EndpointProperty(name="ws-security.callback-handler" value="interop.client.UTPasswordCallback")
@EndpointProperty(name="ws-security.signature.properties" value="etc/keystore.properties")
@EndpointProperty(name="ws-security.encryption.properties" value="etc/truststore.properties")
@EndpointProperty(name="ws-security.encryption.username" value="useReqSigCert")
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
@EndpointProperties annotation
The @EndpointProperties annotation is defined by the org.apache.cxf.annotations.EndpointProperties interface. It is placed on the SEI.

Example 23.17. Configuring WS-Security Using an @EndpointProperties Annotation

@WebService
@EndpointProperties(
  {
  @EndpointProperty(name="ws-security.callback-handler" value="interop.client.UTPasswordCallback"),
  @EndpointProperty(name="ws-security.signature.properties" value="etc/keystore.properties"),
  @EndpointProperty(name="ws-security.encryption.properties" value="etc/truststore.properties"),
  @EndpointProperty(name="ws-security.encryption.username" value="useReqSigCert")
})
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
2.3.6.2. Adding policies
@Policy annotation
The @Policy annotation is defined by the org.apache.cxf.annotations.Policy interface. It can be placed on the SEI or the SEI methods.
This annotation is used to associate a WSDL policy with an SEI or an SEI method. The policy is specified by providing a URI that references an XML file containing a standard wsdl:policy element. If a WSDL contract is to be generated from the SEI (for example, using the java2ws command-line tool), you can specify whether or not you want to include this policy in the WSDL.
Table 23.13, “@Policy Properties” shows the properties supported by the @Policy annotation.

Table 23.13. @Policy Properties

PropertyDescription
uri(Required) The location of the file containing the policy definition.
includeInWSDL(Optional) Whether to include the policy in the generated contract, when generating WSDL. Default is true.
placement(Optional) Specifies where in the WSDL file this documentation is to appear. For the list of possible placement values, see the section called “Placement in the WSDL contract”.
faultClass(Optional) If the placement is set to be BINDING_OPERATION_FAULT or PORT_TYPE_OPERATION_FAULT, you must also set this property to specify which fault this policy applies to. The value is the Java class that represents the fault.
@Policies annotation
The @Policies annotation is defined by the org.apache.cxf.annotations.Policies interface. It can be placed on the SEI or thse SEI methods.
This annotation provides a way of grouping multiple @Policy annotations into a list.
Policy.Placement.BINDING
Policy.Placement.BINDING_OPERATION
Policy.Placement.BINDING_OPERATION_FAULT
Policy.Placement.BINDING_OPERATION_INPUT
Policy.Placement.BINDING_OPERATION_OUTPUT
Policy.Placement.DEFAULT
Policy.Placement.PORT_TYPE
Policy.Placement.PORT_TYPE_OPERATION
Policy.Placement.PORT_TYPE_OPERATION_FAULT
Policy.Placement.PORT_TYPE_OPERATION_INPUT
Policy.Placement.PORT_TYPE_OPERATION_OUTPUT
Policy.Placement.SERVICE
Policy.Placement.SERVICE_PORT
@WebService
@Policy(uri = "annotationpolicies/TestImplPolicy.xml",
        placement = Policy.Placement.SERVICE_PORT),
@Policy(uri = "annotationpolicies/TestPortTypePolicy.xml", 
        placement = Policy.Placement.PORT_TYPE)
public interface HelloWorld {
    @Policy(uri = "annotationpolicies/TestOperationPTPolicy.xml", 
            placement = Policy.Placement.PORT_TYPE_OPERATION),
    String sayHi(@WebParam(name = "text") String text);
}
@WebService
@Policies({
    @Policy(uri = "annotationpolicies/TestImplPolicy.xml",
            placement = Policy.Placement.SERVICE_PORT),
    @Policy(uri = "annotationpolicies/TestPortTypePolicy.xml", 
            placement = Policy.Placement.PORT_TYPE)
})
public interface HelloWorld {
    @Policy(uri = "annotationpolicies/TestOperationPTPolicy.xml", 
            placement = Policy.Placement.PORT_TYPE_OPERATION),
    String sayHi(@WebParam(name = "text") String text);
}

Using Maven

Example 23.18, “Generating WSDL from Java” shows how to set up the java2ws Maven plug-in to generate WSDL.

Example 23.18. Generating WSDL from Java

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-java2ws-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>process-classes</id>
      <phase>process-classes</phase>
      <configuration>
        <className>className</className>
        <genWsdl>true</genWsdl>
      </configuration>
      <goals>
        <goal>java2ws</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Example

Example 23.19, “Generated WSDL from an SEI shows the WSDL contract that is generated for the SEI shown in Example 23.7, “Fully Annotated SEI”.

Example 23.19. Generated WSDL from an SEI

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://demo.eric.org/" 
          xmlns:tns="http://demo.eric.org/" 
		  xmlns:ns1="" 
		  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
		  xmlns:ns2="http://demo.eric.org/types" 
		  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
		  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <xsd:schema>
      <xs:complexType name="quote">
        <xs:sequence>
          <xs:element name="ID" type="xs:string" minOccurs="0"/>
          <xs:element name="time" type="xs:string" minOccurs="0"/>
          <xs:element name="val" type="xs:float"/>
        </xs:sequence>
      </xs:complexType>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="getStockQuote">
    <wsdl:part name="stockTicker" type="xsd:string">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getStockQuoteResponse">
    <wsdl:part name="updatedQuote" type="tns:quote">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="quoteReporter">
    <wsdl:operation name="getStockQuote">
      <wsdl:input name="getQuote" message="tns:getStockQuote">
    </wsdl:input>
      <wsdl:output name="getQuoteResponse" message="tns:getStockQuoteResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="quoteReporterBinding" type="tns:quoteReporter">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getStockQuote">
      <soap:operation style="rpc" />
      <wsdl:input name="getQuote">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getQuoteResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="quoteReporterService">
    <wsdl:port name="quoteReporterPort" binding="tns:quoteReporterBinding">
      <soap:address location="http://localhost:9000/quoteReporterService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>


[2] Board is an assumed class whose implementation is left to the reader.

Chapter 24. Developing a Consumer Without a WSDL Contract

Abstract

You do not need a WSDL contract to develop a service consumer. You can create a service consumer from an annotated SEI. Along with the SEI you need to know the address at which the endpoint exposing the service is published, the QName of the service element that defines the endpoint exposing the service, and the QName of the port element defining the endpoint on which your consumer makes requests. This information can be specified in the SEI's annotations or provided separately.
To create a consumer without a WSDL contract you must do the following:
  1. Create a Service object for the service on which the consumer will invoke operations.
  2. Add a port to the Service object.
  3. Get a proxy for the service using the Service object's getPort() method.

1. Creating a Service Object

Overview

The javax.xml.ws.Service class represents the wsdl:service element which contains the definition of all of the endpoints that expose a service. As such, it provides methods that allow you to get endpoints, defined by wsdl:port elements, that are proxies for making remote invocations on a service.
Note
The Service class provides the abstractions that allow the client code to work with Java types as opposed to working with XML documents.

The create() methods

The Service class has two static create() methods that can be used to create a new Service object. As shown in Example 24.1, “Service create() Methods”, both of the create() methods take the QName of the wsdl:service element the Service object will represent, and one takes a URI specifying the location of the WSDL contract.
Tip
All services publish their WSDL contracts. For SOAP/HTTP services the URI is usually the URI for the service appended with ?wsdl.

Example 24.1. Service create() Methods

public static Service create(URL wsdlLocation,
                             QName serviceName)
    throws WebServiceException;

public static Service create(QName serviceName)
    throws WebServiceException;
The value of the serviceName parameter is a QName. The value of its namespace part is the target namespace of the service. The service's target namespace is specified in the targetNamespace property of the @WebService annotation. The value of the QName's local part is the value of wsdl:service element's name attribute. You can determine this value in one of the following ways:
  1. It is specified in the serviceName property of the @WebService annotation.
  2. You append Service to the value of the name property of the @WebService annotation.
  3. You append Service to the name of the SEI.
Example 24.2, “Creating a Service Object” shows code for creating a Service object for the SEI shown in Example 23.7, “Fully Annotated SEI”.

Example 24.2. Creating a Service Object

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
1    QName serviceName = new QName("http://demo.redhat.com", "stockQuoteReporter");
2    Service s = Service.create(serviceName);
   ...
  }
}
The code in Example 24.2, “Creating a Service Object” does the following:
1
Builds the QName for the service using the targetNamespace property and the name property of the @WebService annotation.
2
Calls the single parameter create() method to create a new Service object.
Note
Using the single parameter create() frees you from having any dependencies on accessing a WSDL contract.

2. Adding a Port to a Service

Overview

The endpoint information for a service is defined in a wsdl:port element, and the Service object creates a proxy instance for each of the endpoints defined in a WSDL contract, if one is specified. If you do not specify a WSDL contract when you create your Service object, the Service object has no information about the endpoints that implement your service, and therefore cannot create any proxy instances. In this case, you must provide the Service object with the information needed to represent a wsdl:port element using the addPort() method.

The addPort() method

The Service class defines an addPort() method, shown in Example 24.3, “The addPort() Method”, that is used in cases where there is no WSDL contract available to the consumer implementation. The addPort() method allows you to give a Service object the information, which is typically stored in a wsdl:port element, necessary to create a proxy for a service implementation.

Example 24.3. The addPort() Method

void addPort(QName portName,
             String bindingId,
             String endpointAddress)
    throws WebServiceException;
The value of the portName is a QName. The value of its namespace part is the target namespace of the service. The service's target namespace is specified in the targetNamespace property of the @WebService annotation. The value of the QName's local part is the value of wsdl:port element's name attribute. You can determine this value in one of the following ways:
  1. Specify it in the portName property of the @WebService annotation.
  2. Append Port to the value of the name property of the @WebService annotation.
  3. Append Port to the name of the SEI.
The value of the bindingId parameter is a string that uniquely identifies the type of binding used by the endpoint. For a SOAP binding you use the standard SOAP namespace: http://schemas.xmlsoap.org/soap/. If the endpoint is not using a SOAP binding, the value of the bindingId parameter is determined by the binding developer.
The value of the endpointAddress parameter is the address where the endpoint is published. For a SOAP/HTTP endpoint, the address is an HTTP address. Transports other than HTTP use different address schemes.

Example 24.4. Adding a Port to a Service Object

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    ...
1    QName portName = new QName("http://demo.redhat.com", "stockQuoteReporterPort");
2    s.addPort(portName, 
3              "http://schemas.xmlsoap.org/soap/", 
4              "http://localhost:9000/StockQuote");
    ...
  }
}
1
Creates the QName for the portName parameter.
2
Calls the addPort() method.
3
Specifies that the endpoint uses a SOAP binding.
4
Specifies the address where the endpoint is published.

3. Getting a Proxy for an Endpoint

Overview

A service proxy is an object that provides all of the methods exposed by a remote service and handles all of the details required to make the remote invocations. The Service object provides service proxies for all of the endpoints it is aware of through the getPort() method. Once you have a service proxy, you can invoke its methods. The proxy forwards the invocation to the remote service endpoint using the connection details specified in the service's contract.

The getPort() method

The getPort() method, shown in Example 24.5, “The getPort() Method”, returns a service proxy for the specified endpoint. The returned proxy is of the same class as the SEI.

Example 24.5. The getPort() Method

public <T> T getPort(QName portName,
                     Class<T> serviceEndpointInterface)
    throws WebServiceException;
The value of the portName parameter is a QName that identifies the wsdl:port element that defines the endpoint for which the proxy is created. The value of the serviceEndpointInterface parameter is the fully qualified name of the SEI.
Tip
When you are working without a WSDL contract the value of the portName parameter is typically the same as the value used for the portName parameter when calling addPort().
Example 24.6, “Getting a Service Proxy” shows code for getting a service proxy for the endpoint added in Example 24.4, “Adding a Port to a Service Object”.

Example 24.6. Getting a Service Proxy

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    ...
    quoteReporter proxy = s.getPort(portName, quoteReporter.class);
    ...
  }
}

4. Implementing the Consumer's Business Logic

Overview

Once you instantiate a service proxy for a remote endpoint, you can invoke its methods as if it were a local object. The calls block until the remote method completes.
Note
If a method is annotated with the @OneWay annotation, the call returns immediately.

Example

Example 24.7. Consumer Implemented without a WSDL Contract

package com.fusesource.demo;

import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    QName serviceName = new QName("http://demo.eric.org", "stockQuoteReporter");
1  Service s = Service.create(serviceName);

    QName portName = new QName("http://demo.eric.org", "stockQuoteReporterPort");
2  s.addPort(portName, "http://schemas.xmlsoap.org/soap/", "http://localhost:9000/EricStockQuote");

3  quoteReporter proxy = s.getPort(portName, quoteReporter.class);

4  Quote quote = proxy.getQuote("ALPHA");
    System.out.println("Stock "+quote.getID()+" is worth "+quote.getVal()+" as of "+quote.getTime());
  }
}
1
Creates a Service object.
2
Adds an endpoint definition to the Service object.
3
Gets a service proxy from the Service object.
4
Invokes an operation on the service proxy.

Chapter 25. A Starting Point WSDL Contract

Example 25.1, “HelloWorld WSDL Contract” shows the HelloWorld WSDL contract. This contract defines a single interface, Greeter, in the wsdl:portType element. The contract also defines the endpoint which will implement the service in the wsdl:port element.

Example 25.1. HelloWorld WSDL Contract

<?xml version="1.0" encoding=";UTF-8"?>
<wsdl:definitions name="HelloWorld"
                  targetNamespace="http://apache.org/hello_world_soap_http"
                  xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:tns="http://apache.org/hello_world_soap_http"
                  xmlns:x1="http://apache.org/hello_world_soap_http/types"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <schema targetNamespace="http://apache.org/hello_world_soap_http/types"
            xmlns="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"><element name="sayHi">
      <element name="sayHi">
        <complexType>
          <sequence>
            <element name="requestType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="sayHiResponse">
        <complexType>
          <sequence>
            <element name="responseType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMe">
        <complexType>
          <sequence>
            <element name="requestType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMeResponse">
        <complexType>
          <sequence>
            <element name="responseType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="greetMeOneWay">
        <complexType>
          <sequence>
            <element name="requestType" type="string"/>
          </sequence>
        </complexType>
      </element>
      <element name="pingMe">
        <complexType/>
      </element>
      <element name="pingMeResponse">
        <complexType/>
      </element>
      <element name="faultDetail">
        <complexType>
          <sequence>
            <element name="minor" type="short"/>
            <element name="major" type="short"/>
          </sequence>
        </complexType>
      </element>
    </schema>
  </wsdl:types>

  <wsdl:message name="sayHiRequest">
    <wsdl:part element="x1:sayHi" name="in"/>
  </wsdl:message>
  <wsdl:message name="sayHiResponse">
    <wsdl:part element="x1:sayHiResponse" name="out"/>
  </wsdl:message>
  <wsdl:message name="greetMeRequest">
    <wsdl:part element="x1:greetMe" name="in"/>
  </wsdl:message>
  <wsdl:message name="greetMeResponse">
    <wsdl:part element="x1:greetMeResponse" name="out"/>
  </wsdl:message>
  <wsdl:message name="greetMeOneWayRequest">
    <wsdl:part element="x1:greetMeOneWay" name="in"/>
  </wsdl:message>
  <wsdl:message name="pingMeRequest">
    <wsdl:part name="in" element="x1:pingMe"/>
  </wsdl:message>
  <wsdl:message name="pingMeResponse">
    <wsdl:part name="out" element="x1:pingMeResponse"/>
  </wsdl:message>
  <wsdl:message name="pingMeFault">
    <wsdl:part name="faultDetail" element="x1:faultDetail"/>
  </wsdl:message>

  <wsdl:portType name="Greeter">
1    <wsdl:operation name="sayHi">
      <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
      <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
    </wsdl:operation>

2    <wsdl:operation name="greetMe">
      <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
      <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
    </wsdl:operation>

3    <wsdl:operation name="greetMeOneWay">
      <wsdl:input message="tns:greetMeOneWayRequest" name="greetMeOneWayRequest"/>
    </wsdl:operation>

4    <wsdl:operation name="pingMe">
      <wsdl:input name="pingMeRequest" message="tns:pingMeRequest"/>
      <wsdl:output name="pingMeResponse" message="tns:pingMeResponse"/>
      <wsdl:fault name="pingMeFault" message="tns:pingMeFault"/>
    </wsdl:operation>
  </wsdl:portType>

  <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
    ...
  </wsdl:binding>

  <wsdl:service name="SOAPService">
    <wsdl:port binding="tns:Greeter_SOAPBinding" name="SoapPort">
      <soap:address location="http://localhost:9000/SoapContext/SoapPort"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
The Greeter interface defined in Example 25.1, “HelloWorld WSDL Contract” defines the following operations:
1
sayHi — Has a single output parameter, of xsd:string.
2
greetMe — Has an input parameter, of xsd:string, and an output parameter, of xsd:string.
3
greetMeOneWay — Has a single input parameter, of xsd:string. Because this operation has no output parameters, it is optimized to be a oneway invocation (that is, the consumer does not wait for a response from the server).
4
pingMe — Has no input parameters and no output parameters, but it can raise a fault exception.

Chapter 26. Top-Down Service Development

Abstract

In the top-down method of developing a service provider you start from a WSDL document that defines the operations and methods the service provider will implement. Using the WSDL document, you generate starting point code for the service provider. Adding the business logic to the generated code is done using normal Java programming APIs.
Once you have a WSDL document, the process for developing a JAX-WS service provider is as follows:
  1. Generate starting point code.
  2. Implement the service provider's operations.
  3. Publish the implemented service.

1. Generating the Starting Point Code

Overview

JAX-WS specifies a detailed mapping from a service defined in WSDL to the Java classes that will implement that service as a service provider. The logical interface, defined by the wsdl:portType element, is mapped to a service endpoint interface (SEI). Any complex types defined in the WSDL are mapped into Java classes following the mapping defined by the Java Architecture for XML Binding (JAXB) specification. The endpoint defined by the wsdl:service element is also generated into a Java class that is used by consumers to access service providers implementing the service.
The cxf-codegen-plugin Maven plug-in generates this code. It also provides options for generating starting point code for your implementation. The code generator provides a number of options for controlling the generated code.

Running the code generator

Example 26.1, “Service Code Generation” shows how to use the code generator to generate starting point code for a service.

Example 26.1. Service Code Generation

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-codegen-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>generate-sources</id>
      <phase>generate-sources</phase>
      <configuration>
        <sourceRoot>outputDir</sourceRoot>
        <wsdlOptions>
          <wsdlOption>
            <wsdl>wsdl</wsdl>
            <extraargs>
              <extraarg>-server</extraarg>
              <extraarg>-impl</extraarg>
            </extraargs>
          </wsdlOption>
        </wsdlOptions>
      </configuration>
      <goals>
        <goal>wsdl2java</goal>
      </goals>
    </execution>
  </executions>
</plugin>
This does the following:
  • The -impl option generates a shell implementation class for each wsdl:portType element in the WSDL contract.
  • The -server option generates a simple main() to run your service provider as a stand alone application.
  • The sourceRoot specifies that the generated code is written to a directory called outputDir.
  • wsdl element specifies the WSDL contract from which code is generated.
For a complete list of the options for the code generator see cxf-codegen-plugin.

Generated code

Table 26.1, “Generated Classes for a Service Provider” describes the files generated for creating a service provider.

Table 26.1. Generated Classes for a Service Provider

FileDescription
portTypeName.java The SEI. This file contains the interface your service provider implements. You should not edit this file.
serviceName.javaThe endpoint. This file contains the Java class consumers use to make requests on the service.
portTypeNameImpl.java The skeleton implementation class. Modify this file to build your service provider.
portTypeNameServer.javaA basic server mainline that allows you to deploy your service provider as a stand alone process. For more information see Chapter 30, Publishing a Service.
In addition, the code generator will generate Java classes for all of the types defined in the WSDL contract.

Generated packages

The generated code is placed into packages based on the namespaces used in the WSDL contract. The classes generated to support the service (based on the wsdl:portType element, the wsdl:service element, and the wsdl:port element) are placed in a package based on the target namespace of the WSDL contract. The classes generated to implement the types defined in the types element of the contract are placed in a package based on the targetNamespace attribute of the types element.
The mapping algorithm is as follows:
  1. The leading http:// or urn:// are stripped off the namespace.
  2. If the first string in the namespace is a valid Internet domain, for example it ends in .com or .gov, then the leading www. is stripped off the string, and the two remaining components are flipped.
  3. If the final string in the namespace ends with a file extension of the pattern .xxx or .xx, then the extension is stripped.
  4. The remaining strings in the namespace are appended to the resulting string and separated by dots.
  5. All letters are made lowercase.
You generate the implementation class used to build your service provider with the code generator's -impl flag.
Tip
If your service's contract includes any custom types defined in XML Schema, you must ensure that the classes for the types are generated and available.

Generated code

The implementation code consists of two files:
  • portTypeName.java — The service interface(SEI) for the service.
  • portTypeNameImpl.java — The class you will use to implement the operations defined by the service.
To provide the business logic for your service's operations complete the stub methods in portTypeNameImpl.java. You usually use standard Java to implement the business logic. If your service uses custom XML Schema types, you must use the generated classes for each type to manipulate them. There are also some Apache CXF specific APIs that can be used to access some advanced features.

Example 26.2. Implementation of the Greeter Service

package demo.hw.server;

import org.apache.hello_world_soap_http.Greeter;

@javax.jws.WebService(portName = "SoapPort", serviceName = "SOAPService", 
                      targetNamespace = "http://apache.org/hello_world_soap_http", 
                      endpointInterface = "org.apache.hello_world_soap_http.Greeter")
                  
public class GreeterImpl implements Greeter {

    public String greetMe(String me) {
       System.out.println("Executing operation greetMe");
       System.out.println("Message received: " + me + "\n");
       return "Hello " + me;
    }
    
    public void greetMeOneWay(String me) {
       System.out.println("Executing operation greetMeOneWay\n");
       System.out.