System Integration II: SOAP, WS-* Web Services & Spring-WS PA165 Enterprise Java Bruno Rossi 2/82 Webservices & WSDL 3/82 W3C Definition of Web Services A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards. 4/82 Web Service Description Language (WSDL) ■ The Web Service Description Language (WSDL) is a technical description of a Web Service ■ It mentions all interfaces available, with the relevant information for the invocation (parameters, return type...) It is possible to generate: ■ the client code for accessing the Web Service ■ A WSDL file from Java source code ■ A Java source code skeleton from WSDL file Thomas Erl's definition 5/82 What are WS-* specifications ■ The term "WS-*" has become a commonly used abbreviation that refers to the second-generation Web services specifications. These are extensions to the basic Web services framework established by first generation standards represented by WSDL, SOAP, and UDDI. ■ The term "WS-*" became popular because the majority of titles given to second-generation Web services specifications have been prefixed with "WS-". Thomas Erl's definition 6/82 Web Services Standards Overview Dependencies ► Interoperability Issues -Q 03 (/) cubing h'-uliltr :tu.w. Standards Badie OASIS S ESTJ ► Business Process Specifications Business process Specifications ► Metadata Specifications 1 Metadata Specifications WcbScrriLC Ucsciiptiun Language 2,0 SOAP Binding ► Messaging Specifications Messaging Specifications ► XML Specifications ► Management Specifications Management Specifications ► Presentation Presentation Specifications ► Reliability Specifications r ► Security Specifications l n Transaction Snerifi rations WS-ReliablelWeisagir-g Security Specifications WS-AEumk rr-dnsitliijn Reliability Specifications EertifLate Tulpen Frafiic ► Resou rce Snpcifiratinns Resource Specifications Transaction Specifications ► SOAP Wä-BjseN utilisation Wi-Ad dressing - Cure WS-Addrasmg - WSUL 1 XML Specifications XMLInlLirmali.jn Sri XML Schema ML binary Optimized 1 1 '' 1 Dtscribing Media Cunltnt ' •. • • Packaging prat] of Binary Data in XML innoQJ innoO Deutsch land GmbH inn oll Sehrt tiz GmbH Halskestralte 17 Gew Er be Strasse 11 O-HiSSO Ratinqsn CH-6330 Cliam Prione +49 7\02 77 162-100 Prione +4141 7430111 info@innoq.com ■ www.inrioq.com 7/82 Web Services Standards for SOA The Web Services Platform Architecture o H- n o < IQ O r+ H- q; r+ H-O > IQ Orchestration Composite Protocols State J Atomic Components Reliable Messaging Security Transactions Quality of Service Interface + Bindings Non-XML Transport Description Messaging Transport 8/82 Web Services Standards for SOA The Web Services Platform Architecture ( 1—1 1 1 LT) > ddr, fD r+ O) GL O) r+ O) Ex n ■ ■ \ Composite WSDL* SOAP, WS-Addr* Atomic Po WS-Policy* Components Quality of Service TransU TTP, TCP/IP, SMTP, FT Description Messaging Transport 9/82 SOAP (Simple Object Access Protocol) 10/82 SOAP, in general terms ■ Acronym for Simple Object Access Protocol ■ Nowadays it refers more to a specification, so it has lost the original meaning ■ Provides a communication protocol for data transport for webservices ■ Exchanges complete documents or call a remote procedure Is platform, language, and protocol independent An historical overview: https://kore.fi. muni. cz/wiki/index.php/PA165/WebServices_(English) 11/82 XML (Extensible Markup Language) ■ Sets of rules for encoding documents to structure, store, and transport data in a convenient way ■ Human-readable and machine-readable format ■ XML 1.0 Specification produced by the W3C ■ two current versions of XML. ■ XML 1.0, currently in its fifth edition, still recommended for general use ■ XML 1.1, not very widely implemented and is recommended for use only by those who need its unique features Schema and Validation ■ Well-formed (compliant to XML standard) vs valid (compliant to DTD) ■ Document contains a reference to DTD, ■ DTD declares elements and attributes, and specifies the grammatical rules ■ XML processors ■ re validating or non-validating ■ If error discovered it is reported, but processing may continue normally ■ schema languages constrain ■ the set of elements in a document, ■ attributes that are applied to them, ■ the order in which they appear, ■ the allowable parent/child relationships XML Schema: XSD (XML Schema Definition) ■schema language, described by the W3C ■ (successor of DTD = Document Type Definition) ■ XML schema is more powerful than DTDs ■ XSDs use an XML-based format, so XML tools can be used process them. 13/82 XML Messaging ■ SOAP 1.1 defined: ■ An XML envelope for XML messaging: ■ Headers + body. ■ An HTTP binding for SOAP messaging: ■ SOAP is "transport independent". ■ A convention for doing RPC ■ An XML serialization format for structured data. ■ SOAP Attachments: How to carry and reference data attachments SOAP Envelope SOAP Header SOAP Message SOAP Message Primary MIME part (text/xml) Attachment e - —i AttMJHMH^t SOAP Body Fault SOAP Message Envelope 15/82 Encoding information Header ■ Optional ■ Contains context knowledge • Security • Transaction Body ■ Methods and parameters ■ Contains application data 16/82 A SOAP Request POST /temp HTTP/1.1 Host: www.somewhere.com Content-Type: text/xml; charset="utf-8 Content-Length: xxx fSOAPAction: "http://www...../temp" if an XML document "The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request." Note: in SOAP 1.2, the SOAPAction header has been replaced with the "action" attribute on the application/soap+xml media type (Content-Type: application/soap+xml; charset=utf-8). But it works almost exactly the same way as SOAPAction. Source: Simple Object Access Protocol (SOAP) 1.1 specifications 17/82 XML message structure Version number • • • SOAP Encoding ■ When SOAP specification was written for the first time, XMLSchema was not available, so a common way to describe messages was defined. ■ Now SOAP encoding defines it's own namespace as http://schemas.xmlsoap.org/so ap/encoding/ and a set of rules to follow. ■ Rules of expressing application-defined data types in XML ■ Based on W3C XML Schema ■ Simple values ■ Built-in types from XML Schema, Part 2 (simple types, enumerations, arrays of bytes) ■ Compound values ■ Structures, arrays, complex types 19/82 SOAP Header (1/3) ■Allows to specify non-body related information ■ For example if some node is the receiver, how intermediary nodes might deal with the message, etc... 20/82 SOAP Header (2/3) ■ Some interesting attributes that are specified in SOAP specifications are mustUnderstand and role ■ MustUnderstand = "true" means that if a node does not understand the header element with such attribute -must send a SOAPFault ■ Role: only a node with the specified role can deal with the header element - other nodes do not need to process See http://www.w3.Org/TR/2003/REC-soapl2-partl-20030624/#soaproles 21/82 SOAP Header (3/3) ■ Relay: whether the element needs to be kept when the message is forwarded even if it has been processed by one node 22/82 WS-Addressing (1/2) WS-* specifications are inserted on top of SOAP messaging For example, looking at SOAP, there is no knowledge about where the message is going, or how to return the response or where to post an error message this can be problematic in case of asynchronous communication WS-Addressing adds this information to the SOAP envelope See \ 23/82 WS-Addressing (2/2) Example UniqueMessageldentifier http://somereceiving.client http://somereceiving.server/ErrorHandler http://somereceiving.server/HandlerURI http://somereceiving.server/ACTION - 59/82 Generating the service code skeleton from the WSDL file java2wsdl -cp . -tn . -stn calculator -cn Webservice «_ Generate wsdl from Java -cp = classpath; -tn target namespace; -stn schema target namespace; -cn class name wsdl2java -ss -sd -uri Products . wsdl ^ Generate scheleton Java -ss = server side; -sd = service descriptor webservice from wsdl > Asrc directory is created with the source code for our server side files > A resources directory is created with the WSDL file for the service and a service descriptor (services.xml) file > A build.xml file is created in the current directory, which will be used to create the ws deployment file 60/82 Summary ■ WS* standards and REST usually complement each others ■ Different ways to develop "Contract first" vs "Contract last" ■ Need to use frameworks for support (we see Spring-WS next) 61/82 Spring Web Services (Spring-WS) 62/82 Spring-WS ■ A Spring "sub-project" that allows to simplify WS-* development ■ You can reuse as such your Spring application context and configuration in your application in your SOA application ■ Plus, you get access to various WS-* standards ■ Note that Spring-WS only supports "contract first" development 63/82 Spring-WS - Configuration org.springframework.ws spring-ws-core 2.2.0.RELEASE Maven dependency Spring-WS Core Spring-WS Support Sprinc-WS Security Webservice client bean Spring-WS-Core depends On Spring's Object/XML Mapping support (OXM) module and on Spring XML module See http://projects.spring.io/spring-ws/ 64/82 Spring-WS ■ Let's look at some of Spring-WS characteristics: ■ MessageDispatcher & MessageDispatcherServlet ■ Automatic WSDL exposure ■ Endpoints & Endpoint Mapping ■ Interceptors ■ Exceptions ■ Testing in Spring-WS 65/82 Spring-WS - Flow of invocations MessageDispatcher iEndpointMapping dispatch(request} gelEndpoi n t (reg uesl^ : I-r J point Adapter endpoint supports (je ndpoiru) endpoint invoke (request) response _D ©MessageDispatcher * DispatcherServlet from SpringMVC @MessageDispatcherServlet: a servlet that wraps MessageDispatcher ^Exceptions thrown are taken care by any exception resolvers defined 0lnvocation chain for an endpoint: includes pre- and post-processors Can you use a MessageDispatcher in Spring MVC DispatcherServlet? 66/82 Spring-WS - Automatic WSDL exposure ■ By defining beans using DefaultWsdl 11 Definition, you can expose WSDL files to clients @Bean(name = "products") public DefaultWsdlllDefinition productsWsdlllDefinition(XsdSchema productsSchema) { DefaultWsdlllDefinition wsdlllDefinition = new DefaultWsdlllDefinition(); wsdlllDefinition.setPortTypeName("productsPort"); wsdlllDefinition.setLocationUri("/"); wsdlllDefinition.setTargetNamespace("http://muni.fi.cz/pal65/ws/entities/products"); wsdlllDefinition.setSchema(productsSchema); return wsdlllDefinition; Is it good idea to expose dynamically generated WSDL resources? What are the pros and cons? 67/82 Spring-WS - Automatic WSDL exposure ■ By setting isTransformWsdlLocations() you can get automatic translation of the WSDL location based on requests public class Servletlnitializer extends AbstractAnnotationConfigMessageDispatcherServletlnitializer { @Override public boolean isTransformWsdlLocations() { return true; } //. . . } Spring-WS - Endpoints 68/82 J|Endpoint^/ public class BookEndpoint { private static final String NAME S PACE_URI = "http://muni.cz/pal65/soa"; private final BookRepository bookRepository; QAutowired public BookEndpoint(BookRepository bookRepository) { QResponsePayload public GetBookResponse getBook(@RequestPayload GetBookRequest request) { this.bookRepository = bookRepository; } localPart = "getBookRequest") GetBookResponse response = new GetBookResponse(); response.setBook(bookRepository.getBookByTitle(request.getTitie())); return response; } } 69/82 Spring-WS - Endpoint Mapping ■ Maps the incoming messages to the correct endpoints ■ EndpointMapping returns a EndpointlnvocationChain, -> endpoint that matches the incoming request and list of endpoint interceptors for request and response ■ By default, PayloadRootAnnotationMethodEndpointMapping (using @PayloadRoot) and SoapActionAnnotationMethodEndpointMapping (using @SoapAction) are enabled by default ■ If you want to use WS-Addressing as discussed before in the slides, you need to use AnnotationActionEndpointMapping and ©Action and ©Address in the endpoint 70/82 Spring-WS - SoapMessage (1/3) ■ If you remember our SOAP with Attachments API for Java (SAAJ) example, it required quite some code ■ In Spring you usually mostly care about the SOAP body that you can get in an endpoint by using @RequestPayload annotation that gives you access to the request ■ Only in cases in which you want to modify/get header information or deal with attachments, you need to care about headers 71/82 Spring-WS - SoapMessage (2/3) Name Supported parameter types TrAX j avax.xml.t ransform . Source and sub-interfaces (DOMSource, SAXSource, St reamSource, and StAXSourcs) W3C DOM org.w3c.dom.Element dom4j org.dom4j.Element JDOM org.j dom.Element XOM nu.xom.Element StAX j avax.xml.st ream.XMLSt reamReader and j avax.xml.st ream.XMLEventReader XPath Any boolean, double, string, org.w3c.Node, org.w3c.dom.Nodei_ist, or type that can be converted from a string by a Spring 3 conversion service, and that is annotated with @XPathParam. Message context org.springf ramework.ws.context.MessageContext SOAP org.springf ramework.ws.soap.SoapMessage, org.springf ramework.ws.soap.SoapBody, org.springf ramework.ws.soap.SoapEnvelope, org.springf ramework.ws.soap.SoapHeader, and org. springf ramework .ws. soap. SoapHeaderElementS when used in combination With the @SoapHeader annotation. JAXB2 Any type that is annotated With javax.xml .bind.annotation.XmlRootElement, and j avax.xml.bind.JAXBElement. OXM Anv tvpe supported bv a Spring OXM Unmarshaller. 72/82 Spring-WS - SoapMessage (3/3) Example, we can get the list of all "mustUnderstand" elements from the header (see mustUnderstand) @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getProductRequestByName") @ResponsePayload public GetProductRespon.se getProduct(@RequestPayload GetProductRequestByName request, SoapHeader header) { // ........ Iterator itMustUnderstand = header.examineMustUnderstandHeaderElements(URI); while (itMustUnderstand.hasNext() ){ SoapHeaderElement element = itMustUnderstand.next(); // do something with the element in case it is not understood, return a SoapFault } //....... 73/82 Spring-WS - Interceptors (1/4) ■ Although you can process SOAP message headers in Endpoints, better is to use interceptors that will be applied to all requests/responses or to a filtered set ■ HandleRequest(..) provides the possibility to handle the request before an endpoint is invoked. If false is returned, the execution chain is interrupted ■ HandleResponse(..) and HandleFault(..) deal with the response after the endpoint is invoked for both the normal and faulty case - if returning false, the response will not be returned back 74/82 Spring-WS - Interceptors (2/4) ■ Example public class Anlnterceptor implements Endpointlnterceptor{ @Override public boolean handleRequest(MessageContext mc, Object o) throws Exception { WebServiceMessage wsm = mc.getRequest(); // from here you can access the payload as in an enpoint SoapMessage sm = (SoapMessage) wsm; // cast the webservicemessage to soapmessage SoapHeader sh = sm.getSoapHeader(); // you can now use the soapheader as before // .... return true; } // other overridden necessary methods 75/82 Spring-WS - Interceptors (3/4) Where the interceptor is invoked Before the EndpointAdapter calls for the invocation of the endpoint ;MessaggDi5patc her iEndpoimMapping dispatch(request} getEndpoi n i{teq uesp endprjinl supports ()end point) :hrci point Aclap-pr r&$pon$e sndno rt invoke (request) response 76/82 Spring-WS - Interceptors (4/4) ■ There are some predefined interceptors that can be useful: ■ PayloadLogginglnterceptor and SoapEnvelopeLogginglnterceptor allow to log payload or whole soap envelopes for responses and/or requests ■ PayloadValidatinglnterceptor to validate requests/response @Bean public PayloadValidatinglnterceptor myPayLoadlnterceptor() { final PayloadValidatinglnterceptor interceptor = new PayloadValidatinglnterceptor(); interceptor.setXsdSchema(this.productsSchema()); interceptor.setValidateRequest(true); interceptor.setValidateResponse(true); return interceptor; } Which one would be more meaningful to validate? Spring docs refer to Posters law or robustness principle: "Be conservative in what you send, be liberal in what you accept" 77/82 Spring-WS - Exceptions (1/2) ■ Easiest way to deal with exceptions is to annotate custom exceptions with @SoapFault that will be dealt with a pre-configured SoapFaultAnnotationExceptionResolver @SoapFault(faultCode = FaultCode.SERVER, faultStringOrReason = "Product not found." ) public class ProductNotFoundException extends RuntimeException { public ProductNotFoundException(String productName) { super("could not find product " + productName ); } } 78/82 Spring-WS - Exceptions (2/2) If you need a more programmatic way, you can implement an EndpointExceptionResolver overriding method resolveException(MessageContext, Endpoint, Exception) Or SimpleSoapExceptionResolver to have access at the SOAP Fault public class EndpointExceptionResolver extends SoapFaultMappingExceptionResolver { //. • • @Override protected void customizeFault ([Object endpoint // Exception ex SoapFault fault) { } You can filter based on the endpoint from which the exception comes from You can filter based on the exception type Add more information to the SOAP fault Spring-WS - Testing (1/3) 79/82 ■ We use MockWebServiceClient to mock a webservice client with some request messages for the enpoints under test that are configured in the ApplicationContext ■ The endpoints will handle the messages and return a response @ContextConfiguration(classes = {WebServiceConfig.class}) public class ProductEndpointTest extends AbstractTestNGSpringContextTests { @Autowired private ApplicationContext applicationContext; @BeforeClass public void createClient() { mockClient = MockWebServiceClient.createClient(applicationContext); } //. . • } Spring-WS - Testing (2/3) 80/82 ■ We use then MockWebServiceClient to test against expected behaviour Source requestPayload = new StringSourcG( M" + "No product" + M"); mockCliGnt.SGndRGquGst(withPayload(rGquGstPayload)). andExpGct(sGrvGrOrRGCGivGrFault("Product not found.")); Would you consider a test written using MockWebServiceClient a unit or an integration test? Would you mock service endpoints? 81/82 Spring-WS - Testing (3/3) ■ You might also implement your own Matcher by implementing ResponseMatcher interface ■ There are however many that you can use: ResponseMatchers method Description payload() Expects a given response payload. validPayload() Expects the response payload to validate against given XSD schema(s). xpath() Expects a given XPath expression to exist, not exist, or evaluate to a given value. soapHeader() Expects a given SOAP header to exist in the response message. noFault() Expects that the response message does not contain a SOAP Fault. mustUnderstandFault(), clientO rSenderFault(), serverOrReceiverFault(), and versionMismatchFault() Expects the response message to contain a specific SOAP Fault. 82/82 References ■ SOAP 1.2 Specifications http://www.w3.org/TR/2007/REC-soapl2-part0-20070427/ http://www.w3.org/TR/2007/REC-soapl2-partl-20070427/ http://www.w3.org/TR/2007/REC-soapl2-part2-20070427/ ■ Spring-WS Reference http://docs.spring.io/spring-ws/docs/2.2.3.BUILD-SNAPSHOT/reference/htmlsingle/ ■ Webservices Standards Overview https://www.mnoq.com/soa/ws-standards/p^