{"id":2920,"date":"2016-06-16T06:12:24","date_gmt":"2016-06-16T04:12:24","guid":{"rendered":"http:\/\/www.pleus.net\/blog\/?p=2920"},"modified":"2019-01-10T13:39:00","modified_gmt":"2019-01-10T12:39:00","slug":"sustainable-microservices","status":"publish","type":"post","link":"https:\/\/www.pleus.net\/blog\/?p=2920","title":{"rendered":"Sustainable Microservices with Spring Boot"},"content":{"rendered":"<p>In my article series about <a title=\"Sustainable Service Design\" href=\"http:\/\/www.pleus.net\/blog\/?p=2546\" target=\"_blank\">Sustainable Service<\/a> (SSD) design I described a design and implementation approach to develop services with technical decoupling to improve reuse.<\/p>\n<p>At the level of IT infrastructure sustainable means that service implementations can be used in different technical environments without a major rewrite. Technical decoupling is a key factor to achieve that. In the second part of the article I have provided an example on how to implement SSD with a JEE stack. Part of this example is a \u00a0<a title=\"Calculator\" href=\"http:\/\/www.pleus.net\/#\/downloads\" target=\"_blank\">calculator service<\/a> which performs simple arithmetic operations.<\/p>\n<p>Due to the technical decoupling, services can be moved with little effort, for example from a JEE Server to other runtimes like Apache Karaf (OSGi) or Spring Boot, just to name a few.<\/p>\n<p>In this blog post I would like to demonstrate how to move the Calculator JEE example from Wildfly JEE Container to Spring Boot. The main difference in the Spring Boot deployment is the fact that each service is bundled with its own HTTP server. The deployment unit is not a JEE EAR which is deployed on a JEE Server, but a so-called \u00fcber-jar which includes the complete HTTP infrastructure. The \u00fcber-jar just requires a Java runtime and no additional infrastructure. This kind of deployment creates a high level of service autonomy which is often used in Microservice architectures.<\/p>\n<p>Let me tell you a little story:<\/p>\n<p>Assume Peter is an IT professional who is working on a fictitious software project for a large insurance company. One day a colleague, let\u2019s call him Max, from another project enters Peter\u02bcs office and starts the following conversation:<\/p>\n<p><strong>Max:<\/strong> I\u2019ve heard you\u2019ve implemented some very useful services. I saw them on your service repository Wiki and think we could use some of them in our new project.<\/p>\n<p><strong>Peter: <\/strong>Yes, that\u2019s right. I am glad we\u2019ve created something valuable.<\/p>\n<p><strong>Max:<\/strong>\u00a0But\u2026I also heard that you are using a full blown <a title=\"JBoss EAP\" href=\"http:\/\/www.jboss.org\/products\/eap\/overview\/\" target=\"_blank\">JEE Applicationserver<\/a> to run your services.<\/p>\n<p><strong>Peter: <\/strong>Yes, this is the best runtime for our project, as it helps us to manage centralized deployment. Each service is deployed in its own EAR file, which gives us great flexibility.<\/p>\n<p><strong>Max:<\/strong>\u00a0For our project we decided to use <a title=\"Spring Boot\" href=\"http:\/\/projects.spring.io\/spring-boot\/\" target=\"_blank\">Spring Boot<\/a> and deploy each service together with its own HTTP Server. I guess we can\u2019t use your service without a major rewrite then?<\/p>\n<p><strong>Peter:<\/strong> You don\u2019t have to rewrite the services because we\u2019ve implemented them based on Sustainable Service Design.<\/p>\n<p><strong>Max:<\/strong> Sounds great, could you please show me what we have to do to run your services?<\/p>\n<p><strong>Peter:<\/strong> Of course. Let&#8217;s start by downloading the <a title=\"Calculator\" href=\"http:\/\/www.pleus.net\/download\/SSD_Calculator_v1.1.zip\" target=\"_blank\">Calculator Example<\/a>, which demonstrates how to build SSD-Services for JEE. First, build the example like\u00a0so:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">mvn clean install\r\n<\/pre>\n<p><strong>Peter:<\/strong> Now you have the following maven artifacts (jars) in your local maven repository.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">net.pleus.services.calculator:calculator_api\r\nnet.pleus.services.calculator:calculator_impl\r\n<\/pre>\n<p><strong>Peter:<\/strong> You can use this artifacts without any modifications.<\/p>\n<p><strong>Max:<\/strong> Ok, I can see that <em>api<\/em> and <em>impl<\/em> form the core service. Our project decided to just use JSON\/HTTP as the protocol for service interaction. I saw that in the orignal example REST, EJB and SOAP are provided.<\/p>\n<p><strong>Peter:<\/strong> No problem, just add the bindings when you need them. With SSD you can add additional bindings any time. So you can start with the bare minimum and expand later. This gives you great flexibility. Add the JSON\/HTTP-binding first.<\/p>\n<p><strong>Max:<\/strong> In the original example I saw that it was called REST-Binding.<\/p>\n<p><strong>Peter:<\/strong> Although the original calculator example uses the term REST-Binding, I prefer to call it JSON\/HTTP-Binding because it better describes what it is. An SSD-Service can manage multiple resources (nouns) and can support arbitrary operations (verbs). This representation is very well suited to modelling the real world (the domain) which is important for proper service design and reuse. If you really have the requirement to create REST-Style APIs, you can do it in the respective binding. But be aware that in this case you create a variation of your service contract (subcontract) which also relies on HTTP-Verbs instead of the verbs in the primary contract. Although it is possible, I would not recommend it. Ok, let\u2019s not digress but move on with Spring Boot.<\/p>\n<p><strong>Max:<\/strong> Ok, please show me how to create the bootable service.<\/p>\n<p><strong>Peter:<\/strong> Sure, start with the following Maven-POM , which is based on the tutorial <a title=\"Building a RESTful Web Service\" href=\"https:\/\/spring.io\/guides\/gs\/rest-service\/\" target=\"_blank\">Building a RESTful Web Service with Spring Boot<\/a>.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;project xmlns=&quot;http:\/\/maven.apache.org\/POM\/4.0.0&quot; xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot;\r\n    xsi:schemaLocation=&quot;http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd&quot;&gt;\r\n    \r\n    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\r\n    &lt;parent&gt;\r\n        &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n        &lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;\r\n        &lt;version&gt;1.3.5.RELEASE&lt;\/version&gt;\r\n    &lt;\/parent&gt;\r\n\r\n    &lt;groupId&gt;net.pleus.services.calculator&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;calculator_boot&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;\r\n    &lt;name&gt;Services :: calculator :: boot&lt;\/name&gt;\r\n\r\n    &lt;dependencies&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\r\n        &lt;\/dependency&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;\r\n        &lt;\/dependency&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;net.pleus.services.calculator&lt;\/groupId&gt;        \r\n            &lt;artifactId&gt;calculator_api&lt;\/artifactId&gt;\r\n            &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;\r\n        &lt;\/dependency&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;net.pleus.services.calculator&lt;\/groupId&gt;        \r\n            &lt;artifactId&gt;calculator_impl&lt;\/artifactId&gt;\r\n            &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;\r\n        &lt;\/dependency&gt;\r\n    &lt;\/dependencies&gt;\r\n    \r\n    &lt;properties&gt;\r\n        &lt;java.version&gt;1.8&lt;\/java.version&gt;\r\n    &lt;\/properties&gt;\r\n\r\n    &lt;build&gt;\r\n        &lt;plugins&gt;\r\n            &lt;plugin&gt;\r\n                &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\r\n                &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;\r\n            &lt;\/plugin&gt;\r\n        &lt;\/plugins&gt;\r\n    &lt;\/build&gt;\r\n\r\n&lt;\/project&gt;\r\n\r\n<\/pre>\n<p><strong>Peter:<\/strong> From lines 25-34 you can see the existing calculator jars. The rest is required to create a minimal Spring Boot \u00fcber-jar. Now we create a JSONHTTP-Binding using Spring MVC.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">@RestController\r\n@RequestMapping(value = &quot;\/services\/calculator\/rest\/api&quot;, method= RequestMethod.POST)\r\npublic class CalculatorJSONHTTPBinding {\r\n\r\n    @Autowired\r\n    private Calculator service;\r\n\r\n    @RequestMapping(value = &quot;\/performcalculations&quot;, method= RequestMethod.POST)\r\n    @ResponseBody\r\n    public PerformCalculationsResponse performCalculations(@RequestBody PerformCalculationsRequest request) {\r\n        return service.performCalculations(request);\r\n    }\r\n}\r\n<\/pre>\n<p><strong>Peter:<\/strong> To add this binding we need some boilerplate code. First an application class.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">@SpringBootApplication\r\npublic class Application {\r\n\r\n    public static void main(String[] args) {\r\n        ApplicationContext ctx = SpringApplication.run(Application.class, args);\r\n    }\r\n}\r\n<\/pre>\n<p><strong>Peter:<\/strong> And second a little factory to create a service instance, so that it can be injected using <em>@Autowired<\/em> in the binding.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">@Configuration\r\npublic class Factory{\r\n    @Bean public Calculator createCalculator(){\r\n        return new CalculatorImpl();\r\n    }\r\n}\r\n<\/pre>\n<p><strong>Peter:<\/strong> That&#8217;s all. Build it and run the \u00fcber-jar with the following command.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">mvn clean install\r\njava -jar target\/calculator_boot-1.0-SNAPSHOT.jar\r\n<\/pre>\n<p><strong>Max:<\/strong> Wow, that&#8217;s all? Can you prove that it works?<\/p>\n<p><strong>Peter:<\/strong> Of course. For example fire up SOAP-UI and send this request to the service at http:\/\/localhost:8080\/services\/calculator\/rest\/api\/performcalculations<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n{\r\n\t&quot;correlationid&quot;:&quot;4711&quot;,\r\n\t&quot;calculations&quot;: {\r\n\t &quot;value&quot;: [\r\n\t   {\r\n\t     &quot;operation&quot;: &quot;ADD&quot;,\r\n\t     &quot;inputs&quot;: {\r\n\t       &quot;value&quot;: [&quot;1&quot;,&quot;2&quot;]\r\n\t     }\r\n\t   }]\r\n\t}\r\n}\r\n<\/pre>\n<p><strong>Peter:<\/strong> This is what you get.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">{\r\n   &quot;correlationid&quot;: &quot;4711&quot;,\r\n   &quot;calculations&quot;: {&quot;value&quot;: [{&quot;result&quot;: 3}]}\r\n}\r\n<\/pre>\n<p><strong>Max:<\/strong> Can I reuse the existing binding from the original example instead of the one we created?<\/p>\n<p><strong>Peter:<\/strong> Yes, but it is technically coupled to JAX-RS. If you want to use it please read the blog <a title=\"JAX-RS instead of Spring MVC\" href=\"https:\/\/dzone.com\/articles\/using-jax-rs-with-spring-boot-instead-of-mvc\" target=\"_blank\">Using JAX-RS With Spring Boot Instead of MVC<\/a>.<\/p>\n<p><strong>Max: <\/strong>I saw that the original example contains a handy Java client to access the service. Can I reuse it?<\/p>\n<p><strong>Peter:<\/strong> You mean <em>net.pleus.services.calculator:calculator_binding_rest_client<\/em>. Yes, you can use it as it is. And it makes sense, as it gives you a nice fluent Java-API to access the service. First add the following Maven artifact to your pom.xml.<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">        \r\n            net.pleus.services.calculator        \r\n            calculator_binding_rest_client\r\n            1.0-SNAPSHOT\r\n        \r\n<\/pre>\n<p><strong>Peter:<\/strong> Now you can use the Java client in your tests like this.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">@Before\r\npublic void setUp() throws Exception {\r\n  client = new CalculatorClient(&quot;localhost&quot;,port);\r\n}\r\n    \r\n@Test\r\npublic void add() throws Exception {\r\n\r\n  \/\/ Create calculation inputs\r\n  Calculation calculation = new Calculation()\r\n   .withOperation(Operation.DIVIDE)\r\n   .withInputs(new ArrayOfInt()\r\n     .withValue(9,3,2)\r\n   );\r\n\t\t\t\t \r\n  \/\/ Create request\r\n  PerformCalculationsRequest request = new PerformCalculationsRequest()\r\n    .withCorrelationid(UUID.randomUUID().toString())\r\n    .withCalculations(new ArrayOfCalculation().withValue(calculation));\r\n\t\t\r\n  \/\/ Call service\t\r\n  PerformCalculationsResponse response = client.performCalculations(request);\r\n\r\n  \/\/ Check correlation\r\n  Assert.assertEquals(request.getCorrelationid(), response.getCorrelationid());\r\n\t\t\r\n  \/\/ Check result\r\n  Assert.assertEquals(new BigDecimal(1.5), response.getCalculations().getValue().get(0).getResult());\t\r\n}\r\n<\/pre>\n<p><strong>Peter:<\/strong> When you run the test Spring Boots starts the HTTP Server and calls the service.<\/p>\n<p><strong>Max: <\/strong>It seems that I can easily run your service and even use the Java client within Spring Boot. We have a sustainable service and a lightweight runtime. Perfect! That saves us a lot of time and money. Maybe we should try to evolve the service together? This way we could create further value for other projects.<\/p>\n<p><strong>Peter:<\/strong>\u00a0Good idea! If you want to try the example I\u2019ve packaged it for <a title=\"SSD Spring Boot\" href=\"http:\/\/www.pleus.net\/download\/SSD_Calculator_Boot_V1.0.zip\" target=\"_blank\">download<\/a>. For convenience it also contains identical copies from the original calculator example.<br \/>\nFeel free to use it as you like.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my article series about Sustainable Service (SSD) design I described a design and implementation approach to develop services with technical decoupling to improve reuse. At the level of IT infrastructure sustainable means that service implementations can be used in different technical environments without a major rewrite. Technical decoupling is a key factor to achieve &hellip; <a href=\"https:\/\/www.pleus.net\/blog\/?p=2920\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Sustainable Microservices with Spring Boot<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69,3],"tags":[23,64,28,77,68,60],"class_list":["post-2920","post","type-post","status-publish","format-standard","hentry","category-microservices","category-soa","tag-java","tag-microservices","tag-rest","tag-soa","tag-spring-boot","tag-ssd"],"_links":{"self":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2920","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2920"}],"version-history":[{"count":96,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2920\/revisions"}],"predecessor-version":[{"id":3252,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2920\/revisions\/3252"}],"wp:attachment":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2920"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2920"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2920"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}