Saturday, May 14, 2011

Sample Contract First Service using Spring-WS 2.0

I have now updated the sample for this article, to use Spring WS 2.0, which now provides a annotation based model for Webservice endpoints. The amount of configuration required to define a Webservice endpoint has reduced considerably between Spring WS 1.x and Spring WS 2.0  - most of the routine boilerplate to define an endpoint has moved from configuration to an annotation:
Whereas earlier, the endpoint would have been defined by a code of the following signature:
public class GetMemberDetailsEndpoint extends
  AbstractMarshallingPayloadEndpoint {
 private MemberManager memberManager;
 protected Object invokeInternal(Object requestObject) throws Exception {
  MemberDetailsRequest request = (MemberDetailsRequest) requestObject;
  MemberDetail memberDetail = memberManager.getMemberDetails(request
    .getId());
  MemberDetailsResponse response = new MemberDetailsResponse(memberDetail);
  return response;
 }

......
}
With Spring-WS 2.0 the endpoint can be more intuitively defined with the following signature:
@Endpoint
public class GetMemberDetailsEndpoint {

 @Autowired private MemberManager memberManager;

 @PayloadRoot(namespace = "http://bk.org/memberservice/", localPart = "MemberDetailsRequest")
 @ResponsePayload
 public MemberDetailsResponse getMemberDetails(@RequestPayload MemberDetailsRequest request) throws Exception {
  MemberDetail memberDetail = memberManager.getMemberDetails(request
    .getId());
  MemberDetailsResponse response = new MemberDetailsResponse(memberDetail);
  return response;

 }

.....

}
Updated code available at:
git://github.com/bijukunjummen/memberservice-contractfirst.git

Contract First and Code First Webservice Development

There are generally two styles for Webservice Development - Contract First and Code First.

Contract First is an approach where the developer starts from defining a contract for the webservice using a WSDL and then goes about generating/developing the codebase - typically using stacks that allow code to be generated from the wsdl.

Code First on the other hand is an approach where the developer starts by defining an interface, then generates the contract for the webservice using tools that allow translating an interface to wsdl.

I have used both approaches now for different projects over time and but am not very opinionated about either of the approaches. A purist approach would be to start with the contract, which I have personally advocated in the past, however in some real world projects I have tended to go with a code first approach, for a few reasons:

  1. Good tool support is required to define a reasonably involved wsdl - Eclipse is not good enough to create a quality wsdl - I would recommend IBM RAD or XML Spy for creating wsdl's
  2. A very deep knowledge of XML schema language is required to generate good constructs
  3. Development time is generally slower -  as creating a wsdl takes a good amount of time


Code First Approach on the other hand is quick. Let me illustrate by changing my DZone Example which is a Contract First example to a Code First using Apache CXF:

The contract for the service was:
<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ms="http://bk.org/memberservice/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="memberservice" targetNamespace="http://bk.org/memberservice/">
 <wsdl:types>
  <xsd:schema targetNamespace="http://bk.org/memberservice/" elementFormDefault="qualified">
   <xsd:complexType name="MemberDetailType">
    <xsd:sequence>
     <xsd:element name="name" type="xsd:string"/>
     <xsd:element name="phone" type="xsd:string"/>
     <xsd:element name="city" type="xsd:string"/>
     <xsd:element name="state" type="xsd:string"/>
    </xsd:sequence>
   </xsd:complexType>
   <xsd:element name="MemberDetailsRequest">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="id" type="xsd:string"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="MemberDetailsResponse">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="memberdetail" type="ms:MemberDetailType"/>
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
  </xsd:schema>
 </wsdl:types>
 <wsdl:message name="MemberDetailsRequest">
  <wsdl:part element="ms:MemberDetailsRequest" name="parameters"/>
 </wsdl:message>
 <wsdl:message name="MemberDetailsResponse">
  <wsdl:part element="ms:MemberDetailsResponse" name="parameters"/>
 </wsdl:message>
 <wsdl:portType name="memberservice">
  <wsdl:operation name="GetMemberDetails">
   <wsdl:input message="ms:MemberDetailsRequest"/>
   <wsdl:output message="ms:MemberDetailsResponse"/>
  </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="memberserviceSOAP" type="ms:memberservice">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
  <wsdl:operation name="GetMemberDetails">
   <soap:operation soapAction="http://bk.org/memberservice/GetMemberDetails"/>
   <wsdl:input>
    <soap:body use="literal"/>
   </wsdl:input>
   <wsdl:output>
    <soap:body use="literal"/>
   </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="memberservice">
  <wsdl:port binding="ms:memberserviceSOAP" name="memberserviceSOAP">
   <soap:address location="http://localhost:8081/memberservice/services/MemberDetailsRequest"/>
  </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

Let us start by defining a java interface that can sufficiently mimic this WSDL:
package org.bk.memberservice.endpoint;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

import org.bk.memberservice.message.MemberDetailsRequest;
import org.bk.memberservice.message.MemberDetailsResponse;

@WebService
public interface MemberEndpoint {
 @WebMethod(operationName = "MemberDetailsRequest")
 @WebResult(name = "MemberDetailsResponse", targetNamespace = "http://bk.org/memberservice/")
 MemberDetailsResponse getMemberDetails(
   @WebParam(name = "MemberDetailsRequest") MemberDetailsRequest memberDetailsRequest);
}

and the JAXB2 annotations on the request and response types:

package org.bk.memberservice.message;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "MemberDetailsRequest", namespace="http://bk.org/memberservice/")
public class MemberDetailsRequest {

 public MemberDetailsRequest() {
 }

 public MemberDetailsRequest(String id) {
  this.id = id;
 }

 private String id;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

}

package org.bk.memberservice.message;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.bk.memberservice.types.MemberDetail;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "MemberDetailsResponse", namespace="http://bk.org/memberservice/")
public class MemberDetailsResponse {

 public MemberDetailsResponse() {
 }

 @XmlElement(name="memberdetail", namespace="http://bk.org/memberservice/")
 private MemberDetail memberDetail;

 public MemberDetailsResponse(MemberDetail memberDetail) {
  this.memberDetail = memberDetail;
 }

 public MemberDetail getMemberDetail() {
  return memberDetail;
 }

 public void setMemberDetail(MemberDetail memberDetail) {
  this.memberDetail = memberDetail;
 }

}
This generates a wsdl fairly close to the manually generated one, but not quite there - there does not seem to be a good way of controlling the namespace of operation name, and the wrappers around the request and the response xml structures.

So considering these factors, a rule that I have used is:

  • If a service is consumed only by a known internal client(say for cases where the same team is the producer AND the consumer) then go for code first, for the speed of development
  • If a service is expected to be more widely used, then go for contract first, with careful wsdl design

Sample code used here is available at :
git://github.com/bijukunjummen/memberservice-codefirst.git

Thursday, May 5, 2011

Layered vs Big Ball of Mud


Layered arch vs Big Ball Of Mud
§  Separation of concerns -  Each layer encapsulates distinct functions –eg Presentation , Business Logic, Data Access in traditional three-tiered architecture.
§  If multiple presentation technology needs to be supported – say Mobile and Web based views, only the presentation tier is affected
§  If a different kind of data access pattern needs to be supported – say Memcache based caching, only the data tier is affected
§  Allows Reuse – lower layers can be re-used by the layers above it.
§  Testability – Each layer can be tested independently.
§  Maintainable – if view breaks, look in the presentation tier. If data seems wrong, look in the data access tier, if business logic seems wrong, look at the business tier
§  Fosters Developer specialization – UI developers looking at Presentation layer

Sunday, May 1, 2011

Learning - How do you learn a new technology area

This is the way I ( or for that matter anyone!) picks up a new technology area - a representation using Simplediagrams :

Say I am learning something about the new version of Spring Core -
I would first download Spring Core, play around with the reference applications(the "10 minute test"), try my own application by copying the reference and trying out more variations, until one day I can claim a level of expertise!


Saturday, February 5, 2011

STS Graph view for Spring Integration Configuration

The Spring Integration Graph View packaged with Spring Source Tool Suite (STS 2.5.2.RELEASE) is brilliant. 
The xml configuration for Spring Integration tends to get a little involved over time, the graphical view helps with visualizing the configuration well. Any high level gaps - no listener on a channel etc(bridge to nowhere?) will stand out in the graphical view -



I have faced one issue though and I have heard of one other in the forums:
  1. If I compose multiple flows into a single Spring configuration file (using import tags), the Graphical view cannot display the composed flow. 
  2. Different Spring Integration components can be created using annotations - these are also not reflected in the Visual view.

Monday, January 24, 2011

org.apache.cxf.service.factory.ServiceConstructionException: Could not resolve a binding for http://schemas.xmlsoap.org/wsdl/soap/

If you see the following at runtime:
org.apache.cxf.service.factory.ServiceConstructionException: Could not resolve a binding for http://schemas.xmlsoap.org/wsdl/soap/
add the following spring resources in your Spring context file:
 <import resource="classpath:META-INF/cxf/cxf.xml" />
 <import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
 <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />

Gradle JDK 1.6 source compatibility

To configure JDK 1.6 compatibility in the generated eclipse JDT preferences file using gradle, add this to the build.gradle file:
eclipseJdt{
 whenConfigured { domain ->
  domain.sourceCompatibility=org.gradle.api.JavaVersion.toVersion("1.6")
  domain.targetCompatibility=org.gradle.api.JavaVersion.toVersion("1.6")
    }
}
Or something simpler, add the following to the build.gradle file:
sourceCompatibility=1.6
targetCompatibility=1.6