Spring Cloud + Netflix Eureka(2021) Hello World Example | CodeUsingJava






















Spring Cloud with Netflix Eureka Server

In this tutorial we will be implementing Microservices architecture using spring cloud Netflix Eureka Server.
An Enterprise Application consist of a number of microservices. As the number of microservices in the aplication increase, the system becomes complex for the communication between them.
So there comes the need to store the addresses of all the service present with their port numbers.This is where Spring Cloud Eureka Server comes into existence.
Eureka Server is therefore also known as Discovery Server and the registered Services ae known as Eureka Client or Discovery Client.
Creating a project which includes the use of Eureka Server is similar like that of implementation of Microservices architecture. The main components required for building large microservices architecture applications includes the following:-
Eureka which is a service discovery
Ribbon which is responsible for load balancing
hysterix which is responsible for circuit breaker
Zuul which is responsible for effective routing.
  • The microservices architecture of Eureka Server and Eureka client can be represented by the following diagram:-
    Spring Cloud intro

    In this example, I would be creating two different services called employee service and the organisation service , both connected with a common medium known as Eureka Server.
    Spring Cloud intro

    Eureka Server

    Eureka Server acts as a Disvcovery Server where all the other microservices register themselves for smooth communication.
    Whenever two different microservices wants to communicate with each other, it is important for them to connect with Eureka Server firstly.
    The project structure for Eureka Server can be defined as follows-
    Spring Cloud server project structure
    We need to start by creating a Maven pom.xml(Project Object Model) file. The pom.xml file contains the project configuration details.
    	<?xml version="1.0" encoding="UTF-8"?>
    	<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    		<modelVersion>4.0.0</modelVersion>
    	
    		<groupId>com.codeusingjava</groupId>
    		<artifactId>EurekaServer</artifactId>
    		<version>0.0.1-SNAPSHOT</version>
    		<packaging>jar</packaging>
    	
    		<name>EurekaServer</name>
    		<description>Spring cloud with Netflix  Eureka Project</description>
    	
    		<parent>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-parent</artifactId>
    			<version>1.5.4.RELEASE</version>
    			<relativePath/> <!-- lookup parent from repository -->
    		</parent>
    	
    		<properties>
    			<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    			<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    			<java.version>1.8</java.version>
    			<spring-cloud.version>Dalston.SR1</spring-cloud.version>
    		</properties>
    	
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-actuator</artifactId>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-starter-eureka-server</artifactId>
    			</dependency>
    	
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-test</artifactId>
    				<scope>test</scope>
    			</dependency>
    		</dependencies>
    	
    		<dependencyManagement>
    			<dependencies>
    				<dependency>
    					<groupId>org.springframework.cloud</groupId>
    					<artifactId>spring-cloud-dependencies</artifactId>
    					<version>0</version>
    					<type>pom</type>
    					<scope>import</scope>
    				</dependency>
    			</dependencies>
    		</dependencyManagement>
    	
    		<build>
    			<plugins>
    				<plugin>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-maven-plugin</artifactId>
    				</plugin>
    			</plugins>
    		</build>
    	
    	
    	</project>
    	
    
    Creating configuration in application.yml as follows-
      server:
    	port: ${PORT:8761}
      
      eureka:
    	client:
    	  registerWithEureka: false
    	  fetchRegistry: false
    	server:
    	  waitTimeInMsWhenSyncEmpty: 0
      
    
    Creating another configuration file known as bootstrap.yml as follows-
    bootsrap.yml file loads before the application.yml. It consist of the properties which make the configuration server ready.On the other hand, the application.yml contains the properties specific to that of applications.
      spring:
    	application:
    	  name: eureka
       
    
    The main class for EurekaServer is as follows:-
    @EnableEurekaServer specifies that the application acts as a Eureka Server.
    	package com.codeusingjava.eurekaserver;
    
    	import org.springframework.boot.SpringApplication;
    	import org.springframework.boot.autoconfigure.SpringBootApplication;
    	import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
    	
    	@EnableEurekaServer
    	@SpringBootApplication
    	public class EurekaServerApplication {
    	
    		public static void main(String[] args) {
    			SpringApplication.run(EurekaServerApplication.class, args);
    		}
    	}
    	
    

    Client Configuration

    We have two client microservices which will register to the Eureka Server- Employee Microservice and Organization Microservice. Both the microservices will communicate with each other with the help of Eureka Server.

    Employee Microservice

    The project structure for the employee microservice is as follows-
    Spring Cloud client project structure
    The pom.xml for eureka client service is as follows:-
    Spring boot starter actuator dependency provides us with a number of endpoints by which application can be monitored effectively.
    		<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.example.howtodoinjava</groupId>
    	<artifactId>spring-eureka-client-student-service</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>EurekaClientEmpService</name>
    	<description>Spring cloud with Netflix Eureka</description>
    
    	<parent>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-parent</artifactId>
    		<version>1.5.4.RELEASE</version>
    		<relativePath/> <!-- lookup parent from repository -->
    	</parent>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    		<java.version>1.8</java.version>
    		<spring-cloud.version>Dalston.SR1</spring-cloud.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-actuator</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-eureka</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-data-rest</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-test</artifactId>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    
    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>0</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    			</plugin>
    		</plugins>
    	</build>
    
    
    </project>
    
    	
    The application.yml in the employee microservice is as follows:-
    server:
      port: 9001
    
    eureka:
      instance:
        leaseRenewalIntervalInSeconds: 1
        leaseExpirationDurationInSeconds: 2
      client:
        serviceUrl:
          defaultZone: http://127.0.0.1:8761/eureka/
    
    spring:
      application:
        name: employee-service
          
    management:
      security:
        enabled: false
    
    logging:
      level:
        com.codeusingjava: DEBUG
    	
    Creating the Employee model class as follows-
    It contains some of the important properties of an employee
    	
    	package com.codeusingjava.eurekaclientempservice.model;
    
    	public class Employee {
    		private String name;
    		private String designation;
    		
    		public String getName() {
    			return name;
    		}
    		public void setName(String name) {
    			this.name = name;
    		}
    		public String getDesignation() {
    			return designation;
    		}
    		public void setDesignation(String designation) {
    			this.designation = designation;
    		}
    		public Employee() {
    			super();
    			// TODO Auto-generated constructor stub
    		}
    		public Employee(String name, String designation) {
    			super();
    			this.name = name;
    			this.designation = designation;
    		}
    	
    		
    		
    	}
    	
    	
    
    Creating the helper class in the employee service.
    Whenever the service gets registered successfully to the Eureka Server, the following method customise the actuators info method. By this way, the info endpoint of our actuators can be represented in an effective manner.
    	package com.codeusingjava.eurekaclientempservice.helper;
    
    import java.util.Collections;
    
    import org.springframework.boot.actuate.info.Info;
    import org.springframework.boot.actuate.info.InfoContributor;
    import org.springframework.stereotype.Component;
    
    @Component
    public class EurekaClientEmpServiceContributor implements InfoContributor {
    
    	@Override
    	public void contribute(Info.Builder builder) {
    		builder.withDetail("details",
    				Collections.singletonMap("description", " It is Employee service,which is dicovery server aware!!! We can call this service by Org Microservice, which is again dicovery server aware!!! "));
    	}
    
    }
    
    
    Creating the controller class for in the employee service:-
    It contains the url that can be accessed by other microservices too.
    	package com.codeusingjava.eurekaclientempservice.controller;
    
    	import java.util.ArrayList;
    	import java.util.HashMap;
    	import java.util.List;
    	import java.util.Map;
    	
    	import org.springframework.web.bind.annotation.PathVariable;
    	import org.springframework.web.bind.annotation.RequestMapping;
    	import org.springframework.web.bind.annotation.RequestMethod;
    	import org.springframework.web.bind.annotation.RestController;
    	
    	import com.codeusingjava.eurekaclientempservice.model.Employee;
    	
    	@RestController
    	public class EmployeeServiceController {
    	
    		private static Map<String, List<Employee>> company = new HashMap<String, List<Employee>>();
    	
    		static {
    			company = new HashMap<String, List<Employee>>();
    	
    			List<Employee> record = new ArrayList<Employee>();
    			Employee e1 = new Employee("Rajesh Gopinathan", "CEO");
    			record.add(e1);
    			Employee e2 = new Employee("Nataraj Chandrashekharan", "Chairperson");
    	
    			record.add(e2);
    	
    			Employee e3 = new Employee("Samir Sekaria", "CFO");
    	
    			record.add(e3);
    	
    			company.put("Tata Consultancy Services", record);
    	
    			record = new ArrayList<Employee>();
    			e1 = new Employee("Salil Parekh", "CEO");
    			record.add(e1);
    			e2 = new Employee("NR Narayan Murthy", "Chairperson");
    			record.add(e2);
    			e3 = new Employee("Nilanjan Roy", "CFO");
    			record.add(e3);
    	
    			company.put("INFOSYS", record);
    	
    		}
    	
    		@RequestMapping(value = "/getEmployeeDetails/{companyname}", method = RequestMethod.GET)
    		public List<Employee> getEmployees(@PathVariable String companyname) {
    			System.out.println("Getting Employee details for " + companyname);
    	
    			List<Employee> empList = company.get(companyname);
    			if (empList == null) {
    				empList = new ArrayList<Employee>();
    				Employee std = new Employee("Not Found", "N/A");
    				empList.add(std);
    			}
    			return empList;
    		}
    	}
    	
    
    The main class for the eurekaclientempservice is as follows:-
    @EnableEurekaClient specifies that the the application is a Eureka client.
    package com.codeusingjava.eurekaclientempservice;
    
    	import org.springframework.boot.SpringApplication;
    	import org.springframework.boot.autoconfigure.SpringBootApplication;
    	import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    	
    	@SpringBootApplication
    	@EnableEurekaClient
    	public class EurekaClientEmpServiceApplication {
    	
    		public static void main(String[] args) {
    			SpringApplication.run(EurekaClientEmpServiceApplication.class, args);
    		}
    	}
    	
    

    Organisation Microservice

    It is a microservice which contains details of the organisatuion registered. We can also get the employee details of a particular organisation by this microservice.
    Spring Cloud client-org project structure
    The pom.xml for eureka client service is as follows:-
    		<?xml version="1.0" encoding="UTF-8"?>
    		<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    			xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    			<modelVersion>4.0.0</modelVersion>
    		
    			<groupId>com.example.howtodoinjava</groupId>
    			<artifactId>spring-eureka-client-school-service</artifactId>
    			<version>0.0.1-SNAPSHOT</version>
    			<packaging>jar</packaging>
    		
    			<name>Eureka-org-service</name>
    			<description>Spring cloud with Netflix Eureka</description>
    		
    			<parent>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-parent</artifactId>
    				<version>1.5.4.RELEASE</version>
    				<relativePath/> 
    			</parent>
    		
    			<properties>
    				<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    				<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    				<java.version>1.8</java.version>
    				<spring-cloud.version>Dalston.SR1</spring-cloud.version>
    			</properties>
    		
    			<dependencies>
    				<dependency>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-actuator</artifactId>
    				</dependency>
    				<dependency>
    					<groupId>org.springframework.cloud</groupId>
    					<artifactId>spring-cloud-starter-eureka</artifactId>
    				</dependency>
    				<dependency>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-data-rest</artifactId>
    				</dependency>
    				<dependency>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-web</artifactId>
    				</dependency>
    		
    				<dependency>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-test</artifactId>
    					<scope>test</scope>
    				</dependency>
    			</dependencies>
    		
    			<dependencyManagement>
    				<dependencies>
    					<dependency>
    						<groupId>org.springframework.cloud</groupId>
    						<artifactId>spring-cloud-dependencies</artifactId>
    						<version>0</version>
    						<type>pom</type>
    						<scope>import</scope>
    					</dependency>
    				</dependencies>
    			</dependencyManagement>
    		
    			<build>
    				<plugins>
    					<plugin>
    						<groupId>org.springframework.boot</groupId>
    						<artifactId>spring-boot-maven-plugin</artifactId>
    					</plugin>
    				</plugins>
    			</build>
    		
    		
    		</project>
    		
    
    	
    The application.yml in the organisation microservice is as follows:-
    server:
      port: 9000
    
    eureka:
      instance:
        leaseRenewalIntervalInSeconds: 1
        leaseExpirationDurationInSeconds: 2
      client:
        serviceUrl:
          defaultZone: http://127.0.0.1:8761/eureka/
    
    spring:
      application:
        name: Organisation-service
          
    management:
      security:
        enabled: false
    
    logging:
      level:
        com.codeusingjava: DEBUG
    	
    The controller class for the organization service is as follows:-
    The restTemplate is used for creating RESTful web applications. The exchange() method in the restTemplate effectively fulfills the web services for all http methods.
    	package com.codeusingjava.eurekaclientorgservice.controller;
    
    	import org.springframework.beans.factory.annotation.Autowired;
    	import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    	import org.springframework.context.annotation.Bean;
    	import org.springframework.core.ParameterizedTypeReference;
    	import org.springframework.http.HttpMethod;
    	import org.springframework.web.bind.annotation.PathVariable;
    	import org.springframework.web.bind.annotation.RequestMapping;
    	import org.springframework.web.bind.annotation.RequestMethod;
    	import org.springframework.web.bind.annotation.RestController;
    	import org.springframework.web.client.RestTemplate;
    	
    	@RestController
    	public class OrgServiceController {
    		@Autowired
    		RestTemplate restTemplate;
    	
    		@RequestMapping(value = "/getOrgDetails/{companyname}", method = RequestMethod.GET)
    		public String getStudents(@PathVariable String companyname) {
    			System.out.println("Getting School details for " + companyname);
    			String response = restTemplate.exchange("http://employee-service/getEmployeeDetails/{companyname}", HttpMethod.GET, null, new ParameterizedTypeReference() {
    			}, companyname).getBody();
    	
    			System.out.println("Response Received as " + response);
    	
    			return "Company Name -  " + companyname + " \n\n Employee Details " + response;
    		}
    	
    		@Bean
    		@LoadBalanced
    		public RestTemplate restTemplate() {
    			return new RestTemplate();
    		}
    	}
    		
    
    Run the following Spring Boot class for starting our application. This class contains the main method for the Organisation-service.
    @EnableEurekaClient annotation shows that the application acts as a eureka client.
    	package com.codeusingjava.eurekaclientorgservice;
    
    	import org.springframework.boot.SpringApplication;
    	import org.springframework.boot.autoconfigure.SpringBootApplication;
    	import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    	
    	@SpringBootApplication
    	@EnableEurekaClient
    	public class EurekaClientOrgServiceApplication {
    	
    		public static void main(String[] args) {
    			SpringApplication.run(EurekaClientOrgServiceApplication.class, args);
    		}
    	}
    	
    
    
    Run the applications
    First we need to run the eureka server as Spring boot Application.
    Then we need to run both the Eureka Client as Spring Boot Application.
    The output can be displayed as follows:-
    Spring Cloud Actuator
    If we click on the url of Employee Services. The customised info is shown by the helper class.
    info url
    Accessing the link as mentioned in the controller
    controller url
    We can see that the employee details can also be fetched successfully after registering both the services on Eureka Server.
    Org controller url

    Downloads-

    Spring Cloud + Eureka Hello World Example