Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A whirlwind tour of codeless SOAP services

Tom Bujok
December 04, 2012

A whirlwind tour of codeless SOAP services

SOAP Web-Services are everywhere. There is a plethora of Java frameworks supporting SOAP but most of them follow the paradigm of the explicit or implicit code (stubs) generation. Handy as it may seem at the beginning, it can also be redundant and cumbersome. Problems occur when a single WSDL/XSD change triggers a full recompilation and redeployment of the app or when many versions of the same service have to be maintained within one code-base. The trickery that is then applied, like postfixing class names, adding version numbers to packages, sharing common classes, etc., does not scale well, causes a rapid code-base growth and is clearly against the "best practices". Finally, marshalling and unmarshalling the whole payload may also cause a significant performance deterioration. This session will be a critical whirlwind tour of SOAP Web-Services reviewing the existing solutions and emphasizing some of the biggest drawbacks of the frameworks based on the code generation. It will rethink the idea of Java Web-Services refuting widely-accepted concepts that nobody reflects on anymore. It will also offer people handy tools to overcome above mentioned problems and prevent them from following bad practices. On the example of soap-ws, project authored by me, a completly different approach will be presented. soap-ws provides a lightweight Java Web-Services stack (based on Spring-WS) that handles the SOAP protocol "codelessly" on a purely XML level. Using soap-ws enables handy generation, transmission and handling of SOAP messages without the usage of stubs, no matter what flavors the WS client and server are (RPC,document; literal,encoded). You simply cannot miss out if you have ever used a Web-Service!

http://projects.reficio.org/soap-ws
http://www.jdays.se/speakers?abstractId=19846258253

Tom Bujok

December 04, 2012
Tweet

More Decks by Tom Bujok

Other Decks in Programming

Transcript

  1. A WHIRLWIND TOUR OF {CODELESS} SOAP SERVICES TOM BUJOK JDAYS,

    GOTHENBURG, SWEDEN 4TH of DECEMBER 2012
  2. A WHIRLWIND TOUR OF {CODELESS} SOAP SERVICES ABOUT ME Tom

    BUJOk centeractive ag, BERN, CH @TOMBUJOK WWW.REFICIO.ORG
  3. XML PARSING <?xml version="1.0" encoding="UTF-8"?> <stocks> <stock> <symbol>Citibank</symbol> <price>100</price> <quantity>1000</quantity>

    </stock> <stock> <symbol>UBS</symbol> <price>90</price> <quantity>2000</quantity> </stock> </stocks>
  4. JAVA DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document

    doc = dBuilder.parse(stocks); doc.getDocumentElement().normalize(); NodeList nodes = doc.getElementsByTagName("stock"); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element el = (Element) node; NodeList list = el.getElementsByTagName("symbol") NodeList children = list.item(0).getChildNodes(); System.out.println(children(0).getNodeValue()); } } }
  5. WEB-SERVICE STACKS ‣ APACHE AXIS 1.4 (✝2006) ‣ XFIRE 1.2.6

    (✝2007) ‣ APACHE AXIS 2 1.6.2 ‣ Apache cxf 2.7.0 ‣ SPRING-WS 2.1.1 ‣ JAX-WS RI 2.2.7 ‣ GLASSFISh METRO 2.2.1-1 ‣ WSo2
  6. HOWTO? R U N C O M P I L

    E D E P L O Y G E N E R AT E A N N O TAT E
  7. @WebService(name = "PersonService") public class PersonService { public Person getPerson(String

    uuid) { return new Person(); } } @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(namespace = "http://jdays/person") public class Person { String uuid; String firstName; String lastName; } tIGHT-COUPLING vs. DTO (ANTI) PATTERN
  8. @WebMethod(action = "urn:getBook") @WebResult(name = "getBookReturn", targetNamespace = "http://jdays/library/wsdl") @RequestWrapper(localName

    = "getBook", targetNamespace = "http://jdays/library/wsdl", className = "se.jdays.GetBook") @ResponseWrapper(localName = "getBookResponse", targetNamespace = "http://jdays/library/wsdl", className = "se.jdays.GetBookResponse") public Book getName( @WebParam(name = "isbn", targetNamespace = "http://jdays/library/wsdl") String isbn); CODE-FIRST (ANTI) pattern
  9. ├── resources │ ├── CustomerService.wsdl │ ├── binding.xml │ ├──

    client-applicationContext.xml │ ├── cxf.xml │ └── server-applicationContext.xml └── webapp └── WEB-INF ├── cxf-servlet.xml └── web.xml IS IT REALLY THAT EASY (CLIENT <-> SERVER)? ‣ ant / maven ‣ CXF-CODEGEN PLUGIN ‣ BUILDEr-HELPER-PLUGIN ‣ WAR-PLUGIN ‣ JETTY-PLUGIN
  10. WSDL STRUCTURE T Y P E M E S S

    A G E P O R T T Y P E B I N D I N G S E R V I C E P O R T S O P E R AT I O N
  11. SOAP BINDING STYLES ‣ RPC-ENCODED ‣ RPC-LITERAL ‣ DOCUMENT-ENCODED ‣

    DOCUMENT-LITERAL ‣ DOCUMENT-LITERAL-WRAPPED http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
  12. SOAP BUILDER String url = "http://CurrencyConvertor.com?WSDL"; WsdlParser parser = WsdlParser.parse(url);

    SoapBuilder builder = parser.binding() .localPart("CurrencyConvertorSoap") .builder(); SoapOperation operation = builder.operation() .soapAction("http://ConversionRate") .find(); String input = builder.buildInputMessage(operation);
  13. SOAP BUILDER - ONE LINER String input = WsdlParser .parse(WSDL_URL)

    .binding(BINDING_QNAME) .operation() .soapAction(SOAP_ACTION) .find() .buildInputMessage()
  14. SOAP BUILDER - INTERFACE String buildInputMessage() String buildOutputMessage() String buildFault(String

    code, String message) String buildEmptyFault() String buildEmptyMessage()
  15. SOAP CLIENT SoapClient client = SoapClient.builder() .endpointUrl("http://service.com/endpoint") .basicAuth("user", "pass") .connectTimeoutInMillis(30000)

    .readTimeoutInMillis(10000) .build(); client.post(soapAction, message) P R O X Y S S L T R U S T S T O R E
  16. SOAP SERVER SoapServer server = SoapServer.builder() .httpPort(8080) .acceptorThreads(4) .maxThreads(8) .reuseAddress(true)

    .build() server.start() server.stop() T I M E O U T S H T T P S K E Y S T O R E
  17. Request RESPONDER public interface RequestResponder { /** * Returns a

    response to a SOAP message. * <p/> * @param request SOAP message to handle * @return XML response with the whole SOAP envelope */ javax.xml.Source respond(SoapMessage request); }
  18. ABSTRACT RESPONDER public abstract class AbstractResponder implements RequestResponder { //

    ... /** * @param invokedOperation op matched to the SOAP msg * @param message SOAP message passed by the client * @return XML response with the whole SOAP envelope */ public abstract javax.xml.Source respond( SoapOperation invokedOperation, SoapMessage message ); }
  19. Custom RESPONDER new AbstractResponder(builder) { @Override public Source respond(SoapOperation operation,

    SoapMessage message) { // build the response using builder String response = builder.buildOutputMessage(operation) // here you can tweak the response //... return XmlUtils.xmlStringToSource(response) } };
  20. SOAP with CODE - 2 versions W S D L

    S T U B S B U S I N E S S L O G I C SERVER SOAP W S D L’ S T U B S ’ S T U B S B U S I N E S S L O G I C CLIENt S T U B S ’ SOAP
  21. COMPONENT COMPATIBLE INCOMPATIBLE SOAP HEADER ADD OPTIONAL CHANGE, REMOVE OPT.

    ADD, CHANGE, REMOVE REQ. PARAMETER ADD OPTIONAL IN REQUEST ADD, CHANGE, REMOVE OPERATION ADD A NEW OPERATION CHANGE, REMOVE RESPONSE CHANGE WS BACKWARD COMPATIBILITY http://help.yahoo.com/l/us/yahoo/ewsapt/webservices/support/wss_faq_versioning.html
  22. WISDOM BY BIG-BROTHERS ‣ LAYER OF INDIRECTION PATTERN ‣ ORACLE

    SERVICE BUS ‣ ORACLE PORTAL SERVER http://www.newhorizons.com/LOCALWEBADMIN/images/306/outlines/partner%20images/logo-oracle-large.jpg http://www.oracle.com/technetwork/articles/web-services-versioning-094384.html
  23. WISDOM BY BIG-BROTHERS ‣ IBM WEB-SPHERE UDDI ‣ IBM WEB-SPHERE

    SERVER http://upload.wikimedia.org/wikipedia/commons/5/51/IBM_logo.svg http://www.ibm.com/developerworks/webservices/library/ws-uddisecure/
  24. SOAP with CODE - WISDOM FROM THE WEB W S

    D L S T U B S B U S I N E S S L O G I C SERVER W S D L’ S T U B S ’ http://www.gridshore.nl/blog/index.php?/archives/68-Web-service-versioning-in-the-java-world.html findicons.com/icon/130548/llama_glyph?id=130575 LoL
  25. SOAP with CODE - WISDOM FROM THE WEB W S

    D L S T U B S B U S I N E S S L O G I C SERVER W S D L’ S T U B S ’ http://www.gridshore.nl/blog/index.php?/archives/68-Web-service-versioning-in-the-java-world.html NO VERSIONING Force clients to migrate LoL findicons.com/icon/130548/llama_glyph?id=130575
  26. SOAP with CODE - WISDOM FROM THE WEB W S

    D L S T U B S B U S I N E S S L O G I C SERVER W S D L’ S T U B S ’ http://www.gridshore.nl/blog/index.php?/archives/68-Web-service-versioning-in-the-java-world.html DIFFERENT PACKAGEs LoL findicons.com/icon/130548/llama_glyph?id=130575
  27. SOAP with CODE - WISDOM FROM THE WEB W S

    D L S T U B S B U S I N E S S L O G I C http://www.gridshore.nl/blog/index.php?/archives/68-Web-service-versioning-in-the-java-world.html DIFFERENT ARTIFACTS LoL findicons.com/icon/130548/llama_glyph?id=130575 B U S I N E S S L O G I C SERVER W S D L’ S T U B S ’
  28. SOAP with CODE - WISDOM FROM THE WEB W S

    D L S T U B S B U S I N E S S L O G I C http://www.gridshore.nl/blog/index.php?/archives/68-Web-service-versioning-in-the-java-world.html MEDIATION BY HAND LoL findicons.com/icon/130548/llama_glyph?id=130575 SERVER W S D L’ S T U B S ’ W S D L S T U B S MEDIATOR
  29. SOAP-WS - VERSIONING MADE EASY W S D L S

    T U B S B U S I N E S S L O G I C SERVER
  30. SOAP-WS - VERSIONING MADE EASY B U S I N

    E S S L O G I C SERVER B U I L D E R S U P P L E M E N T S E R V E R
  31. SOAP-WS - VERSIONING MADE EASY B U S I N

    E S S L O G I C SERVER B U I L D E R S U P P L E M E N T S E R V E R S E R V E R ’ B U I L D E R ’ S U P P L E M E N T ’
  32. SOAP-WS - SUPPLEMENTATION++ // modify the request providing real data

    def slurper = new XmlSlurper().parseText(input) slurper.Body.ConversionRate.FromCurrency = "SEK" slurper.Body.ConversionRate.ToCurrency = "CHF" def output = toXmlString(slurper) <web:ConversionRate> <web:FromCurrency>SEK</web:FromCurrency> <web:ToCurrency>CHF</web:ToCurrency> </web:ConversionRate> GROOVY TRANSFORMATION: RESULT:
  33. SOAP-WS - VERSIONING MADE EASY B U S I N

    E S S L O G I C SERVER B U I L D E R S U P P L E M E N T S E R V E R S E R V E R ’ B U I L D E R S U P P L E M E N T D B F I L E
  34. SOAP TESTING DONE RIGHT @Server(wsdl = "http://srv.com?wsdl", binding = "Binding")

    public class TestExample { @Test @Server(wsdl = URL, binding = "Binding", port = 41414) public void testSoapMock_serverPerMethod() { } @Test public void testSoapMock_serverPerClass() { } }
  35. FULL SPRING INTEGRATION <bean id="soapServerFactory" class="com.centeractive.ws.server.core.SoapServerFactory"> <property name="httpPort" value="8778"/> <property

    name="responders"> <map> <entry key="/currencyConverter/soap" value-ref="autoResponder" /> </map> </property> </bean>
  36. SOAP-ws ROADMAP GROOVY MODULE GRAILS PLUGIN GRIFFON PLUGIN ARQUILLAN deista.files.wordpress.com/2011/04/internet-explorer-y-mozilla-firefox.jpg?w=640

    WEB-CONTAINERs HTTP BINDING WS-SECURITY cdn1.iconfinder.com/data/icons/secureicons/png/512/PadLock.png WS-ATTACHMENT cdn1.iconfinder.com/data/icons/softwaredemo/PNG/256x256/PaperClip4_Black.png WS-ADDRESSING cdn1.iconfinder.com/data/icons/Primo_Icons/PNG/128x128/address_black.png SPRING-WS
  37. THANK YOU TOM BUJOK JDAYS, GOTHENBURG, SWEDEN 4TH of DECEMBER

    2012 @TOMBUJOK WWW.REFICIO.ORG http://gamedevwithoutacause.com/wp-content/uploads/2011/11/singleton-12yr.jpeg