Executor humidity #104

Merged
julius-lautz merged 5 commits from executor_humidity into dev 2021-12-15 11:10:12 +00:00
15 changed files with 494 additions and 24 deletions

View File

@ -1,4 +1,4 @@
package ch.unisg.executorbase.executor.adapter.in.web; package ch.unisg.executorBase.executor.adapter.in.web;
import java.util.logging.Logger; import java.util.logging.Logger;

View File

@ -1,4 +1,4 @@
package ch.unisg.executorbase.executor.adapter.out.web; package ch.unisg.executorBase.executor.adapter.out.web;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;

View File

@ -1,10 +1,11 @@
package ch.unisg.executorbase.executor.domain; package ch.unisg.executorbase.executor.domain;
import java.io.IOException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import ch.unisg.common.valueobject.ExecutorURI; import ch.unisg.common.valueobject.ExecutorURI;
import ch.unisg.executorbase.executor.adapter.out.web.ExecutionFinishedEventAdapter; import ch.unisg.executorBase.executor.adapter.out.web.ExecutionFinishedEventAdapter;
import ch.unisg.executorbase.executor.adapter.out.web.GetAssignmentAdapter; import ch.unisg.executorbase.executor.adapter.out.web.GetAssignmentAdapter;
import ch.unisg.executorbase.executor.adapter.out.web.NotifyExecutorPoolAdapter; import ch.unisg.executorbase.executor.adapter.out.web.NotifyExecutorPoolAdapter;
import ch.unisg.executorbase.executor.application.port.out.ExecutionFinishedEventPort; import ch.unisg.executorbase.executor.application.port.out.ExecutionFinishedEventPort;

View File

@ -1,11 +1,11 @@
package ch.unisg.executorbase.executor.domain; package ch.unisg.executorbase.executor.domain;
public enum ExecutorType { public enum ExecutorType {
COMPUTATION, ROBOT; COMPUTATION, ROBOT, HUMIDITY;
/** /**
* Checks if the give executor type exists. * Checks if the give executor type exists.
* @return Wheter the given executor type exists * @return Whether the given executor type exists
**/ **/
public static boolean contains(String test) { public static boolean contains(String test) {

77
executor-humidity/pom.xml Normal file
View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.unisg</groupId>
<artifactId>executor-humidity</artifactId>
<version>1.0-SNAPSHOT</version>
<name>executor-humidity</name>
<description>Demo project for Spring Boot</description>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.10</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.unisg</groupId>
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.Interactions-HSG</groupId>
<artifactId>wot-td-java</artifactId>
<version>0.1.1</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,16 @@
package ch.unisg.executorhumidity;
import ch.unisg.executorhumidity.executor.domain.Executor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ExecutorhumidityApplication {
public static void main(String[] args) {
SpringApplication.run(ExecutorhumidityApplication.class, args);
Executor.getExecutor();
}
}

View File

@ -0,0 +1,38 @@
package ch.unisg.executorhumidity.executor.adapter.in.web;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import ch.unisg.executorbase.executor.application.port.in.TaskAvailableCommand;
import ch.unisg.executorbase.executor.application.port.in.TaskAvailableUseCase;
import ch.unisg.executorbase.executor.domain.ExecutorType;
import java.util.concurrent.CompletableFuture;
@RestController
public class TaskAvailableController {
private final TaskAvailableUseCase taskAvailableUseCase;
public TaskAvailableController(TaskAvailableUseCase taskAvailableUseCase) {
this.taskAvailableUseCase = taskAvailableUseCase;
}
@GetMapping(path="/newtask/{taskType}")
public ResponseEntity<String> retrieveTaskfromTaskList(@PathVariable("taskType") String taskType) {
if (ExecutorType.contains(taskType.toUpperCase())) {
TaskAvailableCommand command = new TaskAvailableCommand(
ExecutorType.valueOf(taskType.toUpperCase()));
CompletableFuture.runAsync(() -> taskAvailableUseCase.newTaskAvailable(command));
}
// Add the content type as a response header
HttpHeaders responseHeaders = new HttpHeaders();
return new ResponseEntity<>("OK", responseHeaders, HttpStatus.OK);
}
}

View File

@ -0,0 +1,78 @@
package ch.unisg.executorhumidity.executor.adapter.out;
import ch.unisg.executorhumidity.executor.application.port.out.GetHumidityPort;
import ch.unisg.ics.interactions.wot.td.ThingDescription;
import ch.unisg.ics.interactions.wot.td.affordances.Form;
import ch.unisg.ics.interactions.wot.td.affordances.PropertyAffordance;
import ch.unisg.ics.interactions.wot.td.clients.TDCoapRequest;
import ch.unisg.ics.interactions.wot.td.clients.TDCoapResponse;
import ch.unisg.ics.interactions.wot.td.io.TDGraphReader;
import ch.unisg.ics.interactions.wot.td.schemas.ObjectSchema;
import ch.unisg.ics.interactions.wot.td.vocabularies.TD;
import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.elements.exception.ConnectorException;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
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.Map;
import java.util.Optional;
@Component
@Primary
public class GetHumidityAdapter implements GetHumidityPort {
@Override
public String getHumidity() {
String endpoint = "https://api.interactions.ics.unisg.ch/search/searchEngine";
String input = "@prefix dct: <http://purl.org/dc/terms/> . select ?title where { ?title dct:title 'Mirogate' }";
var httpRequest = HttpRequest.newBuilder()
.uri(URI.create(endpoint))
.header("Content-Type", "application/sparql-query")
.POST(HttpRequest.BodyPublishers.ofString(input))
.build();
var client = HttpClient.newHttpClient();
try {
String description = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body();
// Parse a TD from a string
ThingDescription td = TDGraphReader.readFromString(ThingDescription.TDFormat.RDF_TURTLE, description);
Optional<PropertyAffordance> humidity = td.getPropertyByName("humidity");
if (humidity.isPresent()) {
Optional<Form> form = humidity.get().getFirstFormForOperationType(TD.readProperty);
if (form.isPresent()) {
TDCoapRequest request = new TDCoapRequest(form.get(), TD.readProperty);
try {
TDCoapResponse response = request.execute();
Map<String, Object> payload = response.getPayloadAsObject((ObjectSchema) humidity.get().getDataSchema());
Object result = payload.get("https://interactions.ics.unisg.ch/mirogate#HumidityValue");
return result.toString();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,9 @@
package ch.unisg.executorhumidity.executor.application.port.out;
import org.eclipse.californium.elements.exception.ConnectorException;
import java.io.IOException;
public interface GetHumidityPort {
String getHumidity();
}

View File

@ -0,0 +1,27 @@
package ch.unisg.executorhumidity.executor.application.service;
import ch.unisg.executorbase.executor.domain.ExecutorStatus;
import ch.unisg.executorhumidity.executor.domain.Executor;
import org.springframework.stereotype.Component;
import ch.unisg.executorbase.executor.application.port.in.TaskAvailableCommand;
import ch.unisg.executorbase.executor.application.port.in.TaskAvailableUseCase;
import lombok.RequiredArgsConstructor;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@Component
@Transactional
public class TaskAvailableService implements TaskAvailableUseCase {
@Override
public void newTaskAvailable(TaskAvailableCommand command) {
Executor executor = Executor.getExecutor();
if(executor.getExecutorType() == command.getTaskType() &&
executor.getStatus() == ExecutorStatus.IDLING) {
executor.getAssignment();
}
}
}

View File

@ -0,0 +1,31 @@
package ch.unisg.executorhumidity.executor.domain;
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 final GetHumidityPort getHumidityPort = new GetHumidityAdapter();
private Executor(ExecutorType executorType) {super(executorType);}
public static Executor getExecutor() {return executor;}
@Override
protected
String execution(String input) {
//TODO: Fill
String result = getHumidityPort.getHumidity();
return result;
}
}

View File

@ -18,6 +18,12 @@
<sonar.organization>scs-asse-fs21-group1</sonar.organization> <sonar.organization>scs-asse-fs21-group1</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url> <sonar.host.url>https://sonarcloud.io</sonar.host.url>
</properties> </properties>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -45,7 +51,43 @@
<artifactId>executor-base</artifactId> <artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>ch.unisg</groupId>
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.unisg</groupId>
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.unisg</groupId>
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.unisg</groupId>
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.unisg</groupId>
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.Interactions-HSG</groupId>
<artifactId>wot-td-java</artifactId>
<version>0.1.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -17,16 +17,16 @@ public class DeleteUserFromRobotAdapter implements DeleteUserFromRobotPort {
@Override @Override
public boolean deleteUserFromRobot(String key) { public boolean deleteUserFromRobot(String key) {
String url = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.0/user/" + key; String url = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.4/user/" + key;
var request = HttpRequest.newBuilder() var request = HttpRequest.newBuilder()
.uri(URI.create(url)) .uri(URI.create(url))
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.DELETE() .DELETE()
.build(); .build();
var client = HttpClient.newHttpClient(); var client = HttpClient.newHttpClient();
try { try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString()); var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); System.out.println(response.statusCode());
@ -38,5 +38,5 @@ public class DeleteUserFromRobotAdapter implements DeleteUserFromRobotPort {
} }
return false; return false;
} }
} }

View File

@ -4,7 +4,21 @@ import java.net.URI;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; 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.context.annotation.Primary;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -16,9 +30,70 @@ public class InstructionToRobotAdapter implements InstructionToRobotPort {
@Override @Override
public boolean instructionToRobot(String key) { public boolean instructionToRobot(String key) {
String endpoint = "https://api.interactions.ics.unisg.ch/search/searchEngine";
String input = "@prefix dct: <http://purl.org/dc/terms/> . select ?title where { ?title dct:title 'Mirogate' }";
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<String, Object> elbowPayload = new HashMap<>();
elbowPayload.put("http://www.w3.org/2001/XMLSchema#int", 400);
// Get the affordance "setElbow" from the TD
Optional<ActionAffordance> action = td.getActionByName("setElbow");
// Get the first form
if (action.isPresent()) {
Optional<Form> form = action.get().getFirstForm();
// Retrieve the input data schema from the action affordance
Optional<DataSchema> 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 putEndpoint = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.0/elbow";
String inputJson = "{ \"value\": 400}"; String inputJson = "{ \"value\": 400}";
var request = HttpRequest.newBuilder() var request = HttpRequest.newBuilder()
.uri(URI.create(putEndpoint)) .uri(URI.create(putEndpoint))
@ -26,9 +101,9 @@ public class InstructionToRobotAdapter implements InstructionToRobotPort {
.header("X-API-KEY", key) .header("X-API-KEY", key)
.PUT(HttpRequest.BodyPublishers.ofString(inputJson)) .PUT(HttpRequest.BodyPublishers.ofString(inputJson))
.build(); .build();
var client = HttpClient.newHttpClient(); var client = HttpClient.newHttpClient();
try { try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString()); var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); System.out.println(response.statusCode());
@ -40,7 +115,7 @@ public class InstructionToRobotAdapter implements InstructionToRobotPort {
e.printStackTrace(); e.printStackTrace();
} }
return false; return false;
*/
} }
} }

View File

@ -4,7 +4,20 @@ import java.net.URI;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; 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.vocabularies.TD;
import org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -16,17 +29,77 @@ public class UserToRobotAdapter implements UserToRobotPort {
@Override @Override
public String userToRobot() { public String userToRobot() {
String postEndpoint = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.0/user";
String endpoint = "https://api.interactions.ics.unisg.ch/search/searchEngine";
String input = "@prefix dct: <http://purl.org/dc/terms/> . select ?title where { ?title dct:title 'Mirogate' }";
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<String, Object> 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<ActionAffordance> action = td.getActionByName("logIn");
// Get the first form
if (action.isPresent()) {
Optional<Form> form = action.get().getFirstForm();
// Retrieve the input data schema from the action affordance
Optional<DataSchema> 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();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
/*
String inputJson = "{ \"name\":\"keanu rahimian\", \"email\":\"keanu.rahimian@student.unisg.ch\"}"; String inputJson = "{ \"name\":\"keanu rahimian\", \"email\":\"keanu.rahimian@student.unisg.ch\"}";
var request = HttpRequest.newBuilder() var request = HttpRequest.newBuilder()
.uri(URI.create(postEndpoint)) .uri(URI.create(postEndpoint))
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(inputJson)) .POST(HttpRequest.BodyPublishers.ofString(inputJson))
.build(); .build();
var client = HttpClient.newHttpClient();
try { try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString()); var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); System.out.println(response.statusCode());
@ -40,7 +113,10 @@ public class UserToRobotAdapter implements UserToRobotPort {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
*/
return null;
} }
} }