1. AN ALTERNATIVE APPROACH TO THREADLOCAL USING SPRING
In a blog post published sometime ago, Multitenant applications using Spring Boot JPA Hibernate and Postgres I included some code to set to and to retrieve from, the tenant identifier (a discriminator for selecting its associated datasource) using a ThreadLocal reference:
- A context holder class for holding the tenant data:
- A Spring MVC interceptor (which could have been also done using a servlet filter) to set and clear such tenant identifier:
- And somewhere in the application:
I normally try to avoid using ThreadLocal and would also advise to limit their usage. They can be handy, solve difficult problems but can also introduce memory leaks.
In this post I discuss how to use Spring’s ThreadLocalTargetSource to prevent dealing directly with the dangerous ThreadLocal while practicing dependency injection and proper mocking in unit tests.
1. DISABLING REDIS AUTO-CONFIGURATION IN SPRING BOOT APPLICATIONS
I was recently working on a Spring Boot web application where it was decided to reduce external services dependencies to speedup development, caching using Redis in this specific case.
The interaction between the web application and a Redis server is done using Spring’s RedisTemplate, an implemention of the Template design pattern, used similarly to RestTemplate, JdbcTemplate, JmsTemplate, etc..
A RedisTemplate and related beans are auto-configured by Spring Boot when including spring-boot-starter-data-redis as a dependency for the application. This posts covers some tips to prevent such connection from being auto-configured.
1. ROUTING REQUESTS AND DYNAMICALLY REFRESHING ROUTES USING SPRING CLOUD ZUUL SERVER
Having covered infrastructure services Spring Cloud Config server here with Refreshable Configuration here and Registration and Discovery here with Multi-versioned service support here, in this post I’ll cover the Spring Cloud Netflix Zuul server, another infrastructure service used in a microservice architecture.
Zuul is an edge server that seats between the outside world and the downstream services and can handle cross-cutting concerns like security, geolocation, rate limiting, metering, routing, request / response normalization (encoding, headers, urls). Developed and used by Netflix to handle tens of billions of requests daily, it has also been integrated for Spring Boot / Spring Cloud applications by Pivotal.
A core component of the Zuul server is the Zuul filters, which Zuul provides four types of:
|pre filters||Executed before the request is routed.|
|routing filters||Handles the actual routing of the request.|
|post filters||Executed after the request has been routed.|
|error filters||Executed if an error happens while handling the request.|
This post shows how to configure a Spring Cloud Netflix Zuul server to route requests to a demo downstream service using the provided
routing filter RibbonRoutingFilter and how to dynamically refresh the Zuul routes using Spring Cloud Eureka and Spring Cloud Config servers.
1. FIXING LOGGERFACTORY NOT A LOGBACK LOGGERCONTEXT BUT LOGBACK IS ON THE CLASSPATH, SPRING BOOT-COBERTURA ERROR
A few days ago I was working on a new Spring Boot web application where some dependencies version and common Maven plugins configuration were inherited from a parent pom. Everything was just fine, APIs would work as intended, Unit and Integration Tests were passing except when generating the Cobertura code coverage report. It didn’t matter how minimalist this Spring Boot app could get, code coverage was just failing attempt after attempt.
This posts describes troubleshooting a Spring Boot application and Cobertura dependencies to fix multiple SLF4J bindings - found in the classpath - Failed to load ApplicationContext.
1. CACHING USING RESTTEMPLATE, EHCACHE AND ETAGS
Often times I have seen API implementations not taking advantage of client side caching. Consider this example, a REST service needs to get data from a handful of other services and for every request, even though the upstream response might have not changed for the same input, it’s being calculated repeatedly and sent back to the client.
Depending on how expensive this calculation might be, wouldn’t be a better approach if the HTTP request includes data about what it previously has stored from a prior server response in an attempt for the server to find out if this calculation would be needed at all? This will improve the application performance while saving on server resources.
And what about if this expensive calculation is not needed, wouldn’t be a good practice for the server to let the client know that nothing has changed on the server side for that request? This will also save on bandwidth, assuming the client service is able to reconstruct the response payload.
This post focuses on the client side of this improvement, configuring Spring’s RestTemplate to use HttpClient and Ehcache to cache upstream HTTP responses using ETags.
1. IMPLEMENTING A CUSTOM SPRING BOOT STARTER FOR CXF AND SWAGGER
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 we setup this up for a dozen or more services? Do we create a baseline project to be copied and pasted for each service? Do we 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.
1. IMPLEMENTING APIS USING SPRING BOOT, CXF AND SWAGGER
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.
1. MULTI-VERSION SERVICE DISCOVERY USING SPRING CLOUD NETFLIX EUREKA AND RIBBON
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.
1. REFRESHABLE CONFIGURATION USING SPRING CLOUD CONFIG SERVER, SPRING CLOUD BUS, RABBITMQ AND GIT
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.
1. MULTI-TENANT APPLICATIONS USING SPRING BOOT, JPA, HIBERNATE AND POSTGRES
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.