MicroServices with Spring

From My Limbic Wiki

Modules

General Architecture

Martin Flower : Testing Strategies in a Microservice Architecture https://martinfowler.com/articles/microservice-testing/

Spring Cloud

Netflix

Spring Cloud Netflix provides Netflix OSS integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms. With a few simple annotations you can quickly enable and configure the common patterns inside your application and build large distributed systems with battle-tested Netflix components. The patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix), Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).. More infos: https://spring.io/projects/spring-cloud-netflix

Netflix Eureka Client

REST service which registers itself at the registry

Netflix Eureka Server

Is the registration service, all services will connect to the same adress: http://localhost:9000 for example

Netflix Zuul

Zuul is a JVM based router and server side load balancer by Netflix Intelligent Routing

Netflix Hystrix

  • Hystrix is no longer in active development, and is currently in maintenance mode
  • Can be use through the context of spring cloud
  • Most Popular Circuit Breaker Technology
  • The fault tolerance library
  • it will forward all subsequent calls to the fallback method, to prevent future failures
  • Creates a time buffer for the related service to recover from its failing state.


  • `@EnableHystrixDashBoard`
  • `@EnableCircuitBreaker`
  • `@HistrixCommand`

Circuit Breaker

Helps to avoid cascading failure into Micro Services

Pattern
  • By creating a GateKeeper wich is an Interceptor that intercept all the requests going through
  • it can be configured and it has to keeps track of the lasts N successfull and failed requests
  • Whenever there is an issue with the associated service, the interceptor will stop
  • So the interceptor will not allowed any subsequent requests, instead it will immediatly send back a default response
  • A time is configured to allow the requests to go through after the service has recovered
    • it can be configured as allow partial to test the service with few request before to allow all the request again

Sleuth

Spring Cloud Sleuth implements a distributed tracing solution for Spring Cloud, borrowing heavily from Dapper, Zipkin and HTrace. For most users Sleuth should be invisible, and all your interactions with external systems should be instrumented automatically. You can capture data simply in logs, or by sending it to a remote collector service. More about: https://spring.io/projects/spring-cloud-sleuth

Spring Boot Security

Lombok

Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.

jjwt: Jswon Web Token

f your working with an API that uses JSON Web Tokens for authentication you’ll need to quick way to base64 decode and view the token contents. JWT.io is a free service by Auth0 that does exactly that. https://en.wikipedia.org/wiki/JSON_Web_Token

Repositories

Milestone

Java 11 compatibility

JaXB

from com.sun.xml.bind:

jaxb-core

api

impl

Vulgarisation of the architecture

/ Pom.xml Properties Files
Server
  • Dependencies
spring-cloud-starter-netflix-eureka-server
spring-boot : web, test & devtools
com.sun.xml.bind: jaxb-core,api,impl
  • dependencyManagement
org.springframework.cloud: spring-cloud-dependencies
  • Repositories
https://repo.spring.io/milestone
spring.application.name=eureka-server
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
  • com.microservices.server.EurekaServerApplication.java
@SpringBootApplication
@EnableEurekaServer // Enable eureka server
Zuul
  • Dependencies
spring-cloud-starter-netflix-eureka-client
spring-cloud-starter-netflix-zuul
o.jsonwebtoken: jjwt
com.microservices.common: SpringEurekaCommon
spring-boot : web, test, devtools & security 
com.sun.xml.bind: jaxb-core,api,impl
  • dependencyManagement
org.springframework.cloud: spring-cloud-dependencies
  • Repositories
https://repo.spring.io/milestone
server.port=8762
spring.application.name=zuul-server
eureka.client.service-url.default-zone=http://localhost:8761/eureka/
#zuul.prefix=/api
  • Disable accessing services using service name (i.e. gallery-service).
zuul.ignored-services=*
  • Map paths to services
zuul.routes.gallery-service.path=/gallery/**
zuul.routes.gallery-service.service-id=gallery-service
zuul.routes.auth-service.path=/auth/**
zuul.routes.auth-service.service-id=AUTH-SERVICE$
  • So, if request is "/gallery/view/1", gallery service will get "/view/1".
zuul.routes.auth-service.strip-prefix=false
zuul.routes.auth-service.sensitive-headers=Cookie,Set-Cookie  #Exclude authorization from sensitive headers
  • com.microservices.zuul.EurekaZuulApplication.java
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
  • com.microservices.zuul.security.JwtAuthenticationEntryPoint.java
@Component
  • com.microservices.zuul.security.JwtTokenAuthenticationFilter.java
//import com.eureka.common.security.JwtConfig;
private final JwtConfig jwtConfig;
  • com.microservices.zuul.security.SecurityTokenConfig.java
@EnableWebSecurity
  @Autowired
  //import com.eureka.common.security.JwtConfig;
  private JwtConfig jwtConfig;
@Bean
public JwtConfig jwtConfig() {
    return new JwtConfig();
}
Image
  • Dependencies
spring-cloud-starter-netflix-eureka-client
spring-boot : web, test & devtools
org.springframework.cloud: spring-cloud-starter-sleuth
  • dependencyManagement
org.springframework.cloud: spring-cloud-dependencies
  • Repositories
https://repo.spring.io/milestone
 spring.application.name=image-service
 server.port=8200
 eureka.client.service-url.default-zone=http://localhost:8761/eureka
  • com.microservices.image.EurekaImageApplication.java
@SpringBootApplication
@EnableEurekaClient
  • com.microservices.image.controllers.ImageController.java
@RestController
@RequestMapping("/")
@Autowired
   private Environment env;
  • com.microservices.image.entities.Image.java
Gallery
  • Dependencies
spring-cloud-starter-netflix-eureka-client
spring-cloud-starter-netflix-hystrix
spring-cloud-starter-data-rest
spring-cloud-starter-sleuth
spring-boot : web, test & devtools
  • dependencyManagement
org.springframework.cloud: spring-cloud-dependencies
  • Repositories
https://repo.spring.io/milestone
spring.application.name=gallery-service
server.port=8100
eureka.client.service-url.default-zone=http://localhost:8761/eureka
  • fr.dalichamp.microservices.gallery
@SpringBootApplication
@EnableEurekaClient //Enable eureka client
@EnableCircuitBreaker 	// Enable circuit breakers
@Configuration
class RestTemplateConfig {	
  // Create a bean for restTemplate to call services
  // So, we can use the service name (like image-service) instead of localhost:port
  @Bean
  @LoadBalanced		// Load balance between service instances running at different ports.
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

}

  • fr.dalichamp.microservices.gallery.controllers.HomeController.java
@RestController
@RequestMapping("/")	
  @Autowired
  private RestTemplate restTemplate;
  @Autowired
  private Environment env;
 
  @HystrixCommand(fallbackMethod = "fallback")
  @RequestMapping("/{id}")
  public Gallery getGallery(@PathVariable final int id) {
    ...
  }
  • fr.dalichamp.microservices.gallery.entities;
Common
  • Dependencies
spring-cloud-starter-netflix-eureka-client
org.projectlombok: lombok
spring-boot : web, test & devtools
  • dependencyManagement
org.springframework.cloud: spring-cloud-dependencies
  • Repositories
https://repo.spring.io/milestone
spring.application.name=common-service
server.port=9200
eureka.client.service-url.default-zone=http://localhost:8761/eureka
  • com.microservices.common
@SpringBootApplication
@EnableEurekaClient
  • com.microservices.common.security.JwtConfig.java
@Getter
@ToString	
@Value("${security.jwt.uri:/auth/**}")
@Value("${security.jwt.header:Authorization}")
@Value("${security.jwt.prefix:Bearer }")
@Value("${security.jwt.expiration:#{24*60*60}}")
@Value("${security.jwt.secret:JwtSecretKey}")
  • com.microservices.common.security.UserRole.java
Auth
  • Dependencies
spring-cloud-starter-netflix-eureka-client
spring-boot : web, test, devtools & Security
io.jsonwebtoken: jjwt
com.microservices.common: SpringEurekaCommon
com.sun.xml.bind: jaxb-core,api,impl
  • dependencyManagement
org.springframework.cloud: spring-cloud-dependencies
  • Repositories
https://repo.spring.io/milestone
spring.application.name=auth-service
server.port=9100
eureka.client.service-url.default-zone=http://localhost:8761/eureka
  • com.microservices.auth.SpringEurekaAuthApp.java
@SpringBootApplication
@EnableEurekaClient
  • com.microservices.common.security.SecurityCredentialsConfig.java
@EnableWebSecurity
  @Autowired
 private UserDetailsService userDetailsService;
  @Autowired
 //import com.eureka.common.security.JwtConfig;
 private JwtConfig jwtConfig;
@Bean
public JwtConfig jwtConfig() {
  return new JwtConfig();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
  return new BCryptPasswordEncoder();
}
  • com.microservices.common.security.JwtUsernameAndPasswordAuthenticationFilter.java
  • com.microservices.common.security.UserDetailsServiceImpl.java
@Service
@Autowired
  private BCryptPasswordEncoder encoder;
@Override
  public UserDetails