First stop: A SOAP service

Marco Capo
FAUN — Developer Community 🐾
9 min readApr 8, 2019

--

Let’s use Spring boot 2 to build our first service for a real-world scenario

Client specifications

Imagine that your client client streamflix wants to create a SOAP service based on a service description (schema), by providing basic user information it will return a list of messages or client offers that the business needs to attract new clients but also offer promotions based on specific dates.

So, What is a SOAP?

Web service is a standardized medium to send messages between the client and server applications on the internet which is designed to perform a certain set of tasks.

There are mainly two types of web services.

  • SOAP web services.
  • RESTful web services.

Today we will cover web services known as SOAP (Simple Object Access Protocol) for sending the XML data between applications over normal HTTP. The data is sent through SOAP message (XML document) obtaining the advantage of the client application calling the web service can be written in any programming language.

Advantage

  • Enable communication: Web services came about in the first place to provide a platform which could allow different applications to talk to each other.
  • Exposing Business Functionality on the network: A web service is some code that provides the functionality to a client-invoked over the HTTP protocol over the internet.
  • A Standardized Protocol: Web services use a standardized protocol for communication by exposing a definition document (WSDL).
  • Loosely Coupled: Loosely coupled means that the client and the web service are not bound to each other. Adopting a loosely coupled architecture tends to make software systems more manageable and allows simpler integration between different systems.

Creating our promotion service

You can find the code in the repository, clone it and follow this tutorial to get detailed information of this system.
I will describe the main files on every section while we move through each part of this tutorial, you will find a link to the class file next to the topic.

Use this project as a base template to build and customize it as it suits you. Also, I’m assuming it’s not your first time with java, but you can ask me whatever you want.

What you will learn in this post

  • Base SOAP project or a platform to build your first SOAP service.
  • A better understanding of spring boot and its components.
  • How to make your unit and integration tests
  • Use of JUnit 5 with parameterized tests.
  • Package your service for delivery with Docker.
  • How to handle properties production ready.

Pre-requirements

Service description file

I’ve defined a simple schema so you can tune it as you require and add the complexity needed for your solution, but first, take a look into the schema.

Start building our service

Gradle configuration

First, we will use Gradle with the help of a plugin to generate the necessary classes based on the .xsd file provided.

The task genJaxb is used to generate the classes specified in the .xsd file in this line:
ext.schema = “src/main/resources/promo.xsd”
What does this do behind the scenes? Well, first it produces the java classes based on the schema, then places everything in the sourceDir location. Then java compiles all those java classes and places them in a classesDir location.

Finally, we need to set the dependencies for the project to make it easy for us developers to build a system. We are using spring boot starter web service which has all the autoconfiguration for this service and an embedded web container so there is no need to deploy a war in a tomcat. Well, we need a test starter because we are responsible developers that ensure their work by developing some unit tests for everything we do. Also, we have wsdl4j library to generate the WSDL contract of the service and Lombok to make our code cleaner and to reduce the development process.

If you don’t know what project Lombok is and what is capable of taking a look to their library you will love it, is one of those libraries that once you know them you won’t be able to avoid using it, there is no going back.

Web service configuration

Well, now we start with the fun part… code! Well not code, but configuring spring.

So we have 3 beans first is the servlet that we set our application context (Injected by the magic of spring).

We have our wsdl definition configuration, it’s important to name a couple of things, the bean name “promo” will be the name of the wsdl file that we can find in /ws/promo.wsdl location. Also, we have the port type name, this is important since it will map it with the schema definition by adding the request and response suffix (promotionRequest and promotionResponse). The URL location of the service, we set it as /ws so your endpoint will be http://localhost:8080/ws and the target namespace that we find in our schema (targetNamespace=”http://www.gueka.net/promo/schema"). Last the .xsd file location that spring boot will search inside the resource java folder by convention.

Endpoint

File: link

Here is where the request will come when a call is executed. The annotation:

@PayloadRoot(namespace = NAMESPACE_URI, localPart = SUBMIT_SM_REQ)

Links the specified request to this method, so whenever a promotionRequest from target namespace is invoked to this service, spring will generate the POJO request and execute this method.

OfferService

File: link

This class is our business logic where we encapsulate all the promotions rules that will be applied.

For the purpose of this tutorial we have only 2 rules defined, one is for a 6-month discount promotion for a new user subscribed to our service and the other is a 10% discount for the month that the user subscribed. If any of these rules apply we should add a message notifying the offer.

Properties

A quick tip about properties in spring boot, you have several ways to arrange the properties based on the environment you are running, profiles is a good way to organize this but since we are in a path to microservices and dockerize, we will use the power of environment variables and defaults values.

server.port=${SERVER_PORT:8080}

Here we have a spring boot server port property that will start the embedded tomcat in the port specified in this property but we added a special twist that is set as a variable an env property SERVER_PORT, just like JAVA_HOME but for our port, if this env variable is not present it will use 8080 as a default.

Hey! don’t forget to test

File: link

Here we will test our business logic layer, since it’s the most important part to test, in this test you can find the year promotion, the new user promotion and no promotion. I’m using JUnit Jupiter (JUnit 5) because is the latest JUnit is the most popular unit-test framework in Java and because I like to keep up to date.

I didn’t cover all test cases, near the edge dates of promotion for example, but feel free to add them if you want and share it with me.

But, what I did was use JUnit 5 power of parameterized tests, with the help of 2 annotations you can reuse test to make sure your code works properly, this annotations are quite verbose and self-explanatory so check the code… it speaks by itself.

If you want to know how to do an integration test, search in the repository for ServiceEndpointTest it contains a basic demonstration on how to do it.

Dockerize it!

Docker is an open source container-based technology… so what is a container?. A container allow us as developers to package up an application and all of its parts, stacks that run on, dependencies needed and packaged all in this box that we call container creating an isolated environment so the application has all that it needs to run inside this container so the operating system/host environment that runs on is completely abstracted from the application. The best analogy is where this technology has been inspired from, ships containers that travel around the world with all kind of products, from food to batteries, it protects the goods from harsh environment, climate, maintain its temperature so the food is not rotten or the batteries don’t explode so it can make it be delivered to its final destination in perfect conditions.

I will leave these 4 keys of why docker is so cool:

  • Onboard faster and stop wasting hours trying to set up development environments, spin up new instances and make copies of production code to run locally.
  • Enable polyglot development and use any language, stack or tools without the worry of application conflicts.
  • Eliminate environment inconsistencies and the “works on my machine” problem by packaging the application, configs, and dependencies into an isolated container.
  • Alleviate concern over application security

Each line in the Dockerfile is a layer so the container will build each layer on top of the last, so describe it one by one.

FROM openjdk:8-jre-alpine

As a rule of thumb use this image for spring boot, you should search for other images if you use Debian related stuff or its running in a windows server and use windows related stuff.

ARG JAR_FILE

Define a JAR_FILE argument that has to be specified in build execution.

ADD ${JAR_FILE} app.jar

Add file as app.jar. The JAR_FILE argument will point to the actual jar file built by Gradle.

ENTRYPOINT [“java”,”-jar”,”/app.jar”]

On startup, it will execute the app initializing spring web container.

How to run this!

Easy steps to build and run it in a docker container.
Let’s get familiar with using a console.

Open a console and execute these steps:

  1. mkdir ~/tutorials && cd ~/tutorials
  2. git clone https://github.com/Gueka/spring-boot-tutorials.git
  3. cd sb2-soap-tutorial
  4. gradle build
  5. docker build -t gueka:sb2-soap-tutorial — build-arg JAR_FILE=./build/libs/spring-boot-docker-tutorial-0.0.1-SNAPSHOT.jar .
  6. docker run -p 8080:8080 gueka:sb2-soap-tutorial
  7. curl — request POST — url http://localhost:8080/ws — header ‘Content-Type: text/xml’ — data ‘<soapenv:Envelope xmlns:soapenv=”http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns=”http://www.gueka.net/promo/schema"><soapenv:Header> </soapenv:Header><soapenv:Body><tns:promotionRequest><tns:data><tns:userId>007</tns:userId><tns:initDate>2019–04–04T09:00:00</tns:initDate></tns:data></tns:promotionRequest></soapenv:Body></soapenv:Envelope>’

Since the curl is quite ugly to read and if you like postman as I do and want to see the things as I see look at the postman file, also you will find a start.sh to build and start the application.

Conclusion

So today we learn how to create a contract based service, test it and prepare it for deploy. This service will allow scalability and is production ready since is dockerized and the application has everything necessary to run, so now you are ready to connect a better world.

I also provided links for a further description of each topic we talked about, but you can ask me any question you like or what topics you would like to see.

Next, we will learn how to create a REST service, it’s a schema-free service more suitable for the changing world that we are leaving and for microservices.

Comment how you will do it or what you should change… or as Morfeo said “show me” and never forget to have fun coding.

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--

I’m a senior software engineer working in technology development for 12+ years from marketing, videogames and microservices for big companies