Web Services for Java Developers - PowerPoint

Document Sample
Web Services for Java Developers - PowerPoint Powered By Docstoc
					Web Services for Java
Developers
SOAP which leaves you smelling all service-like
Who are you?

 Dan Diephouse (dan@netzooid.com)

 Day job consists of running a logistics software
  business and consulting

 Pet WS Project: XFire SOAP toolkit
  (http://xfire.codehaus.org)
Questions, questions, questions…

 Why web services?

 How do I implement and design web services?

 What are all these different web services technologies?

 How do I build better web services?

 How do I integrate my services?
Goals

 Answer the questions on the previous slides

 Give a good mix of practical hands on knowledge with
 higher level design issues
Agenda

 Introduction to web services

 Web service design and best practices

 Toolkit Review

 Debugging, testing, and performance

 WS-*

 Service Design Process

 Integration (SOA & ESBs)
Code for this presentation

 Download the code:



 http://netzooid.com/jia/code.zip

 http://netzooid.com/jia/jia.ppt
Introduction to Web Services
     •   Why oh why?
     •   XML Schema
     •   SOAP
     •   WSDL
Why Web Services? (Technical)

 XML is the universal language
  • RMI can’t really talk to .NET

 Interoperability

 More agile development
Why Web Services? (Business)

 Create tight integration between consumers and your
  service
  •   You create convenience for your consumer
  •   Tight integration may make it hard for them to switch

 Consumers may find uses for your service that you:
  •   Don’t have time to explore
  •   Didn’t think to explore

 Example: 40% of EBay’s sales happen over its API
Why SOAP services?

 Sophisticated tools to consume these services
  in every language
   • We’ll see an example later on

 With large APIs, REST/HTTP services become
  hard to consume (IMHO!)

 SOAP works over any transport, not just HTTP
SOAP Basics

 XML Schema describes the messages

 WSDL describes the service’s operations

 SOAP provides the packaging to send
  messages

 We’ll cover the basics of each before exploring
 service creation and design
XML Schema

 Way to express XML structure

 A valid document conforms to a particular
  schema

<xsd:schema xmlns:xsd=http://www.w3.org/2001/XMLSchema
  targetNamespace=“http://acme.com/foo”>
 …
</xsd:schema>
Simple Types

 XML Schema includes several simple types
  • xs:double
  • xs:int
  • xs:decimal
  • xs:GMonth
  • Etc

 You can extend and redefine these, as well as
  create your own
Simple Type Examples
<Count>5</Count>
<Month>10</Count>
<DepartureDate></DepartureDate>
<xsd:schema xmlns:xsd=“http://www.w3.org/2001/XMLSchema”
  targetNamespace=“http://acme.com/foo”
  elementFormDefault=“unqalified”>
  <xsd:element name=“Size” type=“xsd:int”/>
  <xsd:element name=“Month” type=“xsd:GMonth”/>
  <xsd:element name=“DepartureDate”
               type=“xsd:date”/>
</xsd:schema>
Complex Types
<developer country=“US”>
  <name>Dan Diephouse</name>
  <role>Code Monkey</role>
</developer>
<xsd:element name=“developer”>
 <xsd:complexType>
  <xsd:sequence>
    <xsd:element name=“name” type=“xsd:string”/>
    <xsd:element name=“role” type=“xsd:string”/>
  </xsd:sequence>
  <xsd:attribute name=“country” type=“xsd:string”/>
 </xsd:complexType>
</xsd:element>
“Abstract” Complex Types

 Allows a measure of reuse
<xsd:schema …>
 <xsd:element name=“developer”
 type=“developerType”>

 <xsd:complexType name=“developerType”>
  <xsd:sequence>
    <xsd:element name=“name” type=“xsd:string”/>
    <xsd:element name=“role” type=“xsd:string”/>
  </xsd:sequence>
 </xsd:complexType>
</xsd:schema>
Restrictions

<xsd:attribute name=“country”>
 <xsd:simpleType>
  <xsd:restriction base=“xsd:string”>
   <xsd:enumeration value=“United States”/>
   <xsd:enumeration value=“Canadia”/>
 </xsd:simpleType>
</xsd:element>
What is SOAP?
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-
envelope">
 <env:Header>
  <n:alertcontrol
xmlns:n="http://example.org/alertcontrol">
   <n:priority>1</n:priority>
   <n:expires>2001-06-22T14:00:00-05:00</n:expires>
  </n:alertcontrol>
 </env:Header>
 <env:Body>
  <m:alert xmlns:m="http://example.org/alert">
   <m:msg>Pick up Mary at school at 2pm</m:msg>
  </m:alert>
 </env:Body>
</env:Envelope>
SOAP Properties

 Its just XML (kinda)
   • It can’t contain PIs or DTDs

 Body: Contains a message to the SOAP
  endpoint (“ultimate recipient”)
Headers

 Extensible location. Often used for:
  •   Authentication Tokens
  •   Transactions
  •   Metadata about where the message is going to

 MustUnderstand attribute - if receiver does not
  understand the header, then it must throw a fault.

 Role attribute – Says which intermediary the Header is
  destined for
SOAP Properties

 Transport Neutral.

 Runs over things named with capital letters:
 HTTP, SMTP, JMS, XMPP, TCP, UDP, JXTA
It’s not my fault

 The “exceptions” of SOAP


<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-
envelope">
<env:Body>
  <env:Fault>
    <faultcode>env:MustUnderstand</faultcode>
    <faultstring>Header was not understood</faultstring>
  </env:Fault>
</env:Envelope>
Faults

 Contain fault code, message, role, and detail elements

 Fault code: A general fault code – Server,
  MustUnderstand, Version mismatch, etc.

 SOAP 1.2 includes an additional SubCode field which
  can be used for application specific error codes.

 Detail: place for arbitrary XML which can contain
  application specific error codes
RPC Encoding

 Portion of the SOAP specs which specify an xml
  “encoding”

 Written because
  •   XML Schema spec wasn’t finished at the time
  •   Needed a way to allow circular object graphs

 Ambiguous part of the spec that caused a lot of
  interoperability problems

 Just don’t use it (more on this later)
RPC-Encoding Example
<e:Book>
   <title>My Life and Work</title>
   <author href="#Person-1"/>
</e:Book>
<e:Person id="Person-1">
   <name>Henry Ford</name>
   <address href="#Address-2"/>
</e:Person>
<e:Address id="Address-2">
   <email>mailto:henryford@hotmail.com</email>
   <web>http://www.henryford.com</web>
</e:Address>
SOAP Versions

 1.1
   • Everyone uses and supports it

 1.2
   • Being used more and more
   • RPC-encoding is no longer required to be compliant
   • Fault code is a QName
   • Allows fault subcodes
   • More...
WSDL

 Web Service Description Language

 Describes your service, its location and its
  operations

 Two flavors
   • 1.1 – Widely used
   • 2.0 – In process, much clearer application of concepts
Components in WSDL 1.1

 Types – holds the XML Schema

 Messages – Messages which are sent as part of
  operations

 Port Type – the service “interface”
  •   Specifies operations

 Binding – Binds a port type to a particular transport

 Service – Describes the location of a binding
Component XML pieces
<wsdl>
  <types/>?
  <message/>*
  <portType/>*
  <binding/>*
  <service/>*
</wsdl>
Walkthrough: Book Service

 We’ll write a service description to gain an
  understanding of the concepts

 Book price service

 One operation – getPrice - which returns the
  price for an ISBN #
PortType – Your Interface
<portType name="BookPrice">
  <operation name="getBookPrice">
    <input name="isbn“
           message="a:GetBookPriceRequest"/>
    <output name="price“
            message="a:GetBookPriceResponse"/>
  </operation>
</portType>
Messages
<message name="GetBookPriceRequest">
  <part name="isbn" type="xs:string" />
</message>

<message name="GetBookPriceResponse">
  <part name="price" element="a:Book"/>
</message>
XML Schema Types
<types>
  <xs:schema
targetNamespace="http://www.acme.com/BookQuote">
    <xs:element name="Book">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="Title" type="xs:string"/>
          <xs:element name="Author" type="xs:string"/>
          <xs:element name=“Price” type=“xs:decimal”/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:schema>
</types>
Binding – Concrete Implementation
<binding name="BookPriceBinding" type="a:BookQuote">
  <soap:binding style="document"
    transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="getBookPrice">
    <soap:operation soapAction=""/>
    <input>
      <soapbind:body use="literal"
        namespace="http://www.acme.com/BookQuote"/>
    </input>
    <output>
      <soapbind:body use="literal"
        namespace="http://www.acme.com/BookQuote"/>
    </output>
  </operation>
</binding>
Sidenote: Encoding and Style

 How many ways are there to send an XML
  message?
  • 4ish

 Encoding: literal vs. encoded (covered earlier)

 Style: document, rpc, “wrapped”
Style

 RPC: <operation> element is implied, the
  toolkit needs to create it even though its not in
  the schema
 Document: Follow the schema exactly.
 Wrapped: A type of document style which puts
  the operation name in the schema
   • Microsoft pioneered this style which is a simple
    convenience for the developer
Wrapped Schema Example
<xs:element name=“getBookPrice">
  <xs:complexType>
    <xs:sequence>
      <xs:element name=“isbn” type=“xs:string”/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name=“getBookPriceResponse">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref=“tns:Book"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
Which Operation??

 Document/Wrapped: Operations are inferred
  from the XML types and the number of
 elements in the Body

 RPC: <getFoo> is translated into “getFoo”
  operation

 WS-Addressing can also be used (more later)
Service
<service name="BookPriceService">
  <port name="BookPrice_Port"
        binding="a:BookPriceBinding">
    <soap:address
        location="http://acme.com/foo/BookPrice"/>
  </port>
</service>
Service in Action: Request

<env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Body xmlns:a="http://www.acme.com/BookQuote">
  <a:isbn>0123456789</a:isbn>
 </env:Body>
</env:Envelope>
Service in Action: Response
<env:Envelope
 xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Body xmlns:a="http://www.acme.com/BookQuote">
  <a:Book>
    <a:Title>Web Services for Java Developers</a:Title>
    <a:Author>Dan Diephouse</a:Author>
    <a:Price>19.95</a:Price>
  </a:Book>
 </env:Body>
</env:Envelope>
Wrapped Example Request
<env:Envelope
 xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Body xmlns:a="http://www.acme.com/BookQuote">
  <a:getBookPrice>
    <a:isbn>0123456789</a:isbn>
  </a:getBookPrice>
 </env:Body>
</env:Envelope>
Wrapped Example Response
<env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body xmlns:a="http://www.acme.com/BookQuote">
    <a:getBookPriceResponse>
      <a:Book>
        <a:Title>Web Services for Java
           Developers</a:Title>
        <a:Author>Dan Diephouse</a:Author>
        <a:Price>19.95</a:Price>
      </a:Book>
    </a:getBookPriceResponse>
  </env:Body>
</env:Envelope>
WSDL and Faults

 Just like you can declare exceptions with Java
  you can declare Faults with WSDL

 Custom faults declare one element in the
  schema that will provide more information to
  the consumer

 Lets retrofit our book service to throw an
  InvalidISBN fault
PortType
<portType name="BookPrice">
  <operation name="getBookPrice">
    <input name="isbn"
           message="a:GetBookPriceRequest"/>
    <output name="price"
            message="a:GetBookPriceResponse"/>
    <fault name="InvalidISBNFault"
           message="a:InvalidISBNFault"/>
  </operation>
</portType>
Messages
<message name="GetBookPriceRequest">
  <part name="isbn" type="xs:string" />
</message>

<message name="GetBookPriceResponse">
  <part name="price" element ="a:Book"/>
</message>

<message name="InvalidISBNFault">
  <part name="InvalidISBNFaultDetail" e
        element="a:InvalidISBNFaultDetail"/>
</message>
XML Schema


<xs:element name="InvalidISBNFaultDetail">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="invalid-isbn"
                   type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
Binding
<binding name="BookPriceBinding" type="a:BookQuote">
  <soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="getBookPrice">
    <soap:operation soapAction=""/>
    …
    <fault name="InvalidISBNFault">
      <soap:fault name="InvalidISBNFault"
                  use="literal"/>
    </fault>
  </operation>
</binding>
Fault Example
<env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Body xmlns:a="http://www.acme.com/BookQuote">
  <env:Fault>
    <faultcode>env:Client</faultcode>
    <faultstring>
      "#" is an invalid ISBN character
    </faultstring>
    <detail>
      <a:InvalidISBNFaultDetail>
        <invalid-isbn>#123</invalid-isbn>
      </a:InvalidISBNFaultDetail>
    </detail>
  </env:Fault>
 </env:Body>
</env:Envelope>
WSDL 1.1 vs 2.0

 portType renamed interface

 2.0 has better MEP support

 2.0 is not widely supported yet

 If you don’t know why you should be using it,
  then you shouldn’t be (yet)
Basic Profile

 Basic Profile – http://ws-i.org

 Tries to make ambiguous parts of the
 WSDL/SOAP specs unambiguous.

 Versions 1.0/1.1

 We’ll talk about portions as we move through
 the session
Designing Services

So much XML! Where’s the Java???
Design Services Breakdown
 Coding services
   • POJOs and JSR 181
   • XMLBeans (Schema)
   • WSDL->Service
   • Interop issues will be interspersed
 Schema Design
 Extensibility
 Break
 Versioning
Your First Service: POJOs and JSR 181

 POJOs are the language of a Java Developer

 The idea: use POJOs as Data Transfer Objects
 (DTO). Bind them to XML and generate an XML
 schema automatically

 JSR 181 provides annotations for web services
 (more in a minute…)
A Bird’s Eye View


   The               Service           Your API
  Toolkit          and DTOs                &
  Generates XSD
     & WSDL,
                   Converts back and
                   forth between your  Business
    binds XML
                  internal API and the
                       web service.      Logic
Why Not This?


         The           Your API
        Toolkit            &
       Generates XSD
          & WSDL,
                       Business
         binds XML       Logic
Data Transfer Objects (DTOs)

 Exposing your core business classes is bad:
  •   Often contains things irrelevant to end user
  •   Often contains things you don’t want the end user to have access
      to
  •   If you change your internal API, your external API (the web
      service) changes too. Bad for backward compatability

 DTOs are used as a wrapper around your core logic

 Used to expose functionality to the consumer
Our Service

 We’re going to create a Purchase Order
  service

 We want to:
  • Receive purchase orders
  • Retreive purchase orders
  • Get a list of recent purchase orders
Step 1: Create our service class
public interface OrderService {
    @WebMethod
    @WebResult(name = "purchaseOrderId")
    long receiveOrder(
            @WebParam(name = "purchaseOrder")
            PurchaseOrder order)
            throws XFireFault;

    @WebResult(name = "purchaseOrder")
    PurchaseOrder getPurchaseOrder(
            @WebParam(name = "purchaseOrderId")
            long id) throws XFireFault;

    @WebResult(name = "purchaseOrders")
    Collection<PurchaseOrder> getRecentOrders()
            throws XFireFault;
}
Whats in a service class..

 One method for each operation

 Exceptions: Instead of just throwing
 NoSuchOrderException, we’ll catch our
 internal exceptions and create the appropriate
 fault info.

 Annotations…
JSR 181 Annotations

 Annotate classes with web service specific data

 @WebMethod

 @WebParam
  •   Java doesn’t store the name of method parameters, so we need to
      provide it: @WebParam(name=“foo”)

 @WebResult – like @WebParam, but for results
Step 2: Create the implementation

@WebService(endpointInterface="com.acme.code.OrderService")
public class OrderServiceImpl implements
        OrderService {…
}


  @WebService – demarcates a class as a web
   service
    • endpointInterface – specifies the interface to generate the
      port type against
Step 3: Create Your DTOs

public class PurchaseOrder {
    private Address shipTo;
    private Address billTo;
    private String comment;
    private List<Item> items;
    private long purchaseOrderId;
    .
    .
}
Step 4: Deploy!

 Deploying is different with every toolkit

 Typically with HTTP you register a servlet and
 there is a configuration mechanism

 To the web browser….
Step 5: Create a client

 Users can use the WSDL to:
  • Generate classes to access your service
  • Dynamically access your service

 Lets take a look at using .NET…
Accessing with .NET

And we’re off to Visual Studio momentarily…
TCPMon: Watching your Service

 TCPMon allows you to see your messages
  going across the wire

 “java –cp axis.jar
  org.apache.axis.utils.tcpmon”
 Our Request Part 1
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
    <receiveOrder xmlns="http://code.acme.com">
       <purchaseOrder>
        <billTo>
          <city>Grand Rapids</city>
          <name>Dan Diephouse</name>
          <state>MI</state>
          <street>2032 Lake Dr</street>
          <zip>49506</zip>
        </billTo>
Our Request Part 2
      <comment xsi:nil="true" />
      <items>
        <Item>
          <USPrice>0</USPrice>
          <comment xsi:nil="true" />
          <partNumber>123</partNumber>
          <productName>Good smelling SOAP</productName>
          <quantity>0</quantity>
          <shipDate>0001-01-01T00:00:00</shipDate>
        </Item>
      </items>
      <purchaseOrderId>0</purchaseOrderId>
    </purchaseOrder>
   </receiveOrder>
 </soap:Body>
</soap:Envelope
Our Response

<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <receiveOrderResponse xmlns="http://code.acme.com">
      <purchaseOrderId>5</purchaseOrderId>
    </receiveOrderResponse>
  </soap:Body>
</soap:Envelope>
BP - Interopability: nillable

 Example Schema
  <element name=“Date” nillable=“true” type=“dateTime”/>

 Example XML
  <Date xsi:nil=“true”/>

 What happens: .NET or Java will barf if the the
 element is a “value type”
BP - Interoperability: nillable

 Value types (int/long/etc) cannot be null

 Value types differ from language to language
  • DateTime is a value type in .NET, but Date is not in Java

 Some toolkits (.NET 2.0, XMLBeans, etc) can
  handle this.

 Others (Axis 1.x, .NET 1.0) cannot
BP - Interopability: nillable

 Be aware of what your toolkit is outputting in
  the schema

 Nillable will break on any sort of value type in
  any language

 BE AWARE: that XML != Java
BP - Style and Encoding

 If you have any doubt use literal encoding always

 Encoded use is kind of against the basic profile
  •   The wording is ambiguous

 Wrapped vs Document style: its up to you.

 Document style has the connotations “message
  passing” which is what SOAP is all about
BP – Faults

 Declare a fault in the WSDL for specific errors
  that you feel your consumers need to deal
 with

 Faults have faultcode, faultstring and
  faultactor fields. USE THEM
Toolkits

 JSR 181:
   • Axis + Beehive WSM – http://ws.apache.org/axis
   • XFire – http://xfire.codehaus.org
   • Sun’s JAX-WS?
 POJO/XML Bindings
   • Axis’s internal type system - http://ws.apache.org/axis
   • JAXB 1.1 & 2.0
   • JiBX – http://jibx.sourceforge.net
   • XFire’s Aegis Binding – http://xfire.codehaus.org
Service #2: Schema and XMLBeans

 Steps are basically the same as Service #1

 Instead of POJOs we’ll use XMLBeans

 XMLBeans are classes generated from XML
  Schema
Step 1: Design the Schema
Step 2: Compile XMLBeans
<java
  classname="org.apache.xmlbeans.impl.tool.SchemaCompiler"
  classpathref="xmlbeans.path" fork="true">
  <arg value="-d" />
  <arg value=“outputdir" />
  <arg value="${basedir}/src/schema" />
</java>
Step 3: Write the Service Class
public interface OrderService {
    PurchaseOrderIdDocument receiveOrder(
            PurchaseOrderDocument purchaseOrder)
            throws XFireFault;

    PurchaseOrderDocument getPurchaseOrder(
            PurchaseOrderIdDocument id)
            throws XFireFault;

    Collection<PurchaseOrderDocument> getRecentOrders()
            throws XFireFault;
}
Step 3: Write the Service Class
public PurchaseOrderIdDocument receiveOrder(
            PurchaseOrderDocument purchaseOrder)
            throws XFireFault {
  PurchaseOrderType order =
    purchaseOrder.getPurchaseOrder();
  order.setPurchaseOrderId(count++);

    PurchaseOrderIdDocument pid =
      PurchaseOrderIdDocument.Factory.newInstance();
    pid.setPurchaseOrderId(order.getPurchaseOrderId());

    return pid;
}
Step 4: Deploy
Step 5: Write the client
Some things to note

 Writing a schema really wasn’t that hard…
  • You gained control and coherency at the expense of some
     up front thought and design time

 Reusability
  • Our PurchaseOrderId type is reused for a more coherent
     and elegant schema

 XMLBeans is very XMLish, while retaining
  some sense of javaness
More on XMLBeans

 Can access the document at any time
   • xmlBean.getDomNode();
   • xmlBean.newXMLStreamReader();
   • Etc

 Can modify the xml and have changes
  reflected in the bean and vise a versa
Schema->Java Toolkits

 Any JAX-RPC toolkit (i.e. Axis 1.x)

 Castor

 GLUE

 JiBX

 JAXB 1.1 & 2.0

 Systinet

 XMLBeans
Code first vs. schema first

 Schema first gives you a much more well
  defined contract

 Forces you to think in terms of XML and
  messages instead of objects, which is a Good
  Thing

 Not too much extra work
Service #3: WSDL->Service

 Most toolkits actually require more than just a
  Schema – the full WSDL

 We’ll look at using Axis’s WSDL2Java tool to
  build a service
Step 1: Write the WSDL

 Use WSCF to create our WSDL via our schema

 Constructs WSDL an operation at a time

 Forces you to think about whats coming in and
  what is going out

 The WSDL is a CONTRACT. It must not break!
Step 2: Build service stubs

 WSDL2Java tool builds us our DTOs and a
  service stub which we can fill in

 java org.apache.axis.wsdl.WSDL2Java
  foo.wsdl
Joys of JAX-RPC

 OrderServiceInterface: Service Interface

 OrderServiceImpl: Our implementation

 DTOs are also generated
  • Address
  • PurchaseOrder
  • etc
Step 3: Service Implementation
public class OrderServiceImpl implements
com.acme._2005._05.OrderServiceInterface {

    public
      com.acme.purchase_order._2005._08.PurchaseOrderType
      getPurchaseOrder(long purchaseOrderId) throws
        java.rmi.RemoteException {
          return null;
      }
.
.
}
 Step 4: Deploy

  Axis uses a WSDD configuration syntax

<deployment
  xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <service name=“OrderService" provider="java:RPC">
    <parameter name="className"
       value=“com.acme.OrderService"/>
    <parameter name="allowedMethods" value="*"/>
  </service>
</deployment>
Schema Design

“No, you can’t write web services just in Java.”
The XML/Java Mismatch

 There is not an equivalent Java type for every XML type.
  Examples:
   • GMonth
   • A Regex restriction
   • PositiveInteger
 This applies to ALL Languages
 You need to be aware of your consumers
 Toolkits such as XMLBeans/JAXB 2.0/.NET 2.0 make
  great strides in this area
Think in Messages

 SOAP is asynchronous message passing

 SOAP is NOT serialized objects

 SOAP is NOT RMI

 Exceptions are NOT Faults

 Thinking otherwise will result in performance
  and design problems
Problem

 Sometimes I want a whole message

 Sometimes I want part of a message

 If I always send the whole message it results
  in latency and performance issues
Parameter Driven Messages

 Effective way to combat bandwith and latency
  issues
 Often messages contain many different chunks
 Specify parameters which tell the service
  whether or not the client needs the chunk
 Creates smaller messages, lower processing
  time, lower latency
Request #1
<getPurchaseOrder>
  <PurchaseOrderId>100</PurchaseOrderId>
  <RetrieveItems>true</RetrieveItems>
</getPurchaseOrder>
Response #1
<a:PurchaseOrder
xmlns:a="http://acme.com/purchaseOrder/2005/08">
  <a:ShipTo>...</a:ShipTo>
  <a:BillTo>...</a:BillTo>
  <a:Items>
    <a:Item>
      <a:ProductName>ACME Explosives</a:ProductName>
      <a:Quantity>1</a:Quantity>
      <a:PartNum></a:PartNum>
      <a:USPrice>999.99</a:USPrice>
      <a:ShipDate>2005-08-13T10:22:24.335-
04:00</a:ShipDate>
    </a:Item>
  </a:Items>
</a:PurchaseOrder>
Request #2
<getPurchaseOrder>
  <PurchaseOrderId>100</PurchaseOrderId>
  <RetrieveItems>false</RetrieveItems>
</getPurchaseOrder>
Response #1
<a:PurchaseOrder
xmlns:a="http://acme.com/purchaseOrder/2005/08">
  <a:ShipTo>...</a:ShipTo>
  <a:BillTo>...</a:BillTo>
</a:PurchaseOrder>
Flattened Your Schema

 Don’t reproduce fragments over and over

 Advantages
  • Better structure
  • Much more friendly to your end user
  • Decreased bandwidth
<Projects>
  <Project>
    <Name>Operation Foo</Name>
                                    Bad Example
    <Employee>
      <Name>Dan Diephouse</Name>
      <Title>Web Services Developer</Title>
    </Employee>
    <Employee>
      <Name>James Bond</Name>
      <Title>Secret Agent</Title>
    </Employee>
  </Project>
  <Project>                              Replication!
    <Name>Operation Bar</Name>
    <Employee>
      <Name>James Bond</Name>
      <Title>Secret Agent</Title>
    </Employee>
  </Project>
</Projects>
<ProjectInfo>
  <Project>
                                Good Example
    <Name>Operation Foo</Name>
    <Employee id="1"/>
    <Employee id="2"/>
  </Project>
  <Project>
    <Name>Operation Bar</Name>
    <Employee id="2"/>
  </Project>
  <Employee id=“1”>
    <Name>Dan Diephouse</Name>
    <Title>Web Services Developer</Title>
  </Employee>
  <Employee id=“2”>
    <Name>James Bond</Name>
    <Title>Secret Agent</Title>
  </Employee>
</ProjectInfo>
Namespace Versioning

 How do I determine which version an XML
  document is?

 Anytime you make a change to your schema
  which isn’t backward compatible, change your
  namespace version
Namespace Versioning

 Examples:

 http://acme.com/purchase-order/2005/08

 http://acme.com/purchase-order/2005/11

 urn:acme-com:purchase-order:2005:08
Namespace Versioning

 Example in eclipse…
Making your schema Extensible

 What happens if you want to add an element
  or attribute later?

 <xsd:sequence> only allows declared
  elements

 Future documents would no longer be valid

 Need wildcard to allow anything
Extensibility and Enums

 No equivalent of xs:anyType with
  enumerations

 Therefore, if you add things to a schema
  enum, it must be a new version
Schema Code Conventions

 complexTypes are often named FooType
  instead of Foo

 Be nice to your consumers and use
  documentation annotations
Handling binary data: inline it

 xsd:byte[]

 Base64 encodes data

 30% increase in size

 Easy to use

 Doesn’t work if you can’t fit data from all
  requests in memory
Handling binary data: Attachments

 Soap w/ Attachments outlines way to attach
  binary data via MIME attachments

 Must be Base 64 encoded
Handling binary data: MTOM

 An optimized way of handling binary
  attachments

 SOAP envelope is MIME root

 Each attachment is another MIME element

 Doesn’t require you to base64 encode
Handling binary data: Don’t send it

 Send a URL which specifies where to get the
  resources

 This is used by Amazon and other
   • Example: album clip art
   • <ImageURL>http://amazon.com/../foo.jpg</ImageURL>
Using Relax NG

 Relax NG is an XML Schema alternative that
  many find more intuitive

 You can develop in RNG and convert to XML
  Schema
Break sponsored
by
Versioning Tactics
Why Versioning is an Issue

 Obviously, you need to be able to update and
  change your API

 Causes problems:
   • Maintenance increases for each version
   • Code bloat
   • No good way to map multiple sets of XML to a single set of
     objects
Sidenote: Schema Maintenance

 If every division has their own schema, your
  maintenance costs are going to grow
 exponentially (n^2)

 It’ll be worth the effort to get different
  divisions to agree on a schema and maintain
 them centrally

 If you’re exposing your services outside your
  organization, this isn’t as big of an issue
Unified DTO pattern

 Maps arbitrary XML forms to the same set of
  objects

 Very few toolkits support this
  • JiBX – http://jibx.sf.net

 Impossible with Annotations
Multiple DTO pattern

 DTO layer between your service and the world



 Service         DTO v1
                                Your API
 Router          DTO v2
Service Routing

 You’ll need a way to determine which service
  you want to invoke

 Methods
  • Endpoint
  • Header
  • Namespace
Routing: Endpoint

 Create different endpoints for each service
  version
   • http://localhost/OrderService/v1
   • http://localhost/OrderService/v2
Routing: Header

 Version Header (EBay does this)
  • <Version>341</Version>

 You can create interceptors which route the
  message to the appropriate service based on
  this header
Routing: Namespace

 Create a Map between namespace versions
  and the appropriate service to invoke
   • Namespace urn:purchase-order:2005:08 goes to
    implementation #1

 Use an interceptor to handle this routing
Transformations

 Keep one service which is the current version

 Use XSLT to transform messages between
 different versions

 Can get complicated depending on how many
  service versions you have and your XSLT
 experience
“Deployment Versioning”

 Database becomes ultimate authority

 New endpoint for each version

 If your database changes singificantly, this fails.

      http://.../v1         http://.../v2

     Application 1.0       Application 2.0

              Database
Web Service Toolkits
Choosing a databinding API

 Your application requirements will help determine the
  databinding or lack there of

 XML APIs:
  •   SAX, DOM, StAX

 Databinding
  •   JAXB, XMLBeans, JAX-RPC 1.1, JiBX, Castor

 Depends on your versioning, performance and time
  requirements
XML: SAX & StAX

 Why:
  • Low memory
  • Fast

 When:
  • You have very contstrained memory requirements
  • You are writing your own databinding
StAX Example
int event = reader.getEventType();
while ( reader.hasNext() )
{
    switch( event )
    {
    case XMLStreamConstants.START_ELEMENT:
         QName name = reader.getName();
    case XMLStreamConstants.END_ELEMENT:
    case XMLStreamConstants.CHARACTERS:
         // can read characters as stream or string
    default:
        break;
    }

    event = reader.next();
}
XML: DOM

 Why: Easy API to work with XML

 When:
  • You want random access to the document you are
      receiving
  •   WS-Security (and other specs) requires DOM model
  •   Memory isn’t a big issue
XML: Which DOM?

 W3C DOM
  •   Pros: in every JDK
  •   Cons: Bad API, Crapshoot as to how it will work on different JDKs

 XOM – Great API, fast, low memory for DOM, LGPL

 DOM4J – OK API, moderately fast, ASL

 JDOM – OK API, moderately fast
JAXB

 Medium performance

 New set of DTOs for each version

 When:
  • You want to bind your XML to a very POJO like structure
  • You’re using JAX-WS
XMLBeans

 Medium performance

 New set of DTOs for each version

 When: You want a very XMLish API. Can
  access DOM at any time
JiBX

 Fastest databinding that I know of

 Unified DTO & multiple DTO versions available

 When: You want a very fast, Javaish
  databinding
Toolkits

 The Sun Way: JAX-RPC 1.1, JAX-WS

 Alternative: Axis, GLUE, WASP, XFire

 Roll-your-own: Listen on HTTP, process
The Truth about Toolkits

 It matters, but…

 More important is
  • Good design principles
  • Using the correct databinding API

 Good web services are hard period (but
  getting easier)
JAX-RPC

 JAX-RPC 1.1 is just BAD
   • Very RPC oriented
   • Developer unfriendly
   • W3C DOM based
JAX-WS

 Looking good, but not out yet

 Handler concept from JAX-RPC

 Based on much more “WSDLish” concepts, and
  less “RPCish” concepts
Axis 1.X

 Open source

 Very interoperable

 Supports RPC-Encoding if you need it

 SLOW & Memory intensive

 Hard to use

 SAX/DOM based

 Databinding: JAX-RPC style, XMLBeans
Axis 2

 Rework of Axis 1 based on StAX

 Still in progress: 0.9x release

 Databinding:
  • AXIOM is a StAX based parser that can cache nodes in a
       tree if need be
   •   Will (soon?) support JiBX/XMLBeans in addition
GLUE

 Very interoperable

 Easy to use

 $$$

 Databinding: based on Electric XML (DOM)
WASP/Systinet

 Very good toolkit

 Cost is % of revenue (hard to determine)

 Databinding: its very own
XFire

 Fast

 Embeddable

 Easy to use

 Open Source

 Low on the WS-* support

 Databinding: JAXB, JiBX (soon), XMLBeans, XOM and
  Aegis bindings
The Real Reason to use XFire

 Hani Suleiman uses it
  • (and hasn’t biled it)
  • (yet)
Roll Your Own

Just don’t

Spec is big, all sorts of minor issues
 which could come up
Testing and Debugging
TCPMon

 We saw this in action earlier

 Very easy to use and free (http://ws.apache.org/axis)

 Doesn’t tell you what went wrong, you still need to
  figure it out
Mindreef’s SOAP Scope

 The BEST tool for debugging everything to do
  with web services

 Will tell you whats wrong with your WSDL,
  schema or messages
Unit Testing

 You test your code, you should test your
  services as well

 How do you test against .NET without
  complicated set up?

 Answer: Capture messages and resend in your
 unit tests
Unit Test example from XFire

1. Send the document

2. If there is a response, run XPath assertions to
   test for the correct results.

 What you should test:
  • Response values and structure
  • Faults are sent in appropriate cases (i.e. Bad login)
Unit Test example from XFire
Document response =
  invokeService("Test",
     "/org/your/classpath/Message1.xml");

addNamespace("test", "urn:Test");
assertInvalid("//s:Fault");
assertValid("//test:Response", response);
assertValid("//test:Response[text()='howdy']",
            response);
Performance
Performance

 Web services have high latency and high
  bandwidth due to XML

 Large documents may not fit in memory
Caching

 Why reconstruct the purchase order document
  for every request?

 Create an interceptor which stores the
  document

 If the incoming request meets certain
 requirements, resend stored request
Memory

 StAX and SAX allow you to parse documents
  incrementally

 StAX: Streaming API for XML. Allows you to
  work with documents in a pull fashion

 Axis 2 and XFire are both built on this model
Working with large documents

 Possible to work with objects in low memory

 JiBX allows you to do this easily by iterating
 over document portions
ctx.parsePastStartTag("element namespace", "element
name");
while (!ctx.isEnd()) {
  Object obj = ctx.unmarshalElement();
  // do whatever you want with the unmarshalled element
}
ctx.parsePastEndTag();
Latency

 The biggest problem with XML is latency since parsing
  text takes time
 Reduce document size as much as possible
   • Remember parameter driven design?
 Reduce the number of messages that need to be sent
 Make sure you use a StAX toolkit
  • Doesn’t require a double transformation from InputStream to DOM
     to Objects

 You could use Binary XML…
Caveat

 Good architecture and planning can help
  anything scale

 Some very very large corporations are running
  on Axis 1.x

 You will just need more hardware
Binary XML

 About 4-5 times faster than just regular XML
 Many different flavors
  • Fast Infoset: StAX driver available (http://fi.dev.java.net)
 Question: If you control both endpoints why
  are you using XML?
   • Make sense in an intermediary situation
   • Or interdepartment communication where everyone agrees
     on a standard schema
WS-*

Navigating the landscape
WS-*

 Term which refers to the proliferation of web
  service specifications

 Which ones are important?

 Which ones can I use?

 Answer: it depends
WS-Addressing

 In protocols without URIs, how do we adress
  things?

 How do we do addressing in intermediary
  scenarios?

 How do we specify the action/operation we
 want to perform?
 WS-Addressing Example

<S:Header xmlns:S="http://www.w3.org/2003/05/soap-envelope"
  xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
  xmlns:fabrikam="http://www.fabrikam123.com/svc53">
  <wsa:MessageID>…</wsa:MessageID>
  <wsa:RelatesTo>…</wsa:RelatesTo>
  <wsa:To>http://business456.example/client1</wsa:To>
  <wsa:Action>http://fabrikam123.com/mail/DeleteAck</wsa:Action>
  <wsa:ReplyTo>
    <wsa:Address>http://business456.example/client1</wsa:Address>
    …
  </wsa:ReplyTo>
</S:Header>
WS-Security

 Used to encrypt and verify messages or
  portions of messages

 Standard authentication tokens

 Why not encrypt at transport?

 SOAP messages may go through
 intermediaries
WS-Security

 Kind of hard to integrate
  • Not supported by all clients
  • .NET people can use Microsoft’s Web Service’s Extensions
  • Axis people can use WSS4J
  • WASP/GLUE have libraries they can use

 Greatly slows things down

 Use transport level encryption if possible
Reliability and Web Services

 How do you guarantee message delivery?

 (Shhhh… HTTP isn’t reliable!)
WS-RX

 WS-Reliability specifies a way to guarantee via
  a set of soap messages

 CreateSequence, Acknowledge messages

 Reality: Its slow, high latency
SOAP over JMS

 Instead of WS-RX, use SOAP over JMS
  whenever possible

 JMS is “crazy fast” and very reliable

 Easy to configure and use

 When using with .NET or other platforms:
  • Create a JMS proxy in Java
  • Use your JMS provider via IKVM
Service Design Process
Steps to a successful service

1. Establish the scope of the service

2. Identify consumers

3. Determine anticipated usage

4. Model the service

5. Identify interaction scenarios

6. Design the message structure
Establish Service Scope

 What is this service trying to accomplish

 Questions such as:
  • Are we providing read access? Write access?
Identify consumers

 Will this service be used internally, externally or both?

 What type of security do we need?

 Are the consumers competent in WS-*?

 Do we anticipate future usage of this service by people
  outside the original target audience?
Determine anticipated usage

 Obviously you want to be able to handle the load

 Use appropriate technologies to achieve desired
  performance

 Determine hardware processing requirements

 What kind of latency will be appropriate?
Model the service

 Map out which operations your consumers will be
  performing

 Determine authentication mechanism
Identify interaction scenarios

 Don’t try to be too flexible

 Identify what operations your users actually need

 Will users always need all the data from an operation?

 Will the never need all the data?

 Will different users need different Data?

 How will the service interact with your other services?
Design the message structure

 You should now have enough information to design
  your XML schemas
Purchase Order Example

 Our examples earlier were a bit contrived

 Lets go through and achieve a much better design
Establish Service Scope

 We’re a provider of ACME Scented Soaps.

 We want our customers to be able to submit orders for
  our goods

 We should provide some kind of account history so
  they can view their transactions

 We’ll allow them to cancel order, but not revise them
Identify Consumers

 Off site customers, familiar with web services

 Customers are only in the US (for now…)

 Use Java and .NET primarily

 We’ll need encryption: HTTPS will suffice as there are
  no intermidiaries
Model the Service

 long pid submitOrder(PurchaseOrder order)

 void cancelOrder (long pid)

 List<PurchaseOrder> getOrders(Date start,
  Date end)
Identify Interaction Scenarios

 getOrders: Do consumers really need all the
  data in the PurchaseOrder?
   • We may want to add a <RetrieveItems> parameter here

 We have no other services to worry about here
  • If we add more later on it’d be nice to have an
    authentication mechanism that worked for all of them
Design the Message Structure

 PurchaseOrder
   • ShipTo
   • BillTo
   • Items

 BillTo/ShipTo: Only need to handle US
  Adresses
Integration: SOA & ESBs

Putting it all together
What is SOA?

 SOA: Service oriented architecture

 Traditional: Design an application, tack on a
 web service

 SOA: Design application as a service
How?

 You’ve already learned the basics

 Design good schemas

 Design good WSDLs

 They’re your service CONTRACT
What is ESB?

 Depends on who you ask

 A message broker between a collection of
 services

 Provides routing, caching, security, reliability
What is JBI?

 The Java SOA+ESB Buzzword Compliant JSR

 Normalized Message Router

 JBI is a way to connect everything

 WSDL like

 Or for the cynical: glorified SOAP over JMS
JBI the Acronym Collector
 XPATH
 XSLT
 SOAP
 WSDL
 JCA
 FTP
 HTTP
 JMS
 JMX
JBI Implementations

 ServiceMix: http://servicemix.org

 Sun: http://java.sun.com/integration
Audience Response

Questions?