Open In App

Spring Cloud Zookeeper

Last Updated : 06 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

For Spring Boot applications, Zookeeper integrates via autoconfiguration, binding to the Spring Environment, and other Spring programming models. Building massively distributed systems with Zookeeper-based components is made possible with just a few annotations to enable and define common patterns within our application.

In this article, we will learn to implement Zookeeper in Spring Cloud by following the steps.

Implementation of Spring Cloud Zookeeper

Below are the steps to implement Zookeeper in Spring Cloud.

Step 1: Add Maven Dependencies

Let’s start by adding to our pom.xml file the necessary spring-cloud-starter-zookeeper-discovery, spring-cloud-starter-feign dependencies.

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>

Step 2: Annotate main class with @EnableDiscoveryClient

Next, we will add @EnableDiscoveryClient annotations to our main class. This will enable discovery awareness for the application:

Java




import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
  
/**
 * Spring Boot Application for the Employee Service.
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EmployeeServiceApplication 
{
      
    /**
     * Main method to start the Spring Boot Application.
     
     * @param args the command-line arguments
     */
    public static void main(String args[]) 
    {
        SpringApplication.run(EmployeeServiceApplication.class, args);
    }
}


Step 3: Use the Spring Cloud Feign Integration

To access this service programmatically, we autowire an interface with @FeignClient(“service-name”) and annotate it. Here, we are referring to the service-name of the service producer we previously defined in the annotation @FeignClient(name = “DepartmentService”).

Java




import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
  
/**
 * Feign client interface to communicate with the Department Service.
 */
@FeignClient(name = "DepartmentService")
public interface DepartmentServiceClient {
  
    /**
     * Retrieves the department by its ID.
     
     * @param id the ID of the department
     * @return the department
     */
    @GetMapping("/departments/{id}")
    Department getDepartmentById(@PathVariable("id") Long id);
}


Step 4: Create a Service Class to manage Employees

To manage employees, we need to create one service class where employee details will be fetched from the database.

Java




/**
 * Service class to manage employee-related functionality.
 */
@Service
public class EmployeeService 
{
  
    @Autowired
    private DepartmentServiceClient departmentServiceClient;
  
    /**
     * Retrieves an employee by their ID.
     
     * @param id the ID of the employee
     * @return the employee
     */
    public Employee getEmployeeById(Long id) 
    {
        // Simulate fetching employee details from a database
        Employee employee = new Employee();
        employee.setId(id);
        employee.setFirstName("Sweta");
        employee.setLastName("Dash");
  
        // Use Feign client to get department details
        Long departmentId = 217AS; // Assuming a department ID
        Department department = departmentServiceClient.getDepartmentById(departmentId);
  
        // Set department details in employee object
        employee.setDepartment(department);
  
        return employee;
    }
}


Step 5: Construct a Controller Class

This is the basic service controller class that will use the injected interface employeeService object to call the service provider method on our faux client class, consuming the service (details abstracted using service discovery) and displaying the result:

Java




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
  
/**
 * Controller class to handle employee-related HTTP requests.
 */
@RestController
@RequestMapping("/employees")
public class EmployeeController {
  
    @Autowired
    private EmployeeService employeeService;
  
    /**
     * Retrieves an employee by their ID.
     
     * @param id the ID of the employee
     * @return the employee
     */
    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable("id") Long id) {
        return employeeService.getEmployeeById(id);
    }
}


Step 6: Create Department Class

Java




public class Department {
    private Long id;
    private String name;
  
    public Long getId() {
        return id;
    }
  
    public void setId(Long id) {
        this.id = id;
    }
  
    public String getName() {
        return name;
    }
  
    public void setName(String name) {
        this.name = name;
    }
}


Step 7: Create Employee Class

Java




public class Employee {
    private Long id;
    private String firstName;
    private String lastName;
    private Department department;
  
    public Long getId() {
        return id;
    }
  
    public void setId(Long id) {
        this.id = id;
    }
  
    public String getFirstName() {
        return firstName;
    }
  
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
  
    public String getLastName() {
        return lastName;
    }
  
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
  
    public Department getDepartment() {
        return department;
    }
  
    public void setDepartment(Department department) {
        this.department = department;
    }
}


Step 8: Create a YAML file Application

Then we will configure the Zookeeper in an application in YAML format. The application uses port 2181 by default to search for the Zookeeper. Should Zookeeper be situated elsewhere, the following configuration must be added:

application.yml:

spring:
cloud:
zookeeper:
connect-string: localhost:2181
discovery:
enabled: true
root: /services
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}

bootstrap.yml:

spring:
application:
name: employee-service
  • After setting up the Zookeeper server and running, run the Employee service. It should register with Zookeeper and be ready to handle requests.
  • Then we will test our Service by making a GET request to http://localhost:8080/employees/{id} and verify that the employee details are returned along with the department details.

Apache Curator is used by Spring Cloud Zookeeper. Although the Zookeeper development team still refers to Zookeeper 3.5.x as “beta,” many users actually utilize it in production.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads