Consider this scenario, the development team has increased over the last few years, software releases and deployment takes more time, that quick fix or feature couldn’t be delivered this Sprint because the deliverable now includes many changes that haven’t been signed off by QA and it might take another month to do so.
This seems like a good opportunity to break up the big Java monolithic application into multiple services or for that legacy set of applications in which business logic is duplicated to be refactored or rewritten, each by a small team benefiting from more frequent releases, easier to understand a small piece of functionality, having a low impact on other services, promoting ownership and accountability, etc..
Assuming for instance, it has been decided to implement the APIs using Spring Boot, Apache CXF and Swagger along with logging, metrics, security, etc. and maybe packaging the service in a Docker image, how do you setup this up for a dozen or more services? Do you create a baseline project to be copied and pasted for each service? Do you create a custom Maven archetype? What are other options?
This post covers how to create a custom Spring Boot starter for Apache CXF 3.1.x and Swagger 2 as the starting point to create services with a common set of dependencies and functionality also providing Spring beans auto-configuration to reduce explicit beans definition.
A while back I published a blog post about Microservices using Spring Boot, Jersey, Swagger and Docker that takes advantage of the Spring ecosystem and a JAX-RS implementation in Jersey 2. In another post, Services Registration and Discovery using Eureka, Ribbon and Feign I also mentioned that Jersey 2-based endpoints attempting to register with Spring Cloud Netflix Eureka registry failed due to the fact that Eureka and Ribbon clients bring in Jersey 1 dependencies and thus conflicting with Jersey 2’s.
Instead some endpoints were implemented using Jersey 1 successfully registering with Eureka but the downside was it required configuring Jersey 1 in a multi-module Maven setup because there is no Spring Boot starter for Jersey 1 and a limitation to scan nested jars.
In this follow up post I plan to demonstrate how to integrate Apache CXF 3.1.x JAX-RS-based endpoints implementation with Spring Boot and documenting them using Swagger. The services following this setup should be able to register with Spring Cloud Netflix Eureka since no Jersey dependency would be transitively included.
As services evolve over time, changes are made to the domain that very-likely require API versioning to prevent breaking backwards compatibility.
Unless you work in a very controlled environment, for instance, where it’s known that client applications are also distributed with the API services and there is no possibility of an old client using newer API services deployment, I’m a firm believer you should never break backwards compatibility.
I’ll say it again because this is very important, you should never break backwards compatibility, if you do, customers and partners get very angry and fixing it afterwards normally requires more effort than versioning from the beginning.
The question now is, how does versioning work in a microservice architecture where services are registered with and discovered using a Discovery infrastructure microservice such as Netflix Eureka?
In this post I’ll explain how to register and discover multiple version of a service using Spring Cloud Netflix Eureka and Ribbon.
This post is a continuation of Centralized and versioned configuration using Spring Cloud Config Server and Git where I covered the Spring Cloud Config server to prevent hard-coding properties that most-likely would be different for each deployment environment.
At the end of said post I outlined how updating a Git-backed property and sending a POST request to the client application’s
/refresh actuator endpoint caused the configuration property to be reloaded and the dependent Spring beans to be refreshed picking up the new value.
But what if it’s not just one or two microservices but maybe dozens or even hundreds that would need to reload those properties changes? Hitting
/refresh for each one doesn’t seem like an elegant solution. What if the numbers of instances keep growing?
In this post I’ll extend the Spring Cloud Config Server and the client service implemented in part 1 with Spring Cloud Bus and RabbitMQ support and a Bitbucket webhook to automatically notify subscribed client services of changes in the Git-backed configuration files.
Multitenancy is an approach in which an instance of an application is used by different customers and thus dropping software development and deployment costs when compared to a single-tenant solution where multiple parts would need to be touched in order to provision new clients or update existing tenants.
There are multiple well known strategies to implement this architecture, ranging from highly isolated (like single-tenant) to everything shared.
In this post I’ll review configuring and implementing a multitenancy solution with multiple databases and one API service using Spring Boot, JPA, Hibernate and Postgres.
Spring’s RestTemplate is one of the options to make client HTTP requests to endpoints, it facilitates communication with the HTTP servers, handles the connections and transforms the XML, JSON, … request / response payloads to / from POJOs via HttpMessageConverter.
By default RestTemplate doesn’t use a connection pool to send requests to a server, it uses a SimpleClientHttpRequestFactory that wraps a standard JDK’s HttpURLConnection taking care of opening and closing the connection.
But what if an application needs to send a large number of requests to a server? Wouldn’t it be a waste of efforts to open and close a connection for each request sent to the same host? Wouldn’t it make sense to use a connection pool the same way a JDBC connection pool is used to interact with a DB or a thread pool is used to execute tasks concurrently?
In this post I’ll cover configuring RestTemplate to use a connection pool using a pooled-implementation of the ClientHttpRequestFactory interface, run a load test using JMeter, troubleshoot requests timeout and reconfigure the connection pool.
Today I landed in a stackoverflow question about how to access the JavaMelody UI using a port other than the one used by the APIs. I went ahead I answered the question with some initial code I had for another blog post I’m working on but then decided to make it its own post.
While this could certainly be accomplished adding a couple of Spring Boot configuration properties: management.context-path and management.port to
application.yml for instance, and reuse the same path used for actuator endpoints (
/admin/health, …), there might be some cases where having the servlet container listening on a port other that the two mentioned earlier might make sense, maybe for monitoring, traffic analysis, firewall rules, etc..
In this post I’ll add support for configuring embedded Tomcat to listen on multiple ports and configure JavaMelody to exclusively use one of those ports to display its reports using Spring Boot.
The previous blog post covered Service Registration and Discovery as an infrastructure service used in a microservice architecture. In this post I’ll review another infrastructure microservice, the Configuration management service.
Configuration is used to prevent hard-coding values in the applications. But it’s also used to specify what is expected to be different between deployment environments (qa, staging, production, …) such as host names, mail and database credentials and other backing services. The latter type of configuration is identified as one of the elements in The Twelve-Factor App.
The benefits of this practice are that it promotes building only one artifact, only one binary to be executed in all the environments. You should never have to build a different executable for each environment, this will most-likely cause troubleshooting and debugging headaches.
As part of the Spring Cloud Series, this post describes the Spring Cloud Config’s server and client usage, the configuration storage options and its relation with the Discovery Server in a registration-first and configuration-first approaches.
This blog post reviews an implementation pattern used in microservice architectural style: Service Registration and Discovery. The Discovery service and Configuration service, the latter discussed in this post, are most-likely the first infrastructure microservices needed when implementing such architecture.
Why is the Discovery service needed in a microservice architecture? Because if a running instance of service X needs to send requests to a running instance of service Y, it first needs to know the host and port service Y runs and listens on. One might think that service X may know this information via some static configuration file but this approach doesn’t sound very practical in an elastic-like distributed setup where services are dynamically (de)provisioned, triggered either manually or by some condition such as an auto-scaling policy or failure for instance.
Continuing with the Spring Cloud Series covered in this blog, this post discusses Spring Cloud Netflix’s Service Discovery component, a Spring-friendly and embedded Eureka server where services instances can register with and clients can discover such instances.
The integration testing goal is to verify that interaction between different parts of the system work well.
Consider this simple example:
Successful run of this integration test validates that:
- Class attribute actorDao is found in the dependency injection container.
- If there are multiple implementations of ActorDao interface, the dependency injection container is able to sort out which one to use.
- Credentials needed to communicate with the backend database are correct.
- Actor class attributes are correctly mapped to database column names.
- actor table has exactly 200 rows.
This trivial integration test is taking care of possible issues that unit testing wouldn’t be able to find. It comes at a cost though, a backend database needs to be up and running. If resources used by the integration test also includes a message broker or text-based search engine, instances of such services would need to be running and reachable. As can be seen, extra effort is needed to provision and maintain VMs / Servers / … for integration tests to interact with.
In this blog entry, a continuation of the Spring Cloud Series, I’ll show and explain how to implement integration testing using Spring Boot, Postgres and Docker to pull Docker images, start container(s), run the DAOs-related tests using one or multiple Docker containers and dispose them once the tests are completed.