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. WHY SOAP? IT’s NOt 2005... Non-CLOUD / non-SOCIAL / non-BIG

    DATA NOT reST / NOSQL
  4. http://assets3.notonthehighstreet.com/system/product_images/images/000/502/304/normal_SIWS_-_Good_Clean_Fun.jpg?1335135213 WE USE IT DAILY...

  5. BUZZWORD DRIVEN ARCHITECTURE

  6. JAVA DEVELOPERS ARE NUTS

  7. 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>
  8. 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()); } } }
  9. def doc = new XmlSlurper().parse(stocks) doc.stock.each { println it.symbol.text() }

    GROOVY +
  10. RETHINK THE BASICS

  11. WEB SERVICE STACKS ???

  12. 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
  13. 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
  14. CODE-FIRST vs. CONTRACT-FIRST

  15. @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
  16. @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
  17. ├── 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
  18. OBJECT-ORIENTED PARADIGM Objects have failed Richard p. Gabriel

  19. is THIS SOAP REALLY clean? http://assets3.notonthehighstreet.com/system/product_images/images/000/502/304/normal_SIWS_-_Good_Clean_Fun.jpg?1335135213

  20. def url="api.twitter.com/1/statuses/user_timeline.json" def response = ("https://$url?id=tombujok").toURL().text println new JsonSlurper().parseText(response)?.text.first() GROOVY

    REST CLIENT
  21. BUT SOAP IS NOT QUITE THAT EASY...

  22. 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
  23. SOAP BINDING STYLES ‣ RPC-ENCODED ‣ RPC-LITERAL ‣ DOCUMENT-ENCODED ‣

    DOCUMENT-LITERAL ‣ DOCUMENT-LITERAL-WRAPPED http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
  24. SOAP MESSAGE RPC-ENCODED <soap:envelope> <soap:body> <myMethod> <x xsi:type="xsd:int">5</x> <y xsi:type="xsd:float">5.0</y>

    </myMethod> </soap:body> </soap:envelope>
  25. SOAP MESSAGE DOCUMENT-LITERAL <soap:envelope> <soap:body> <xElement>5</xElement> <yElement>5.0</yElement> </soap:body> </soap:envelope>

  26. IT LOOKS A BIT SCARY...

  27. MEET rEFICIO SOAp-WS LIGHTWEIGHT and FANCY XMl-ORIENTED SOAP STACK BASED

    on SPRING-WS
  28. MESSAGE GENERATION

  29. 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);
  30. SOAP BUILDER - ONE LINER String input = WsdlParser .parse(WSDL_URL)

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

    code, String message) String buildEmptyFault() String buildEmptyMessage()
  32. SOAP CONTEXT SoapContext context = SoapContext.builder() .alwaysBuildHeaders(true) .buildOptional(true) .exampleContent(true) .typeComments(false)

    .valueComments(false) .excludedTypes(types) .multiValuesProvider(provider) .build()
  33. MESSAGE GENERATION DONE

  34. 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
  35. MESSAGE TRANSMISSION DONE

  36. 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
  37. SOAP ENDPOINTS AutoResponder responder = new AutoResponder(builder); server.registerRequestResponder("/service", responder); server.unregisterRequestResponder("/service");

  38. 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); }
  39. 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 ); }
  40. 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) } };
  41. MESSAGE SERVING DONE

  42. DEMO - THIS IS HOW WE ROLL

  43. TWEET #SOAPWS

  44. WHAT’s THE BUZZ ABOUT VERSIONING?

  45. 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
  46. 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
  47. 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
  48. 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/
  49. 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
  50. 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
  51. 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
  52. 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 ’
  53. 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
  54. HOW TO DO IT IN SOAP-WS?

  55. 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
  56. 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
  57. 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 ’
  58. SOAP-WS - SUPPLEMENTATION++ <web:ConversionRate> <web:FromCurrency>?</web:FromCurrency> <web:ToCurrency>?</web:ToCurrency> </web:ConversionRate> <web:ConversionRate> <web:FromCurrency>SEK</web:FromCurrency> <web:ToCurrency>CHF</web:ToCurrency>

    </web:ConversionRate> FROM: TO:
  59. 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:
  60. 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
  61. OTHER STUFF

  62. 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() { } }
  63. 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>
  64. FULL SPRING INTEGRATION @Autowired private SoapBuilder builder; @Autowired private SoapClient

    client; @Autowired private SoapServer server;
  65. ROADMAP

  66. 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
  67. SUCCESS STORIES

  68. WRAP-UP

  69. ANY QUESTIONS?

  70. 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