diff --git a/pom.xml b/pom.xml
index b0a6389..d72f7b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,41 +1,80 @@
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 2.6.3
-
-
- com.accenture.codingtest
- spring-boot-coding-test
- 0.0.1-SNAPSHOT
- spring-boot-coding-test
- Demo project for Spring Boot
-
- 11
-
-
-
- org.springframework.boot
- spring-boot-starter
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.6.3
+
+
+ com.accenture.codingtest
+ spring-boot-coding-test
+ 0.0.1-SNAPSHOT
+ spring-boot-coding-test
+ Demo project for Spring Boot
+
+ 11
+ Hoxton.SR6
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.projectlombok
+ lombok
+ 1.18.26
+ compile
+
+
+ org.modelmapper
+ modelmapper
+ 3.1.1
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.cloud
+ spring-cloud-starter-oauth2
+
+
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/SpringBootCodingTestApplication.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/SpringBootCodingTestApplication.java
index 14e2bbf..7c974c7 100644
--- a/src/main/java/com/accenture/codingtest/springbootcodingtest/SpringBootCodingTestApplication.java
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/SpringBootCodingTestApplication.java
@@ -1,13 +1,20 @@
package com.accenture.codingtest.springbootcodingtest;
+import org.modelmapper.ModelMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringBootCodingTestApplication {
- public static void main(String[] args) {
- SpringApplication.run(SpringBootCodingTestApplication.class, args);
- }
+ public static void main(String[] args) {
+ SpringApplication.run(SpringBootCodingTestApplication.class, args);
+ }
+
+ @Bean
+ public ModelMapper modelMapper() {
+ return new ModelMapper();
+ }
}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/config/WebSecurityConfiguration.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/config/WebSecurityConfiguration.java
new file mode 100644
index 0000000..2223b17
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/config/WebSecurityConfiguration.java
@@ -0,0 +1,73 @@
+package com.accenture.codingtest.springbootcodingtest.config;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.factory.PasswordEncoderFactories;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+
+
+@Configuration
+@EnableWebSecurity
+public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ private UserDetailsService userDetailsService;
+
+ @Bean
+ protected AuthenticationManager getAuthenticationManager() throws Exception {
+ return super.authenticationManager();
+ }
+
+ @Bean
+ PasswordEncoder passwordEncoder() {
+ return PasswordEncoderFactories.createDelegatingPasswordEncoder();
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = new CorsConfiguration();
+ config.setAllowCredentials(true);
+ config.addAllowedOrigin("*");
+ config.addAllowedHeader("*");
+ config.addAllowedMethod("OPTIONS");
+ config.addAllowedMethod("GET");
+ config.addAllowedMethod("POST");
+ config.addAllowedMethod("PUT");
+ config.addAllowedMethod("PATCH");
+ config.addAllowedMethod("DELETE");
+ source.registerCorsConfiguration("/**", config);
+ return new CorsFilter(source);
+ }
+
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
+
+ }
+
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.csrf().disable()
+ .authorizeRequests().antMatchers("/v1/**")
+ .permitAll()
+ .antMatchers("/v1/User/**").access("hasRole('ROLE_ADMIN')")
+ .antMatchers("/v1/Task/**", "/v1/Project/**").access("hasRole('ROLE_PROJECT_OWNER')");
+ }
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/ProjectController.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/ProjectController.java
new file mode 100644
index 0000000..37d3ead
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/ProjectController.java
@@ -0,0 +1,53 @@
+package com.accenture.codingtest.springbootcodingtest.controller;
+
+import com.accenture.codingtest.springbootcodingtest.model.ProjectDto;
+import com.accenture.codingtest.springbootcodingtest.service.ProjectService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/api/v1/projects")
+@RequiredArgsConstructor
+public class ProjectController {
+ private final ProjectService projectService;
+
+ @GetMapping
+ public Collection findAll() {
+ return projectService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ public ProjectDto findById(@PathVariable("id") String id) {
+ return projectService.findById(UUID.fromString(id));
+ }
+
+ @PostMapping("/")
+ @PreAuthorize("hasAuthority('ROLE_PRODUCT_OWNER')")
+ public ProjectDto create(@RequestBody ProjectDto projectDto) {
+ return projectService.create(projectDto);
+ }
+
+ @PutMapping("/{id}")
+ public ProjectDto update(@PathVariable("id") String id, @RequestBody ProjectDto projectDto) {
+ return projectService.update(UUID.fromString(id), projectDto);
+ }
+
+ @PatchMapping("/{id}")
+ public ProjectDto updatePartially(@PathVariable("id") String id, @RequestBody ProjectDto projectDto) {
+ return projectService.updatePartially(UUID.fromString(id), projectDto);
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteById(@PathVariable("id") String id) {
+ projectService.deleteById(UUID.fromString(id));
+ return ResponseEntity.ok().build();
+ }
+
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/TaskController.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/TaskController.java
new file mode 100644
index 0000000..2aad6ba
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/TaskController.java
@@ -0,0 +1,53 @@
+package com.accenture.codingtest.springbootcodingtest.controller;
+
+import com.accenture.codingtest.springbootcodingtest.model.TaskDto;
+import com.accenture.codingtest.springbootcodingtest.service.TaskService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/api/v1/tasks")
+@RequiredArgsConstructor
+public class TaskController {
+ private final TaskService taskService;
+
+ @GetMapping
+ public Collection findAll() {
+ return taskService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ public TaskDto findById(@PathVariable("id") String id) {
+ return taskService.findById(UUID.fromString(id));
+ }
+
+ @PostMapping("/")
+ @PreAuthorize("hasAuthority('ROLE_PRODUCT_OWNER')")
+ public TaskDto create(@RequestBody TaskDto taskDto) {
+ return taskService.create(taskDto);
+ }
+
+ @PutMapping("/{id}")
+ public TaskDto update(@PathVariable("id") String id, @RequestBody TaskDto taskDto) {
+ return taskService.update(UUID.fromString(id), taskDto);
+ }
+
+ @PatchMapping("/{id}")
+ @PreAuthorize("hasAuthority('ROLE_PRODUCT_OWNER')")
+ public TaskDto updatePartially(@PathVariable("id") String id, @RequestBody TaskDto taskDto) {
+ return taskService.updatePartially(UUID.fromString(id), taskDto);
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteById(@PathVariable("id") String id) {
+ taskService.deleteById(UUID.fromString(id));
+ return ResponseEntity.ok().build();
+ }
+
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/UserController.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/UserController.java
new file mode 100644
index 0000000..8bffbcb
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/UserController.java
@@ -0,0 +1,55 @@
+package com.accenture.codingtest.springbootcodingtest.controller;
+
+import com.accenture.codingtest.springbootcodingtest.model.UserDto;
+import com.accenture.codingtest.springbootcodingtest.service.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/api/v1/users")
+@RequiredArgsConstructor
+@PreAuthorize("hasAuthority('ROLE_ADMIN')")
+@Secured("ROLE_ADMIN")
+public class UserController {
+ private final UserService userService;
+
+ @GetMapping
+ public Collection findAll() {
+ return userService.findAll();
+ }
+
+ @GetMapping("/{id}")
+ public UserDto findById(@PathVariable("id") String id) {
+ return userService.findById(UUID.fromString(id));
+ }
+
+ @PostMapping("/")
+ public UserDto create(@RequestBody UserDto userDto) {
+ return userService.create(userDto);
+ }
+
+ @PutMapping("/{id}")
+ public UserDto update(@PathVariable("id") String id, @RequestBody UserDto userDto) {
+ return userService.update(UUID.fromString(id), userDto);
+ }
+
+ @PatchMapping("/{id}")
+ public UserDto updatePartially(@PathVariable("id") String id, @RequestBody UserDto userDto) {
+ return userService.updatePartially(UUID.fromString(id), userDto);
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteById(@PathVariable("id") String id) {
+ userService.deleteById(UUID.fromString(id));
+ return ResponseEntity.ok().build();
+ }
+
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Project.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Project.java
new file mode 100644
index 0000000..c1d4c6b
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Project.java
@@ -0,0 +1,17 @@
+package com.accenture.codingtest.springbootcodingtest.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Entity
+@Data
+@Table
+public class Project {
+ @Id
+ @GeneratedValue
+ private UUID id;
+ @Column(nullable = false)
+ private String name;
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Task.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Task.java
new file mode 100644
index 0000000..79766f9
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Task.java
@@ -0,0 +1,24 @@
+package com.accenture.codingtest.springbootcodingtest.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Data
+@Entity
+@Table
+public class Task {
+ @Id
+ @GeneratedValue
+ private UUID id;
+ @Column(nullable = false)
+ private String title;
+ private String description;
+ @Column(nullable = false)
+ private String status;
+ @Column(nullable = false)
+ private UUID projectId;
+ @Column(nullable = false)
+ private UUID userId;
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/User.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/User.java
new file mode 100644
index 0000000..4bfb7ef
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/User.java
@@ -0,0 +1,19 @@
+package com.accenture.codingtest.springbootcodingtest.entity;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Entity
+@Data
+@Table
+public class User {
+ @Id
+ @GeneratedValue
+ private UUID id;
+ @Column(nullable = false, unique = true)
+ private String username ;
+ @Column(nullable = false)
+ private String password ;
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/model/ProjectDto.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/ProjectDto.java
new file mode 100644
index 0000000..8ba7cf8
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/ProjectDto.java
@@ -0,0 +1,13 @@
+package com.accenture.codingtest.springbootcodingtest.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+
+@Data
+public class ProjectDto {
+ private UUID id;
+ private String name;
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/model/Status.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/Status.java
new file mode 100644
index 0000000..cb61146
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/Status.java
@@ -0,0 +1,10 @@
+package com.accenture.codingtest.springbootcodingtest.model;
+
+public enum Status {
+ NOT_STARTED,
+ IN_PROGRESS,
+ READY_FOR_TEST,
+ COMPLETED
+
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/model/TaskDto.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/TaskDto.java
new file mode 100644
index 0000000..1bc70c3
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/TaskDto.java
@@ -0,0 +1,15 @@
+package com.accenture.codingtest.springbootcodingtest.model;
+
+import lombok.Data;
+
+import java.util.UUID;
+
+@Data
+public class TaskDto {
+ private UUID id;
+ private String title;
+ private String description;
+ private String status;
+ private UUID projectId;
+ private UUID userId;
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/model/UserDto.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/UserDto.java
new file mode 100644
index 0000000..4f6df19
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/UserDto.java
@@ -0,0 +1,15 @@
+package com.accenture.codingtest.springbootcodingtest.model;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import java.util.UUID;
+
+@Data
+public class UserDto {
+ private UUID id;
+ private String username;
+ private String password;
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/ProjectRepository.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/ProjectRepository.java
new file mode 100644
index 0000000..40c7f00
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/ProjectRepository.java
@@ -0,0 +1,10 @@
+package com.accenture.codingtest.springbootcodingtest.repository;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.UUID;
+
+public interface ProjectRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/TaskRepository.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/TaskRepository.java
new file mode 100644
index 0000000..1297238
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/TaskRepository.java
@@ -0,0 +1,10 @@
+package com.accenture.codingtest.springbootcodingtest.repository;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+import com.accenture.codingtest.springbootcodingtest.entity.Task;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.UUID;
+
+public interface TaskRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/UserRepository.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/UserRepository.java
new file mode 100644
index 0000000..654bbd3
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/UserRepository.java
@@ -0,0 +1,9 @@
+package com.accenture.codingtest.springbootcodingtest.repository;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.UUID;
+
+public interface UserRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/service/ProjectService.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/ProjectService.java
new file mode 100644
index 0000000..7b7e41c
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/ProjectService.java
@@ -0,0 +1,62 @@
+package com.accenture.codingtest.springbootcodingtest.service;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+import com.accenture.codingtest.springbootcodingtest.model.ProjectDto;
+import com.accenture.codingtest.springbootcodingtest.repository.ProjectRepository;
+import lombok.RequiredArgsConstructor;
+import org.modelmapper.ModelMapper;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.UUID;
+
+@Service
+@RequiredArgsConstructor
+public class ProjectService {
+ private final ProjectRepository projectRepository;
+ private final ModelMapper modelMapper;
+
+ public Collection findAll() {
+ Collection all = new ArrayList<>();
+ projectRepository.findAll().forEach(obj -> {
+ all.add(modelMapper.map(obj, ProjectDto.class));
+ });
+ return all;
+ }
+
+ public ProjectDto findById(UUID id) {
+ Project project = projectRepository.findById(id)
+ .orElseThrow(() -> new EntityNotFoundException("Project not found. Id: " + id));
+ return modelMapper.map(project, ProjectDto.class);
+ }
+
+ public ProjectDto create(ProjectDto projectDto) {
+ Project entity = modelMapper.map(projectDto, Project.class);
+ Project createdEntity = projectRepository.save(entity);
+ return modelMapper.map(createdEntity, ProjectDto.class);
+ }
+
+ public ProjectDto update(UUID id, ProjectDto projectDto) {
+ boolean existsById = projectRepository.existsById(id);
+ if (existsById) {
+ Project entityProject = modelMapper.map(projectDto, Project.class);
+ Project updatedEntity = projectRepository.save(entityProject);
+ return modelMapper.map(updatedEntity, ProjectDto.class);
+ }
+ throw new EntityNotFoundException("Project not found. Id: " + id);
+ }
+
+ public ProjectDto updatePartially(UUID id, ProjectDto projectDto) {
+ ProjectDto target = findById(id);
+ modelMapper.map(projectDto, target);
+ Project targetEntity = modelMapper.map(target, Project.class);
+ projectRepository.save(targetEntity);
+ return target;
+ }
+
+ public void deleteById(UUID id) {
+ projectRepository.deleteById(id);
+ }
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/service/TaskService.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/TaskService.java
new file mode 100644
index 0000000..e293324
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/TaskService.java
@@ -0,0 +1,65 @@
+package com.accenture.codingtest.springbootcodingtest.service;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Task;
+import com.accenture.codingtest.springbootcodingtest.model.TaskDto;
+import com.accenture.codingtest.springbootcodingtest.repository.TaskRepository;
+import lombok.RequiredArgsConstructor;
+import org.modelmapper.ModelMapper;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.UUID;
+
+import static com.accenture.codingtest.springbootcodingtest.model.Status.NOT_STARTED;
+
+@Service
+@RequiredArgsConstructor
+public class TaskService {
+ private final TaskRepository taskRepository;
+ private final ModelMapper modelMapper;
+
+ public Collection findAll() {
+ Collection all = new ArrayList<>();
+ taskRepository.findAll().forEach(obj -> {
+ all.add(modelMapper.map(obj, TaskDto.class));
+ });
+ return all;
+ }
+
+ public TaskDto findById(UUID id) {
+ Task task = taskRepository.findById(id)
+ .orElseThrow(() -> new EntityNotFoundException("Task not found. Id: " + id));
+ return modelMapper.map(task, TaskDto.class);
+ }
+
+ public TaskDto create(TaskDto taskDto) {
+ Task entity = modelMapper.map(taskDto, Task.class);
+ entity.setStatus(NOT_STARTED.name());
+ Task createdEntity = taskRepository.save(entity);
+ return modelMapper.map(createdEntity, TaskDto.class);
+ }
+
+ public TaskDto update(UUID id, TaskDto taskDto) {
+ boolean existsById = taskRepository.existsById(id);
+ if (existsById) {
+ Task entityTask = modelMapper.map(taskDto, Task.class);
+ Task updatedEntity = taskRepository.save(entityTask);
+ return modelMapper.map(updatedEntity, TaskDto.class);
+ }
+ throw new EntityNotFoundException("Task not found. Id: " + id);
+ }
+
+ public TaskDto updatePartially(UUID id, TaskDto taskDto) {
+ TaskDto target = findById(id);
+ modelMapper.map(taskDto, target);
+ Task targetEntity = modelMapper.map(target, Task.class);
+ taskRepository.save(targetEntity);
+ return target;
+ }
+
+ public void deleteById(UUID id) {
+ taskRepository.deleteById(id);
+ }
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/service/UserService.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/UserService.java
new file mode 100644
index 0000000..a3e7360
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/UserService.java
@@ -0,0 +1,63 @@
+package com.accenture.codingtest.springbootcodingtest.service;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+import com.accenture.codingtest.springbootcodingtest.model.UserDto;
+import com.accenture.codingtest.springbootcodingtest.repository.UserRepository;
+import lombok.RequiredArgsConstructor;
+import org.modelmapper.ModelMapper;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.UUID;
+
+@Service
+@RequiredArgsConstructor
+public class UserService {
+ private final UserRepository userRepository;
+ private final ModelMapper modelMapper;
+
+ public Collection findAll() {
+ Collection all = new ArrayList<>();
+ userRepository.findAll().forEach(obj -> {
+ all.add(modelMapper.map(obj, UserDto.class));
+ });
+ return all;
+ }
+
+ public UserDto findById(UUID id) {
+ User user = userRepository.findById(id)
+ .orElseThrow(() -> new EntityNotFoundException("User not found. Id: " + id));
+ return modelMapper.map(user, UserDto.class);
+ }
+
+ public UserDto create(UserDto userDto) {
+ User entityUser = modelMapper.map(userDto, User.class);
+ User createdEntity = userRepository.save(entityUser);
+ return modelMapper.map(createdEntity, UserDto.class);
+ }
+
+ public UserDto update(UUID id, UserDto userDto) {
+ boolean existsById = userRepository.existsById(id);
+ if (existsById) {
+ User entityUser = modelMapper.map(userDto, User.class);
+ User updatedEntity = userRepository.save(entityUser);
+ return modelMapper.map(updatedEntity, UserDto.class);
+ }
+ throw new EntityNotFoundException("User not found. Id: " + id);
+ }
+
+ public UserDto updatePartially(UUID id, UserDto userDto) {
+ UserDto target = findById(id);
+ modelMapper.map(userDto, target);
+ User targetEntity = modelMapper.map(target, User.class);
+ userRepository.save(targetEntity);
+ return target;
+ }
+
+ public void deleteById(UUID id) {
+ userRepository.deleteById(id);
+ }
+}
diff --git a/src/test/java/com/accenture/codingtest/springbootcodingtest/TestRestTemplate.java b/src/test/java/com/accenture/codingtest/springbootcodingtest/TestRestTemplate.java
new file mode 100644
index 0000000..59a10b1
--- /dev/null
+++ b/src/test/java/com/accenture/codingtest/springbootcodingtest/TestRestTemplate.java
@@ -0,0 +1,33 @@
+package com.accenture.codingtest.springbootcodingtest;
+
+import com.accenture.codingtest.springbootcodingtest.model.ProjectDto;
+import com.accenture.codingtest.springbootcodingtest.model.TaskDto;
+import com.accenture.codingtest.springbootcodingtest.model.UserDto;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.web.client.RestTemplate;
+
+
+public class TestRestTemplate extends SpringBootCodingTestApplication {
+ public static final String BASE_URL = "http://localhost:8080";
+ RestTemplate restTemplate;
+
+ @BeforeEach
+ void setUp() {
+ restTemplate = new RestTemplate();
+ }
+
+ @Test
+ public void testcase(){
+ UserDto userDto =new UserDto();
+ userDto.setUsername("user1");
+ userDto.setPassword("password");
+ restTemplate.postForEntity(BASE_URL+"/api/v1/users",userDto, UserDto.class);
+
+ ProjectDto projectDto =new ProjectDto();
+ projectDto.setName("project1");
+ restTemplate.postForEntity(BASE_URL+"/api/v1/projects",projectDto, UserDto.class);
+
+ }
+}