From 9a8596341fcd72d8f84ea2f62fead4866c9bbab8 Mon Sep 17 00:00:00 2001 From: reynisson Date: Fri, 17 Dec 2021 23:28:28 +0100 Subject: [PATCH 1/6] Removed the TaskList domain object and fixed everything that broke. All task list commands are now implemented via the DB --- .../TaskAssignedEventListenerHttpAdapter.java | 5 +- .../http/TaskEventHttpDispatcher.java | 15 +- .../TaskExecutedEventListenerHttpAdapter.java | 5 +- .../TaskStartedEventListenerHttpAdapter.java | 5 +- .../in/web/DeleteTaskWebController.java | 10 +- .../out/persistence/mongodb/TaskMapper.java | 4 +- .../mongodb/TaskPersistenceAdapter.java | 14 +- .../persistence/mongodb/TaskRepository.java | 6 +- .../handler/TaskAssignedHandler.java | 26 ++- .../handler/TaskExecutedHandler.java | 34 +++- .../handler/TaskStartedHandler.java | 30 +++- .../port/in/DeleteTaskCommand.java | 6 +- .../application/port/out/DeleteTaskPort.java | 7 + .../application/port/out/LoadTaskPort.java | 3 +- .../application/port/out/TaskListLock.java | 11 -- .../service/AddNewTaskToTaskListService.java | 18 +-- .../service/CompleteTaskService.java | 28 ++-- .../service/DeleteTaskService.java | 18 ++- .../application/service/NoOpTaskListLock.java | 18 --- .../RetrieveTaskFromTaskListService.java | 8 +- .../service/TaskAssignedService.java | 14 +- .../tasks/domain/DeleteTaskEvent.java | 4 +- .../unisg/tapastasks/tasks/domain/Task.java | 10 +- .../tapastasks/tasks/domain/TaskList.java | 152 ------------------ .../AddNewTaskToTaskListSystemTest.java | 5 +- .../mongodb/TaskPersistenceAdapterTest.java | 3 +- .../AddNewTaskToTaskListServiceTest.java | 8 - .../tapastasks/tasks/domain/TaskListTest.java | 10 +- 28 files changed, 194 insertions(+), 283 deletions(-) create mode 100644 tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/DeleteTaskPort.java delete mode 100644 tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java delete mode 100644 tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java delete mode 100644 tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/TaskList.java diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskAssignedEventListenerHttpAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskAssignedEventListenerHttpAdapter.java index 4c26b80..7061e45 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskAssignedEventListenerHttpAdapter.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskAssignedEventListenerHttpAdapter.java @@ -7,6 +7,7 @@ import ch.unisg.tapastasks.tasks.application.port.in.TaskAssignedEventHandler; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.Task.TaskId; import com.fasterxml.jackson.databind.JsonNode; +import lombok.RequiredArgsConstructor; import java.util.Optional; @@ -18,8 +19,11 @@ import java.util.Optional; * * See also {@link TaskAssignedEvent}, {@link Task}, and {@link TaskEventHttpDispatcher}. */ +@RequiredArgsConstructor public class TaskAssignedEventListenerHttpAdapter extends TaskEventListener { + private final TaskAssignedEventHandler taskAssignedEventHandler; + /** * Handles the task assigned event. * @@ -32,7 +36,6 @@ public class TaskAssignedEventListenerHttpAdapter extends TaskEventListener { Optional serviceProvider = representation.extractFirstServiceProviderChange(); TaskAssignedEvent taskAssignedEvent = new TaskAssignedEvent(new TaskId(taskId), serviceProvider); - TaskAssignedEventHandler taskAssignedEventHandler = new TaskAssignedHandler(); return taskAssignedEventHandler.handleTaskAssigned(taskAssignedEvent); } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskEventHttpDispatcher.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskEventHttpDispatcher.java index 4f13af7..4c806d4 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskEventHttpDispatcher.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskEventHttpDispatcher.java @@ -3,10 +3,14 @@ package ch.unisg.tapastasks.tasks.adapter.in.messaging.http; import ch.unisg.tapastasks.tasks.adapter.in.formats.TaskJsonPatchRepresentation; import ch.unisg.tapastasks.tasks.adapter.in.formats.TaskJsonRepresentation; import ch.unisg.tapastasks.tasks.adapter.in.messaging.UnknownEventException; +import ch.unisg.tapastasks.tasks.application.port.in.TaskAssignedEventHandler; +import ch.unisg.tapastasks.tasks.application.port.in.TaskExecutedEventHandler; +import ch.unisg.tapastasks.tasks.application.port.in.TaskStartedEventHandler; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.TaskNotFoundException; import com.fasterxml.jackson.databind.JsonNode; import com.github.fge.jsonpatch.JsonPatch; +import lombok.RequiredArgsConstructor; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -37,6 +41,7 @@ import java.util.logging.Logger; * For some sample HTTP requests, see the README. */ @RestController +@RequiredArgsConstructor public class TaskEventHttpDispatcher { // The standard media type for JSON Patch registered with IANA // See: https://www.iana.org/assignments/media-types/application/json-patch+json @@ -44,6 +49,9 @@ public class TaskEventHttpDispatcher { Logger logger = Logger.getLogger(TaskEventHttpDispatcher.class.getName()); + private final TaskStartedEventHandler taskStartedEventHandler; + private final TaskAssignedEventHandler taskAssignedEventHandler; + private final TaskExecutedEventHandler taskExecutedEventHandler; /** * Handles HTTP PATCH requests with a JSON Patch payload. Routes the requests based on the * the operations requested in the patch. In this implementation, one HTTP Patch request is @@ -58,6 +66,7 @@ public class TaskEventHttpDispatcher { @PatchMapping(path = "/tasks/{taskId}", consumes = {JSON_PATCH_MEDIA_TYPE}) public ResponseEntity dispatchTaskEvents(@PathVariable("taskId") String taskId, @RequestBody JsonNode payload) { + logger.info("TaskList | Incoming patch task request for task: " + taskId); try { // Throw an exception if the JSON Patch format is invalid. This call is only used to @@ -74,13 +83,13 @@ public class TaskEventHttpDispatcher { if (status.isPresent()) { switch (status.get()) { case ASSIGNED: - listener = new TaskAssignedEventListenerHttpAdapter(); + listener = new TaskAssignedEventListenerHttpAdapter(taskAssignedEventHandler); break; case RUNNING: - listener = new TaskStartedEventListenerHttpAdapter(); + listener = new TaskStartedEventListenerHttpAdapter(taskStartedEventHandler); break; case EXECUTED: - listener = new TaskExecutedEventListenerHttpAdapter(); + listener = new TaskExecutedEventListenerHttpAdapter(taskExecutedEventHandler); break; default: break; diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskExecutedEventListenerHttpAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskExecutedEventListenerHttpAdapter.java index f1db541..0d567c7 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskExecutedEventListenerHttpAdapter.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskExecutedEventListenerHttpAdapter.java @@ -6,6 +6,7 @@ import ch.unisg.tapastasks.tasks.application.port.in.TaskExecutedEvent; import ch.unisg.tapastasks.tasks.application.port.in.TaskExecutedEventHandler; import ch.unisg.tapastasks.tasks.domain.Task; import com.fasterxml.jackson.databind.JsonNode; +import lombok.RequiredArgsConstructor; import java.util.Optional; @@ -17,8 +18,11 @@ import java.util.Optional; * * See also {@link TaskExecutedEvent}, {@link Task}, and {@link TaskEventHttpDispatcher}. */ +@RequiredArgsConstructor public class TaskExecutedEventListenerHttpAdapter extends TaskEventListener { + private final TaskExecutedEventHandler taskExecutedEventHandler; + public Task handleTaskEvent(String taskId, JsonNode payload) { TaskJsonPatchRepresentation representation = new TaskJsonPatchRepresentation(payload); @@ -27,7 +31,6 @@ public class TaskExecutedEventListenerHttpAdapter extends TaskEventListener { TaskExecutedEvent taskExecutedEvent = new TaskExecutedEvent(new Task.TaskId(taskId), serviceProvider, outputData); - TaskExecutedEventHandler taskExecutedEventHandler = new TaskExecutedHandler(); return taskExecutedEventHandler.handleTaskExecuted(taskExecutedEvent); } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskStartedEventListenerHttpAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskStartedEventListenerHttpAdapter.java index aa2f6b4..5cc12fc 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskStartedEventListenerHttpAdapter.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/messaging/http/TaskStartedEventListenerHttpAdapter.java @@ -7,6 +7,7 @@ import ch.unisg.tapastasks.tasks.application.port.in.TaskStartedEventHandler; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.Task.TaskId; import com.fasterxml.jackson.databind.JsonNode; +import lombok.RequiredArgsConstructor; import java.util.Optional; @@ -18,14 +19,16 @@ import java.util.Optional; * * See also {@link TaskStartedEvent}, {@link Task}, and {@link TaskEventHttpDispatcher}. */ +@RequiredArgsConstructor public class TaskStartedEventListenerHttpAdapter extends TaskEventListener { + private final TaskStartedEventHandler taskStartedEventHandler; + public Task handleTaskEvent(String taskId, JsonNode payload) { TaskJsonPatchRepresentation representation = new TaskJsonPatchRepresentation(payload); Optional serviceProvider = representation.extractFirstServiceProviderChange(); TaskStartedEvent taskStartedEvent = new TaskStartedEvent(new TaskId(taskId), serviceProvider); - TaskStartedEventHandler taskStartedEventHandler = new TaskStartedHandler(); return taskStartedEventHandler.handleTaskStarted(taskStartedEvent); } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/web/DeleteTaskWebController.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/web/DeleteTaskWebController.java index 11c2442..b6dc045 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/web/DeleteTaskWebController.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/in/web/DeleteTaskWebController.java @@ -9,9 +9,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ResponseStatusException; import javax.validation.ConstraintViolationException; @@ -26,10 +24,10 @@ public class DeleteTaskWebController { } // TODO change to DELETE and why are we using task URI here? - @PostMapping(path="/tasks/deleteTask", consumes = {TaskJsonRepresentation.MEDIA_TYPE}) - public ResponseEntity deleteTask (@RequestBody Task task){ + @DeleteMapping(path="/tasks/{taskId}") + public ResponseEntity deleteTask (@PathVariable String taskId){ try { - DeleteTaskCommand command = new DeleteTaskCommand(task.getTaskId(), task.getOriginalTaskUri()); + DeleteTaskCommand command = new DeleteTaskCommand(new Task.TaskId(taskId)); Optional deleteATask = deleteClassUseCase.deleteTask(command); diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java index 43ac2f9..d9d4273 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java @@ -1,7 +1,6 @@ package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import java.util.Objects; @@ -22,6 +21,7 @@ class TaskMapper { ); } + // TODO stupid task list name MongoTaskDocument mapToMongoDocument(Task task) { return new MongoTaskDocument( task.getTaskId().getValue(), @@ -31,7 +31,7 @@ class TaskMapper { task.getTaskStatus().getValue().toString(), Objects.isNull(task.getInputData()) ? null : task.getInputData().getValue(), Objects.isNull(task.getOutputData()) ? null : task.getOutputData().getValue(), - TaskList.getTapasTaskList().getTaskListName().getValue() + "task-list-name" ); } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java index a8cda22..5813323 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java @@ -1,9 +1,9 @@ package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; +import ch.unisg.tapastasks.tasks.application.port.out.DeleteTaskPort; import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -12,7 +12,8 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class TaskPersistenceAdapter implements AddTaskPort, - LoadTaskPort { + LoadTaskPort, + DeleteTaskPort { @Autowired private final TaskRepository taskRepository; @@ -26,8 +27,13 @@ public class TaskPersistenceAdapter implements } @Override - public Task loadTask(Task.TaskId taskId, TaskList.TaskListName taskListName) { - MongoTaskDocument mongoTaskDocument = taskRepository.findByTaskId(taskId.getValue(),taskListName.getValue()); + public Task loadTask(Task.TaskId taskId) { + MongoTaskDocument mongoTaskDocument = taskRepository.findByTaskId(taskId.getValue()); return taskMapper.mapToDomainEntity(mongoTaskDocument); } + + @Override + public void deleteTask(Task.TaskId taskId) { + taskRepository.deleteByTaskId(taskId.getValue()); + } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java index 867671c..a6585c7 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java @@ -8,7 +8,9 @@ import java.util.List; @Repository public interface TaskRepository extends MongoRepository { - public MongoTaskDocument findByTaskId(String taskId, String taskListName); + public MongoTaskDocument findByTaskId(String taskId); - public List findByTaskListName(String taskListName); + public List getAllBy(); + + public void deleteByTaskId(String taskId); } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskAssignedHandler.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskAssignedHandler.java index 7deb844..6c68130 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskAssignedHandler.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskAssignedHandler.java @@ -2,18 +2,36 @@ package ch.unisg.tapastasks.tasks.application.handler; import ch.unisg.tapastasks.tasks.application.port.in.TaskAssignedEvent; import ch.unisg.tapastasks.tasks.application.port.in.TaskAssignedEventHandler; +import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; +import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import ch.unisg.tapastasks.tasks.domain.TaskNotFoundException; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import javax.transaction.Transactional; +import java.util.Optional; + +@RequiredArgsConstructor @Component +@Transactional public class TaskAssignedHandler implements TaskAssignedEventHandler { + // TODO Why do we need this event handler when a service exists that does the same? + private final AddTaskPort addTaskToRepositoryPort; + private final LoadTaskPort loadTaskFromRepositoryPort; @Override public Task handleTaskAssigned(TaskAssignedEvent taskAssignedEvent) throws TaskNotFoundException { - TaskList taskList = TaskList.getTapasTaskList(); - return taskList.changeTaskStatusToAssigned(taskAssignedEvent.getTaskId(), - taskAssignedEvent.getServiceProvider()); + // retrieve the task based on ID + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(taskAssignedEvent.getTaskId())); + + // update the status to assigned + Task updatedTask = taskFromRepo.get(); + updatedTask.setTaskStatus(new Task.TaskStatus(Task.Status.ASSIGNED)); + + // save updated task in repo + addTaskToRepositoryPort.addTask(updatedTask); + + return updatedTask; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskExecutedHandler.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskExecutedHandler.java index ec21e8c..1cfed54 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskExecutedHandler.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskExecutedHandler.java @@ -2,18 +2,44 @@ package ch.unisg.tapastasks.tasks.application.handler; import ch.unisg.tapastasks.tasks.application.port.in.TaskExecutedEvent; import ch.unisg.tapastasks.tasks.application.port.in.TaskExecutedEventHandler; +import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; +import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import ch.unisg.tapastasks.tasks.domain.TaskNotFoundException; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import javax.transaction.Transactional; +import java.util.Optional; + +@RequiredArgsConstructor @Component +@Transactional public class TaskExecutedHandler implements TaskExecutedEventHandler { + private final AddTaskPort addTaskToRepositoryPort; + private final LoadTaskPort loadTaskFromRepositoryPort; + @Override public Task handleTaskExecuted(TaskExecutedEvent taskExecutedEvent) throws TaskNotFoundException { - TaskList taskList = TaskList.getTapasTaskList(); - return taskList.changeTaskStatusToExecuted(taskExecutedEvent.getTaskId(), - taskExecutedEvent.getServiceProvider(), taskExecutedEvent.getOutputData()); + // retrieve the task based on ID + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(taskExecutedEvent.getTaskId())); + + // update the status to assigned + Task updatedTask = taskFromRepo.get(); + updatedTask.setTaskStatus(new Task.TaskStatus(Task.Status.EXECUTED)); + + if(taskExecutedEvent.getServiceProvider().isPresent()){ + updatedTask.setProvider(taskExecutedEvent.getServiceProvider().get()); + } + + if(taskExecutedEvent.getOutputData().isPresent()){ + updatedTask.setOutputData(taskExecutedEvent.getOutputData().get()); + } + + // save updated task in repo + addTaskToRepositoryPort.addTask(updatedTask); + + return updatedTask; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskStartedHandler.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskStartedHandler.java index 758be0b..61428d9 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskStartedHandler.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/handler/TaskStartedHandler.java @@ -2,18 +2,40 @@ package ch.unisg.tapastasks.tasks.application.handler; import ch.unisg.tapastasks.tasks.application.port.in.TaskStartedEvent; import ch.unisg.tapastasks.tasks.application.port.in.TaskStartedEventHandler; +import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; +import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import ch.unisg.tapastasks.tasks.domain.TaskNotFoundException; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import javax.transaction.Transactional; +import java.util.Optional; + +@RequiredArgsConstructor @Component +@Transactional public class TaskStartedHandler implements TaskStartedEventHandler { + private final AddTaskPort addTaskToRepositoryPort; + private final LoadTaskPort loadTaskFromRepositoryPort; + @Override public Task handleTaskStarted(TaskStartedEvent taskStartedEvent) throws TaskNotFoundException { - TaskList taskList = TaskList.getTapasTaskList(); - return taskList.changeTaskStatusToRunning(taskStartedEvent.getTaskId(), - taskStartedEvent.getServiceProvider()); + // retrieve the task based on ID + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(taskStartedEvent.getTaskId())); + + // update the status to assigned + Task updatedTask = taskFromRepo.get(); + updatedTask.setTaskStatus(new Task.TaskStatus(Task.Status.RUNNING)); + + if(taskStartedEvent.getServiceProvider().isPresent()){ + updatedTask.setProvider(taskStartedEvent.getServiceProvider().get()); + } + + // save updated task in repo + addTaskToRepositoryPort.addTask(updatedTask); + + return updatedTask; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/in/DeleteTaskCommand.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/in/DeleteTaskCommand.java index e76c53a..7c30728 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/in/DeleteTaskCommand.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/in/DeleteTaskCommand.java @@ -14,12 +14,8 @@ public class DeleteTaskCommand extends SelfValidating { @NotNull private final TaskId taskId; - @NotNull - private final OriginalTaskUri taskUri; - - public DeleteTaskCommand(TaskId taskId, OriginalTaskUri taskUri){ + public DeleteTaskCommand(TaskId taskId){ this.taskId=taskId; - this.taskUri = taskUri; this.validateSelf(); } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/DeleteTaskPort.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/DeleteTaskPort.java new file mode 100644 index 0000000..3843a9d --- /dev/null +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/DeleteTaskPort.java @@ -0,0 +1,7 @@ +package ch.unisg.tapastasks.tasks.application.port.out; + +import ch.unisg.tapastasks.tasks.domain.Task; + +public interface DeleteTaskPort { + void deleteTask(Task.TaskId taskId); +} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java index acca3c0..c54bcdd 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java @@ -1,10 +1,9 @@ package ch.unisg.tapastasks.tasks.application.port.out; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; public interface LoadTaskPort { - Task loadTask(Task.TaskId taskId, TaskList.TaskListName taskListName); + Task loadTask(Task.TaskId taskId); } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java deleted file mode 100644 index 802abba..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java +++ /dev/null @@ -1,11 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.port.out; - -import ch.unisg.tapastasks.tasks.domain.TaskList; - -public interface TaskListLock { - - void lockTaskList(TaskList.TaskListName taskListName); - - void releaseTaskList(TaskList.TaskListName taskListName); - -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java index d8218c3..4b0c62e 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java @@ -4,11 +4,9 @@ import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListCommand import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListUseCase; import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; import ch.unisg.tapastasks.tasks.application.port.out.NewTaskAddedEventPort; -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.NewTaskAddedEvent; -import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @@ -28,34 +26,32 @@ public class AddNewTaskToTaskListService implements AddNewTaskToTaskListUseCase @Override public Task addNewTaskToTaskList(AddNewTaskToTaskListCommand command) { - TaskList taskList = TaskList.getTapasTaskList(); - Task newTask; if (command.getOriginalTaskUri().isPresent() && command.getInputData().isPresent()) { - newTask = taskList.addNewTaskWithNameAndTypeAndOriginalTaskUriAndInputData(command.getTaskName(), + newTask = Task.createTaskWithNameAndTypeAndOriginalTaskUriAndInputData(command.getTaskName(), command.getTaskType(), command.getOriginalTaskUri().get(), command.getInputData().get()); } else if (command.getOriginalTaskUri().isPresent()) { - newTask = taskList.addNewTaskWithNameAndTypeAndOriginalTaskUri(command.getTaskName(), + newTask = Task.createTaskWithNameAndTypeAndOriginalTaskUri(command.getTaskName(), command.getTaskType(), command.getOriginalTaskUri().get()); } else if (command.getInputData().isPresent()) { - newTask = taskList.addNewTaskWithNameAndTypeAndInputData(command.getTaskName(), + newTask = Task.createTaskWithNameAndTypeAndInputData(command.getTaskName(), command.getTaskType(), command.getInputData().get()); } else { - newTask = taskList.addNewTaskWithNameAndType(command.getTaskName(), command.getTaskType()); + newTask = Task.createTaskWithNameAndType(command.getTaskName(), command.getTaskType()); } - addTaskToRepositoryPort.addTask(newTask); - //Here we are using the application service to emit the domain event to the outside of the bounded context. //This event should be considered as a light-weight "integration event" to communicate with other services. //Domain events are usually rather "fat". In our implementation we simplify at this point. In general, it is //not recommended to emit a domain event via an application service! You should first emit the domain event in //the core and then the integration event in the application layer. + // TODO What to do with this task list name if (newTask != null) { + addTaskToRepositoryPort.addTask(newTask); NewTaskAddedEvent newTaskAdded = new NewTaskAddedEvent( newTask.getTaskName().getValue(), - taskList.getTaskListName().getValue(), + "tapas-tasks-group1", newTask.getTaskId().getValue(), newTask.getTaskType().getValue(), Objects.isNull(newTask.getInputData()) ? null : newTask.getInputData().getValue() diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/CompleteTaskService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/CompleteTaskService.java index 8ded0ea..af06613 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/CompleteTaskService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/CompleteTaskService.java @@ -2,11 +2,12 @@ package ch.unisg.tapastasks.tasks.application.service; import ch.unisg.tapastasks.tasks.application.port.in.CompleteTaskCommand; import ch.unisg.tapastasks.tasks.application.port.in.CompleteTaskUseCase; +import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; import ch.unisg.tapastasks.tasks.application.port.out.ExternalTaskExecutedEvent; import ch.unisg.tapastasks.tasks.application.port.out.ExternalTaskExecutedEventHandler; +import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.Task.*; -import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -18,26 +19,31 @@ import java.util.Optional; @Transactional public class CompleteTaskService implements CompleteTaskUseCase { + private final AddTaskPort addTaskToRepositoryPort; + private final LoadTaskPort loadTaskFromRepositoryPort; private final ExternalTaskExecutedEventHandler externalTaskExecutedEventHandler; @Override public Task completeTask(CompleteTaskCommand command){ - TaskList taskList = TaskList.getTapasTaskList(); - Optional updatedTask = taskList.retrieveTaskById(command.getTaskId()); + // retrieve the task based on ID + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(command.getTaskId())); - Task newTask = updatedTask.get(); - newTask.setOutputData(command.getOutputData()); - newTask.setTaskStatus(new TaskStatus(Task.Status.EXECUTED)); + Task updatedTask = taskFromRepo.get(); + updatedTask.setOutputData(command.getOutputData()); + updatedTask.setTaskStatus(new TaskStatus(Task.Status.EXECUTED)); - if (newTask.getOriginalTaskUri() != null) { + // save updated task in repo + addTaskToRepositoryPort.addTask(updatedTask); + + if (updatedTask.getOriginalTaskUri() != null) { ExternalTaskExecutedEvent event = new ExternalTaskExecutedEvent( - newTask.getTaskId(), - newTask.getOriginalTaskUri(), - newTask.getOutputData() + updatedTask.getTaskId(), + updatedTask.getOriginalTaskUri(), + updatedTask.getOutputData() ); externalTaskExecutedEventHandler.handleEvent(event); } - return newTask; + return updatedTask; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/DeleteTaskService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/DeleteTaskService.java index c3d392c..4ed47d1 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/DeleteTaskService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/DeleteTaskService.java @@ -3,10 +3,12 @@ package ch.unisg.tapastasks.tasks.application.service; import ch.unisg.tapastasks.tasks.application.port.in.DeleteTaskCommand; import ch.unisg.tapastasks.tasks.application.port.in.DeleteTaskUseCase; +import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; import ch.unisg.tapastasks.tasks.application.port.out.CanTaskBeDeletedPort; +import ch.unisg.tapastasks.tasks.application.port.out.DeleteTaskPort; +import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.DeleteTaskEvent; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import jdk.jshell.spi.ExecutionControl; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -19,18 +21,20 @@ import java.util.Optional; @Transactional public class DeleteTaskService implements DeleteTaskUseCase { + private final DeleteTaskPort deleteTaskFromRepositoryPort; + private final LoadTaskPort loadTaskFromRepositoryPort; private final CanTaskBeDeletedPort canTaskBeDeletedPort; @Override public Optional deleteTask(DeleteTaskCommand command){ + // retrieve the task based on ID + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(command.getTaskId())); - TaskList taskList = TaskList.getTapasTaskList(); - Optional updatedTask = taskList.retrieveTaskById(command.getTaskId()); - - if(updatedTask.isPresent() && updatedTask.get().getTaskStatus().getValue().equals(Task.Status.OPEN)){ + if(taskFromRepo.isPresent() && taskFromRepo.get().getTaskStatus().getValue().equals(Task.Status.OPEN)){ // If task exists, and it is open then we try deleting it from the roster - if(canTaskBeDeletedPort.canTaskBeDeletedEvent(new DeleteTaskEvent(command.getTaskId().getValue(), command.getTaskUri().getValue()))){ - return taskList.deleteTaskById(command.getTaskId()); + if(canTaskBeDeletedPort.canTaskBeDeletedEvent(new DeleteTaskEvent(command.getTaskId().getValue()))){ + deleteTaskFromRepositoryPort.deleteTask(taskFromRepo.get().getTaskId()); + return taskFromRepo; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java deleted file mode 100644 index 783dca1..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java +++ /dev/null @@ -1,18 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.service; - -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import org.springframework.stereotype.Component; - -@Component -public class NoOpTaskListLock implements TaskListLock { - @Override - public void lockTaskList(TaskList.TaskListName taskListName) { - //do nothing - } - - @Override - public void releaseTaskList(TaskList.TaskListName taskListName) { - //do nothing - } -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java index 696514b..a586c1b 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java @@ -4,7 +4,6 @@ import ch.unisg.tapastasks.tasks.application.port.in.RetrieveTaskFromTaskListQue import ch.unisg.tapastasks.tasks.application.port.in.RetrieveTaskFromTaskListUseCase; import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @@ -22,12 +21,9 @@ public class RetrieveTaskFromTaskListService implements RetrieveTaskFromTaskList @Override public Optional retrieveTaskFromTaskList(RetrieveTaskFromTaskListQuery query) { - TaskList taskList = TaskList.getTapasTaskList(); - Optional task = taskList.retrieveTaskById(query.getTaskId()); + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(query.getTaskId())); - Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(query.getTaskId(), taskList.getTaskListName())); - - return task; + return taskFromRepo; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/TaskAssignedService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/TaskAssignedService.java index fc13db3..bbb74ee 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/TaskAssignedService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/TaskAssignedService.java @@ -2,9 +2,10 @@ package ch.unisg.tapastasks.tasks.application.service; import ch.unisg.tapastasks.tasks.application.port.in.TaskAssignedCommand; import ch.unisg.tapastasks.tasks.application.port.in.TaskAssignedUseCase; +import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; +import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.Task.*; -import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -16,16 +17,21 @@ import java.util.Optional; @Transactional public class TaskAssignedService implements TaskAssignedUseCase { + private final AddTaskPort addTaskToRepositoryPort; + private final LoadTaskPort loadTaskFromRepositoryPort; + @Override public Task assignTask(TaskAssignedCommand command) { // retrieve the task based on ID - TaskList taskList = TaskList.getTapasTaskList(); - Optional task = taskList.retrieveTaskById(command.getTaskId()); + Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(command.getTaskId())); // update the status to assigned - Task updatedTask = task.get(); + Task updatedTask = taskFromRepo.get(); updatedTask.setTaskStatus(new TaskStatus(Status.ASSIGNED)); + // save updated task in repo + addTaskToRepositoryPort.addTask(updatedTask); + return updatedTask; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/DeleteTaskEvent.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/DeleteTaskEvent.java index 16e803b..9114b22 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/DeleteTaskEvent.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/DeleteTaskEvent.java @@ -2,10 +2,8 @@ package ch.unisg.tapastasks.tasks.domain; public class DeleteTaskEvent { public String taskId; - public String taskUri; - public DeleteTaskEvent(String taskId, String taskUri){ + public DeleteTaskEvent(String taskId){ this.taskId = taskId; - this.taskUri = taskUri; } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java index db650be..3fe7e1a 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java @@ -91,7 +91,7 @@ public class Task { this.outputData = outputData; } - protected static Task createTaskWithNameAndType(TaskName name, TaskType type) { + public static Task createTaskWithNameAndType(TaskName name, TaskType type) { return new Task(name, type); } @@ -100,13 +100,13 @@ public class Task { return new Task(name, type, originalTaskUri); } - protected static Task createTaskWithNameAndTypeAndInputData(TaskName name, TaskType type, - InputData inputData) { + public static Task createTaskWithNameAndTypeAndInputData(TaskName name, TaskType type, + InputData inputData) { return new Task(name, type, inputData); } - protected static Task createTaskWithNameAndTypeAndOriginalTaskUriAndInputData(TaskName name, TaskType type, - OriginalTaskUri originalTaskUri, InputData inputData) { + public static Task createTaskWithNameAndTypeAndOriginalTaskUriAndInputData(TaskName name, TaskType type, + OriginalTaskUri originalTaskUri, InputData inputData) { return new Task(name, type, originalTaskUri, inputData); } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/TaskList.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/TaskList.java deleted file mode 100644 index af1e82f..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/TaskList.java +++ /dev/null @@ -1,152 +0,0 @@ -package ch.unisg.tapastasks.tasks.domain; - -import lombok.Getter; -import lombok.Value; - -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; -import java.util.logging.Level; -import java.util.logging.Logger; - - -/**This is our aggregate root**/ -public class TaskList { - - Logger logger = Logger.getLogger(TaskList.class.getName()); - - @Getter - private final TaskListName taskListName; - - @Getter - private final ListOfTasks listOfTasks; - - //Note: We do not care about the management of task lists, there is only one within this service - //--> using the Singleton pattern here to make lives easy; we will later load it from a repo - - private static final TaskList taskList = new TaskList(new TaskListName("tapas-tasks-group1")); - - private TaskList(TaskListName taskListName) { - this.taskListName = taskListName; - this.listOfTasks = new ListOfTasks(new LinkedList()); - } - - public static TaskList getTapasTaskList() { - return taskList; - } - - //Only the aggregate root is allowed to create new tasks and add them to the task list. - //Note: Here we could add some sophisticated invariants/business rules that the aggregate root checks - public Task addNewTaskWithNameAndType(Task.TaskName name, Task.TaskType type) { - Task newTask = Task.createTaskWithNameAndType(name, type); - this.addNewTaskToList(newTask); - - return newTask; - } - - public Task addNewTaskWithNameAndTypeAndOriginalTaskUri(Task.TaskName name, Task.TaskType type, - Task.OriginalTaskUri originalTaskUri) { - Task newTask = Task.createTaskWithNameAndTypeAndOriginalTaskUri(name, type, originalTaskUri); - this.addNewTaskToList(newTask); - - return newTask; - } - - public Task addNewTaskWithNameAndTypeAndInputData(Task.TaskName name, Task.TaskType type, - Task.InputData inputData) { - Task newTask = Task.createTaskWithNameAndTypeAndInputData(name, type, inputData); - this.addNewTaskToList(newTask); - - return newTask; - } - - public Task addNewTaskWithNameAndTypeAndOriginalTaskUriAndInputData(Task.TaskName name, Task.TaskType type, - Task.OriginalTaskUri originalTaskUri, Task.InputData inputData) { - Task newTask = Task.createTaskWithNameAndTypeAndOriginalTaskUriAndInputData(name, type, originalTaskUri, inputData); - this.addNewTaskToList(newTask); - - return newTask; - } - - - private void addNewTaskToList(Task newTask) { - //Here we would also publish a domain event to other entities in the core interested in this event. - //However, we skip this here as it makes the core even more complex (e.g., we have to implement a light-weight - //domain event publisher and subscribers (see "Implementing Domain-Driven Design by V. Vernon, pp. 296ff). - listOfTasks.value.add(newTask); - String message = "New task created! Id: " + newTask.getTaskId().getValue() + - " | Name: " + newTask.getTaskName().getValue(); - if (newTask.getInputData() != null) { - message += " | Input data: " + newTask.getInputData().getValue(); - } - logger.log(Level.INFO, message); - logger.log(Level.INFO, "Number of tasks: {0}", listOfTasks.value.size()); - } - - public Optional retrieveTaskById(Task.TaskId id) { - for (Task task : listOfTasks.value) { - if (task.getTaskId().getValue().equalsIgnoreCase(id.getValue())) { - return Optional.of(task); - } - } - - return Optional.empty(); - } - - public Optional deleteTaskById(Task.TaskId id) { - for (Task task : listOfTasks.value) { - if (task.getTaskId().getValue().equalsIgnoreCase(id.getValue())) { - listOfTasks.value.remove(task); - return Optional.of(task); - } - } - - return Optional.empty(); - } - public Task changeTaskStatusToAssigned(Task.TaskId id, Optional serviceProvider) - throws TaskNotFoundException { - return changeTaskStatus(id, new Task.TaskStatus(Task.Status.ASSIGNED), serviceProvider, Optional.empty()); - } - - public Task changeTaskStatusToRunning(Task.TaskId id, Optional serviceProvider) - throws TaskNotFoundException { - return changeTaskStatus(id, new Task.TaskStatus(Task.Status.RUNNING), serviceProvider, Optional.empty()); - } - - public Task changeTaskStatusToExecuted(Task.TaskId id, Optional serviceProvider, - Optional outputData) throws TaskNotFoundException { - return changeTaskStatus(id, new Task.TaskStatus(Task.Status.EXECUTED), serviceProvider, outputData); - } - - private Task changeTaskStatus(Task.TaskId id, Task.TaskStatus status, Optional serviceProvider, - Optional outputData) { - Optional taskOpt = retrieveTaskById(id); - - if (taskOpt.isEmpty()) { - throw new TaskNotFoundException(); - } - - Task task = taskOpt.get(); - task.setTaskStatus(status); - - if (serviceProvider.isPresent()) { - task.setProvider(serviceProvider.get()); - } - - if (outputData.isPresent()) { - task.setOutputData(outputData.get()); - } - - return task; - } - - @Value - public static class TaskListName { - private String value; - } - - @Value - public static class ListOfTasks { - private List value; - } -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java index e17c2e2..3d7b51d 100644 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java +++ b/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java @@ -3,7 +3,6 @@ package ch.unisg.tapastasks; import ch.unisg.tapastasks.tasks.adapter.in.formats.TaskJsonRepresentation; import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Test; @@ -42,7 +41,7 @@ public class AddNewTaskToTaskListSystemTest { then(respTaskId).isNotEmpty(); then(respTaskName).isEqualTo(taskName.getValue()); then(respTaskType).isEqualTo(taskType.getValue()); - then(TaskList.getTapasTaskList().getListOfTasks().getValue()).hasSize(1); + //then(TaskList.getTapasTaskList().getListOfTasks().getValue()).hasSize(1); } @@ -51,7 +50,7 @@ public class AddNewTaskToTaskListSystemTest { Task.TaskType taskType, Task.OriginalTaskUri originalTaskUri) throws JSONException { - TaskList.getTapasTaskList().getListOfTasks().getValue().clear(); + //TaskList.getTapasTaskList().getListOfTasks().getValue().clear(); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", TaskJsonRepresentation.MEDIA_TYPE); diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java index 886b8ac..e7ceee8 100644 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java +++ b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java @@ -1,7 +1,6 @@ package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo; @@ -45,7 +44,7 @@ public class TaskPersistenceAdapterTest { ); adapterUnderTest.addTask(testTask); - MongoTaskDocument retrievedDoc = taskRepository.findByTaskId(testTaskId,testTaskListName); + MongoTaskDocument retrievedDoc = taskRepository.findByTaskId(testTaskId); assertThat(retrievedDoc.taskId).isEqualTo(testTaskId); assertThat(retrievedDoc.taskName).isEqualTo(testTaskName); diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java index 5584c35..d73a165 100644 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java +++ b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java @@ -3,10 +3,8 @@ package ch.unisg.tapastasks.tasks.application.service; import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListCommand; import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; import ch.unisg.tapastasks.tasks.application.port.out.NewTaskAddedEventPort; -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; import ch.unisg.tapastasks.tasks.domain.NewTaskAddedEvent; import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -19,7 +17,6 @@ import static org.assertj.core.api.Assertions.*; public class AddNewTaskToTaskListServiceTest { private final AddTaskPort addTaskPort = Mockito.mock(AddTaskPort.class); - private final TaskListLock taskListLock = Mockito.mock(TaskListLock.class); private final NewTaskAddedEventPort newTaskAddedEventPort = Mockito.mock(NewTaskAddedEventPort.class); private final AddNewTaskToTaskListService addNewTaskToTaskListService = new AddNewTaskToTaskListService( newTaskAddedEventPort, addTaskPort); @@ -46,11 +43,6 @@ public class AddNewTaskToTaskListServiceTest { } - private TaskList givenAnEmptyTaskList(TaskList taskList) { - taskList.getListOfTasks().getValue().clear(); - return taskList; - } - private Task givenATaskWithNameAndTypeAndURI(Task.TaskName taskName, Task.TaskType taskType, Optional originalTaskUri) { Task task = Mockito.mock(Task.class); diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java index 05dc664..cc467db 100644 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java +++ b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java @@ -11,7 +11,7 @@ public class TaskListTest { @Test void addNewTaskToTaskListSuccess() { - TaskList taskList = TaskList.getTapasTaskList(); + /*TaskList taskList = TaskList.getTapasTaskList(); taskList.getListOfTasks().getValue().clear(); Task newTask = taskList.addNewTaskWithNameAndType(new Task.TaskName("My-Test-Task"), new Task.TaskType("My-Test-Type")); @@ -19,11 +19,12 @@ public class TaskListTest { assertThat(newTask.getTaskName().getValue()).isEqualTo("My-Test-Task"); assertThat(taskList.getListOfTasks().getValue()).hasSize(1); assertThat(taskList.getListOfTasks().getValue().get(0)).isEqualTo(newTask); - +*/ } @Test void retrieveTaskSuccess() { + /* TaskList taskList = TaskList.getTapasTaskList(); Task newTask = taskList.addNewTaskWithNameAndType(new Task.TaskName("My-Test-Task2"), new Task.TaskType("My-Test-Type2")); @@ -31,11 +32,12 @@ public class TaskListTest { Task retrievedTask = taskList.retrieveTaskById(newTask.getTaskId()).get(); assertThat(retrievedTask).isEqualTo(newTask); - +*/ } @Test void retrieveTaskFailure() { + /* TaskList taskList = TaskList.getTapasTaskList(); Task newTask = taskList.addNewTaskWithNameAndType(new Task.TaskName("My-Test-Task3"), new Task.TaskType("My-Test-Type3")); @@ -45,5 +47,7 @@ public class TaskListTest { Optional retrievedTask = taskList.retrieveTaskById(fakeId); assertThat(retrievedTask.isPresent()).isFalse(); + + */ } } -- 2.45.1 From 0022ebaf885267a5c22b5b72d82cca33e039eee8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 18 Dec 2021 16:18:54 +0100 Subject: [PATCH 2/6] added humidity executor to deployment --- .deployment/docker-compose.yml | 22 +++++++++ .github/workflows/build-and-deploy.yml | 4 ++ .../executor/domain/Executor.java | 8 ++-- .../out/web/PublishNewTaskEventAdapter.java | 45 +++++++++++++------ 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/.deployment/docker-compose.yml b/.deployment/docker-compose.yml index 666f162..12684cd 100644 --- a/.deployment/docker-compose.yml +++ b/.deployment/docker-compose.yml @@ -91,6 +91,7 @@ services: auction.house.uri: http://tapas-auction-house:8086 executor.robot.uri: http://executor-robot:8084 executor.computation.uri: http://executor-computation:8085 + executor.humidity.uri: http://executor-humidity:8087 mqtt.broker.uri: tcp://broker.hivemq.com:1883 spring.data.mongodb.uri: mongodb://root:password@tapas-db:27017 labels: @@ -164,3 +165,24 @@ services: - "traefik.http.routers.executor-robot.tls=true" - "traefik.http.routers.executor-robot.entryPoints=web,websecure" - "traefik.http.routers.executor-robot.tls.certresolver=le" + executor-humidity: + image: openjdk + command: "java -jar /data/executor-humidity-0.0.1-SNAPSHOT.jar" + restart: unless-stopped + depends_on: + - executor-pool + - roster + - tapas-db + volumes: + - ./:/data/ + environment: + EXECUTOR_POOL_URI: http://executor-pool:8083 + ROSTER_URI: http://roster:8082 + labels: + - "traefik.enable=true" + - "traefik.http.routers.executor-computation.rule=Host(`executor-humidity.${PUB_IP}.nip.io`)" + - "traefik.http.routers.executor-computation.service=executor-computation" + - "traefik.http.services.executor-computation.loadbalancer.server.port=8087" + - "traefik.http.routers.executor-computation.tls=true" + - "traefik.http.routers.executor-computation.entryPoints=web,websecure" + - "traefik.http.routers.executor-computation.tls.certresolver=le" diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 7290452..54f74be 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -55,6 +55,10 @@ jobs: run: mvn -f executor-robot/pom.xml --batch-mode --update-snapshots verify - run: cp ./executor-robot/target/executor-robot-0.0.1-SNAPSHOT.jar ./target + - name: Build executor-humidity service + run: mvn -f executor-humidity/pom.xml --batch-mode --update-snapshots verify + - run: cp ./executor-humidity/target/executor-humidity-0.0.1-SNAPSHOT.jar ./target + - name: Build tapas-task service run: mvn -f tapas-tasks/pom.xml --batch-mode --update-snapshots verify - run: cp ./tapas-tasks/target/tapas-tasks-0.0.1-SNAPSHOT.jar ./target diff --git a/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java b/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java index 6c0cb59..788d558 100644 --- a/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java +++ b/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java @@ -29,7 +29,6 @@ public class Executor extends ExecutorBase { protected String execution(String inputData) { - executorLogger.info("TEST"); executorLogger.info("Executor | Starting execution with inputData: " + inputData); ScriptEngineManager mgr = new ScriptEngineManager(); @@ -45,10 +44,11 @@ public class Executor extends ExecutorBase { } try { - TimeUnit.SECONDS.sleep(5); + TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { - executorLogger.log(Level.SEVERE, e.getLocalizedMessage(), e); - Thread.currentThread().interrupt(); + return result; + // executorLogger.log(Level.SEVERE, e.getLocalizedMessage(), e); + // Thread.currentThread().interrupt(); } executorLogger.info("Executor | Finish execution"); diff --git a/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishNewTaskEventAdapter.java b/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishNewTaskEventAdapter.java index 3349522..d4fa2c3 100644 --- a/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishNewTaskEventAdapter.java +++ b/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishNewTaskEventAdapter.java @@ -25,6 +25,9 @@ public class PublishNewTaskEventAdapter implements NewTaskEventPort { @Value("${executor.computation.uri}") private String server2; + @Value("${executor.humidity.uri}") + private String server3; + Logger logger = Logger.getLogger(PublishNewTaskEventAdapter.class.getName()); /** @@ -34,21 +37,21 @@ public class PublishNewTaskEventAdapter implements NewTaskEventPort { @Override public void publishNewTaskEvent(NewTaskEvent event) { - // HttpClient client = HttpClient.newHttpClient(); - // HttpRequest request = HttpRequest.newBuilder() - // .uri(URI.create(server + "/newtask/" + event.taskType.getValue())) - // .GET() - // .build(); + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(server + "/newtask/" + event.taskType.getValue())) + .GET() + .build(); - // try { - // client.send(request, HttpResponse.BodyHandlers.ofString()); - // } catch (InterruptedException e) { - // logger.log(Level.SEVERE, e.getLocalizedMessage(), e); - // Thread.currentThread().interrupt(); - // } catch (IOException e) { - // logger.log(Level.SEVERE, e.getLocalizedMessage(), e); - // } + try { + client.send(request, HttpResponse.BodyHandlers.ofString()); + } catch (InterruptedException e) { + logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + Thread.currentThread().interrupt(); + } catch (IOException e) { + logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + } HttpClient client2 = HttpClient.newHttpClient(); HttpRequest request2 = HttpRequest.newBuilder() @@ -65,6 +68,22 @@ public class PublishNewTaskEventAdapter implements NewTaskEventPort { } catch (IOException e) { logger.log(Level.SEVERE, e.getLocalizedMessage(), e); } + + HttpClient client3 = HttpClient.newHttpClient(); + HttpRequest request3 = HttpRequest.newBuilder() + .uri(URI.create(server3 + "/newtask/" + event.taskType.getValue())) + .GET() + .build(); + + + try { + client3.send(request3, HttpResponse.BodyHandlers.ofString()); + } catch (InterruptedException e) { + logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + Thread.currentThread().interrupt(); + } catch (IOException e) { + logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + } } } -- 2.45.1 From 0eb21d2083e9093523cbba5034fb15480bfe22d5 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 19 Dec 2021 16:33:11 +0100 Subject: [PATCH 3/6] fixes --- .../executor/domain/ExecutorType.java | 2 +- .../ExecutorcomputationApplication.java | 8 - executor-robot/pom.xml | 9 +- .../ExecutorrobotApplication.java | 8 - .../out/DeleteUserFromRobotAdapter.java | 42 ---- .../out/InstructionToRobotAdapter.java | 121 --------- .../adapter/out/UserToRobotAdapter.java | 231 +++++++++++++----- .../port/out/DeleteUserFromRobotPort.java | 5 - .../port/out/InstructionToRobotPort.java | 5 - .../executor/domain/Executor.java | 29 +-- .../tapas/TapasAuctionHouseApplication.java | 44 ++-- .../web/AuctionHouseDiscoveryHttpAdapter.java | 4 +- .../service/StartAuctionService.java | 11 +- .../domain/AuctionHouseDiscovery.java | 9 +- .../src/main/resources/application.properties | 2 +- 15 files changed, 225 insertions(+), 305 deletions(-) delete mode 100644 executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/DeleteUserFromRobotAdapter.java delete mode 100644 executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/InstructionToRobotAdapter.java delete mode 100644 executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/DeleteUserFromRobotPort.java delete mode 100644 executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/InstructionToRobotPort.java diff --git a/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorType.java b/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorType.java index 30460e6..5ad22a7 100644 --- a/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorType.java +++ b/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorType.java @@ -1,7 +1,7 @@ package ch.unisg.executorbase.executor.domain; public enum ExecutorType { - COMPUTATION, ROBOT, HUMIDITY; + COMPUTATION, SMALLROBOT, HUMIDITY; /** * Checks if the give executor type exists. diff --git a/executor-computation/src/main/java/ch/unisg/executorcomputation/ExecutorcomputationApplication.java b/executor-computation/src/main/java/ch/unisg/executorcomputation/ExecutorcomputationApplication.java index ea9910a..1ee615d 100644 --- a/executor-computation/src/main/java/ch/unisg/executorcomputation/ExecutorcomputationApplication.java +++ b/executor-computation/src/main/java/ch/unisg/executorcomputation/ExecutorcomputationApplication.java @@ -15,14 +15,6 @@ public class ExecutorcomputationApplication { static Logger logger = Logger.getLogger(ExecutorcomputationApplication.class.getName()); public static void main(String[] args) { - - try { - TimeUnit.SECONDS.sleep(1); - } catch (InterruptedException e) { - logger.log(Level.SEVERE, e.getLocalizedMessage(), e); - Thread.currentThread().interrupt(); - } - SpringApplication.run(ExecutorcomputationApplication.class, args); Executor.getExecutor(); } diff --git a/executor-robot/pom.xml b/executor-robot/pom.xml index 570bd18..2fa8a0f 100644 --- a/executor-robot/pom.xml +++ b/executor-robot/pom.xml @@ -82,11 +82,10 @@ compile - com.github.Interactions-HSG - wot-td-java - 0.1.1 - compile - + com.github.Interactions-HSG + wot-td-java + master-SNAPSHOT + diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/ExecutorrobotApplication.java b/executor-robot/src/main/java/ch/unisg/executorrobot/ExecutorrobotApplication.java index 79a204f..15e2491 100644 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/ExecutorrobotApplication.java +++ b/executor-robot/src/main/java/ch/unisg/executorrobot/ExecutorrobotApplication.java @@ -11,14 +11,6 @@ import ch.unisg.executorrobot.executor.domain.Executor; public class ExecutorrobotApplication { public static void main(String[] args) { - - try { - TimeUnit.SECONDS.sleep(40); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - SpringApplication.run(ExecutorrobotApplication.class, args); Executor.getExecutor(); } diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/DeleteUserFromRobotAdapter.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/DeleteUserFromRobotAdapter.java deleted file mode 100644 index 37b605a..0000000 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/DeleteUserFromRobotAdapter.java +++ /dev/null @@ -1,42 +0,0 @@ -package ch.unisg.executorrobot.executor.adapter.out; -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; - -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; - -import ch.unisg.executorrobot.executor.application.port.out.DeleteUserFromRobotPort; - -@Component -@Primary -public class DeleteUserFromRobotAdapter implements DeleteUserFromRobotPort { - - @Override - public boolean deleteUserFromRobot(String key) { - - String url = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.4/user/" + key; - - var request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .header("Content-Type", "application/json") - .DELETE() - .build(); - - var client = HttpClient.newHttpClient(); - - try { - var response = client.send(request, HttpResponse.BodyHandlers.ofString()); - System.out.println(response.statusCode()); - return true; - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return false; - } - -} diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/InstructionToRobotAdapter.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/InstructionToRobotAdapter.java deleted file mode 100644 index 763e530..0000000 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/InstructionToRobotAdapter.java +++ /dev/null @@ -1,121 +0,0 @@ -package ch.unisg.executorrobot.executor.adapter.out; -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import ch.unisg.ics.interactions.wot.td.ThingDescription; -import ch.unisg.ics.interactions.wot.td.affordances.ActionAffordance; -import ch.unisg.ics.interactions.wot.td.affordances.Form; -import ch.unisg.ics.interactions.wot.td.clients.TDHttpRequest; -import ch.unisg.ics.interactions.wot.td.clients.TDHttpResponse; -import ch.unisg.ics.interactions.wot.td.io.TDGraphReader; -import ch.unisg.ics.interactions.wot.td.schemas.DataSchema; -import ch.unisg.ics.interactions.wot.td.schemas.ObjectSchema; -import ch.unisg.ics.interactions.wot.td.schemas.StringSchema; -import ch.unisg.ics.interactions.wot.td.security.APIKeySecurityScheme; -import ch.unisg.ics.interactions.wot.td.vocabularies.TD; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; - -import ch.unisg.executorrobot.executor.application.port.out.InstructionToRobotPort; - -@Component -@Primary -public class InstructionToRobotAdapter implements InstructionToRobotPort { - - @Override - public boolean instructionToRobot(String key) { - - String endpoint = "https://api.interactions.ics.unisg.ch/search/searchEngine"; - - String input = "@prefix dct: . select ?title where { ?title dct:title 'leubot1' }"; - - var httpRequest = HttpRequest.newBuilder() - .uri(URI.create(endpoint)) - .header("Content-Type", "application/json") - .POST(HttpRequest.BodyPublishers.ofString(input)) - .build(); - - var client = HttpClient.newHttpClient(); - - try { - var description = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body(); - - // Parse a TD from a string - ThingDescription td = TDGraphReader.readFromString(ThingDescription.TDFormat.RDF_TURTLE, description); - - // Create the payload to be sent with the Http request - Map elbowPayload = new HashMap<>(); - elbowPayload.put("http://www.w3.org/2001/XMLSchema#int", 400); - - // Get the affordance "setElbow" from the TD - Optional action = td.getActionByName("setElbow"); - - // Get the first form - if (action.isPresent()) { - Optional
form = action.get().getFirstForm(); - - // Retrieve the input data schema from the action affordance - Optional inputSchema = action.get().getInputSchema(); - - // If a form is found, use it to create and execute the Http request - if (form.isPresent()) { - TDHttpRequest request = new TDHttpRequest(form.get(), TD.invokeAction); - - if (inputSchema.isPresent()) { - request.setObjectPayload((ObjectSchema) inputSchema.get(), elbowPayload); - - try { - TDHttpResponse response = request.execute(); - System.out.println("Received response with status code: " + response.getStatusCode()); - return true; - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } - - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return false; - - - - - /* - String putEndpoint = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.0/elbow"; - - String inputJson = "{ \"value\": 400}"; - var request = HttpRequest.newBuilder() - .uri(URI.create(putEndpoint)) - .header("Content-Type", "application/json") - .header("X-API-KEY", key) - .PUT(HttpRequest.BodyPublishers.ofString(inputJson)) - .build(); - - var client = HttpClient.newHttpClient(); - - try { - var response = client.send(request, HttpResponse.BodyHandlers.ofString()); - System.out.println(response.statusCode()); - System.out.println(response.headers()); - return true; - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return false; - */ - } - -} diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/UserToRobotAdapter.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/UserToRobotAdapter.java index b2db44f..deb4a8b 100644 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/UserToRobotAdapter.java +++ b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/adapter/out/UserToRobotAdapter.java @@ -1,5 +1,6 @@ package ch.unisg.executorrobot.executor.adapter.out; import java.io.IOException; +import java.io.StringReader; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -7,6 +8,11 @@ import java.net.http.HttpResponse; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import ch.unisg.ics.interactions.wot.td.ThingDescription; import ch.unisg.ics.interactions.wot.td.affordances.ActionAffordance; @@ -16,10 +22,19 @@ import ch.unisg.ics.interactions.wot.td.clients.TDHttpResponse; import ch.unisg.ics.interactions.wot.td.io.TDGraphReader; import ch.unisg.ics.interactions.wot.td.schemas.DataSchema; import ch.unisg.ics.interactions.wot.td.schemas.ObjectSchema; +import ch.unisg.ics.interactions.wot.td.security.APIKeySecurityScheme; +import ch.unisg.ics.interactions.wot.td.security.SecurityScheme; import ch.unisg.ics.interactions.wot.td.vocabularies.TD; +import ch.unisg.ics.interactions.wot.td.vocabularies.WoTSec; + import org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import ch.unisg.executorrobot.executor.application.port.out.UserToRobotPort; @@ -32,7 +47,7 @@ public class UserToRobotAdapter implements UserToRobotPort { String endpoint = "https://api.interactions.ics.unisg.ch/search/searchEngine"; - String input = "@prefix dct: . select ?title where { ?title dct:title 'Mirogate' }"; + String input = "@prefix dct: . select ?title where { ?title dct:title 'leubot1' }"; var httpRequest = HttpRequest.newBuilder() .uri(URI.create(endpoint)) @@ -43,82 +58,184 @@ public class UserToRobotAdapter implements UserToRobotPort { var client = HttpClient.newHttpClient(); try { - var description = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body(); + String description = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body(); + String leubot1Uri = null; - String uri = "http://yggdrasil.interactions.ics.unisg.ch/environments/61/workspaces/102/artifacts/leubot1"; + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new InputSource(new StringReader(description))); - // Parse a TD from a string - ThingDescription td = TDGraphReader.readFromURL(ThingDescription.TDFormat.RDF_TURTLE, uri); + doc.getDocumentElement().normalize(); - // Create the payload to be sent with the HTTP request - Map logInPayload = new HashMap<>(); - logInPayload.put("http://xmlns.com/foaf/0.1/Name", "keanu rahimian"); - logInPayload.put("http://xmlns.com/foaf/0.1/Mbox", "keanu.rahimian@student.unisg.ch"); - - // Get the affordance "Log-In" from the TD - Optional action = td.getActionByName("logIn"); - - // Get the first form - if (action.isPresent()) { - Optional form = action.get().getFirstForm(); - - // Retrieve the input data schema from the action affordance - Optional inputSchema = action.get().getInputSchema(); - - // If a form is found, use it to create and execute the HTTP request - if (form.isPresent()) { - TDHttpRequest request = new TDHttpRequest(form.get(), TD.invokeAction); - - if (inputSchema.isPresent()) { - request.setObjectPayload((ObjectSchema) inputSchema.get(), logInPayload); - - try { - TDHttpResponse response = request.execute(); - System.out.println("Received response with status code: " + response.getStatusCode()); - - // TODO: Get the key from the response and return it - // Not exactly sure how to get the headers from the payload, as we need them - // to get the key - - return null; - - } catch (IOException e) { - e.printStackTrace(); - } - } + NodeList results = doc.getElementsByTagName("uri"); + for (int temp = 0; temp < results.getLength(); temp += 1) { + Node nNode = results.item(temp); + if (nNode.getTextContent().contains("leubot1")) { + leubot1Uri = nNode.getTextContent(); } } + if (leubot1Uri == null) { + // TODO implement logic if execution failed + return "ERROR"; + } + + // Parse a TD from a string + ThingDescription td = TDGraphReader.readFromURL(ThingDescription.TDFormat.RDF_TURTLE, leubot1Uri); + + String apiUrl = getAPIKey(td); + System.out.println("FOUND API URL " + apiUrl); + + String apiKey = apiUrl.split("/")[apiUrl.split("/").length-1].split("]")[0]; + System.out.println("FOUND KEY " + apiKey); + + if(apiKey == null) { + // TODO implement logic if execution failed + return "ERROR"; + } + + try { + TimeUnit.MILLISECONDS.sleep(1500); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if (!moveRobot(td, apiKey)) { + return "ERROR"; + } + + try { + TimeUnit.MILLISECONDS.sleep(1500); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + delteUserFromRobot(apiUrl); + } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); + } catch (SAXException e1) { + e1.printStackTrace(); + } catch (ParserConfigurationException e1) { + e1.printStackTrace(); + } + return "OK"; + } + + + private String getAPIKey(ThingDescription td) { + // Create the payload to be sent with the HTTP request + Map logInPayload = new HashMap<>(); + logInPayload.put("http://xmlns.com/foaf/0.1/Name", "keanu rahimian"); + logInPayload.put("http://xmlns.com/foaf/0.1/Mbox", "keanu.rahimian@student.unisg.ch"); + + // Get the affordance "Log-In" from the TD + Optional action = td.getActionByName("logIn"); + + // Get the first form + if (action.isEmpty()) { + // TODO implement logic if execution failed + return null; } - /* - String inputJson = "{ \"name\":\"keanu rahimian\", \"email\":\"keanu.rahimian@student.unisg.ch\"}"; - var request = HttpRequest.newBuilder() - .uri(URI.create(postEndpoint)) - .header("Content-Type", "application/json") - .POST(HttpRequest.BodyPublishers.ofString(inputJson)) - .build(); + Optional form = action.get().getFirstFormForOperationType(TD.invokeAction); + + if (form.isEmpty()) { + // TODO implement logic if execution failed + return null; + } + + // If a form is found, use it to create and execute the HTTP request + TDHttpRequest request = new TDHttpRequest(form.get(), TD.invokeAction); + + // Retrieve the input data schema from the action affordance + Optional inputSchema = action.get().getInputSchema(); + + if(inputSchema.isPresent()) { + request.setObjectPayload((ObjectSchema) inputSchema.get(), logInPayload); + } + + try { + TDHttpResponse response = request.execute(); + System.out.println("Received response with status code: " + response.getStatusCode()); + + String url = response.getHeaders().get("Location"); + return url; + + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + + } + + private boolean moveRobot(ThingDescription td, String key) { + + // Create the payload to be sent with the Http request + Map elbowPayload = new HashMap<>(); + elbowPayload.put("value", 400); + + // Get the affordance "setElbow" from the TD + Optional action = td.getActionByName("setElbow"); + + // Get the first form + if (action.isEmpty()) { + return false; + } + + Optional form = action.get().getFirstFormForOperationType(TD.invokeAction); + + if (form.isEmpty()) { + // TODO implement logic if execution failed + return false; + } + + // Retrieve the input data schema from the action affordance + Optional inputSchema = action.get().getInputSchema(); + + TDHttpRequest request = new TDHttpRequest(form.get(), TD.invokeAction); + + if(inputSchema.isPresent()) { + request.setObjectPayload((ObjectSchema) inputSchema.get(), elbowPayload); + } + + Optional securityScheme = td.getFirstSecuritySchemeByType(WoTSec.APIKeySecurityScheme); + if (securityScheme.isPresent()) { + request.setAPIKey((APIKeySecurityScheme) securityScheme.get(), key); + } + + try { + TDHttpResponse response = request.execute(); + System.out.println("Received response with status code: " + response.getStatusCode()); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + + return false; + } + + private void delteUserFromRobot(String apiUrl) { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(apiUrl)) + .header("Content-Type", "application/json") + .DELETE() + .build(); + + HttpClient client = HttpClient.newHttpClient(); try { var response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); - System.out.println(response.headers()); - String url = response.headers().map().get("location").toString(); - String key = url.split("/")[url.split("/").length-1].split("]")[0]; - return key; } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } - return null; - */ - - - return null; } } diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/DeleteUserFromRobotPort.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/DeleteUserFromRobotPort.java deleted file mode 100644 index 2411353..0000000 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/DeleteUserFromRobotPort.java +++ /dev/null @@ -1,5 +0,0 @@ -package ch.unisg.executorrobot.executor.application.port.out; - -public interface DeleteUserFromRobotPort { - boolean deleteUserFromRobot(String key); -} diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/InstructionToRobotPort.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/InstructionToRobotPort.java deleted file mode 100644 index 97985b0..0000000 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/application/port/out/InstructionToRobotPort.java +++ /dev/null @@ -1,5 +0,0 @@ -package ch.unisg.executorrobot.executor.application.port.out; - -public interface InstructionToRobotPort { - boolean instructionToRobot(String key); -} diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java index e83579c..cc08bc1 100644 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java +++ b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java @@ -1,22 +1,14 @@ package ch.unisg.executorrobot.executor.domain; -import java.util.concurrent.TimeUnit; - -import ch.unisg.executorrobot.executor.adapter.out.DeleteUserFromRobotAdapter; -import ch.unisg.executorrobot.executor.adapter.out.InstructionToRobotAdapter; import ch.unisg.executorrobot.executor.adapter.out.UserToRobotAdapter; -import ch.unisg.executorrobot.executor.application.port.out.DeleteUserFromRobotPort; -import ch.unisg.executorrobot.executor.application.port.out.InstructionToRobotPort; import ch.unisg.executorrobot.executor.application.port.out.UserToRobotPort; import ch.unisg.executorbase.executor.domain.ExecutorBase; import ch.unisg.executorbase.executor.domain.ExecutorType; public class Executor extends ExecutorBase { - private static final Executor executor = new Executor(ExecutorType.ROBOT); + private static final Executor executor = new Executor(ExecutorType.SMALLROBOT); private final UserToRobotPort userToRobotPort = new UserToRobotAdapter(); - private final InstructionToRobotPort instructionToRobotPort = new InstructionToRobotAdapter(); - private final DeleteUserFromRobotPort deleteUserFromRobotPort = new DeleteUserFromRobotAdapter(); public static Executor getExecutor() { return executor; @@ -29,24 +21,7 @@ public class Executor extends ExecutorBase { @Override protected String execution(String input) { - - String key = userToRobotPort.userToRobot(); - try { - TimeUnit.MILLISECONDS.sleep(1500); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - boolean result1 = instructionToRobotPort.instructionToRobot(key); - try { - TimeUnit.MILLISECONDS.sleep(10000); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - deleteUserFromRobotPort.deleteUserFromRobot(key); - - return Boolean.toString(result1); + return userToRobotPort.userToRobot(); } } diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java index ff6b95c..c57c8c5 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java @@ -4,6 +4,10 @@ import ch.unisg.tapas.auctionhouse.adapter.common.clients.TapasMqttClient; import ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt.AuctionEventsMqttDispatcher; import ch.unisg.tapas.auctionhouse.adapter.common.clients.WebSubSubscriber; import ch.unisg.tapas.auctionhouse.application.service.GetExecutorsService; +import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscovery; +import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation; +import ch.unisg.tapas.common.AuctionHouseResourceDirectory; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.paho.client.mqttv3.MqttException; @@ -13,6 +17,9 @@ import org.springframework.core.env.ConfigurableEnvironment; import java.net.URI; import java.net.URISyntaxException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * Main TAPAS Auction House application. @@ -30,7 +37,7 @@ public class TapasAuctionHouseApplication { ENVIRONMENT = tapasAuctioneerApp.run(args).getEnvironment(); // TODO Set start up of message services with config // We will use these bootstrap methods in Week 6: - // bootstrapMarketplaceWithWebSub(); + bootstrapMarketplaceWithWebSub(); bootstrapMarketplaceWithMqtt(); var getExecutorsService = new GetExecutorsService(); getExecutorsService.getExecutorsFromExecutorPool(); @@ -39,19 +46,20 @@ public class TapasAuctionHouseApplication { * Discovers auction houses and subscribes to WebSub notifications */ private static void bootstrapMarketplaceWithWebSub() { - // discoverAuctionHouseEndpoints(); + discoverAuctionHouseEndpoints(); WebSubSubscriber subscriber = new WebSubSubscriber(ENVIRONMENT.getProperty("auction.house.uri")); - // for (AuctionHouseDiscoveryInformation endpoint : AuctionHouseDiscovery.getInstance().getAuctionHouseDiscoveryList()) { - // subscriber.subscribeToAuctionHouseEndpoint(endpoint.getWebSubUri().getValue()); - // } - try { - subscriber.subscribeToAuctionHouseEndpoint(new URI("http://6b4e-130-82-250-227.ngrok.io/websub-discovery")); - } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + for (AuctionHouseDiscoveryInformation endpoint : AuctionHouseDiscovery.getInstance().getAuctionHouseDiscoveryList()) { + System.out.println(endpoint.getWebSubUri().getValue()); + subscriber.subscribeToAuctionHouseEndpoint(endpoint.getWebSubUri().getValue()); } + // try { + // subscriber.subscribeToAuctionHouseEndpoint(new URI("http://6b4e-130-82-250-227.ngrok.io/websub-discovery")); + // } catch (URISyntaxException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } } /** @@ -76,17 +84,17 @@ public class TapasAuctionHouseApplication { } } - // private static void discoverAuctionHouseEndpoints() { + private static void discoverAuctionHouseEndpoints() { - // AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory( - // URI.create(ENVIRONMENT.getProperty("discovery.endpoint.uri")) - // ); + AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory( + URI.create(ENVIRONMENT.getProperty("discovery.endpoint.uri")) + ); - // AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints()); + AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints()); - // ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); - // executor.scheduleAtFixedRate(crawlerRunnable, 300, 300, TimeUnit.SECONDS); - // } + // ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + // executor.scheduleAtFixedRate(crawlerRunnable, 300, 300, TimeUnit.SECONDS); + } // private static Runnable crawlerRunnable = new Runnable() { diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java index e37c989..e9f5a04 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java @@ -41,8 +41,8 @@ public class AuctionHouseDiscoveryHttpAdapter implements AuctionHouseDiscoveryPo { var informationJSON = arrayOfInformation.getJSONObject(i); var information = new AuctionHouseDiscoveryInformation( - new AuctionHouseDiscoveryInformation.AuctionHouseUri(URI.create(informationJSON.getString("auctionHouseURI"))), - new AuctionHouseDiscoveryInformation.WebSubUri(URI.create(informationJSON.getString("webSubURI"))), + new AuctionHouseDiscoveryInformation.AuctionHouseUri(URI.create(informationJSON.getString("auctionHouseUri"))), + new AuctionHouseDiscoveryInformation.WebSubUri(URI.create(informationJSON.getString("webSubUri"))), new AuctionHouseDiscoveryInformation.TaskTypes(getTaskTypes(informationJSON.getJSONArray("taskTypes"))), new AuctionHouseDiscoveryInformation.TimeStamp(Timestamp.valueOf(informationJSON.getString("timeStamp"))), new AuctionHouseDiscoveryInformation.GroupName(informationJSON.getString("groupName")) diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/application/service/StartAuctionService.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/application/service/StartAuctionService.java index 7839b5b..f0f1546 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/application/service/StartAuctionService.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/application/service/StartAuctionService.java @@ -65,8 +65,17 @@ public class StartAuctionService implements LaunchAuctionUseCase { auctions.addAuction(auction); // Schedule the closing of the auction at the deadline - service.schedule(new CloseAuctionTask(auction.getAuctionId()), deadline.getValue().getTime() - System.currentTimeMillis(), + System.out.println(deadline.getValue().getTime()); + System.out.println(System.currentTimeMillis()); + System.out.println(deadline.getValue().getTime() - System.currentTimeMillis()); + if (deadline.getValue().getTime() == DEFAULT_AUCTION_DEADLINE_MILLIS.getTime()) { + System.out.println("DEFAULT TIMESTAMP USED"); + service.schedule(new CloseAuctionTask(auction.getAuctionId()), 10000, TimeUnit.MILLISECONDS); + } else { + service.schedule(new CloseAuctionTask(auction.getAuctionId()), deadline.getValue().getTime() - System.currentTimeMillis(), + TimeUnit.MILLISECONDS); + } // Publish an auction started event AuctionStartedEvent auctionStartedEvent = new AuctionStartedEvent(auction); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/domain/AuctionHouseDiscovery.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/domain/AuctionHouseDiscovery.java index c234b64..c51ec98 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/domain/AuctionHouseDiscovery.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/domain/AuctionHouseDiscovery.java @@ -15,8 +15,9 @@ public class AuctionHouseDiscovery { private final List tasktypes = new ArrayList() { { - add("computation"); - add("smallrobot"); + add("COMPUTATION"); + add("SMALLROBOT"); + add("HUMIDITY"); } }; @@ -31,8 +32,8 @@ public class AuctionHouseDiscovery { try { // Add our information to list auctionHouseDiscoveryList.add(new AuctionHouseDiscoveryInformation( - new AuctionHouseDiscoveryInformation.AuctionHouseUri(new URI("http://localhost:8086")), - new AuctionHouseDiscoveryInformation.WebSubUri(new URI("http://localhost:8086/websub/auctions")), + new AuctionHouseDiscoveryInformation.AuctionHouseUri(new URI("https://tapas-auction-house.86-119-35-40.nip.io")), + new AuctionHouseDiscoveryInformation.WebSubUri(new URI("https://tapas-auction-house.86-119-35-40.nip.io/websub/auctions")), new AuctionHouseDiscoveryInformation.TaskTypes(tasktypes), new AuctionHouseDiscoveryInformation.TimeStamp(new Timestamp(new Date().getTime())), new AuctionHouseDiscoveryInformation.GroupName("Group 1") diff --git a/tapas-auction-house/src/main/resources/application.properties b/tapas-auction-house/src/main/resources/application.properties index 03a5542..dade5ce 100644 --- a/tapas-auction-house/src/main/resources/application.properties +++ b/tapas-auction-house/src/main/resources/application.properties @@ -15,4 +15,4 @@ websub.hub.uri=https://pubsubhubbub.appspot.com mqtt.broker.uri=tcp://broker.hivemq.com # mqtt.broker.uri=tcp://localhost:1883 -discovery.endpoint.uri=http://localhost:3500 +discovery.endpoint.uri=https://tapas-auction-house.86-119-34-242.nip.io -- 2.45.1 From 56788d7150adcdd443e9235ebcbc3f126de229d8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 21 Dec 2021 15:30:33 +0100 Subject: [PATCH 4/6] bugfixes --- .deployment/docker-compose.yml | 3 +- .github/workflows/build-and-deploy.yml | 3 +- executor-computation/pom.xml | 11 +++++ executor-humidity/pom.xml | 2 +- .../executor/domain/Executor.java | 3 +- .../tapas/TapasAuctionHouseApplication.java | 6 ++- .../common/clients/WebSubSubscriber.java | 3 ++ ...uctionStartedEventListenerMqttAdapter.java | 6 +-- ...tionStartedEventListenerWebSubAdapter.java | 6 +-- .../AuctionHouseDiscoveryWebController.java | 2 +- .../in/web/WinningBidWebController.java | 6 ++- ...blishAuctionStartedEventWebSubAdapter.java | 1 + .../web/AuctionHouseDiscoveryHttpAdapter.java | 44 ++++++++++--------- .../out/web/AuctionWonEventHttpAdapter.java | 7 ++- .../src/main/resources/application.properties | 1 - .../web/ExternalTaskExecutedWebAdapter.java | 2 +- .../src/main/resources/application.properties | 2 +- 17 files changed, 66 insertions(+), 42 deletions(-) diff --git a/.deployment/docker-compose.yml b/.deployment/docker-compose.yml index 12684cd..a23fa53 100644 --- a/.deployment/docker-compose.yml +++ b/.deployment/docker-compose.yml @@ -67,8 +67,9 @@ services: - ./:/data/ environment: mqtt.broker.uri: tcp://broker.hivemq.com:1883 - discovery.endpoint.uri: https://tapas-auction-house.86.119.35.213.nip.io/discovery/ + discovery.endpoint.uri: https://tapas-auction-house.86-119-34-242.nip.io auction.house.uri: https://tapas-auction-house.86-119-35-40.nip.io + tasks.list.uri: https://tapas-tasks.86-119-35-40.nip.io labels: - "traefik.enable=true" - "traefik.http.routers.tapas-auction-house.rule=Host(`tapas-auction-house.${PUB_IP}.nip.io`)" diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 54f74be..cc46404 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -107,5 +107,6 @@ jobs: cd /home/${{ secrets.SSH_USER }}/ touch acme.json sudo chmod 0600 acme.json + sudo docker-compose down --remove-orphans sudo echo "PUB_IP=$(wget -qO- http://ipecho.net/plain | xargs echo)" | sed -e 's/\./-/g' > .env - sudo docker-compose up -d --build --force-recreate + sudo docker-compose up -d diff --git a/executor-computation/pom.xml b/executor-computation/pom.xml index 8692c3e..c6c5167 100644 --- a/executor-computation/pom.xml +++ b/executor-computation/pom.xml @@ -67,6 +67,17 @@ org.springframework.boot spring-boot-test + + + org.graalvm.js + js + 21.3.0 + + + org.graalvm.js + js-scriptengine + 21.3.0 + diff --git a/executor-humidity/pom.xml b/executor-humidity/pom.xml index 001c752..f6390b0 100644 --- a/executor-humidity/pom.xml +++ b/executor-humidity/pom.xml @@ -11,7 +11,7 @@ ch.unisg executor-humidity - 1.0-SNAPSHOT + 0.0.1-SNAPSHOT executor-humidity Demo project for Spring Boot diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java index cc08bc1..4468f14 100644 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java +++ b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java @@ -21,7 +21,8 @@ public class Executor extends ExecutorBase { @Override protected String execution(String input) { - return userToRobotPort.userToRobot(); + userToRobotPort.userToRobot(); + return ""; } } diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java index c57c8c5..f738311 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java @@ -51,8 +51,10 @@ public class TapasAuctionHouseApplication { WebSubSubscriber subscriber = new WebSubSubscriber(ENVIRONMENT.getProperty("auction.house.uri")); for (AuctionHouseDiscoveryInformation endpoint : AuctionHouseDiscovery.getInstance().getAuctionHouseDiscoveryList()) { - System.out.println(endpoint.getWebSubUri().getValue()); - subscriber.subscribeToAuctionHouseEndpoint(endpoint.getWebSubUri().getValue()); + // Don't subscribe to our own auction house + if (!endpoint.getWebSubUri().getValue().toString().equalsIgnoreCase("https://tapas-auction-house.86-119-35-40.nip.io/websub/auctions")) { + subscriber.subscribeToAuctionHouseEndpoint(endpoint.getWebSubUri().getValue()); + } } // try { // subscriber.subscribeToAuctionHouseEndpoint(new URI("http://6b4e-130-82-250-227.ngrok.io/websub-discovery")); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/common/clients/WebSubSubscriber.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/common/clients/WebSubSubscriber.java index ea74603..c73faa0 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/common/clients/WebSubSubscriber.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/common/clients/WebSubSubscriber.java @@ -101,6 +101,9 @@ public class WebSubSubscriber { return; } + System.out.println("HUB: " + hub); + System.out.println("TOPIC: " + topic); + HttpRequest request = HttpRequest.newBuilder() .uri(hubURI) .header("Content-Type", "application/x-www-form-urlencoded") diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/mqtt/ExternalAuctionStartedEventListenerMqttAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/mqtt/ExternalAuctionStartedEventListenerMqttAdapter.java index c952771..50e145c 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/mqtt/ExternalAuctionStartedEventListenerMqttAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/mqtt/ExternalAuctionStartedEventListenerMqttAdapter.java @@ -22,11 +22,9 @@ import java.net.http.HttpResponse; public class ExternalAuctionStartedEventListenerMqttAdapter extends AuctionEventMqttListener{ private static final Logger LOGGER = LogManager.getLogger(ExternalAuctionStartedEventListenerMqttAdapter.class); - // String auctionHouseURI = "https://tapas-auction-house.86-119-35-40.nip.io/"; - String auctionHouseURI = "http://a888-77-59-152-182.eu.ngrok.io"; + String auctionHouseURI = "https://tapas-auction-house.86-119-35-40.nip.io/"; - // String taskListURI = "https://tapas-tasks.86-119-35-40.nip.io"; - String taskListURI = "http://e021-77-59-152-182.ngrok.io"; + String taskListURI = "https://tapas-tasks.86-119-35-40.nip.io"; @Override public boolean handleEvent(MqttMessage message){ diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/websub/AuctionStartedEventListenerWebSubAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/websub/AuctionStartedEventListenerWebSubAdapter.java index 520e0a5..5da2733 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/websub/AuctionStartedEventListenerWebSubAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/messaging/websub/AuctionStartedEventListenerWebSubAdapter.java @@ -69,11 +69,9 @@ public class AuctionStartedEventListenerWebSubAdapter { // } - // String auctionHouseURI = "https://tapas-auction-house.86-119-35-40.nip.io/"; - String auctionHouseURI = "http://b311-130-82-247-153.eu.ngrok.io"; + String auctionHouseURI = "https://tapas-auction-house.86-119-35-40.nip.io/"; - // String taskListURI = "https://tapas-tasks.86-119-35-40.nip.io"; - String taskListURI = "http://c64f-130-82-247-153.ngrok.io"; + String taskListURI = "https://tapas-tasks.86-119-35-40.nip.io"; // TODO Sanitize URIs String auctionId = auction.getString("auctionId"); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/AuctionHouseDiscoveryWebController.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/AuctionHouseDiscoveryWebController.java index 22fbb09..8c184fa 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/AuctionHouseDiscoveryWebController.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/AuctionHouseDiscoveryWebController.java @@ -30,7 +30,7 @@ public class AuctionHouseDiscoveryWebController { this.auctionHouseDiscoveryUseCase = auctionHouseDiscoveryUseCase; } - @GetMapping(path="/discovery/", consumes = AuctionHouseDiscoveryJsonRepresentation.MEDIA_TYPE) + @GetMapping(path="/discovery/") public ResponseEntity auctionHouseDiscovery() { List auctionHouseDiscoveryInformation = auctionHouseDiscoveryUseCase.auctionHouseDiscovery(); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java index cad0538..6dbc820 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java @@ -27,9 +27,11 @@ public class WinningBidWebController { @PostMapping(path = "/taskwinner", consumes = TaskJsonRepresentation.MEDIA_TYPE) public ResponseEntity winningBid(@RequestBody TaskJsonRepresentation payload){ + LOGGER.info("New Task Winner"); try { var body = payload.serialize(); - LOGGER.info(body); + LOGGER.info("Task Winner body: " + body); + LOGGER.info("Task Winner taskListURI: " + taskListURI); var postURI = URI.create(taskListURI + "/tasks/"); HttpRequest postRequest = HttpRequest.newBuilder() .uri(postURI) @@ -40,7 +42,7 @@ public class WinningBidWebController { HttpClient client = HttpClient.newHttpClient(); var postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString()); - LOGGER.info(postResponse.statusCode()); + LOGGER.info("Create task internally with status code: " + postResponse.statusCode()); HttpHeaders responseHeaders = new HttpHeaders(); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/messaging/websub/PublishAuctionStartedEventWebSubAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/messaging/websub/PublishAuctionStartedEventWebSubAdapter.java index ccb1225..77e51a8 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/messaging/websub/PublishAuctionStartedEventWebSubAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/messaging/websub/PublishAuctionStartedEventWebSubAdapter.java @@ -32,6 +32,7 @@ public class PublishAuctionStartedEventWebSubAdapter implements AuctionStartedEv @Override public void publishAuctionStartedEvent(AuctionStartedEvent event) { logger.info("AuctionHouse | Publish auction started over WebSub!"); + logger.info("AuctionHouse | AuctionHouseURI: " + auctionHouseUri + " WebSubHubUri: " + webSubHubUri); HttpClient client = HttpClient.newHttpClient(); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java index e9f5a04..1db4a18 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionHouseDiscoveryHttpAdapter.java @@ -6,6 +6,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.JSONArray; import org.json.JSONObject; +import org.springframework.http.HttpStatus; import java.io.IOException; import java.net.URI; @@ -22,36 +23,37 @@ public class AuctionHouseDiscoveryHttpAdapter implements AuctionHouseDiscoveryPo public List fetchAuctionHouseInformation(URI auctionHouseURI){ - System.out.println(auctionHouseURI); - try{ var client = HttpClient.newHttpClient(); var request = HttpRequest.newBuilder() .uri(auctionHouseURI) .GET() .build(); - var response = client.send(request, HttpResponse.BodyHandlers.ofString()); - LOGGER.info(response.body()); - var responseBody = new JSONObject(response.body()); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + LOGGER.info("Response status code: " + response.statusCode()); + LOGGER.info("Response body:" + response.body()); + if (response.statusCode() == HttpStatus.OK.value()) { + var responseBody = new JSONObject(response.body()); - var arrayOfInformation = responseBody.getJSONArray("auctionHouseInfo"); - var returnList = new LinkedList(); + var arrayOfInformation = responseBody.getJSONArray("auctionHouseInfo"); + var returnList = new LinkedList(); - for(int i = 0; i < arrayOfInformation.length(); i++) - { - var informationJSON = arrayOfInformation.getJSONObject(i); - var information = new AuctionHouseDiscoveryInformation( - new AuctionHouseDiscoveryInformation.AuctionHouseUri(URI.create(informationJSON.getString("auctionHouseUri"))), - new AuctionHouseDiscoveryInformation.WebSubUri(URI.create(informationJSON.getString("webSubUri"))), - new AuctionHouseDiscoveryInformation.TaskTypes(getTaskTypes(informationJSON.getJSONArray("taskTypes"))), - new AuctionHouseDiscoveryInformation.TimeStamp(Timestamp.valueOf(informationJSON.getString("timeStamp"))), - new AuctionHouseDiscoveryInformation.GroupName(informationJSON.getString("groupName")) - ); - returnList.add(information); - } - - return returnList; + for(int i = 0; i < arrayOfInformation.length(); i++) + { + var informationJSON = arrayOfInformation.getJSONObject(i); + var information = new AuctionHouseDiscoveryInformation( + new AuctionHouseDiscoveryInformation.AuctionHouseUri(URI.create(informationJSON.getString("auctionHouseUri"))), + new AuctionHouseDiscoveryInformation.WebSubUri(URI.create(informationJSON.getString("webSubUri"))), + new AuctionHouseDiscoveryInformation.TaskTypes(getTaskTypes(informationJSON.getJSONArray("taskTypes"))), + new AuctionHouseDiscoveryInformation.TimeStamp(Timestamp.valueOf(informationJSON.getString("timeStamp"))), + new AuctionHouseDiscoveryInformation.GroupName(informationJSON.getString("groupName")) + ); + returnList.add(information); + } + return returnList; + } + return Collections.emptyList(); } catch (IOException e) { e.printStackTrace(); return Collections.emptyList(); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java index 607c2c7..e89e1e3 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java @@ -52,13 +52,18 @@ public class AuctionWonEventHttpAdapter implements AuctionWonEventPort { LOGGER.info(response.body()); JSONObject responseBody = new JSONObject(response.body()); + String inputData = ""; + if (!responseBody.isNull("inputData")) { + inputData = responseBody.getString("inputData"); + } + var task = new Task( new Task.TaskName(responseBody.getString("taskName")), new Task.TaskType(responseBody.getString("taskType")), new Task.OriginalTaskUri(auction.get().getTaskUri().getValue().toString()), new Task.TaskStatus(ch.unisg.tapas.auctionhouse.domain.Task.Status.ASSIGNED), new Task.TaskId(responseBody.getString("taskId")), - new Task.InputData(responseBody.getString("inputData")), + new Task.InputData(inputData), new Task.ServiceProvider("TODO") ); diff --git a/tapas-auction-house/src/main/resources/application.properties b/tapas-auction-house/src/main/resources/application.properties index dade5ce..508f27b 100644 --- a/tapas-auction-house/src/main/resources/application.properties +++ b/tapas-auction-house/src/main/resources/application.properties @@ -7,7 +7,6 @@ websub.hub.publish=https://websub.appspot.com/ group=tapas-group-1 auction.house.uri=https://tapas-auction-house.86-119-35-40.nip.io -# auction.house.uri=http://a888-77-59-152-182.eu.ngrok.io tasks.list.uri=http://localhost:8081 application.environment=development diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java index 8d28159..b74e89b 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java @@ -43,7 +43,7 @@ public class ExternalTaskExecutedWebAdapter implements ExternalTaskExecutedEvent op2 = new JSONObject() .put("op", "add") .put("path", "/outputData") - .put("value", externalTaskExecutedEvent.getOutputData()); + .put("value", externalTaskExecutedEvent.getOutputData().getValue()); } catch (JSONException e) { logger.log(Level.SEVERE, e.getLocalizedMessage(), e); return; diff --git a/tapas-tasks/src/main/resources/application.properties b/tapas-tasks/src/main/resources/application.properties index 08b86d0..20e7f41 100644 --- a/tapas-tasks/src/main/resources/application.properties +++ b/tapas-tasks/src/main/resources/application.properties @@ -2,7 +2,7 @@ server.port=8081 spring.data.mongodb.uri=mongodb://root:password@localhost:27017/ spring.data.mongodb.database=tapas-tasks # baseuri=http://e021-77-59-152-182.ngrok.io/ -baseuri=https://tapas-tasks.86-119-34-23.nip.io/ +baseuri=https://tapas-tasks.86-119-35-40.nip.io/ roster.uri=http://127.0.0.1:8082 -- 2.45.1 From 1153b75322bf7790f028ef1f837e4d57e6823129 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 22 Dec 2021 13:04:03 +0100 Subject: [PATCH 5/6] use json patch --- .../executor/domain/ExecutorBase.java | 5 +- .../executor/domain/Executor.java | 7 ++- .../executor/domain/Executor.java | 11 ++-- .../executor/domain/Executor.java | 6 +-- .../web/PublishTaskAssignedEventAdapter.java | 44 ++++++++++++---- .../web/PublishTaskCompletedEventAdapter.java | 52 +++++++++++++++---- 6 files changed, 88 insertions(+), 37 deletions(-) diff --git a/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorBase.java b/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorBase.java index fca2758..aeafb4d 100644 --- a/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorBase.java +++ b/executor-base/src/main/java/ch/unisg/executorBase/executor/domain/ExecutorBase.java @@ -33,12 +33,11 @@ public abstract class ExecutorBase { Logger logger = Logger.getLogger(ExecutorBase.class.getName()); - protected ExecutorBase(ExecutorType executorType) { + protected ExecutorBase(ExecutorType executorType, String uri) { logger.info("ExecutorBase | Starting Executor"); this.status = ExecutorStatus.STARTING_UP; this.executorType = executorType; - // TODO set this automaticly - this.executorURI = new ExecutorURI("http://localhost:8084"); + this.executorURI = new ExecutorURI(uri); // TODO do this in main // Notify executor-pool about existence. If executor-pools response is successfull start with getting an assignment, else shut down executor. logger.info("ExecutorBase | Notifying executor-pool about existens"); diff --git a/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java b/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java index 788d558..bd22336 100644 --- a/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java +++ b/executor-computation/src/main/java/ch/unisg/executorcomputation/executor/domain/Executor.java @@ -1,7 +1,6 @@ package ch.unisg.executorcomputation.executor.domain; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; import java.util.logging.Logger; import javax.script.ScriptEngine; @@ -15,14 +14,14 @@ public class Executor extends ExecutorBase { private static Logger executorLogger = Logger.getLogger(Executor.class.getName()); - private static final Executor executor = new Executor(ExecutorType.COMPUTATION); + private static final Executor executor = new Executor(ExecutorType.COMPUTATION, "http://localhost:8085"); public static Executor getExecutor() { return executor; } - private Executor(ExecutorType executorType) { - super(executorType); + private Executor(ExecutorType executorType, String uri) { + super(executorType, uri); } @Override diff --git a/executor-humidity/src/main/java/ch/unisg/executorhumidity/executor/domain/Executor.java b/executor-humidity/src/main/java/ch/unisg/executorhumidity/executor/domain/Executor.java index 1e888aa..9205100 100644 --- a/executor-humidity/src/main/java/ch/unisg/executorhumidity/executor/domain/Executor.java +++ b/executor-humidity/src/main/java/ch/unisg/executorhumidity/executor/domain/Executor.java @@ -4,17 +4,16 @@ import ch.unisg.executorbase.executor.domain.ExecutorBase; import ch.unisg.executorbase.executor.domain.ExecutorType; import ch.unisg.executorhumidity.executor.adapter.out.GetHumidityAdapter; import ch.unisg.executorhumidity.executor.application.port.out.GetHumidityPort; -import org.eclipse.californium.elements.exception.ConnectorException; - -import java.io.IOException; public class Executor extends ExecutorBase { - private static final Executor executor = new Executor(ExecutorType.HUMIDITY); + private static final Executor executor = new Executor(ExecutorType.HUMIDITY, "http://localhost:8087"); private final GetHumidityPort getHumidityPort = new GetHumidityAdapter(); - private Executor(ExecutorType executorType) {super(executorType);} + private Executor(ExecutorType executorType, String uri) { + super(executorType, uri); + } public static Executor getExecutor() {return executor;} @@ -22,8 +21,6 @@ public class Executor extends ExecutorBase { @Override protected String execution(String input) { - //TODO: Fill - String result = getHumidityPort.getHumidity(); return result; diff --git a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java index 4468f14..2bf2489 100644 --- a/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java +++ b/executor-robot/src/main/java/ch/unisg/executorrobot/executor/domain/Executor.java @@ -7,15 +7,15 @@ import ch.unisg.executorbase.executor.domain.ExecutorType; public class Executor extends ExecutorBase { - private static final Executor executor = new Executor(ExecutorType.SMALLROBOT); + private static final Executor executor = new Executor(ExecutorType.SMALLROBOT, "http://localhost:8084"); private final UserToRobotPort userToRobotPort = new UserToRobotAdapter(); public static Executor getExecutor() { return executor; } - private Executor(ExecutorType executorType) { - super(executorType); + private Executor(ExecutorType executorType, String uri) { + super(executorType, uri); } @Override diff --git a/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskAssignedEventAdapter.java b/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskAssignedEventAdapter.java index d83c9c2..0902b03 100644 --- a/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskAssignedEventAdapter.java +++ b/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskAssignedEventAdapter.java @@ -8,6 +8,7 @@ import java.net.http.HttpResponse; import java.util.logging.Level; import java.util.logging.Logger; +import org.json.JSONArray; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Primary; @@ -32,19 +33,22 @@ public class PublishTaskAssignedEventAdapter implements TaskAssignedEventPort { @Override public void publishTaskAssignedEvent(TaskAssignedEvent event) { - String body = new JSONObject() - .put("taskId", event.taskID) - .toString(); + try { - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(server + "/tasks/assignTask")) + JSONObject op1 = new JSONObject() + .put("op", "replace") + .put("path", "/taskStatus") + .put("value", "ASSIGNED"); + + String body = new JSONArray().put(op1).toString(); + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(server + "/tasks/" + event.taskID)) .header("Content-Type", "application/task+json") - .POST(HttpRequest.BodyPublishers.ofString(body)) + .method("PATCH", HttpRequest.BodyPublishers.ofString(body)) .build(); - - try { client.send(request, HttpResponse.BodyHandlers.ofString()); } catch (InterruptedException e) { logger.log(Level.SEVERE, e.getLocalizedMessage(), e); @@ -52,6 +56,28 @@ public class PublishTaskAssignedEventAdapter implements TaskAssignedEventPort { } catch (IOException e) { logger.log(Level.SEVERE, e.getLocalizedMessage(), e); } + + + // String body = new JSONObject() + // .put("taskId", event.taskID) + // .toString(); + + // HttpClient client = HttpClient.newHttpClient(); + // HttpRequest request = HttpRequest.newBuilder() + // .uri(URI.create(server + "/tasks/assignTask")) + // .header("Content-Type", "application/task+json") + // .POST(HttpRequest.BodyPublishers.ofString(body)) + // .build(); + + + // try { + // client.send(request, HttpResponse.BodyHandlers.ofString()); + // } catch (InterruptedException e) { + // logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + // Thread.currentThread().interrupt(); + // } catch (IOException e) { + // logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + // } } } diff --git a/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskCompletedEventAdapter.java b/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskCompletedEventAdapter.java index 8ea95ec..116121a 100644 --- a/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskCompletedEventAdapter.java +++ b/roster/src/main/java/ch/unisg/roster/roster/adapter/out/web/PublishTaskCompletedEventAdapter.java @@ -8,6 +8,7 @@ import java.net.http.HttpResponse; import java.util.logging.Level; import java.util.logging.Logger; +import org.json.JSONArray; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Primary; @@ -32,21 +33,27 @@ public class PublishTaskCompletedEventAdapter implements TaskCompletedEventPort @Override public void publishTaskCompleted(TaskCompletedEvent event) { - String body = new JSONObject() - .put("taskId", event.taskID) - .put("status", event.status) - .put("outputData", event.result) - .toString(); + try { - HttpClient client = HttpClient.newHttpClient(); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(server + "/tasks/completeTask/")) + JSONObject op1 = new JSONObject() + .put("op", "replace") + .put("path", "/taskStatus") + .put("value", event.status); + + JSONObject op2 = new JSONObject() + .put("op", "replace") + .put("path", "/outputData") + .put("value", event.result); + + String body = new JSONArray().put(op1).put(op2).toString(); + + HttpClient client = HttpClient.newHttpClient(); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(server + "/tasks/" + event.taskID)) .header("Content-Type", "application/task+json") - .POST(HttpRequest.BodyPublishers.ofString(body)) + .method("PATCH", HttpRequest.BodyPublishers.ofString(body)) .build(); - - try { client.send(request, HttpResponse.BodyHandlers.ofString()); } catch (InterruptedException e) { logger.log(Level.SEVERE, e.getLocalizedMessage(), e); @@ -55,6 +62,29 @@ public class PublishTaskCompletedEventAdapter implements TaskCompletedEventPort logger.log(Level.SEVERE, e.getLocalizedMessage(), e); } + // String body = new JSONObject() + // .put("taskId", event.taskID) + // .put("status", event.status) + // .put("outputData", event.result) + // .toString(); + + // HttpClient client = HttpClient.newHttpClient(); + // HttpRequest request = HttpRequest.newBuilder() + // .uri(URI.create(server + "/tasks/completeTask/")) + // .header("Content-Type", "application/task+json") + // .POST(HttpRequest.BodyPublishers.ofString(body)) + // .build(); + + + // try { + // client.send(request, HttpResponse.BodyHandlers.ofString()); + // } catch (InterruptedException e) { + // logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + // Thread.currentThread().interrupt(); + // } catch (IOException e) { + // logger.log(Level.SEVERE, e.getLocalizedMessage(), e); + // } + } } -- 2.45.1 From 8faabb4d4481fc3fa5ebc379aa1b5e3af646caea Mon Sep 17 00:00:00 2001 From: reynisson Date: Wed, 22 Dec 2021 15:55:48 +0000 Subject: [PATCH 6/6] Final submission draft --- .../0001-record-architecture-decisions.md | 0 ...0002-seperate-service-for-executor-pool.md | 29 ++++++++++++++++++ .../0003-seperate-service-for-roster.md | 0 .../0004-seperate-service-for-task-list.md | 0 .../0005-event-driven-communication.md | 0 ...al-database-or-one-database-per-service.md | 0 ...0007-seperate-service-for-auction-house.md | 0 ...event-driven-microservices-architecture.md | 0 .../0009-common-library-for-shared-code.md | 0 .../decisions/0010-executor-base-library.md | 0 ...ion-of-common-and-executor-base-library.md | 0 ...0012-separate-service-for-each-executor.md | 27 ++++++++++++++++ ...0012-seperate-service-for-each-executor.md | 0 .../0013-microservice-architecture.md | 0 .../decisions/0014-data-ownership.md | 0 {doc => TAPAS-Final/doc}/workflow.bpmn | 0 {doc => TAPAS-Final/doc}/workflow.png | Bin ...0002-seperate-service-for-executor-pool.md | 21 ------------- 18 files changed, 56 insertions(+), 21 deletions(-) rename {doc => TAPAS-Final/doc}/architecture/decisions/0001-record-architecture-decisions.md (100%) create mode 100644 TAPAS-Final/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md rename {doc => TAPAS-Final/doc}/architecture/decisions/0003-seperate-service-for-roster.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0004-seperate-service-for-task-list.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0005-event-driven-communication.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0006-one-global-database-or-one-database-per-service.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0007-seperate-service-for-auction-house.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0009-common-library-for-shared-code.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0010-executor-base-library.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0011-seperation-of-common-and-executor-base-library.md (100%) create mode 100644 TAPAS-Final/doc/architecture/decisions/0012-separate-service-for-each-executor.md rename {doc => TAPAS-Final/doc}/architecture/decisions/0012-seperate-service-for-each-executor.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0013-microservice-architecture.md (100%) rename {doc => TAPAS-Final/doc}/architecture/decisions/0014-data-ownership.md (100%) rename {doc => TAPAS-Final/doc}/workflow.bpmn (100%) rename {doc => TAPAS-Final/doc}/workflow.png (100%) delete mode 100644 doc/architecture/decisions/0002-seperate-service-for-executor-pool.md diff --git a/doc/architecture/decisions/0001-record-architecture-decisions.md b/TAPAS-Final/doc/architecture/decisions/0001-record-architecture-decisions.md similarity index 100% rename from doc/architecture/decisions/0001-record-architecture-decisions.md rename to TAPAS-Final/doc/architecture/decisions/0001-record-architecture-decisions.md diff --git a/TAPAS-Final/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md b/TAPAS-Final/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md new file mode 100644 index 0000000..60b14e0 --- /dev/null +++ b/TAPAS-Final/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md @@ -0,0 +1,29 @@ +# 2. Seperate service for Executor Pool + +Date: 2021-11-21 + +## Status + +Accepted + +## Context + +The Executor Pool has to keep track of which Executors are online and what task types they can execute. The Roster keeps track of tasks that need to be executed and assigns Executors to tasks. The Executor Pool functionalty could be implemented in a seperate service or as a part of the Roster. + +## Decision + +The executor pool will be implemented as a seperate service. + +Most importantly, the Executor Pool and the Roster have quite different responsibilities and reasons to change. On one hand, the Executor Pool manages the Executors, and therefore it will change if we want to add functionality that impacts how Executors log onto the system and how we keep track of them. For example, if we want to check if an executor fulfills some requirements before logging on. On the other hand, the Roster manages the execution of tasks. TODO + +Single responsibility + +Potential Code volatility + +Scalability - Roster needs much more scale + +## Consequences + +The one funcionalty that is duplicated is error handling when an executor disconnects nongracefully... + +TODO \ No newline at end of file diff --git a/doc/architecture/decisions/0003-seperate-service-for-roster.md b/TAPAS-Final/doc/architecture/decisions/0003-seperate-service-for-roster.md similarity index 100% rename from doc/architecture/decisions/0003-seperate-service-for-roster.md rename to TAPAS-Final/doc/architecture/decisions/0003-seperate-service-for-roster.md diff --git a/doc/architecture/decisions/0004-seperate-service-for-task-list.md b/TAPAS-Final/doc/architecture/decisions/0004-seperate-service-for-task-list.md similarity index 100% rename from doc/architecture/decisions/0004-seperate-service-for-task-list.md rename to TAPAS-Final/doc/architecture/decisions/0004-seperate-service-for-task-list.md diff --git a/doc/architecture/decisions/0005-event-driven-communication.md b/TAPAS-Final/doc/architecture/decisions/0005-event-driven-communication.md similarity index 100% rename from doc/architecture/decisions/0005-event-driven-communication.md rename to TAPAS-Final/doc/architecture/decisions/0005-event-driven-communication.md diff --git a/doc/architecture/decisions/0006-one-global-database-or-one-database-per-service.md b/TAPAS-Final/doc/architecture/decisions/0006-one-global-database-or-one-database-per-service.md similarity index 100% rename from doc/architecture/decisions/0006-one-global-database-or-one-database-per-service.md rename to TAPAS-Final/doc/architecture/decisions/0006-one-global-database-or-one-database-per-service.md diff --git a/doc/architecture/decisions/0007-seperate-service-for-auction-house.md b/TAPAS-Final/doc/architecture/decisions/0007-seperate-service-for-auction-house.md similarity index 100% rename from doc/architecture/decisions/0007-seperate-service-for-auction-house.md rename to TAPAS-Final/doc/architecture/decisions/0007-seperate-service-for-auction-house.md diff --git a/doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md b/TAPAS-Final/doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md similarity index 100% rename from doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md rename to TAPAS-Final/doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md diff --git a/doc/architecture/decisions/0009-common-library-for-shared-code.md b/TAPAS-Final/doc/architecture/decisions/0009-common-library-for-shared-code.md similarity index 100% rename from doc/architecture/decisions/0009-common-library-for-shared-code.md rename to TAPAS-Final/doc/architecture/decisions/0009-common-library-for-shared-code.md diff --git a/doc/architecture/decisions/0010-executor-base-library.md b/TAPAS-Final/doc/architecture/decisions/0010-executor-base-library.md similarity index 100% rename from doc/architecture/decisions/0010-executor-base-library.md rename to TAPAS-Final/doc/architecture/decisions/0010-executor-base-library.md diff --git a/doc/architecture/decisions/0011-seperation-of-common-and-executor-base-library.md b/TAPAS-Final/doc/architecture/decisions/0011-seperation-of-common-and-executor-base-library.md similarity index 100% rename from doc/architecture/decisions/0011-seperation-of-common-and-executor-base-library.md rename to TAPAS-Final/doc/architecture/decisions/0011-seperation-of-common-and-executor-base-library.md diff --git a/TAPAS-Final/doc/architecture/decisions/0012-separate-service-for-each-executor.md b/TAPAS-Final/doc/architecture/decisions/0012-separate-service-for-each-executor.md new file mode 100644 index 0000000..66444c0 --- /dev/null +++ b/TAPAS-Final/doc/architecture/decisions/0012-separate-service-for-each-executor.md @@ -0,0 +1,27 @@ +# 12. separate service for each executor + +Date: 2021-11-21 + +## Status + +Accepted + +## Context + +Executors must receive tasks of different types and execute them. The executors could either all be implemented within one service or as multiple services, one for each type of executor. + +## Decision + +We will have a seperate service for each type of executor. + +Firstly, execution time differs significantly between task types. Therefore, having seperate services will allow the executos to scale differently based on their tasks' specific needs. + +Secondly, the systems functioning should not be disrupted in case an Executor fails. Having each type of executor in a seperate service will increase fault tolerance in this regard. + +Lastly, extensibility is one of the systems most important non-functional requirement and providers of executors need to be able to easily add executors to the executor pool. These factors are also positively impacted by having seperate services. + +There should not be any shared data between the executors. Additionally, there should be no flow of information between them. Thus, there should be no issues due to workflow and data concerns due to this decision. + +## Consequences + +Executors share a lot of functionality when it comes to connecting to the rest of the system. Therefore, this decision means that we will either have to duplicate the code that implements the common functionality, or we have to have a way to share the code (e.g. through a common library) diff --git a/doc/architecture/decisions/0012-seperate-service-for-each-executor.md b/TAPAS-Final/doc/architecture/decisions/0012-seperate-service-for-each-executor.md similarity index 100% rename from doc/architecture/decisions/0012-seperate-service-for-each-executor.md rename to TAPAS-Final/doc/architecture/decisions/0012-seperate-service-for-each-executor.md diff --git a/doc/architecture/decisions/0013-microservice-architecture.md b/TAPAS-Final/doc/architecture/decisions/0013-microservice-architecture.md similarity index 100% rename from doc/architecture/decisions/0013-microservice-architecture.md rename to TAPAS-Final/doc/architecture/decisions/0013-microservice-architecture.md diff --git a/doc/architecture/decisions/0014-data-ownership.md b/TAPAS-Final/doc/architecture/decisions/0014-data-ownership.md similarity index 100% rename from doc/architecture/decisions/0014-data-ownership.md rename to TAPAS-Final/doc/architecture/decisions/0014-data-ownership.md diff --git a/doc/workflow.bpmn b/TAPAS-Final/doc/workflow.bpmn similarity index 100% rename from doc/workflow.bpmn rename to TAPAS-Final/doc/workflow.bpmn diff --git a/doc/workflow.png b/TAPAS-Final/doc/workflow.png similarity index 100% rename from doc/workflow.png rename to TAPAS-Final/doc/workflow.png diff --git a/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md b/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md deleted file mode 100644 index 5624c0b..0000000 --- a/doc/architecture/decisions/0002-seperate-service-for-executor-pool.md +++ /dev/null @@ -1,21 +0,0 @@ -# 2. Seperate service for Executor Pool - -Date: 2021-11-21 - -## Status - -Accepted - -## Context - -The Executor Pool has to keep track of which Executors are online and what task types they can execute. The Roster keeps track of tasks that need to be executed and assigns Executors to tasks. The Executor Pool functionalty could be implemented in a seperate service or as a part of the Roster. - -## Decision - -The executor pool will be implemented as a seperate service. (TODO decision might change. Need to reevaluate) - -TODO explain why. - -## Consequences - -TODO \ No newline at end of file -- 2.45.1