Spring Cloud Consul Service and Discovery(2021) Hello World Example | CodeUsingJava






















Spring Cloud Consul Service and Discovery

In this tutorial we will be implementing a Spring Cloud Consul using Spring Cloud.
Consul is one of the products of HashiCorp. Spring consul provides an easy way by which one can register instances as consul agent and that instances can be further discovered by clients using spring beans. There are sveral features provided by consul. Some of them includes configuration management with the use of Key/Value store , health checking etc. are provided by the consul.
Let us understand by a sceanerio of a system without the consul and a system using consul.
Sceanerio without consul
Case 1- Services without consul
Sceanerio with consul
Case 2- Services with consul
We can clearly see that with the help of consul, a centralised configuration can be done. Multiple environment support is provided by the consul.Consul also provides the benifit of instance update.
Firstly we need to download the consul agent. Now we need to find the ip address of our system.
Now run the following command in command prompt.
consullog
Now run the following url
http://localhost:8500/ui/dc1/services
You would see the consul running. Now we create the spring boot project and register their instance in the consul.
we will create two services and register their instances in consul.
  • Info

    This will be the standard directory layout for maven project structure-
    Info Maven Project
    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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    		<modelVersion>4.0.0</modelVersion>
    		<parent>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-parent</artifactId>
    			<version>2.1.4.RELEASE</version>
    			<relativePath/> <!-- lookup parent from repository -->
    		</parent>
    		<groupId>com.javatechie</groupId>
    		<artifactId>info-service</artifactId>
    		<version>0.0.1-SNAPSHOT</version>
    		<name>info-service</name>
    		<description>Demo project for Spring Boot</description>
    	
    		<properties>
    			<java.version>1.8</java.version>
    			<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    		</properties>
    	
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-web</artifactId>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-starter-consul-discovery</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.properties file is as follows- Here we define the name for which the service will be registered in the consul.
    	spring.application.name=Info-service
    	server.port=8889
    	
    
    The main class can be defined as follows-
    	package com.codeusingjava;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    @RestController
    public class DemoApplication {
    	@GetMapping("/test")
    	public String getApp() {
    		return "Finally you have achieved your goal";
    	}
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    	}
    
    }
    

    InfoReceiver

    The project structure for the service is as follows-
    InfoReceiver Maven Project
    The standard pom.xml file can be defined 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>
    		<parent>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-parent</artifactId>
    			<version>2.1.4.RELEASE</version>
    			<relativePath/> <!-- lookup parent from repository -->
    		</parent>
    		<groupId>com.codeusingjava</groupId>
    		<artifactId>inforeceiver</artifactId>
    		<version>0.0.1-SNAPSHOT</version>
    		<name>user-service</name>
    		<description>Spring cloud consul</description>
    	
    		<properties>
    			<java.version>1.8</java.version>
    			<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    		</properties>
    	
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-starter-web</artifactId>
    			</dependency>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-starter-consul-discovery</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.properties file for the service camn be defined as follows-
    spring.application.name=info-receiver
    server.port=8890
    
    The main class for the InfoReceiver can be defined as follows-
    EnableDiscoveryClient annotation is implemented when working on consul. We can use this annotation with any of the DiscoveryClient.
    package com.codeusingjava.consul;
    
    import java.net.URI;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    @RestController
    public class InfoReceiverApplication {
    
    	@Autowired
    	private RestTemplate template;
    
    	@Autowired
    	private DiscoveryClient client;
    
    	@GetMapping("/getInfo")
    	public String invokeGreetingService() {
    		URI geturi = client.getInstances("Info-service").stream().map(si -> si.getUri()).findFirst()
    				.map(s -> s.resolve("/test")).get();
    		return template.getForObject(geturi, String.class);
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(InfoReceiverApplication.class, args);
    	}
    
    	@Bean
    	public RestTemplate template() {
    		return new RestTemplate();
    	}
    }
    
    
If we now run the application we get the output as follows
Run the application
Firstly run Info-service as spring boot application.
Now run the info-receiver as spring boot application.
Refresh the above url. Both the instances of the service will be registered.
Now run the following url and see the output. The output will be displayed only when both the instances are successfully registered.
The consul output is as follows:
consul output

api output

Downloads-

Spring Cloud + Consul Hello World Example