TaskService Microservice

In this microservice, We can develop the microservice for creating the task and modification of the tasks and assigning the users and one more thing only admin can create the tasks and user unable to create the tasks.

Create the spring project using spring STS IDE on creating the spring project adding the below dependencies into the project.

Dependencies:

  • Spring Web
  • Netflix eureka client server
  • OpenFeign
  • Spring data for mongodb
  • Spring Actuator
  • Spring Dev Tools
  • Zipkin Server
  • Lombok

Once the create the project including mention dependencies into the project then file structure look like below the image.

File Structure:

Open the application.properties file and put the below code for data base configuration and server port assigning the project.

server.port=8082
spring.data.mongodb.uri=mongodb://localhost:27017/userData
spring.application.name= TASK-SERVICE
#eureka server configuration
eureka.instance.prefer-ip-address=true
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.service-url.defaultZone = http://localhost:8085/eureka
#Zipkin server configuration
spring.zipkin.base-url=http://localhost:9411
spring.sleuth.sampler.probability=1.0

Step 1: Create the package in in.mahesh.tasks location and it named as the taskModel. In taskModel, Create the class named as Task.

Go to src > java > in.mahesh.tasks > TaskModel > Task and put the below code:

Java




package in.mahesh.tasks.taskModel;
  
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
  
import com.fasterxml.jackson.annotation.JsonFormat;
  
import in.mahesh.tasks.enums.TaskStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
  
@Data
@Document(collection="Tasks")
@AllArgsConstructor
@NoArgsConstructor
public class Task {
      
    @Id
    private String id;
    private String title;
    private String description;
    private String imageUrl;
    private String assignedUserId;
      
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private TaskStatus status;
  
    private LocalDateTime deadline;
    private LocalDateTime createAt;
  
    private List<String> tags = new ArrayList<>();
  
    public String getId() {
        return id;
    }
  
    public void setId(String id) {
        this.id = id;
    }
  
    public String getTitle() {
        return title;
    }
  
    public void setTitle(String title) {
        this.title = title;
    }
  
    public String getDescription() {
        return description;
    }
  
    public void setDescription(String description) {
        this.description = description;
    }
  
    public String getImageUrl() {
        return imageUrl;
    }
  
    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
  
    public String getAssignedUserId() {
        return assignedUserId;
    }
  
    public void setAssignedUserId(String assignedUserId) {
        this.assignedUserId = assignedUserId;
    }
  
  
    public LocalDateTime getDeadline() {
        return deadline;
    }
  
    public void setDeadline(LocalDateTime deadline) {
        this.deadline = deadline;
    }
  
    public LocalDateTime getCreateAt() {
        return createAt;
    }
  
    public void setCreateAt(LocalDateTime createAt) {
        this.createAt = createAt;
    }
  
    public List<String> getTags() {
        return tags;
    }
  
    public void setTags(List<String> tags) {
        this.tags = tags;
    }
  
    public TaskStatus getStatus() {
        return status;
    }
  
    public void setStatus(TaskStatus status) {
        this.status = status;
    }
      
}


Step 2: In taskModel, Create the one more class named as UserDTO

Go to src > java > in.mahesh.tasks > TaskModel > UserDTO and put the below code:

Java




package in.mahesh.tasks.taskModel;
  
  
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
  
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {
  
  
    private String id;
    private String fullName;
    private String email;
    private String password;
    private String role;
    private String mobile;
      
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getFullName() {
        return fullName;
    }
    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public String getMobile() {
        return mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }
       
}


Step 3: Create the package in in.mahesh.tasks location and it named as the enums. In enums, Create the enum named as TaskStatus.

Go to src > java > in.mahesh.tasks > TaskModel > enums > TaskStatus and put the below code:

Java




package in.mahesh.tasks.enums;
  
import com.fasterxml.jackson.annotation.JsonFormat;
  
@JsonFormat(shape = JsonFormat.Shape.STRING)
public enum TaskStatus {
     PENDING("PENDING"),
        ASSIGNED("ASSIGNED"),
        DONE("DONE");
  
  
    private final String name;
  
    TaskStatus (String name) {
        this.name = name;
    }
  
    public String getName() {
        return name;
    }
}


Step 4: Create the package in in.mahesh.tasks location and it named as the repository. In repository, Create the interface named as TaskRepository.

Go to src > java > in.mahesh.tasks > repository> TaskRepository and put the below code:

Java




package in.mahesh.tasks.repository;
  
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
  
import in.mahesh.tasks.taskModel.Task;
  
import java.util.List;
import java.util.Optional;
  
@Repository
  
public interface TaskRepository extends MongoRepository<Task,String> {
    
  
    public List<Task> findByassignedUserId(String userId);
  
    public void deleteById(String id);
  
  
     public Task getTaskById(String id);
  
      
  
}


Step 5: Create the package in in.mahesh.tasks location and it named as the service. In service, Create the class named as TaskService.

Go to src > java > in.mahesh.tasks > service> TaskService and put the below code:

Java




package in.mahesh.tasks.service;
  
import java.util.List;
  
import in.mahesh.tasks.enums.TaskStatus;
import in.mahesh.tasks.taskModel.Task;
  
public interface TaskService {
    Task create(Task task, String requestRole) throws Exception;
      
    Task getTaskById(String id) throws Exception;
      
    List<Task> getAllTasks(TaskStatus taskStatus, String sortByDeadline, String sortByCreatedAt);
      
    Task updateTask(String id, Task updatedTask, String userId) throws Exception;
      
    void deleteTask(String id) throws Exception;
      
    Task assignedToUser(String userId, String id) throws Exception;
      
    List<Task> assignedUsersTask(String userId, TaskStatus taskStatus, String sortByDeadline, String sortByCreatedAt);
      
    Task completeTask(String taskId) throws Exception;
      
      
  
}


Step 6: In service, Create the class named as TaskServiceImplementation.

Go to src > java > in.mahesh.tasks > service> TaskServiceImplementation and put the below code:

Java




package in.mahesh.tasks.service;
  
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
  
import org.springframework.beans.factory.annotation.Autowired;
  
import in.mahesh.tasks.enums.TaskStatus;
import in.mahesh.tasks.repository.TaskRepository;
import in.mahesh.tasks.taskModel.Task;
import org.springframework.stereotype.Service;
  
@Service
public class TaskServiceImplementation implements TaskService {
      
    @Autowired
    private TaskRepository taskRepository;
     public TaskServiceImplementation(TaskRepository taskRepository) {
            this.taskRepository = taskRepository;
        }
  
    @Override
    public Task create(Task task, String requestRole) throws Exception {
        if (!requestRole.equals("ROLE_ADMIN")) {
            throw new Exception("Only admin can create tasks");
        }
  
        task.setStatus(TaskStatus.PENDING);
        task.setCreateAt(LocalDateTime.now());
  
        return taskRepository.save(task);
    }
  
    @Override
    public Task getTaskById(String id) {
        return taskRepository.findById(id)
                             .orElse(null); // Return null if task is not found
    }
  
       
  
  
    public List<Task> getAllTasks(TaskStatus taskStatus) {
        List<Task> allTasks = taskRepository.findAll();
  
        List<Task> fliteredTasks = allTasks.stream().filter(
                task -> taskStatus == null || task.getStatus().name().equalsIgnoreCase(taskStatus.toString())
  
        ).collect(Collectors.toList());
        // TODO Auto-generated method stub
        return fliteredTasks;
    }
  
    @Override
    public Task updateTask(String id, Task updatedTask, String userId) throws Exception {
        Task existingTasks = getTaskById(id);
        if(updatedTask.getTitle() != null) {
            existingTasks.setTitle(updatedTask.getTitle());
        }
        if(updatedTask.getImageUrl() != null) {
            existingTasks.setImageUrl(updatedTask.getImageUrl());
        }
        if (updatedTask.getDescription() != null) {
            existingTasks.setDescription(updatedTask.getDescription());
        }
          
          if (updatedTask.getStatus() != null) {
          existingTasks.setStatus(updatedTask.getStatus()); }
           
        if (updatedTask.getDeadline() != null) {
            existingTasks.setDeadline(updatedTask.getDeadline());
        }
  
        return taskRepository.save(existingTasks);
    }
  
    @Override
    public void deleteTask(String id) throws Exception {
        getTaskById(id);
        taskRepository.deleteById(id);
  
          
    }
  
    @Override
    public Task assignedToUser(String userId, String taskId) throws Exception {
        Task task = getTaskById(taskId);
        task.setAssignedUserId(userId);
        task.setStatus(TaskStatus.DONE);
  
        return taskRepository.save(task);
    }
  
      
      
    public List<Task> assignedUsersTask(String userId, TaskStatus taskStatus) {
        List<Task> allTasks = taskRepository.findByassignedUserId(userId);
  
        return allTasks.stream()
                .filter(task -> taskStatus == null || task.getStatus() == taskStatus)
                .collect(Collectors.toList());
    }
  
    @Override
    public Task completeTask(String taskId) throws Exception {
        Task task = getTaskById(taskId);
        task.setStatus(TaskStatus.DONE);
  
        // TODO Auto-generated method stub
        return taskRepository.save(task);
    }
  
    @Override
    public List<Task> getAllTasks(TaskStatus taskStatus, String sortByDeadline, String sortByCreatedAt) {
        // TODO Auto-generated method stub
        return null;
    }
  
     public List<Task> assignedUsersTask(String userId,TaskStatus status, String sortByDeadline, String sortByCreatedAt) {
            List<Task> allTasks = taskRepository.findByassignedUserId(userId);
  
  
            List<Task> filteredTasks = allTasks.stream()
                    .filter(task -> status == null || task.getStatus().name().equalsIgnoreCase(status.toString()))
  
  
                    .collect(Collectors.toList());
  
  
            if (sortByDeadline != null && !sortByDeadline.isEmpty()) {
                filteredTasks.sort(Comparator.comparing(Task::getDeadline));
            } else if (sortByCreatedAt != null && !sortByCreatedAt.isEmpty()) {
               // filteredTasks.sort(Comparator.comparing(Task::getCreatedAt));
            }
  
            return filteredTasks;
  
        }
  
}


Step 7: In service, Create the class named as UserService.

Go to src > java > in.mahesh.tasks > service> UserService and put the below code:

Java




package in.mahesh.tasks.service;
  
  
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
  
import in.mahesh.tasks.taskModel.UserDTO;
  
//connect with taskUserService microService
@FeignClient(name = "user-SERVICE",url = "http://localhost:8081")
public interface UserService { 
  
    @GetMapping("/api/users/profile")
    public UserDTO getUserProfileHandler(@RequestHeader("Authorization") String jwt);
}


Step 8: Create the package in in.mahesh.tasks location and it named as the controller. In controller, Create the class named as HomeController.

Go to src > java > in.mahesh.tasks > controller > HomeController and put the below code:

Java




package in.mahesh.tasks.controller;
  
  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
  
import in.mahesh.tasks.service.UserService;
  
@RestController
public class HomeController {
  
    @GetMapping("/tasks")
    public ResponseEntity<String> HomeController() {
          
        return new ResponseEntity<>("Welcome to task Service", HttpStatus.OK);
  
    }
}


Step 9: In Controller, Create the class named as TaskController.

Go to src > java > in.mahesh.tasks > controller > TaskController and put the below code:

Java




package in.mahesh.tasks.controller;
  
import in.mahesh.tasks.enums.TaskStatus;
import in.mahesh.tasks.service.TaskService;
import in.mahesh.tasks.service.UserService;
import in.mahesh.tasks.taskModel.Task;
import in.mahesh.tasks.taskModel.UserDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
  
import java.util.List;
  
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
  
      private TaskService taskService;
        private UserService userService;
  
        @Autowired
        public TaskController(TaskService taskService, UserService userService) {
            this.taskService = taskService;
            this.userService=userService;
        }
  
    // create Task API
  
    @PostMapping
    public ResponseEntity<Task> createTask(@RequestBody Task task, @RequestHeader("Authorization") String jwt)
            throws Exception {
          
         if(jwt==null){
                throw new Exception("jwt required...");
            }
        UserDTO user = userService.getUserProfileHandler(jwt);
        Task createdTask = taskService.create(task, user.getRole());
  
        return new ResponseEntity<>(createdTask, HttpStatus.CREATED);
  
    }
  
    @GetMapping("/{id}")
    public ResponseEntity<Task> getTaskById(@PathVariable String id, @RequestHeader("Authorization") String jwt)
            throws Exception {
         if(jwt==null){
                throw new Exception("jwt required...");
            }
          
        //UserDTO user = userService.getUserProfile(jwt);
        Task task = taskService.getTaskById(id);
  
        //return new ResponseEntity<>(task, HttpStatus.OK);
        return task != null ? new ResponseEntity<>(task, HttpStatus.OK) : new ResponseEntity<>(HttpStatus.NOT_FOUND);
  
    }
  
     @GetMapping("/user")
        public ResponseEntity< List<Task> > getAssignedUsersTask(
                @RequestHeader("Authorization") String jwt,
                @RequestParam(required = false) TaskStatus status,
                @RequestParam(required = false) String sortByDeadline,
                @RequestParam(required = false) String sortByCreatedAt) throws Exception {
            UserDTO user=userService.getUserProfileHandler(jwt);
            List<Task> tasks = taskService.assignedUsersTask(user.getId(),status, sortByDeadline, sortByCreatedAt);
            return new ResponseEntity<>(tasks, HttpStatus.OK);
        }
      
  
    /*
     * Test with Posman with Post Method http://localhost:8082/api/tasks requestBody
     * and gobal config with JWT { "title":"New Website Creation using springBoot",
     * "image":"https://www.image.com/dhdbhjf.png",
     * "description":"Do it this Website as soon as possible ",
     * "deadline":"2024-02-29T12:34:38.9056991 " } reponse { "id":
     * "65b913d02071402a82b2f9b8", "title": "New Website Creation using springBoot",
     * "description": "Do it this Website as soon as possible ", "imageUrl": null,
     * "assignedUserId": 0, "status": "PENDING", "deadline":
     * "2024-02-29T12:34:38.9056991", "createAt": "2024-01-30T20:50:48.2276611" }
     */
  
      
  
     @GetMapping
        public ResponseEntity<List<Task>> getAllTasks(
                @RequestHeader("Authorization") String jwt,
                @RequestParam(required = false) TaskStatus status,
                @RequestParam(required = false) String sortByDeadline,
                @RequestParam(required = false) String sortByCreatedAt
        ) throws Exception {
            if(jwt==null){
                throw new Exception("jwt required...");
            }
            List<Task> tasks = taskService.getAllTasks(status, sortByDeadline, sortByCreatedAt);
            return new ResponseEntity<>(tasks, HttpStatus.OK);
        }
       
        @PutMapping("/{id}/user/{userId}/assigned")
        public ResponseEntity<Task> assignedTaskToUser(
                @PathVariable String id,
                @PathVariable String userId,
                @RequestHeader("Authorization") String jwt
        ) throws Exception {
            UserDTO user=userService.getUserProfileHandler(jwt);
            Task task = taskService.assignedToUser(userId,id);
            return new ResponseEntity<>(task, HttpStatus.OK);
        }
  
        @PutMapping("/{id}")
        public ResponseEntity<Task> updateTask(
                @PathVariable String id,
                @RequestBody Task req,
                @RequestHeader("Authorization") String jwt
        ) throws Exception {
            if(jwt==null){
                throw new Exception("jwt required...");
            }
            UserDTO user=userService.getUserProfileHandler(jwt);
            Task task = taskService.updateTask(id, req, user.getId());
            return task != null ? new ResponseEntity<>(task, HttpStatus.OK) : new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
  
        @DeleteMapping("/{id}")
        public ResponseEntity<Void> deleteTask(@PathVariable String id) {
            try {
                taskService.deleteTask(id);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
  
        @PutMapping("/{id}/complete")
        public ResponseEntity<Task> completeTask(@PathVariable String id) throws Exception {
            Task task = taskService.completeTask(id);
            return new ResponseEntity<>(task, HttpStatus.NO_CONTENT);
        }
}


Step 10: Once completed the project and it run the application as spring project and once it will run successfully and then project runs as port number 8082. Refer the below image for the better understanding.

Endpoint of the TaskService microservice:

Methods

Endpoints

POST

http://localhost:8082/api/tasks

GET

http://localhost:8082/api/tasks/{id}

GET

http://localhost:8082/api/tasks/user

PUT

http://localhost:8082/api/tasks/{id}

GET

http://localhost:8082/

PUT

http://localhost:8082/api/tasks/{id}/user/{userId}/assigned

PUT

http://localhost:8082/api/tasks/{id}/complete

DELETE

http://localhost:8082/api/tasks/{id}

Refer the below Images:

Create the Task:

Get the Task by TaskId:

Get All Tasks:

Create a Backend Task Management System using Microservices

Microservices is an architectural pattern, and its approach can be used in software development where the large applications are built as a collection of loosely coupled and independent deployable services. All microservices communicate with each other using a well-defined API, typically using lightweight protocols using HTTP.

Developing the backend task management system using microservices involves breaking down the smaller functionalities into independent services that can communicate with each other using the eureka server and implementing the API Gateway for routing client requests.

In this project, we can develop the 5 individual microservices and communicate with each other.

  • Task User Service
  • Task Creation Service
  • Task Submission Service
  • Eureka Server configuration
  • API Gateway

TaskUserService:

In this microservice, we can develop the microservice for responsible for managing the user-related operations such as user authentication, authorization and user profile management. In this service we can develop the USER and ADMIN role then admin can be able to create the tasks and approve the tasks of the user.

TaskCreationService:

In this microservice, we can develop the microservice for creating the task and modification of the tasks and assigning the users and one more thing only admin can create the tasks and user unable to create the tasks.

TaskSubmissionService:

In this microservice, we can develop the microservice can be manages the submission of the tasks by users and handles the related functionalities such as validation and processing.

EurekaServerConfiguration:

In this microservice, we can develop the microservice and it can be used to establish the communication of the microservices using eureka server using discovery client and server with communicates with each dynamically.

APIGatway:

In this microservice, we can develop the microservice and it can be used to API Gateway and establish the routing the client requests of the system.

Similar Reads

TaskUserService Microservice:

In this microservice, we can develop the microservice for responsible for managing the user-related operations such as user authentication, authorization and user profile management. In this service we can develop the USER and ADMIN role then admin can able to create the tasks and approve the tasks of the user....

TaskService Microservice

...

TaskSubmissionService Microservice:

...

EurekaServerConfiguration microservice:

...

APIGatway microservice:

...

Contact Us