{"id":16179277,"url":"https://github.com/jonashackt/soap-spring-boot-cxf","last_synced_at":"2025-03-19T01:30:57.160Z","repository":{"id":29991065,"uuid":"33538463","full_name":"jonashackt/soap-spring-boot-cxf","owner":"jonashackt","description":"Sample Project for producing \u0026 testing a SOAP-WSDL-driven Service with Spring Boot, Apache CXF \u0026 JAX-WS","archived":false,"fork":false,"pushed_at":"2021-06-15T15:57:47.000Z","size":1989,"stargazers_count":64,"open_issues_count":1,"forks_count":31,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-02-28T13:47:42.105Z","etag":null,"topics":["apache-cxf","java","jax-ws","soap","spring-boot","wsdl"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonashackt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-07T11:12:53.000Z","updated_at":"2025-01-02T06:00:44.000Z","dependencies_parsed_at":"2022-09-15T01:02:58.462Z","dependency_job_id":null,"html_url":"https://github.com/jonashackt/soap-spring-boot-cxf","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fsoap-spring-boot-cxf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fsoap-spring-boot-cxf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fsoap-spring-boot-cxf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fsoap-spring-boot-cxf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonashackt","download_url":"https://codeload.github.com/jonashackt/soap-spring-boot-cxf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243960361,"owners_count":20375102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-cxf","java","jax-ws","soap","spring-boot","wsdl"],"created_at":"2024-10-10T05:26:33.354Z","updated_at":"2025-03-19T01:30:56.501Z","avatar_url":"https://github.com/jonashackt.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SOAP-Webservices with Apache CXF \u0026 SpringBoot using JAX-WS RI \u0026 JAXB - Annotations only, absolutely no XML\n[![Build Status](https://travis-ci.org/jonashackt/soap-spring-boot-cxf.svg?branch=master)](https://travis-ci.org/jonashackt/soap-spring-boot-cxf)\n[![Coverage Status](https://coveralls.io/repos/jonashackt/soap-spring-boot-cxf/badge.svg)](https://coveralls.io/r/jonashackt/soap-spring-boot-cxf)\n[![Dependency Status](https://www.versioneye.com/user/projects/56cc650818b27104252de8f6/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56cc650818b27104252de8f6)\n\nAs Example SOAP-Service I did some research, but after all the well-known [Weather-Service] seemed to be the best Use-Case, although (or because?) it is used by nearly every tutorial. It is really hard to find free SOAP-Services on the web.\n\nBut i had to extend the Weather-Service a lot through out development - e.g. Custom Exceptions, more complex\nInput-Requests and a little less methods, so i can show my findings better. The biggest change was to split it into a WSDL (as \"just the SOAP-interface\") and a bunch of XSDs that import each other. That should represent a more complex domain and although they do not contain that much definitions, i can show many related techniques much better, that appear commonly in real-world scenarios.\n\nSo this example-project is capable for bigger Use-Cases in Realworld-Scenarios with huge WSDLs and lots of imported XSDs, which again import tons of other XSDs. If you want, test it with your Service and i appreciate feedback :)\n\n### General choices\n\nIn the project I tried to use some relevant technologies for getting SOAP-Services running, like:\n* [Spring] with the aim to use absolutely no XML-Configuration (just Annotations)\n* [Spring Boot], for easy \"not care about Container\" (cause it has an embedded [Tomcat]) and simple deployment - like Microservices (without the \"micro\" in the interface, since we are bound to SOAP...)\n* One of the most relevant SOAP-Stack [Apache CXF] 3 as the Webservice-Stack to expose the SOAP-Webservices\n* Oracle´s JAX-WS RI (Reference Implementation) with the [JAX-WS-commons project] as \"the Standard\" to define Webservices in Java\n* [JAXB Java-XML-Binding] for working with XML\n* JAX-WS Commons for Generating the Class-Files for JAXB, managed by the maven plugin [jaxws-maven-plugin]\n\nI reached my aim to not use any XML-configuration, but it was harder than i thought... If you look on some detail, you´ll see what i mean.\n\n### HowTo Use\n\nRun \"mvn clean package\"-command at command-line, to ensure that all necessary Java-Classes \u0026 JAXB-Bindings are generated\n\nThen, you could use Spring Boot with maven to expose your SOAP-Webservices\n```sh\nmvn spring-boot:run\n```\nor run the build .jar-File with\n```sh\njava -jar soap-spring-boot-cxf-0.0.5-SNAPSHOT.jar\n```\n\n### Testing\n\nFor testing end-to-end purposes I would recommend also getting [SOAP-UI], where you can check WSDL/XSD-compliance of the provided services very easily and you \"see\" your services.\n\nBut getting to know, how stuff is working, it´s often better to have a look at some tests. There should be a amount of test-cases, that show standard (JAX-WS with CXF) ways to test webservices, but also non-standard approaches to test some\nUseCases i came across developing e.g. the custom SoapFaults on incorrect XML-messages.\n\n### Facade-Mode\n\nSometimes, you are in need of a facade-mode, where your implementation doesn´t call real backends and only returns Dummy-Responses. E.g. when you want to protect your backends when load is getting to high for them (not for your server :), that is based on solid Spring-technology) or even if you want to build up a new environment, where your backends are not available right from the start. And you want this configurable, so you can react fast, when needed.\n\nFor this Scenario, Spring´s powerful [Aspect oriented programming (AOP)] mechanism will serve you well. In combination with using org.springframework.core.io.Resource to load your Dummy-Response-Files instead of Java´s NIO.2 (that could [fuck you up] because of classloader-differences in other environments than your local machine), your done with that task quite fast.\n\n\n### Done´s\n* No XML-configuration, also for undocumented CXF-details :)\n* Readable Namespace-Prefixes\n* Testcases with Apache CXF\n* Custom SoapFault, when non-schmeme-compliant or syntactically incorrect XML is send to the service\n* Tests with Raw HTTP-Client for Reaction on syntactically incorrect XML\n* Custom Exception in Weather-WSDL/XSDs\n* Example of Controller and Mappers, that map to and from an internal Domain-Model - for loose coupling between generated JAXB-Classes and Backends\n* Facade-Mode, that only returns Dummy-Responses, if configured\n* Logging-Framework for centralization of logging and message-creation, including chance to define individial logging-Ids\n* Webservice-Method that returns a PDF-File (you can view the base64-encoded String inside the Webservice´ Response with a small Angular/Boot-App I wrote for that: [base64gular])\n* PDF-Test with asserts of the PDF-contents via [Pdfbox]\n* Deployment to [Heroku], with inspiration from my colleague´s [blogpost] - see it in action (maybe you have to wait a while, cause it´s just a free Heroku-Dyno) [here] - or call it via [SOAP-UI]\n\n\n## Loganalysis with [ELK-Stack]\n\nIf you´re going some steps further into a more production-ready environment, you´ll need a more indepth view what´s going on with your SOAP-Infrastructure. I used the [ELK-Stack] with Logstash -\u003e Elasticsearch -\u003e Kibana. I used the [logstash-logback-encoder] for getting JSONized Logoutputs directly into logstash´s input-phase.\n\n![Kibana SOAP-Message Analytics](https://github.com/jonashackt/soap-spring-boot-cxf/blob/master/kibana_SOAP-Message-Analytics.png)\n\nMaking your SpringBoot-App ready for logstash, you have to add a maven-dependency and a logback.xml-File with the apropriate configuration, also described in [logstash-logback-encoder]. Before doing so, you need a running ELK-Stack, for me I used a docker-compose(ition) from [docker-elk].\nFor Mac-Users remember the new [docker-machine] superseeding boot2docker.\n\nTesting your configured ELK-Stack is easy by using [SOAP-UI]´s Load-Test-Feature.\n\nAfter having set up your ELK-Stack and logs are transferred via logstash into Elasticsearch and you activated SOAP-Message-Logging as shown in the CXF-WebService-Configuration, you for shure want to play aroung with the [Kibana´s Visualisation-Features]. And in the end you also want a [Dashboard] configured to show all your stylish Visualisations. You could end up with something like that:\n\n![Kibana-Dashboard for SOAP-Message Analytics](https://github.com/jonashackt/soap-spring-boot-cxf/blob/master/kibana_SOAP-Analytics_dashboard.png)\n\nIf if you can´t wait to start or the tutorials are [tldr;], then import my [kibana_export.json](https://github.com/jonashackt/soap-spring-boot-cxf/blob/master/kibana_export.json) as an example.\n\n\n\n### Done´s with Loganalysis with ELK-Stack\n* Correlate all Log-Messages (Selfmade + ApacheCXFs SOAP-Messages) within the Scope of one Service-Consumer`s Call in Kibana via logback´s [MDC], placed in a Servlet-Filter\n* Log SOAP-Messages to logfile (configurable)\n* Log SOAP-Messages only to Elasticsearch-Field, not Console (other Implementation)\n* Extract SOAP-Service-Method for Loganalysis\n* SOAP-Messages-Only logged and formatted for Analysis\n* Added anonymize-logstash-filter for personal data in SOAP-Messages (e.g. for production environments in german companies)\n* Dead simple Calltime-Logging\n\n\n\n## Functional plausibility check of request-data in the internal Domain-Model\n\nA very common problem of projects that implement SOAP-Webservices: the internal Domain-Model differs from the externally defined Model (the XML-Schema/XSD, that´s imported into the WSDL). This leads to mapping data from the generated JAXB-Classes to the internal Domain-Model, which could be handled simply in Java. But the internal Domain-Model´s data has to be validated after that mapping - e.g. to make sure, everything is correct and functionally plausible for further processing when backend-Systems are called. \n\nIMHO this topic isn´t covered well in the tutorial-landscape - the very least you can find is the hint to use [JSR303/349 Bean Validation], which is quite fast to apply but also quite limited, when it comes to more complex scenarios. And having multiple SOAP-Methods described in multiple Webservices with a multitude of fields that shouldn´t be null (and aren´t described as such in the XML-Schema) and lot´s of plausibilty to check depending on the former, you are in complexity hell. Than all research points you to the ongoing war of the [pros and cons to use RuleEngines](in deed, [Martin Fowler has something to say about that]) and trying to setup something like Drools (including the attempt to reduce Drools predominant complexity by building your own [spring-boot-starter-drools]). After getting into that trouble, you begin to hate all RulesEngines and try to build something yourself or use [EasyRules] with the problems pointed out well in [this presentation].\n\nBut i´am sorry, the complexity will stay there and you will get so many rule-classes and tests to handle, that you find you´re self in serious trouble, if your project is under pressure to release - which fore sure is the case, if you went through all this.\n\nFinally your domain-expert will visit you, showing a nice Excel-Table, which contains everything we discussed above - still relatively long - but much shorter than all your classes developed by hand - and you didn´t cover 10% of it by now. Maybe at this point you remember something you learned back in the days of your study - [decision tables]. The domain expert found the simplest solution possible for this complex problem with easy. Would´nt it be nice, if you had something like that - without the need to use something complex and hard to develop like Drools?\n\n[JSR303/349 Bean Validation]:https://en.wikipedia.org/wiki/Bean_Validation\n[Martin Fowler has something to say about that]:http://martinfowler.com/bliki/RulesEngine.html\n[pros and cons to use RuleEngines]:http://stackoverflow.com/questions/775170/when-should-you-not-use-a-rules-engine\n[spring-boot-starter-drools]:https://github.com/jonashackt/spring-boot-starter-drools\n[EasyRules]:http://www.easyrules.org/\n[this presentation]:https://speakerdeck.com/benas/easy-rules\n[decision tables]:https://en.wikipedia.org/wiki/Decision_table\n\n\n## Rules with DMN-Decision Tables compliant to the OMG-Standard\n\nOne approach is to check the request-data with [decision tables]. For that I used a neat small but yet powerful Engine, which is quite a young one: [camunda´s DMN Engine](https://github.com/camunda/camunda-engine-dmn). It implements OMG´s [DMN-Standard](http://www.omg.org/spec/DMN/).\n\nIn our Usecase we have Fields described in the internal Domain-Model, that have to be checked depending on the called WebService-Method and the Product. So I decided to go with two DMN-Decision-Tables:\n\nThe first \"weatherFields2Check.dmn\" inherits rule to check, if the current field must be checked in the next step:\n\n![WeatherFields2Check-DMN](https://github.com/jonashackt/soap-spring-boot-cxf/blob/master/weatherFields2CheckDMN.png)\n\nIf the field has to be checked, the actual functional plausibility rules are applied - depending on the Product again:\n\n![WeatherRules-DMN](https://github.com/jonashackt/soap-spring-boot-cxf/blob/master/weatherRulesDMN.png)\n\nFor now, you have to separate Rules with different datatypes to different Decisiontable-columns.\n\n\n## Todo's\n\n* Configure Servicename in logback.xml from static fields\n* Fault Tolerance with Hystrix (e.g. to avoid problems because of accumulated TimeOuts)\n\n\n\n\n[Spring]:https://spring.io\n[Spring Boot]:http://projects.spring.io/spring-boot/\n[Spring WS]:http://projects.spring.io/spring-ws/\n[Apache CXF]:http://cxf.apache.org/\n[JAXB Java-XML-Binding]:http://en.wikipedia.org/wiki/Java_Architecture_for_XML_Binding\n[SOAP-UI]:http://www.soapui.org/\n[jaxws-maven-plugin]:https://jax-ws-commons.java.net/jaxws-maven-plugin/\n[JAX-WS-commons project]:https://jax-ws-commons.java.net/spring/\n[Weather-Service]:http://wsf.cdyne.com/WeatherWS/Weather.asmx\n[Tomcat]:http://tomcat.apache.org/\n[decision tables]:https://en.wikipedia.org/wiki/Decision_table\n[Aspect oriented programming (AOP)]:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html\n[fuck you up]:https://github.com/jonashackt/springbootreadfilejar\n[ELK-Stack]:https://www.elastic.co/products\n[logstash-logback-encoder]:https://github.com/logstash/logstash-logback-encoder/tree/logstash-logback-encoder-4.5\n[docker-elk]:https://github.com/jonashackt/docker-elk\n[docker-machine]:https://docs.docker.com/machine/get-started/\n[Pdfbox]:https://pdfbox.apache.org/index.html\n[base64gular]:https://github.com/jonashackt/base64gular\n[MDC]:http://logback.qos.ch/manual/mdc.html\n[Heroku]:https://www.heroku.com/home\n[blogpost]:https://blog.codecentric.de/en/2015/10/deploying-spring-boot-applications-to-heroku/\n[here]:https://soap-spring-boot-cxf.herokuapp.com/soap-api\n[Kibana´s Visualisation-Features]:https://www.timroes.de/2015/02/07/kibana-4-tutorial-part-3-visualize/\n[Dashboard]:https://www.timroes.de/2015/02/07/kibana-4-tutorial-part-4-dashboard/\n[tldr;]:https://en.wiktionary.org/wiki/TLDR","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonashackt%2Fsoap-spring-boot-cxf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonashackt%2Fsoap-spring-boot-cxf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonashackt%2Fsoap-spring-boot-cxf/lists"}