diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/Project-Module-Feb-2022.iml b/.idea/Project-Module-Feb-2022.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/Project-Module-Feb-2022.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..af773d4 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..77b6cb4 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,68 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..fdc392f --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..c7f6841 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d152667 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/taskmanager/README.md b/taskmanager/README.md index aa2cd3e..ea645d2 100644 --- a/taskmanager/README.md +++ b/taskmanager/README.md @@ -21,14 +21,14 @@ task manager + notes support API Endpoints (REST URLs) GET /tasks get all tasks ✅ -GET /tasks/{id} get a task by id -DELETE /tasks/{id} delete task by id -PATCH /tasks/{id} update details of a task +GET /tasks/{id} get a task by id ✅ +DELETE /tasks/{id} delete task by id ✅ +PATCH /tasks/{id} update details of a task ✅ POST /tasks create a new task ✅ -GET /tasks/{id}/notes show all notes of a task -POST /tasks/{id}/notes add notes to a task -DELETE /tasks/{id}/notes/{nid} delete a note from a task +GET /tasks/{id}/notes show all notes of a task ✅ +POST /tasks/{id}/notes add notes to a task ✅ +DELETE /tasks/{id}/notes/{nid} delete a note from a task ✅ ---- "idempotent" diff --git a/taskmanager/build.gradle b/taskmanager/build.gradle index 79e1823..098053d 100644 --- a/taskmanager/build.gradle +++ b/taskmanager/build.gradle @@ -6,7 +6,7 @@ plugins { group = 'com.scaler' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '17' +//sourceCompatibility = '17' configurations { compileOnly { @@ -21,6 +21,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.5' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/QueryConstants.java b/taskmanager/src/main/java/com/scaler/taskmanager/QueryConstants.java new file mode 100644 index 0000000..23838af --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/QueryConstants.java @@ -0,0 +1,10 @@ +package com.scaler.taskmanager; + + +public final class QueryConstants { + public static final String FETCH_NOTES_BY_TASKID = "SELECT new com.scaler.taskmanager.notes.dto.NoteResponseBody(" + + "notes.id, notes.body,notes.task.id) FROM NoteEntity notes WHERE notes.task.id = :taskId"; + + public static final String DELETE_NOTES_BY_TASKID = "DELETE FROM NoteEntity notes "+ + "WHERE notes.task.id = :taskId"; +} diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/TaskmanagerApplication.java b/taskmanager/src/main/java/com/scaler/taskmanager/TaskManagerApplication.java similarity index 69% rename from taskmanager/src/main/java/com/scaler/taskmanager/TaskmanagerApplication.java rename to taskmanager/src/main/java/com/scaler/taskmanager/TaskManagerApplication.java index 4498794..87c6629 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/TaskmanagerApplication.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/TaskManagerApplication.java @@ -4,10 +4,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class TaskmanagerApplication { +public class TaskManagerApplication { public static void main(String[] args) { - SpringApplication.run(TaskmanagerApplication.class, args); + SpringApplication.run(TaskManagerApplication.class, args); } } diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/notes/NoteEntity.java b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NoteEntity.java index 1ddc244..9bd8e60 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/notes/NoteEntity.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NoteEntity.java @@ -10,7 +10,8 @@ @AllArgsConstructor @NoArgsConstructor @Getter -@Entity(name = "notes") +@Entity +@Table(name = "notes") public class NoteEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) Long id; @@ -20,4 +21,9 @@ public class NoteEntity { @ManyToOne TaskEntity task; + + public NoteEntity(String body, TaskEntity task) { + this.body = body; + this.task = task; + } } diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesController.java b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesController.java new file mode 100644 index 0000000..09966a4 --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesController.java @@ -0,0 +1,54 @@ +package com.scaler.taskmanager.notes; + + +import com.scaler.taskmanager.Constants; +import com.scaler.taskmanager.notes.dto.CreateNoteRequestBody; +import com.scaler.taskmanager.notes.dto.NoteResponseBody; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/tasks/{id}/notes/") +public class NotesController { + + private NotesService notesService; + + public NotesController(NotesService notesService) { + this.notesService = notesService; + } + + @PostMapping("") + ResponseEntity createNotes(@PathVariable("id") Long taskId,@RequestBody CreateNoteRequestBody body) { + NoteResponseBody note = notesService.addNote(body,taskId); + return note == null? ResponseEntity.notFound().build():ResponseEntity.created( + URI.create(Constants.BASE_URL + "/notes" + note.getId())) + .body(note); + } + + @GetMapping("") + ResponseEntity> getAllNotes(@PathVariable("id") Long taskId) { + List noteResponseList = notesService.getAllNotes(taskId); + return noteResponseList == null ? ResponseEntity.notFound().build():ResponseEntity.ok(noteResponseList); + } + + @DeleteMapping("/{noteId}") + ResponseEntity> deleteParticularNote(@PathVariable Long id, @PathVariable Long noteId) { + boolean removed = notesService.removed(id,noteId); + if(removed) { + Map response = new HashMap<>(); + response.put(id,noteId); + return ResponseEntity.ok(response); + } + else { + return ResponseEntity.notFound().build(); + } + } + + + +} diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesRepository.java b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesRepository.java index 507770a..40f4cb8 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesRepository.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesRepository.java @@ -1,4 +1,21 @@ package com.scaler.taskmanager.notes; -public class NotesRepository { +import com.scaler.taskmanager.QueryConstants; +import com.scaler.taskmanager.notes.dto.NoteResponseBody; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface NotesRepository extends JpaRepository { + + @Query(value = QueryConstants.FETCH_NOTES_BY_TASKID) + List fetchAll(@Param(value = "taskId") Long taskId); + + @Query(value = QueryConstants.DELETE_NOTES_BY_TASKID) + void deleteByTaskId(@Param(value = "taskId") Long taskId); + } diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesService.java b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesService.java new file mode 100644 index 0000000..7e93ce0 --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/notes/NotesService.java @@ -0,0 +1,50 @@ +package com.scaler.taskmanager.notes; + +import com.scaler.taskmanager.notes.dto.CreateNoteRequestBody; +import com.scaler.taskmanager.notes.dto.NoteResponseBody; +import com.scaler.taskmanager.tasks.TasksRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + + +@Service +public class NotesService { + + NotesRepository notesRepo; + + TasksRepository taskRepo; + + public NotesService(NotesRepository notesRepo, TasksRepository taskRepo) { + this.notesRepo = notesRepo; + this.taskRepo = taskRepo; + } + + public NoteResponseBody addNote(CreateNoteRequestBody requestBody, Long taskId) { + if(taskRepo.existsById(taskId)) + return convertFromEntity(notesRepo.save(new NoteEntity(requestBody.getBody(),taskRepo.getById(taskId)))); + return null; + } + + public NoteResponseBody convertFromEntity(NoteEntity noteEntity) { + return NoteResponseBody.builder() + .body(noteEntity.getBody()) + .id(noteEntity.getId()) + .taskId(noteEntity.getTask().getId()) + .build(); + } + + public List getAllNotes(Long taskId) { + return taskRepo.existsById(taskId)? notesRepo.fetchAll(taskId):null; + } + + public boolean removed(Long taskId,Long notesId) { + if(taskRepo.existsById(taskId) && notesRepo.existsById(notesId)) { + notesRepo.deleteById(notesId); + return true; + } + return false; + } + + +} diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/notes/dto/CreateNoteRequestBody.java b/taskmanager/src/main/java/com/scaler/taskmanager/notes/dto/CreateNoteRequestBody.java new file mode 100644 index 0000000..a9041b5 --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/notes/dto/CreateNoteRequestBody.java @@ -0,0 +1,10 @@ +package com.scaler.taskmanager.notes.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CreateNoteRequestBody { + String body; +} diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/notes/dto/NoteResponseBody.java b/taskmanager/src/main/java/com/scaler/taskmanager/notes/dto/NoteResponseBody.java new file mode 100644 index 0000000..ce1ce3c --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/notes/dto/NoteResponseBody.java @@ -0,0 +1,13 @@ +package com.scaler.taskmanager.notes.dto; + +import lombok.*; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Builder +public class NoteResponseBody { + Long id; + String body; + Long taskId; +} diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TaskEntity.java b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TaskEntity.java index 28c40f4..4cb2cf8 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TaskEntity.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TaskEntity.java @@ -1,8 +1,6 @@ package com.scaler.taskmanager.tasks; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import javax.persistence.*; import java.time.LocalDate; @@ -10,7 +8,8 @@ @AllArgsConstructor @NoArgsConstructor -@Getter +@Getter(AccessLevel.PUBLIC) +@Setter(AccessLevel.PUBLIC) @Entity(name = "tasks") public class TaskEntity { @@ -20,12 +19,14 @@ public TaskEntity(String name) { this.status = false; } - @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) Long id; @Column(nullable = false) String name; + @Column(nullable = false) LocalDate dueDate; @Column(columnDefinition = "boolean default false") diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksController.java b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksController.java index 91835e3..bb1472e 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksController.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksController.java @@ -1,8 +1,11 @@ package com.scaler.taskmanager.tasks; import com.scaler.taskmanager.Constants; +import com.scaler.taskmanager.tasks.dto.CreateTaskRequestBody; +import com.scaler.taskmanager.tasks.dto.TaskResponseEntity; +import com.scaler.taskmanager.tasks.dto.UpdateTaskRequestBody; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.scheduling.config.Task; import org.springframework.web.bind.annotation.*; import java.net.URI; @@ -26,10 +29,33 @@ ResponseEntity> getAllTasks() { @PostMapping("") ResponseEntity createTask(@RequestBody CreateTaskRequestBody body) { - TaskEntity savedTask = tasksService.addNewTask(body.name); + TaskEntity savedTask = tasksService.addNewTask(body.getName()); return ResponseEntity.created( URI.create(Constants.BASE_URL + "/tasks/" + savedTask.id) ).body(savedTask); } + + @GetMapping("/{id}") + ResponseEntity getTaskById(@PathVariable("id") Long taskId) { + TaskEntity task = tasksService.getTaskById(taskId); + if(task != null) { + return ResponseEntity.ok(new TaskResponseEntity(task.getId(),task.getName(),task.getDueDate(),task.getStatus())); + } + return ResponseEntity.badRequest().build(); + } + + @DeleteMapping("/{id}") + ResponseEntity deleteTaskById(@PathVariable("id") Long taskId) { + if(tasksService.deleteTaskById(taskId)) + { + return new ResponseEntity<>(HttpStatus.OK); + } + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + + @PatchMapping("/{id}") + ResponseEntity updateTaskById(@PathVariable("id") Long taskId, @RequestBody UpdateTaskRequestBody updateEntity) { + return ResponseEntity.ok(tasksService.updateTaskById(taskId, updateEntity)); + } } diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksService.java b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksService.java index e4f7911..54d56e3 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksService.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/TasksService.java @@ -1,27 +1,59 @@ package com.scaler.taskmanager.tasks; +import com.scaler.taskmanager.tasks.dto.TaskResponseEntity; +import com.scaler.taskmanager.tasks.dto.UpdateTaskRequestBody; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; @Service public class TasksService { private TasksRepository tasksRepo; - public TasksService(TasksRepository tasksRepo) { + TasksService(TasksRepository tasksRepo) { this.tasksRepo = tasksRepo; } - List getAllTasks() { + List getAllTasks() { return tasksRepo.findAll(); } - TaskEntity addNewTask(String taskName) { + TaskEntity addNewTask(String taskName) { TaskEntity task = new TaskEntity(taskName); TaskEntity savedTask = tasksRepo.save(task); return savedTask; } + TaskEntity getTaskById(Long id) { + return tasksRepo.getById(id); + } + + boolean deleteTaskById(Long taskId) { + + if(tasksRepo.existsById(taskId)){ + tasksRepo.deleteById(taskId); + return true; + } + return false; + } + + TaskResponseEntity updateTaskById(Long taskId, UpdateTaskRequestBody requestBody) { + return tasksRepo.existsById(taskId)? + convertFromEntity(tasksRepo + .save(requestBody.convertFromUpdateRequest(requestBody,tasksRepo.getById(taskId)))):null; + } + + + TaskResponseEntity convertFromEntity(TaskEntity task) { + return TaskResponseEntity.builder() + .id(task.getId()) + .name(task.getName()) + .dueDate(task.getDueDate()) + .status(task.getStatus()) + .build(); + } + } diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/CreateTaskRequestBody.java b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/CreateTaskRequestBody.java similarity index 84% rename from taskmanager/src/main/java/com/scaler/taskmanager/tasks/CreateTaskRequestBody.java rename to taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/CreateTaskRequestBody.java index 8e63eb6..0fef7aa 100644 --- a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/CreateTaskRequestBody.java +++ b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/CreateTaskRequestBody.java @@ -1,4 +1,4 @@ -package com.scaler.taskmanager.tasks; +package com.scaler.taskmanager.tasks.dto; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/TaskResponseEntity.java b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/TaskResponseEntity.java new file mode 100644 index 0000000..29725aa --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/TaskResponseEntity.java @@ -0,0 +1,19 @@ +package com.scaler.taskmanager.tasks.dto; + +import lombok.*; +import org.springframework.web.bind.annotation.GetMapping; + +import java.time.LocalDate; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +@Builder +public class TaskResponseEntity { + private Long id; + private String name; + private LocalDate dueDate; + private Boolean status; + +} diff --git a/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/UpdateTaskRequestBody.java b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/UpdateTaskRequestBody.java new file mode 100644 index 0000000..d3c758f --- /dev/null +++ b/taskmanager/src/main/java/com/scaler/taskmanager/tasks/dto/UpdateTaskRequestBody.java @@ -0,0 +1,27 @@ +package com.scaler.taskmanager.tasks.dto; + +import com.scaler.taskmanager.tasks.TaskEntity; +import lombok.Getter; +import lombok.Setter; + + +import java.time.LocalDate; + +@Getter +@Setter +public class UpdateTaskRequestBody { + private Long id; + private String name; + private LocalDate dueDate; + private Boolean status; + + public TaskEntity convertFromUpdateRequest(UpdateTaskRequestBody updateRequest, TaskEntity taskEntity) { + if(updateRequest.getName() != null) + taskEntity.setName(updateRequest.getName()); + if(updateRequest.getDueDate() != null) + taskEntity.setDueDate(updateRequest.getDueDate()); + if(updateRequest.getStatus() != null) + taskEntity.setStatus(updateRequest.getStatus()); + return taskEntity; + } +} diff --git a/test.db.mv.db b/test.db.mv.db new file mode 100644 index 0000000..f79ecb0 Binary files /dev/null and b/test.db.mv.db differ diff --git a/test.db.trace.db b/test.db.trace.db new file mode 100644 index 0000000..e36a428 --- /dev/null +++ b/test.db.trace.db @@ -0,0 +1,210 @@ +2022-03-14 19:37:51 jdbc[3]: exception +org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-200] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:622) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) + at org.h2.message.DbException.get(DbException.java:205) + at org.h2.message.DbException.get(DbException.java:181) + at org.h2.message.DbException.get(DbException.java:170) + at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1514) + at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1490) + at org.h2.jdbc.JdbcConnection.getWarnings(JdbcConnection.java:689) + at com.zaxxer.hikari.pool.HikariProxyConnection.getWarnings(HikariProxyConnection.java) + at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.handleAndClearWarnings(SqlExceptionHelper.java:290) + at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logAndClearWarnings(SqlExceptionHelper.java:269) + at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.releaseConnection(LogicalConnectionManagedImpl.java:215) + at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.close(LogicalConnectionManagedImpl.java:261) + at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.close(JdbcCoordinatorImpl.java:175) + at org.hibernate.internal.AbstractSharedSessionContract.close(AbstractSharedSessionContract.java:374) + at org.hibernate.internal.SessionImpl.closeWithoutOpenChecks(SessionImpl.java:417) + at org.hibernate.internal.SessionImpl.close(SessionImpl.java:402) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) + at jdk.proxy4/jdk.proxy4.$Proxy97.close(Unknown Source) + at org.springframework.orm.jpa.EntityManagerFactoryUtils.closeEntityManager(EntityManagerFactoryUtils.java:427) + at org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor.afterCompletion(OpenEntityManagerInViewInterceptor.java:112) + at org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter.afterCompletion(WebRequestHandlerInterceptorAdapter.java:73) + at org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:178) + at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletion(DispatcherServlet.java:1455) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1087) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:833) +2022-03-14 19:37:51 jdbc[3]: exception +org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-200] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:622) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) + at org.h2.message.DbException.get(DbException.java:205) + at org.h2.message.DbException.get(DbException.java:181) + at org.h2.message.DbException.get(DbException.java:170) + at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1514) + at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1490) + at org.h2.jdbc.JdbcConnection.clearWarnings(JdbcConnection.java:703) + at com.zaxxer.hikari.pool.HikariProxyConnection.clearWarnings(HikariProxyConnection.java) + at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.handleAndClearWarnings(SqlExceptionHelper.java:299) + at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logAndClearWarnings(SqlExceptionHelper.java:269) + at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.releaseConnection(LogicalConnectionManagedImpl.java:215) + at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.close(LogicalConnectionManagedImpl.java:261) + at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.close(JdbcCoordinatorImpl.java:175) + at org.hibernate.internal.AbstractSharedSessionContract.close(AbstractSharedSessionContract.java:374) + at org.hibernate.internal.SessionImpl.closeWithoutOpenChecks(SessionImpl.java:417) + at org.hibernate.internal.SessionImpl.close(SessionImpl.java:402) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) + at jdk.proxy4/jdk.proxy4.$Proxy97.close(Unknown Source) + at org.springframework.orm.jpa.EntityManagerFactoryUtils.closeEntityManager(EntityManagerFactoryUtils.java:427) + at org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor.afterCompletion(OpenEntityManagerInViewInterceptor.java:112) + at org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter.afterCompletion(WebRequestHandlerInterceptorAdapter.java:73) + at org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:178) + at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletion(DispatcherServlet.java:1455) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1087) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:833) +2022-03-14 19:37:51 jdbc[3]: exception +org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-200] + at org.h2.message.DbException.getJdbcSQLException(DbException.java:622) + at org.h2.message.DbException.getJdbcSQLException(DbException.java:429) + at org.h2.message.DbException.get(DbException.java:205) + at org.h2.message.DbException.get(DbException.java:181) + at org.h2.message.DbException.get(DbException.java:170) + at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1514) + at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1490) + at org.h2.jdbc.JdbcConnection.clearWarnings(JdbcConnection.java:703) + at com.zaxxer.hikari.pool.ProxyConnection.close(ProxyConnection.java:267) + at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.closeConnection(DatasourceConnectionProviderImpl.java:127) + at org.hibernate.internal.NonContextualJdbcConnectionAccess.releaseConnection(NonContextualJdbcConnectionAccess.java:49) + at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.releaseConnection(LogicalConnectionManagedImpl.java:219) + at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.close(LogicalConnectionManagedImpl.java:261) + at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.close(JdbcCoordinatorImpl.java:175) + at org.hibernate.internal.AbstractSharedSessionContract.close(AbstractSharedSessionContract.java:374) + at org.hibernate.internal.SessionImpl.closeWithoutOpenChecks(SessionImpl.java:417) + at org.hibernate.internal.SessionImpl.close(SessionImpl.java:402) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base/java.lang.reflect.Method.invoke(Method.java:568) + at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362) + at jdk.proxy4/jdk.proxy4.$Proxy97.close(Unknown Source) + at org.springframework.orm.jpa.EntityManagerFactoryUtils.closeEntityManager(EntityManagerFactoryUtils.java:427) + at org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor.afterCompletion(OpenEntityManagerInViewInterceptor.java:112) + at org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter.afterCompletion(WebRequestHandlerInterceptorAdapter.java:73) + at org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:178) + at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletion(DispatcherServlet.java:1455) + at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1087) + at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) + at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) + at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) + at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) + at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) + at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) + at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) + at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) + at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) + at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) + at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) + at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) + at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) + at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) + at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) + at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) + at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) + at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889) + at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735) + at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) + at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) + at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) + at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) + at java.base/java.lang.Thread.run(Thread.java:833) diff --git a/todolist/build.gradle b/todolist/build.gradle index f84df4d..6f66853 100644 --- a/todolist/build.gradle +++ b/todolist/build.gradle @@ -1,12 +1,18 @@ plugins { id 'org.springframework.boot' version '2.6.4' id 'io.spring.dependency-management' version '1.0.11.RELEASE' - id 'java' + id("java-library") +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(17) + } } group = 'com.scaler' version = '0.0.1-SNAPSHOT' -sourceCompatibility = '17' +//sourceCompatibility = '17' configurations { compileOnly { @@ -14,6 +20,7 @@ configurations { } } + repositories { mavenCentral() } diff --git a/todolist/src/main/java/com/scaler/todolist/controllers/TasksController.java b/todolist/src/main/java/com/scaler/todolist/controllers/TasksController.java index a39e36c..197946a 100644 --- a/todolist/src/main/java/com/scaler/todolist/controllers/TasksController.java +++ b/todolist/src/main/java/com/scaler/todolist/controllers/TasksController.java @@ -4,7 +4,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.net.http.HttpResponse; import java.util.ArrayList; import java.util.List; @@ -21,7 +20,7 @@ ResponseEntity> getAllTasks() { @PostMapping("/") ResponseEntity addNewTask(@RequestBody Task task) { - Task taskToAdd = new Task(task.getName()); + Task taskToAdd = new Task(task.getId(),task.getName()); taskList.add(taskToAdd); return ResponseEntity.status(201).body(taskToAdd); } @@ -39,5 +38,39 @@ ResponseEntity addNewTask(@RequestBody Task task) { * if task 5 does not exist, send 404 */ + @GetMapping("/{id}") + ResponseEntity getTaskById(@PathVariable("id") Long taskId) { + for(Task taskItr: taskList) { + if(taskItr.getId() == taskId) { + return ResponseEntity.ok(taskItr); + } + } + return ResponseEntity.status(404).body(null); + } + + @PatchMapping("/{id}") + ResponseEntity updateTaskById(@PathVariable("id") Long taskId,@RequestBody Task task) { + for(Task taskItr:taskList) { + if(taskItr.getId() == taskId) { + taskItr.setDone(task.getDone()); + taskItr.setDue(task.getDue()); + return ResponseEntity.ok(taskItr); + } + } + return ResponseEntity.status(404).body(null); + } + + @DeleteMapping("/{id}") + ResponseEntity deleteTaskById(@PathVariable("id") Long taskId) { + for(Task task:taskList) { + if(task.getId() == taskId) { + taskList.remove(task); + return ResponseEntity.noContent().build(); + } + } + return ResponseEntity.status(404).body(null); + } + + } diff --git a/todolist/src/main/java/com/scaler/todolist/models/Task.java b/todolist/src/main/java/com/scaler/todolist/models/Task.java index d572475..cc21888 100644 --- a/todolist/src/main/java/com/scaler/todolist/models/Task.java +++ b/todolist/src/main/java/com/scaler/todolist/models/Task.java @@ -4,15 +4,15 @@ import java.time.LocalDate; import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalUnit; -import java.util.Calendar; -import java.util.Date; @AllArgsConstructor @NoArgsConstructor @Getter(AccessLevel.PUBLIC) @Setter(AccessLevel.PUBLIC) +//@Entity(name ="tasks") public class Task { + //@Id @GeneratedValue(strategy = GenerationType.SEQUENCE) + private Long id; private String name; private LocalDate due; private Boolean done; @@ -22,7 +22,10 @@ public class Task { * due date 5 days from now, and done = false * @param name */ - public Task(String name) { - this(name, LocalDate.now().plus(5, ChronoUnit.DAYS), false); + public Task(Long id,String name) { + this.id = id; + this.name = name; + due = LocalDate.now().plus(5, ChronoUnit.DAYS); + done = false; } } diff --git a/todolist/src/main/resources/application.properties b/todolist/src/main/resources/application.properties index 2bfe6fa..9a5b335 100644 --- a/todolist/src/main/resources/application.properties +++ b/todolist/src/main/resources/application.properties @@ -1 +1,2 @@ server.port=6543 +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration \ No newline at end of file