Merge branch 'dev' into executor_humidity

This commit is contained in:
Marcel 2021-12-15 12:09:40 +01:00 committed by GitHub
commit dd93be535c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 155 additions and 46 deletions

View File

@ -86,6 +86,7 @@ services:
- ./:/data/ - ./:/data/
environment: environment:
task.list.uri: http://tapas-tasks:8081 task.list.uri: http://tapas-tasks:8081
auction.house.uri: http://tapas-auction-house:8086
executor.robot.uri: http://executor-robot:8084 executor.robot.uri: http://executor-robot:8084
executor.computation.uri: http://executor-computation:8085 executor.computation.uri: http://executor-computation:8085
mqtt.broker.uri: tcp://broker.hivemq.com:1883 mqtt.broker.uri: tcp://broker.hivemq.com:1883

View File

@ -10,6 +10,7 @@ import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ch.unisg.common.valueobject.ExecutorURI; import ch.unisg.common.valueobject.ExecutorURI;
@ -49,12 +50,13 @@ public class GetAssignmentAdapter implements GetAssignmentPort {
.build(); .build();
try { try {
logger.info("Sending getAssignment Request"); logger.info("ExecutorBase | Sending getAssignment request");
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
logger.log(Level.INFO, "getAssignment request result:\n {0}", response.body()); if (response.statusCode() != HttpStatus.CREATED.value()) {
if (response.body().equals("")) { logger.info("ExecutorBase | No task assigned");
return null; return null;
} }
logger.info("ExecutorBase | Task assigned");
JSONObject responseBody = new JSONObject(response.body()); JSONObject responseBody = new JSONObject(response.body());
String inputData = responseBody.getString("inputData"); String inputData = responseBody.getString("inputData");

View File

@ -1,7 +1,7 @@
package ch.unisg.executorbase.executor.domain; package ch.unisg.executorbase.executor.domain;
public enum ExecutorType { public enum ExecutorType {
ADDITION, ROBOT, HUMIDITY; COMPUTATION, ROBOT, HUMIDITY;
/** /**
* Checks if the give executor type exists. * Checks if the give executor type exists.

View File

@ -7,7 +7,7 @@ import ch.unisg.executorbase.executor.domain.ExecutorType;
public class Executor extends ExecutorBase { public class Executor extends ExecutorBase {
private static final Executor executor = new Executor(ExecutorType.ADDITION); private static final Executor executor = new Executor(ExecutorType.COMPUTATION);
public static Executor getExecutor() { public static Executor getExecutor() {
return executor; return executor;

View File

@ -3,6 +3,7 @@ package ch.unisg.roster.roster.adapter.in.web;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -22,10 +23,10 @@ public class DeleteTaskController {
* Controller to delete a task * Controller to delete a task
* @return 200 OK, 409 Conflict * @return 200 OK, 409 Conflict
**/ **/
@DeleteMapping(path = "/task", consumes = {"application/task+json"}) @DeleteMapping(path = "/task/{taskId}")
public ResponseEntity<Void> applyForTask(@RequestBody Task task) { public ResponseEntity<Void> deleteTask(@PathVariable("taskId") String taskId) {
DeleteTaskCommand command = new DeleteTaskCommand(task.getTaskID(), task.getTaskType()); DeleteTaskCommand command = new DeleteTaskCommand(taskId);
if (deleteTaskUseCase.deleteTask(command)) { if (deleteTaskUseCase.deleteTask(command)) {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);

View File

@ -31,7 +31,7 @@ public class NewTaskController {
logger.info("New task with id:" + task.getTaskID()); logger.info("New task with id:" + task.getTaskID());
NewTaskCommand command = new NewTaskCommand(task.getTaskID(), task.getTaskType(), NewTaskCommand command = new NewTaskCommand(task.getTaskID(), task.getTaskUri(), task.getTaskType(),
task.getInputData()); task.getInputData());
boolean success = newTaskUseCase.addNewTaskToQueue(command); boolean success = newTaskUseCase.addNewTaskToQueue(command);

View File

@ -0,0 +1,62 @@
package ch.unisg.roster.roster.adapter.out.web;
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 com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import ch.unisg.roster.roster.application.port.out.LaunchAuctionEventPort;
import ch.unisg.roster.roster.domain.event.LaunchAuctionEvent;
@Component
@Primary
public class LaunchAuctionEventAdapter implements LaunchAuctionEventPort {
@Value("${auction.house.uri}")
String server;
@Override
public void launchAuctionEvent(LaunchAuctionEvent launchAuctionEvent) {
var values = new HashMap<String, String>() {{
put("taskUri", launchAuctionEvent.taskUri);
put("taskType", launchAuctionEvent.taskType.getValue());
}};
var objectMapper = new ObjectMapper();
String requestBody = null;
try {
requestBody = objectMapper.writeValueAsString(values);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(server+"/auctions/"))
.header("Content-Type", "application/task+json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -13,12 +13,8 @@ public class DeleteTaskCommand extends SelfValidating<ApplyForTaskCommand> {
@NotNull @NotNull
private final String taskId; private final String taskId;
@NotNull public DeleteTaskCommand(String taskId) {
private final ExecutorType taskType;
public DeleteTaskCommand(String taskId, ExecutorType taskType) {
this.taskId = taskId; this.taskId = taskId;
this.taskType = taskType;
this.validateSelf(); this.validateSelf();
} }
} }

View File

@ -1,5 +1,7 @@
package ch.unisg.roster.roster.application.port.in; package ch.unisg.roster.roster.application.port.in;
import java.net.URI;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import ch.unisg.roster.roster.domain.valueobject.ExecutorType; import ch.unisg.roster.roster.domain.valueobject.ExecutorType;
@ -20,8 +22,12 @@ public class NewTaskCommand extends SelfValidating<NewTaskCommand> {
@NotNull @NotNull
private final String inputData; private final String inputData;
public NewTaskCommand(String taskID, ExecutorType taskType, String inputData) { @NotNull
private final String taskUri;
public NewTaskCommand(String taskID, String taskUri, ExecutorType taskType, String inputData) {
this.taskID = taskID; this.taskID = taskID;
this.taskUri = taskUri;
this.taskType = taskType; this.taskType = taskType;
this.inputData = inputData; this.inputData = inputData;
this.validateSelf(); this.validateSelf();

View File

@ -0,0 +1,8 @@
package ch.unisg.roster.roster.application.port.out;
import ch.unisg.roster.roster.domain.event.LaunchAuctionEvent;
public interface LaunchAuctionEventPort {
void launchAuctionEvent(LaunchAuctionEvent launchAuctionEvent);
}

View File

@ -21,7 +21,7 @@ public class DeleteTaskService implements DeleteTaskUseCase {
@Override @Override
public boolean deleteTask(DeleteTaskCommand command) { public boolean deleteTask(DeleteTaskCommand command) {
Roster roster = Roster.getInstance(); Roster roster = Roster.getInstance();
return roster.deleteTask(command.getTaskId(), command.getTaskType()); return roster.deleteTask(command.getTaskId());
} }
} }

View File

@ -6,10 +6,12 @@ import org.springframework.stereotype.Component;
import ch.unisg.roster.roster.application.port.in.NewTaskCommand; import ch.unisg.roster.roster.application.port.in.NewTaskCommand;
import ch.unisg.roster.roster.application.port.in.NewTaskUseCase; import ch.unisg.roster.roster.application.port.in.NewTaskUseCase;
import ch.unisg.roster.roster.application.port.out.LaunchAuctionEventPort;
import ch.unisg.roster.roster.application.port.out.NewTaskEventPort; import ch.unisg.roster.roster.application.port.out.NewTaskEventPort;
import ch.unisg.roster.roster.domain.ExecutorRegistry; import ch.unisg.roster.roster.domain.ExecutorRegistry;
import ch.unisg.roster.roster.domain.Roster; import ch.unisg.roster.roster.domain.Roster;
import ch.unisg.roster.roster.domain.Task; import ch.unisg.roster.roster.domain.Task;
import ch.unisg.roster.roster.domain.event.LaunchAuctionEvent;
import ch.unisg.roster.roster.domain.event.NewTaskEvent; import ch.unisg.roster.roster.domain.event.NewTaskEvent;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -20,6 +22,8 @@ public class NewTaskService implements NewTaskUseCase {
private final NewTaskEventPort newTaskEventPort; private final NewTaskEventPort newTaskEventPort;
private final LaunchAuctionEventPort launchAuctionEventPort;
/** /**
* Checks if we can execute the give task, if yes the task gets added to the task queue and return true. * Checks if we can execute the give task, if yes the task gets added to the task queue and return true.
* If the task can not be executed by an internal or auction house executor, the method return false. * If the task can not be executed by an internal or auction house executor, the method return false.
@ -31,7 +35,10 @@ public class NewTaskService implements NewTaskUseCase {
ExecutorRegistry executorRegistry = ExecutorRegistry.getInstance(); ExecutorRegistry executorRegistry = ExecutorRegistry.getInstance();
if (!executorRegistry.containsTaskType(command.getTaskType())) { if (!executorRegistry.containsTaskType(command.getTaskType())) {
return false; LaunchAuctionEvent launchAuctionEvent = new LaunchAuctionEvent( command.getTaskUri(),
command.getTaskType());
launchAuctionEventPort.launchAuctionEvent(launchAuctionEvent);
return true;
} }
Task task = new Task(command.getTaskID(), command.getTaskType(), command.getInputData()); Task task = new Task(command.getTaskID(), command.getTaskType(), command.getInputData());

View File

@ -76,9 +76,14 @@ public class Roster {
* Deletes a task if it is still in the queue. * Deletes a task if it is still in the queue.
* @return Whether the task got deleted or not * @return Whether the task got deleted or not
**/ **/
public boolean deleteTask(String taskID, ExecutorType taskType) { public boolean deleteTask(String taskID) {
logger.log(Level.INFO, "Try to delete task with id {0}", taskID); logger.log(Level.INFO, "Try to delete task with id {0}", taskID);
return queues.get(taskType.getValue()).removeIf(task -> task.getTaskID().equalsIgnoreCase(taskID)); for(var listOfTasks : queues.entrySet()){
if(listOfTasks.getValue().removeIf(task -> task.getTaskID().equals(taskID))){
return true;
}
}
return false;
} }
public void initialiseRoster(List<RosterItem> rosterItemList){ public void initialiseRoster(List<RosterItem> rosterItemList){

View File

@ -12,6 +12,9 @@ public class Task {
@Getter @Getter
private ExecutorType taskType; private ExecutorType taskType;
@Getter
private String taskUri;
@Getter @Getter
@Setter @Setter
private String inputData; private String inputData;
@ -40,6 +43,12 @@ public class Task {
this.inputData = inputData; this.inputData = inputData;
} }
public Task(String taskID, String taskUri, ExecutorType taskType) {
this.taskID = taskID;
this.taskUri = taskUri;
this.taskType = taskType;
}
public Task() {} public Task() {}
} }

View File

@ -0,0 +1,14 @@
package ch.unisg.roster.roster.domain.event;
import ch.unisg.roster.roster.domain.valueobject.ExecutorType;
public class LaunchAuctionEvent {
public final String taskUri;
public final ExecutorType taskType;
public LaunchAuctionEvent(String taskUri, ExecutorType taskType) {
this.taskUri = taskUri;
this.taskType = taskType;
}
}

View File

@ -1,6 +1,7 @@
server.port=8082 server.port=8082
executor.robot.uri=http://127.0.0.1:8084 executor.robot.uri=http://127.0.0.1:8084
executor.computation.uri=http://127.0.0.1:8085 executor.computation.uri=http://127.0.0.1:8085
auction.house.uri=http://127.0.0.1:8086
task.list.uri=http://127.0.0.1:8081 task.list.uri=http://127.0.0.1:8081
mqtt.broker.uri=tcp://localhost:1883 mqtt.broker.uri=tcp://localhost:1883

View File

@ -31,7 +31,7 @@ public class RosterTest {
assertThat(task.getTaskType().getValue().toString()).isEqualTo("TEST-TYPE"); assertThat(task.getTaskType().getValue().toString()).isEqualTo("TEST-TYPE");
assertThat(task.getTaskID()).isEqualTo("TEST-ID"); assertThat(task.getTaskID()).isEqualTo("TEST-ID");
boolean empty_queue = roster.deleteTask("TEST-ID", new ExecutorType("TEST-TYPE")); boolean empty_queue = roster.deleteTask("TEST-ID");
// TODO test that the task was removed from the Queue similar to below --> I don't know if it actually gets deleted or not // TODO test that the task was removed from the Queue similar to below --> I don't know if it actually gets deleted or not
//assertThat(empty_queue).isEqualTo(true); //assertThat(empty_queue).isEqualTo(true);
//assertThat(queues.size()).isEqualTo(0); //assertThat(queues.size()).isEqualTo(0);
@ -44,8 +44,8 @@ public class RosterTest {
queues.clear(); queues.clear();
roster.addTaskToQueue(new Task("TEST-ID", "TEST-TYPE")); roster.addTaskToQueue(new Task("TEST-ID", "TEST-TYPE"));
boolean test = roster.deleteTask("TEST-ID", new ExecutorType("TEST-TYPE")); boolean test = roster.deleteTask("TEST-ID");
// TODO Fix assert for queue
assertThat(test).isEqualTo(true); assertThat(test).isEqualTo(true);
assertThat(queues.size()).isEqualTo(1); assertThat(queues.size()).isEqualTo(1);
} }

View File

@ -25,6 +25,7 @@ public class DeleteTaskWebController {
this.deleteClassUseCase = deleteClassUseCase; this.deleteClassUseCase = deleteClassUseCase;
} }
// TODO change to DELETE and why are we using task URI here?
@PostMapping(path="/tasks/deleteTask", consumes = {TaskJsonRepresentation.MEDIA_TYPE}) @PostMapping(path="/tasks/deleteTask", consumes = {TaskJsonRepresentation.MEDIA_TYPE})
public ResponseEntity<String> deleteTask (@RequestBody Task task){ public ResponseEntity<String> deleteTask (@RequestBody Task task){
try { try {
@ -35,6 +36,7 @@ public class DeleteTaskWebController {
// Check if the task with the given identifier exists // Check if the task with the given identifier exists
if (deleteATask.isEmpty()) { if (deleteATask.isEmpty()) {
// If not, through a 404 Not Found status code // If not, through a 404 Not Found status code
// TODO is 404 the best here?
throw new ResponseStatusException(HttpStatus.NOT_FOUND); throw new ResponseStatusException(HttpStatus.NOT_FOUND);
} }

View File

@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
@ -25,36 +26,24 @@ public class CanTaskBeDeletedWebAdapter implements CanTaskBeDeletedPort {
String server; String server;
@Override @Override
public void canTaskBeDeletedEvent(DeleteTaskEvent event){ public boolean canTaskBeDeletedEvent(DeleteTaskEvent event){
var values = new HashMap<> () {{
put("taskId", event.taskId);
put("taskUri", event.taskUri);
}};
var objectMapper = new ObjectMapper();
String requestBody = null;
try {
requestBody = objectMapper.writeValueAsString(values);
} catch (JsonProcessingException e){
e.printStackTrace();
}
//Todo: Question: How do we include the URI from the DeleteTaskEvent? Do we even need it? //Todo: Question: How do we include the URI from the DeleteTaskEvent? Do we even need it?
HttpClient client = HttpClient.newHttpClient(); HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder() HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(server+"task")) .uri(URI.create(server+"$/task/" + event.taskId))
.header("Content-Type", "application/task+json") .header("Content-Type", "application/task+json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody)) .DELETE()
.build(); .build();
//Todo: The following parameters probably need to be changed to get the right error code
try { try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
return response.statusCode() == HttpStatus.OK.value();
} catch (IOException e){ } catch (IOException e){
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
return false;
} }
} }

View File

@ -3,5 +3,5 @@ package ch.unisg.tapastasks.tasks.application.port.out;
import ch.unisg.tapastasks.tasks.domain.DeleteTaskEvent; import ch.unisg.tapastasks.tasks.domain.DeleteTaskEvent;
public interface CanTaskBeDeletedPort { public interface CanTaskBeDeletedPort {
void canTaskBeDeletedEvent(DeleteTaskEvent event); boolean canTaskBeDeletedEvent(DeleteTaskEvent event);
} }

View File

@ -3,6 +3,8 @@ package ch.unisg.tapastasks.tasks.application.service;
import ch.unisg.tapastasks.tasks.application.port.in.DeleteTaskCommand; 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.in.DeleteTaskUseCase;
import ch.unisg.tapastasks.tasks.application.port.out.CanTaskBeDeletedPort;
import ch.unisg.tapastasks.tasks.domain.DeleteTaskEvent;
import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.Task;
import ch.unisg.tapastasks.tasks.domain.TaskList; import ch.unisg.tapastasks.tasks.domain.TaskList;
import jdk.jshell.spi.ExecutionControl; import jdk.jshell.spi.ExecutionControl;
@ -17,17 +19,21 @@ import java.util.Optional;
@Transactional @Transactional
public class DeleteTaskService implements DeleteTaskUseCase { public class DeleteTaskService implements DeleteTaskUseCase {
private final CanTaskBeDeletedPort canTaskBeDeletedPort;
@Override @Override
public Optional<Task> deleteTask(DeleteTaskCommand command){ public Optional<Task> deleteTask(DeleteTaskCommand command){
TaskList taskList = TaskList.getTapasTaskList(); TaskList taskList = TaskList.getTapasTaskList();
Optional<Task> updatedTask = taskList.retrieveTaskById(command.getTaskId()); Optional<Task> updatedTask = taskList.retrieveTaskById(command.getTaskId());
Task newTask = updatedTask.get();
// TODO: Fill in the right condition into the if-statement and the else-statement if(updatedTask.isPresent() && updatedTask.get().getTaskStatus().getValue().equals(Task.Status.OPEN)){
if (true){ // If task exists, and it is open then we try deleting it from the roster
return taskList.deleteTaskById(command.getTaskId()); if(canTaskBeDeletedPort.canTaskBeDeletedEvent(new DeleteTaskEvent(command.getTaskId().getValue(), command.getTaskUri().getValue()))){
return taskList.deleteTaskById(command.getTaskId());
}
} }
// TODO Handle with a return message
return Optional.empty(); return Optional.empty();
} }
} }