micro-eureka-service: Service Discovery Server created with Eurekamicro-gateway-service: API Gateway created with Zuul that uses the discovery-service to send the requests to the services. It uses Ribbon as a Load Balancermicro-item-service: Simple REST service created withSpring Boot, Spring Data JPA, MySQLto use as a resource servicemicro-sales-service: Simple REST service created withSpring Boot, Spring Data JPA, MySQLto use as a resource service
Follow the link to see Oauth2 in microservice architecturesecure-spring-boot-microservice
-
Maven 3.0+ is your build tool
-
Your favorite IDE but we will recommend
STS-4-4.4.1 version. We use STS. -
MySQL Server
-
JDK 1.8+
- First we need to run
eureka service - Second we need to run
item-servicandsales-service - Finally we need to run
gateway-service, if we did rungateway-servicebefore runningiteam-service, sales-servicethen we have to wait approximately 10 second
Eureka Server is an application that holds the information about all client-service applications. Every Micro service will register into the Eureka server and Eureka server knows all the client applications running on each port and IP address. Eureka Server is also known as Discovery Server.
we need to add @EnableEurekaServer annotation. The @EnableEurekaServer annotation is used to make your Spring Boot application acts as a Eureka Server.
@SpringBootApplication @EnableEurekaServer // Enable eureka server public class EurekaServerRunner { public static void main(String[] args) { SpringApplication.run(EurekaServerRunner.class, args); System.out.println("Eureka Server Started....!!"); } } Make sure Spring cloud Eureka server dependency is added in your build configuration file. The code for Maven user dependency is shown below −
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> By default, the Eureka Server registers itself into the discovery. You should add the below given configuration into your application.properties file or application.yml file.
# Give a name to the eureka server spring.application.name=eureka-server # default port for eureka server server.port=8761 # eureka by default will register itself as a client. So, we need to set it to false. # What's a client server? See other microservices (employee, user, etc). eureka.client.register-with-eureka=false eureka.client.fetch-registry=false click right button on the project >Run As >Spring Boot App
Eureka Discovery-Service URL: http://localhost:8761
A common problem, when building microservices, is to provide a unique gateway to the client applications of your system. The fact that your services are split into small microservices apps that shouldn’t be visible to users otherwise it may result in substantial development/maintenance efforts. Also there are scenarios when whole ecosystem network traffic may be passing through a single point which could impact the performance of the cluster.
Zuul has mainly four types of filters that enable us to intercept the traffic in different timeline of the request processing for any particular transaction. We can add any number of filters for a particular url pattern.
- pre filters – are invoked before the request is routed.
- post filters – are invoked after the request has been routed.
- route filters – are used to route the request.
- error filters – are invoked when an error occurs while handling the request.
Now add the @EnableZuulProxy and @EnableEurekaClient annotation on Spring boot application class present in src folder. With this annotation, this artifact will act like a Zuul service proxy and will enable all the features of a API gateway layer as described before. We will then add some filters and route configurations.
@SpringBootApplication @EnableZuulProxy @EnableEurekaClient public class ZuulApiGetWayRunner { public static void main(String[] args) { SpringApplication.run(ZuulApiGetWayRunner.class, args); System.out.println("Zuul server is running..."); } @Bean public PreFilter preFilter() { return new PreFilter(); } @Bean public PostFilter postFilter() { return new PostFilter(); } @Bean public ErrorFilter errorFilter() { return new ErrorFilter(); } @Bean public RouteFilter routeFilter() { return new RouteFilter(); } } Open application.properties and add below entries-
#Will start the gateway server @8180 server.port=8180 spring.application.name=zuul-server # Disable accessing services using service name (i.e. user-service). # They should be only accessed through the path defined below. zuul.ignored-services=* # Map paths to item service zuul.routes.item-server.path=/item-api/** zuul.routes.item-server.serviceId=item-server zuul.routes.item-server.stripPrefix=false # Map paths to sales service zuul.routes.sales-server.path=/sales-api/** zuul.routes.sales-server.serviceId=sales-server zuul.routes.sales-server.stripPrefix=false eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ eureka.instance.preferIpAddress=true eureka.instance.lease-expiration-duration-in-seconds=1 eureka.instance.lease-renewal-interval-in-seconds=2 ribbon.eager-load.enabled= true ribbon.ConnectTimeout= 30000 ribbon.ReadTimeout= 30000 We will now add few filters as we have already described, Zuul supports 4 types of filters namely pre,post,route, error and CORS . Here we will create each type of filters.
pre filter code – We will add the below pre filter. Currently filters are doing nothing apart from a println for testing purpose. But actually those are powerful enough to do many important aspects as mentioned before.
public class PreFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); System.out.println( "Request Method : " + request.getMethod() + " Request URL : " + request.getRequestURL().toString()); if (request.getHeader("Authorization") != null) { ctx.addZuulRequestHeader("Authorization", request.getHeader("Authorization")); } return null; } } public class PostFilter extends ZuulFilter { @Override public String filterType() { return "post"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { System.out.println("Inside Response Filter"); return null; } } public class RouteFilter extends ZuulFilter { @Override public String filterType() { return "route"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { System.out.println("Inside Route Filter"); return null; } } public class ErrorFilter extends ZuulFilter { @Override public String filterType() { return "error"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { System.out.println("Inside Route Filter"); return null; } } @Component @Order(Ordered.HIGHEST_PRECEDENCE) public class CORSFilter implements Filter { final static Logger logger = LoggerFactory.getLogger(CORSFilter.class); @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers"); if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } @Override public void init(FilterConfig filterConfig) { logger.info("Implementation not required"); } @Override public void destroy() { logger.info("Implementation not required"); } } click right button on the project >Run As >Spring Boot App
After sucessfully run we can refresh Eureka Discovery-Service URL: http://localhost:8761 will see zuul-server instance gate will be run on http://localhost:8180 port
Now we will see micro-item-service as a resource service. The micro-item-service a REST API that lets you CRUD (Create, Read, Update, and Delete) products. It creates a default set of items when the application loads using an ItemApplicationRunner bean.
Add the following dependencies:
- Web: Spring MVC and embedded Tomcat
- Actuator: features to help you monitor and manage your application
- EurekaClient: for service registration
- JPA: to save/retrieve data
- MySQL: to use store data on database
- RestRepositories: to expose JPA repositories as REST endpoints
- Hibernate validator: to use runtime exception handling and return error messages
Configure Application Name, Database Information and a few other configuration in properties file
server.port=8280 spring.application.name=item-server server.servlet.context-path=/item-api spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/item_service?useSSL=false&createDatabaseIfNotExist=true spring.datasource.username=[username] spring.datasource.password=[password] spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect spring.jpa.generate-ddl=true spring.jpa.show-sql=true #eureka server url eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.instance.preferIpAddress=true eureka.instance.lease-expiration-duration-in-seconds=1 eureka.instance.lease-renewal-interval-in-seconds=2 Now add the @SpringBootApplication and @EnableEurekaClient annotation on Spring boot application class present in src folder. With this annotation, this artifact will act like a eureka registry service.
click right button on the project >Run As >Spring Boot App
After sucessfully run we can refresh Eureka Discovery-Service URL: http://localhost:8761 will see item-service instance gate will be run on http://localhost:8280 port
curl --request GET http://localhost:8180/item-api/item/find here [http://localhost:8180/item-api/item/find] on the http means protocol, localhost for hostaddress 8180 are gateway service port because every api will be transmit by the gateway service, item-api are context path of item service and /item/find is method URL.
On this repository we will see simple-microservice-architecture.postman_collection.json file, this file have to import on postman then we will ses all API information for testing api.
Now we will see micro-sales-service as a resource service. The micro-sales-service a REST API that lets you CRUD (Create, Read, Update, and Delete) products. It creates a default set of products when the application loads using an SalesApplicationRunner bean.
Add the following dependencies:
- Web: Spring MVC and embedded Tomcat
- Actuator: features to help you monitor and manage your application
- EurekaClient: for service registration
- JPA: to save/retrieve data
- MySQL: to use store data on database
- RestRepositories: to expose JPA repositories as REST endpoints
- Hibernate validator: to use runtime exception handling and return error messages
Configure Application info, Database info and a few other configuration in properties file
server.port=8380 spring.application.name=sales-server server.servlet.context-path=/sales-api spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/sales_service?useSSL=false&createDatabaseIfNotExist=true spring.datasource.username=[usrename] spring.datasource.password=[password] spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect spring.jpa.generate-ddl=true spring.jpa.show-sql=true #eureka server url configuration eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ eureka.client.register-with-eureka=true eureka.client.fetch-registry=true eureka.instance.preferIpAddress=true eureka.instance.lease-expiration-duration-in-seconds=1 eureka.instance.lease-renewal-interval-in-seconds=2 Now add the @SpringBootApplication and @EnableEurekaClient annotation on Spring boot application class present in src folder. With this annotation, this artifact will act like a eureka registry service.
click right button on the project >Run As >Spring Boot App
After sucessfully run we can refresh Eureka Discovery-Service URL: http://localhost:8761 will see sales-service instance gate will be run on http://localhost:8380 port
curl --request GET http://localhost:8180/sales-api/sales/find here [http://localhost:8180/sales-api/sales/find] on the http means protocol, localhost for hostaddress 8180 are gateway service port because every api will be transmit by the gateway service, sales-api are application context path of sales service and /sales/find is method URL.
On this repository we will see simple-microservice-architecture.postman_collection.json file, this file have to import on postman then we will ses all API information for testing api.
After we seen start sales, item, zuul instance then we can try for getting information secure-microservice-architecture.postman_collection.json imported API from postman with token
After successfully run then we will refresh eureka dashboard and make sure to run item, sales and gateway on the eureka dashboard
Eureka Discovery-Service URL: http://localhost:8761
Below we will see how to configure oauth2 in microservice
To follow link secure-spring-boot-microservice


