diff --git a/src/main/java/com/github/aceton41k/constant/TaskStatus.java b/src/main/java/com/github/aceton41k/constant/TaskStatus.java index d836f33..bf2b602 100644 --- a/src/main/java/com/github/aceton41k/constant/TaskStatus.java +++ b/src/main/java/com/github/aceton41k/constant/TaskStatus.java @@ -2,5 +2,6 @@ public class TaskStatus { public static final String DONE = "done"; + public static final String IDLE = "idle"; public static final String IN_PROGRESS = "in progress"; public static final String FAILED = "failed";} diff --git a/src/main/java/com/github/aceton41k/controller/TaskController.java b/src/main/java/com/github/aceton41k/controller/TaskController.java index 0b23ced..5b9bbc7 100644 --- a/src/main/java/com/github/aceton41k/controller/TaskController.java +++ b/src/main/java/com/github/aceton41k/controller/TaskController.java @@ -1,32 +1,46 @@ package com.github.aceton41k.controller; -import com.github.aceton41k.dto.Task; +import com.github.aceton41k.dto.TaskDto; import com.github.aceton41k.service.TaskService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import java.util.List; +import java.net.URI; @RestController -@RequestMapping("/api/task") +@RequestMapping("/api/tasks") public class TaskController { @Autowired private TaskService taskService; - @GetMapping("/create") - public String createTask(@RequestParam Integer duration) { - Long taskId = taskService.createTask(duration); - return "Task created with ID: " + taskId; + @PostMapping + public ResponseEntity createTask(@RequestParam @Nullable Integer duration) { + TaskDto task = taskService.createTask(duration); + URI location = ServletUriComponentsBuilder.fromCurrentRequest() + .path("/{id}") + .buildAndExpand(task.getId()) + .toUri(); + return ResponseEntity.created(location).body(task); } - @GetMapping("/status/{id}") - public Task getTaskStatus(@PathVariable Long id) { - return taskService.getTaskStatus(id); + @GetMapping("/{id}") + public ResponseEntity getTask(@PathVariable Long id) { + TaskDto task = taskService.getTask(id); + return ResponseEntity.ok(task); } - @GetMapping("/status") - public List getTaskStatus() { - return taskService.getAllTasks(); + @GetMapping + public ResponseEntity> getAllTasks(@RequestParam(value = "page", defaultValue = "0") Integer page, + @RequestParam(value = "size", defaultValue = "10") Integer size) { + Pageable pageable = PageRequest.of(page, size); + Page tasks = taskService.getAllTasks(pageable); + return ResponseEntity.ok(tasks); } } \ No newline at end of file diff --git a/src/main/java/com/github/aceton41k/dto/Task.java b/src/main/java/com/github/aceton41k/dto/TaskDto.java similarity index 70% rename from src/main/java/com/github/aceton41k/dto/Task.java rename to src/main/java/com/github/aceton41k/dto/TaskDto.java index 8bd1bca..e70ebf1 100644 --- a/src/main/java/com/github/aceton41k/dto/Task.java +++ b/src/main/java/com/github/aceton41k/dto/TaskDto.java @@ -9,9 +9,7 @@ @Getter @Setter @NoArgsConstructor -public class Task { -// private final AtomicInteger progress = new AtomicInteger(0); -// private volatile String status = "not started"; +public class TaskDto { private Long id; private Integer progress; diff --git a/src/main/java/com/github/aceton41k/entity/TaskEntity.java b/src/main/java/com/github/aceton41k/entity/TaskEntity.java index 8596038..dd39244 100644 --- a/src/main/java/com/github/aceton41k/entity/TaskEntity.java +++ b/src/main/java/com/github/aceton41k/entity/TaskEntity.java @@ -20,7 +20,7 @@ public class TaskEntity { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) private Long id; diff --git a/src/main/java/com/github/aceton41k/entity/UserEntity.java b/src/main/java/com/github/aceton41k/entity/UserEntity.java index 5a1e645..0bbcde5 100644 --- a/src/main/java/com/github/aceton41k/entity/UserEntity.java +++ b/src/main/java/com/github/aceton41k/entity/UserEntity.java @@ -20,7 +20,7 @@ @EntityListeners(AuditingEntityListener.class) public class UserEntity implements UserDetails { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(nullable = false) private Long id; diff --git a/src/main/java/com/github/aceton41k/service/TaskService.java b/src/main/java/com/github/aceton41k/service/TaskService.java index a8ddb4f..f978ca5 100644 --- a/src/main/java/com/github/aceton41k/service/TaskService.java +++ b/src/main/java/com/github/aceton41k/service/TaskService.java @@ -1,15 +1,16 @@ package com.github.aceton41k.service; -import com.github.aceton41k.dto.Task; +import com.github.aceton41k.dto.TaskDto; import com.github.aceton41k.entity.TaskEntity; import com.github.aceton41k.repository.TaskRepository; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -21,7 +22,7 @@ @Slf4j public class TaskService { - private final Map taskStore = new ConcurrentHashMap<>(); + private final Map taskStore = new ConcurrentHashMap<>(); @Autowired private ApplicationContext applicationContext; // Контекст для получения текущего бина @@ -33,31 +34,28 @@ public class TaskService { // private final AtomicInteger progress = new AtomicInteger(0); // private volatile String status = "not started"; - public Long createTask(Integer duration) { - TaskEntity savedTask = taskRepository.save(new TaskEntity().withProgress(0)); + public TaskDto createTask(Integer duration) { + TaskEntity savedTask = taskRepository.save( + new TaskEntity() + .withProgress(0) + .withStatus(IDLE)); TaskService taskService = applicationContext.getBean(TaskService.class); taskService.performAsyncTask(savedTask.getId(), duration); // Вызываем асинхронный метод через бин - log.info("Task {} created", savedTask.getId()); - return savedTask.getId(); + log.debug("Task {} created", savedTask.getId()); + return convertToDto(savedTask); } @Async public CompletableFuture performAsyncTask(Long taskId, Integer duration) { TaskEntity taskEntity = taskRepository.findById(taskId).get(); taskEntity.setStatus(IN_PROGRESS); - Task task = convertToDto(taskEntity); + TaskDto task = convertToDto(taskEntity); taskStore.put(taskId, task); taskRepository.save(taskEntity); try { - for (int i = 0; i <= duration; i++) { + for (int i = 0; i < duration; i++) { task.setProgress(task.getProgress() + 100 / duration); - if (task.getProgress() > 100) { - task.setProgress(100); - taskEntity.setProgress(100); - task.setStatus(DONE); - taskEntity.setStatus(DONE); - break; - } + log.info("Progress: {}", task.getProgress()); Thread.sleep(1000); @@ -70,6 +68,10 @@ public CompletableFuture performAsyncTask(Long taskId, Integer duration) { task.setStatus(FAILED); taskEntity.setStatus(FAILED); } finally { + task.setProgress(100); + taskEntity.setProgress(100); + task.setStatus(DONE); + taskEntity.setStatus(DONE); taskStore.put(taskId, convertToDto(taskEntity)); taskRepository.save(taskEntity); @@ -78,23 +80,24 @@ public CompletableFuture performAsyncTask(Long taskId, Integer duration) { return CompletableFuture.completedFuture(null); } - public Task getTaskStatus(Long id) { - Task task = taskStore.get(id); // Извлекаем DTO из хранилища + public TaskDto getTask(Long id) { + TaskDto task = taskStore.get(id); // Извлекаем DTO из хранилища // if task finished get it from db return Objects.requireNonNullElseGet(task, () -> convertToDto(taskRepository.findById(id).get())); // Возвращаем текущий прогресс и статус } - public List getAllTasks() { - List tasksFromDb = taskRepository.findAll().stream().map(this::convertToDto).toList(); - for (Task task : tasksFromDb) { - if (task.getStatus().equals("in progress")) - task.setProgress(taskStore.get(task.getId()).getProgress()); - } - return tasksFromDb; + public Page getAllTasks(Pageable pageable) { + Page tasks = taskRepository.findAll(pageable).map(this::convertToDto); + tasks.forEach(taskDto -> { + if (taskDto.getStatus().equals("in progress") && taskStore.get(taskDto.getId()) != null) + taskDto.setProgress(taskStore.get(taskDto.getId()).getProgress()); + }); + return tasks; +// } - private Task convertToDto(TaskEntity entity) { - Task dto = new Task(); + private TaskDto convertToDto(TaskEntity entity) { + TaskDto dto = new TaskDto(); dto.setStatus(entity.getStatus()); dto.setProgress(entity.getProgress()); dto.setId(entity.getId());