33 Commits
v0.0.5 ... demo

Author SHA1 Message Date
dbe2f8c31b fixes 2021-12-19 22:08:32 +01:00
0ae267ac1d bugfixes 2021-12-19 20:51:31 +01:00
a616bd2aad bugfixes 2021-12-19 20:08:58 +01:00
3fb5bc40bc bugfixes 2021-12-19 19:35:20 +01:00
9a2139036e bugfixes 2021-12-19 19:14:34 +01:00
bfde8d8d24 deployment fixes 2021-12-19 19:06:48 +01:00
6391b007eb fixes 2021-12-19 18:59:31 +01:00
2d91ef6330 fixes 2021-12-19 18:42:26 +01:00
44ede54a60 bugfixes 2021-12-19 17:44:09 +01:00
e05c3282ef humidity demo 2021-12-19 17:21:29 +01:00
2e8105ef3a pom fixes 2021-12-19 16:39:12 +01:00
0eb21d2083 fixes 2021-12-19 16:33:11 +01:00
0022ebaf88 added humidity executor to deployment 2021-12-18 16:18:54 +01:00
reynisson
cab63d6b76 Implemented the following points:
- Roster/Auctionhouse send initial getExecutors request
- Remove executor (made DELETE endpoint in executor pool)
2021-12-16 20:39:14 +01:00
6c17b20c55 bugfixes 2021-12-16 11:42:27 +01:00
27ccc54458 Merge pull request #105 from SCS-ASSE-FS21-Group1/websub-improvements
Websub improvements
2021-12-15 12:11:03 +01:00
f66b7ab587 Merge pull request #104 from SCS-ASSE-FS21-Group1/executor_humidity
Executor humidity
2021-12-15 12:10:12 +01:00
dd93be535c Merge branch 'dev' into executor_humidity 2021-12-15 12:09:40 +01:00
reynisson
48d5c6fe90 Merge remote-tracking branch 'origin/dev' into dev 2021-12-14 23:46:42 +01:00
reynisson
3e141e5318 Implemented the remove task workflow. Still got one todo for the workflow that I want to discuss 2021-12-14 23:46:07 +01:00
69b5949f71 roster bugfixes 2021-12-14 22:19:32 +01:00
45edd76c8b executorbase bugfixes 2021-12-14 22:00:32 +01:00
467d7aa015 updates 2021-12-14 21:59:24 +01:00
julius.lautz
b1b94336b2 added td discovery for humidity and robot executor 2021-12-14 21:13:49 +01:00
0460f1c793 Merge pull request #102 from SCS-ASSE-FS21-Group1/Roster-request-auction-when-executor-missing
Roster requests auction when an internal executor is missing
2021-12-14 20:57:22 +01:00
7e34a5a7b1 Merge pull request #101 from SCS-ASSE-FS21-Group1/Renam-task-type
Renaming task type
2021-12-14 20:56:39 +01:00
99e60f656c small bugfixes 2021-12-12 20:40:22 +01:00
rahimiankeanu
13b02aa115 Roster requests auction when an internal executor is missing 2021-12-12 20:26:14 +01:00
4593e5bddb uri updates 2021-12-12 20:24:04 +01:00
7a66f37556 WebSub fixes 2021-12-12 19:41:41 +01:00
rahimiankeanu
bcb8130f78 Renaming task type 2021-12-12 16:49:03 +01:00
julius.lautz
aaffb0371e made changes to executor-humidity 2021-12-11 19:09:34 +01:00
julius.lautz
c87a732e2a added executor-humidity 2021-12-11 18:36:23 +01:00
124 changed files with 3236 additions and 560 deletions

View File

@@ -67,6 +67,9 @@ services:
- ./:/data/
environment:
mqtt.broker.uri: tcp://broker.hivemq.com:1883
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`)"
@@ -86,8 +89,11 @@ services:
- ./:/data/
environment:
task.list.uri: http://tapas-tasks:8081
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
executor.humidity.demo.uri: http://executor-humidity-demo:8088
mqtt.broker.uri: tcp://broker.hivemq.com:1883
spring.data.mongodb.uri: mongodb://root:password@tapas-db:27017
labels:
@@ -161,3 +167,45 @@ 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-humidity.rule=Host(`executor-humidity.${PUB_IP}.nip.io`)"
- "traefik.http.routers.executor-humidity.service=executor-humidity"
- "traefik.http.services.executor-humidity.loadbalancer.server.port=8087"
- "traefik.http.routers.executor-humidity.tls=true"
- "traefik.http.routers.executor-humidity.entryPoints=web,websecure"
- "traefik.http.routers.executor-humidity.tls.certresolver=le"
executor-humidity-demo:
image: openjdk
command: "java -jar /data/executor-humidity-demo-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-humidity-demo.rule=Host(`executor-humidity-demo.${PUB_IP}.nip.io`)"
- "traefik.http.routers.executor-humidity-demo.service=executor-humidity-demo"
- "traefik.http.services.executor-humidity-demo.loadbalancer.server.port=8088"
- "traefik.http.routers.executor-humidity-demo.tls=true"
- "traefik.http.routers.executor-humidity-demo.entryPoints=web,websecure"
- "traefik.http.routers.executor-humidity-demo.tls.certresolver=le"

View File

@@ -55,6 +55,14 @@ 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 executor-humidity-demo service
run: mvn -f executor-humidity-demo/pom.xml --batch-mode --update-snapshots verify
- run: cp ./executor-humidity-demo/target/executor-humidity-demo-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
@@ -103,5 +111,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

3
Californium3.properties Normal file
View File

@@ -0,0 +1,3 @@
# Californium3 CoAP Properties file
# Wed Dec 15 21:41:00 CET 2021
#

View File

@@ -72,15 +72,15 @@ services:
volumes:
- ./executor-computation/src:/opt/app/src
- ./executor-computation/target:/opt/app/target
executor-robot:
container_name: executor-robot
build:
context: "."
dockerfile: "./executor-robot/Dockerfile"
target: development
ports:
- "8084:8084"
- "5009:5005"
volumes:
- ./executor-robot/src:/opt/app/src
- ./executor-robot/target:/opt/app/target
# executor-robot:
# container_name: executor-robot
# build:
# context: "."
# dockerfile: "./executor-robot/Dockerfile"
# target: development
# ports:
# - "8084:8084"
# - "5009:5005"
# volumes:
# - ./executor-robot/src:/opt/app/src
# - ./executor-robot/target:/opt/app/target

View File

@@ -30,7 +30,7 @@ public class TaskAvailableController {
@GetMapping(path = "/newtask/{taskType}", consumes = { "application/json" })
public ResponseEntity<String> retrieveTaskFromTaskList(@PathVariable("taskType") String taskType) {
logger.info("New " + taskType + " available");
logger.info("ExecutorBase | New " + taskType + " task available");
if (ExecutorType.contains(taskType.toUpperCase())) {
TaskAvailableCommand command = new TaskAvailableCommand(

View File

@@ -28,6 +28,8 @@ public class ExecutionFinishedEventAdapter implements ExecutionFinishedEventPort
@Override
public void publishExecutionFinishedEvent(ExecutionFinishedEvent event) {
logger.log(Level.INFO, "ExecutorBase | Sending finish execution event....");
String body = new JSONObject()
.put("taskID", event.getTaskID())
.put("outputData", event.getOutputData())
@@ -51,8 +53,7 @@ public class ExecutionFinishedEventAdapter implements ExecutionFinishedEventPort
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
logger.log(Level.INFO, "Finish execution event sent with result: {0}", event.getOutputData());
logger.log(Level.INFO, "ExecutorBase | Finish execution event sent with result: {0}", event.getOutputData());
}
}

View File

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

View File

@@ -9,7 +9,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@@ -41,7 +40,7 @@ public class NotifyExecutorPoolAdapter implements NotifyExecutorPoolPort {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(server+"/executor-pool/AddExecutor"))
.uri(URI.create(server+"/executor-pool/executors"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();

View File

@@ -4,9 +4,11 @@ import javax.validation.constraints.NotNull;
import ch.unisg.common.validation.SelfValidating;
import ch.unisg.executorbase.executor.domain.ExecutorType;
import lombok.EqualsAndHashCode;
import lombok.Value;
@Value
@EqualsAndHashCode(callSuper=false)
public class TaskAvailableCommand extends SelfValidating<TaskAvailableCommand> {
@NotNull

View File

@@ -15,6 +15,6 @@ public class TaskAvailableService implements TaskAvailableUseCase {
@Override
public void newTaskAvailable(TaskAvailableCommand command) {
// Placeholder so spring can create a bean, implementation of this function is inside the executors
// Placeholder so spring can create a bean, implementation of this service is inside the individual executors
}
}

View File

@@ -34,18 +34,19 @@ public abstract class ExecutorBase {
Logger logger = Logger.getLogger(ExecutorBase.class.getName());
protected ExecutorBase(ExecutorType executorType) {
logger.info("Starting Executor");
logger.info("ExecutorBase | Starting Executor");
this.status = ExecutorStatus.STARTING_UP;
this.executorType = executorType;
// TODO set this automaticly
this.executorURI = new ExecutorURI("http://localhost:8084");
// 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");
if(!notifyExecutorPoolService.notifyExecutorPool(this.executorURI, this.executorType)) {
logger.log(Level.WARNING, "Executor could not connect to executor pool! Shuting down!");
logger.log(Level.WARNING, "ExecutorBase | Executor could not connect to executor pool! Shuting down!");
System.exit(0);
} else {
logger.info("Executor conntected to executor pool");
logger.info("ExecutorBase | Executor conntected to executor pool");
this.status = ExecutorStatus.IDLING;
getAssignment();
}
@@ -58,10 +59,10 @@ public abstract class ExecutorBase {
public void getAssignment() {
Task newTask = getAssignmentPort.getAssignment(this.getExecutorType(), this.getExecutorURI());
if (newTask != null) {
logger.info("Executor got a new task");
logger.info("ExecutorBase | Executor got a new task");
this.executeTask(newTask);
} else {
logger.info("Executor got no new task");
logger.info("ExecutorBase | Executor got no new task");
this.status = ExecutorStatus.IDLING;
}
}
@@ -71,7 +72,7 @@ public abstract class ExecutorBase {
* @return void
**/
private void executeTask(Task task) {
logger.info("Starting execution");
logger.info("ExecutorBase | Starting execution");
this.status = ExecutorStatus.EXECUTING;
task.setOutputData(execution(task.getInputData()));
@@ -80,7 +81,7 @@ public abstract class ExecutorBase {
executionFinishedEventPort.publishExecutionFinishedEvent(
new ExecutionFinishedEvent(task.getTaskID(), task.getOutputData(), "SUCCESS"));
logger.info("Finish execution");
logger.info("ExecutorBase | Finish execution");
getAssignment();
}

View File

@@ -1,11 +1,11 @@
package ch.unisg.executorbase.executor.domain;
public enum ExecutorType {
ADDITION, ROBOT;
COMPUTATION, SMALLROBOT, HUMIDITY, HUMIDITY_DEMO;
/**
* 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) {

View File

@@ -19,7 +19,12 @@ public class Task {
public Task(String taskID, String inputData) {
this.taskID = taskID;
this.inputData= inputData;
this.inputData = inputData;
}
public Task(String taskID) {
this.taskID = taskID;
this.inputData = "";
}
}

View File

@@ -67,6 +67,17 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>21.3.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>21.3.0</version>
</dependency>
</dependencies>
<build>

View File

@@ -1,6 +1,8 @@
package ch.unisg.executorcomputation;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -10,15 +12,9 @@ import ch.unisg.executorcomputation.executor.domain.Executor;
@SpringBootApplication
public class ExecutorcomputationApplication {
static Logger logger = Logger.getLogger(ExecutorcomputationApplication.class.getName());
public static void main(String[] args) {
try {
TimeUnit.SECONDS.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SpringApplication.run(ExecutorcomputationApplication.class, args);
Executor.getExecutor();
}

View File

@@ -1,13 +1,21 @@
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;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
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.ADDITION);
private static Logger executorLogger = Logger.getLogger(Executor.class.getName());
private static final Executor executor = new Executor(ExecutorType.COMPUTATION);
public static Executor getExecutor() {
return executor;
@@ -21,43 +29,30 @@ public class Executor extends ExecutorBase {
protected
String execution(String inputData) {
String operator = "";
if (inputData.contains("+")) {
operator = "+";
} else if (inputData.contains("-")) {
operator = "-";
} else if (inputData.contains("*")) {
operator = "*";
} else {
return "invalid data";
}
executorLogger.info("Executor | Starting execution with inputData: " + inputData);
double result = Double.NaN;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String result = "";
try {
result = engine.eval(inputData).toString();
} catch (ScriptException e1) {
// TODO some logic if execution fails
executorLogger.severe(e1.getMessage());
return result;
}
try {
TimeUnit.SECONDS.sleep(5);
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
return result;
// executorLogger.log(Level.SEVERE, e.getLocalizedMessage(), e);
// Thread.currentThread().interrupt();
}
if (operator.equalsIgnoreCase("+")) {
String[] parts = inputData.split("\\+");
double a = Double.parseDouble(parts[0]);
double b = Double.parseDouble(parts[1]);
result = a + b;
} else if (operator.equalsIgnoreCase("*")) {
String[] parts = inputData.split("\\*");
double a = Double.parseDouble(parts[0]);
double b = Double.parseDouble(parts[1]);
result = a * b;
} else if (operator.equalsIgnoreCase("-")) {
String[] parts = inputData.split("-");
double a = Double.parseDouble(parts[0]);
double b = Double.parseDouble(parts[1]);
result = a - b;
}
return Double.toString(result);
executorLogger.info("Executor | Finish execution");
return result;
}
}

33
executor-humidity-demo/.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

Binary file not shown.

View File

@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

View File

@@ -0,0 +1,3 @@
# Californium3 CoAP Properties file
# Wed Dec 15 22:23:03 CET 2021
#

310
executor-humidity-demo/mvnw vendored Executable file
View File

@@ -0,0 +1,310 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

182
executor-humidity-demo/mvnw.cmd vendored Normal file
View File

@@ -0,0 +1,182 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

View File

@@ -0,0 +1,81 @@
<?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>ch.unisg</groupId>
<artifactId>executor-humidity-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>executor-humidity-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
<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 org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ch.unisg.executorhumidity.executor.domain.Executor;
@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,114 @@
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.springframework.beans.factory.annotation.Value;
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 java.io.IOException;
import java.io.StringReader;
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;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@Component
@Primary
public class GetHumidityAdapter implements GetHumidityPort {
String endpoint = System.getenv("SEARCH_ENGINE_URI") == null ?
"https://api.interactions.ics.unisg.ch/search/searchEngine" : System.getenv("SEARCH_ENGINE_URI");
@Override
public String getHumidity() {
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();
String mirogateUri = null;
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new InputSource(new StringReader(description)));
doc.getDocumentElement().normalize();
NodeList results = doc.getElementsByTagName("uri");
for (int temp = 0; temp < results.getLength(); temp += 1) {
Node nNode = results.item(temp);
if (nNode.getTextContent().contains("mirogate")) {
mirogateUri = nNode.getTextContent();
}
}
if (mirogateUri == null) {
// TODO implement logic if execution failed
return "";
}
// Parse a TD from a string
ThingDescription td = TDGraphReader.readFromURL(ThingDescription.TDFormat.RDF_TURTLE, mirogateUri);
Optional<PropertyAffordance> humidity = td.getPropertyByName("humidity");
if (humidity.isPresent()) {
Optional<Form> form = humidity.get().getFirstFormForOperationType(TD.readProperty);
// System.out.println(humidity.get().getDataSchema().getDatatype());
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();
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SAXException e1) {
// TODO Auto-generated catch block
e1.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_DEMO);
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

@@ -0,0 +1,16 @@
server.port=8088
search.engine.uri=https://api.interactions.ics.unisg.ch/search/searchEngine
spring.profiles.active=chaos-monkey
chaos.monkey.enabled=false
management.endpoint.chaosmonkey.enabled=true
management.endpoint.chaosmonkeyjmx.enabled=true
# include specific endpoints
management.endpoints.web.exposure.include=health,info,chaosmonkey
chaos.monkey.watcher.controller=true
chaos.monkey.watcher.restController=true
chaos.monkey.watcher.service=true
chaos.monkey.watcher.repository=true
chaos.monkey.watcher.component=true

33
executor-humidity/.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;
public class MavenWrapperDownloader {
private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";
/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";
/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}
}

Binary file not shown.

View File

@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar

View File

@@ -0,0 +1,3 @@
# Californium3 CoAP Properties file
# Wed Dec 15 22:23:03 CET 2021
#

310
executor-humidity/mvnw vendored Executable file
View File

@@ -0,0 +1,310 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

182
executor-humidity/mvnw.cmd vendored Normal file
View File

@@ -0,0 +1,182 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

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

@@ -0,0 +1,81 @@
<?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>ch.unisg</groupId>
<artifactId>executor-humidity</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>executor-humidity</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</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>
<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 org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import ch.unisg.executorhumidity.executor.domain.Executor;
@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,114 @@
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.springframework.beans.factory.annotation.Value;
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 java.io.IOException;
import java.io.StringReader;
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;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@Component
@Primary
public class GetHumidityAdapter implements GetHumidityPort {
String endpoint = System.getenv("SEARCH_ENGINE_URI") == null ?
"https://api.interactions.ics.unisg.ch/search/searchEngine" : System.getenv("SEARCH_ENGINE_URI");
@Override
public String getHumidity() {
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();
String mirogateUri = null;
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new InputSource(new StringReader(description)));
doc.getDocumentElement().normalize();
NodeList results = doc.getElementsByTagName("uri");
for (int temp = 0; temp < results.getLength(); temp += 1) {
Node nNode = results.item(temp);
if (nNode.getTextContent().contains("mirogate")) {
mirogateUri = nNode.getTextContent();
}
}
if (mirogateUri == null) {
// TODO implement logic if execution failed
return "";
}
// Parse a TD from a string
ThingDescription td = TDGraphReader.readFromURL(ThingDescription.TDFormat.RDF_TURTLE, mirogateUri);
Optional<PropertyAffordance> humidity = td.getPropertyByName("humidity");
if (humidity.isPresent()) {
Optional<Form> form = humidity.get().getFirstFormForOperationType(TD.readProperty);
// System.out.println(humidity.get().getDataSchema().getDatatype());
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();
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SAXException e1) {
// TODO Auto-generated catch block
e1.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

@@ -0,0 +1,16 @@
server.port=8087
search.engine.uri=https://api.interactions.ics.unisg.ch/search/searchEngine
spring.profiles.active=chaos-monkey
chaos.monkey.enabled=false
management.endpoint.chaosmonkey.enabled=true
management.endpoint.chaosmonkeyjmx.enabled=true
# include specific endpoints
management.endpoints.web.exposure.include=health,info,chaosmonkey
chaos.monkey.watcher.controller=true
chaos.monkey.watcher.restController=true
chaos.monkey.watcher.service=true
chaos.monkey.watcher.repository=true
chaos.monkey.watcher.component=true

View File

@@ -1,7 +1,5 @@
package ch.unisg.executorpool;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,14 +19,6 @@ public class ExecutorPoolApplication {
private LoadExecutorPort loadExecutorPort;
public static void main(String[] args) {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SpringApplication.run(ExecutorPoolApplication.class, args);
}

View File

@@ -27,7 +27,7 @@ public class AddNewExecutorToExecutorPoolWebController {
this.addNewExecutorToExecutorPoolUseCase = addNewExecutorToExecutorPoolUseCase;
}
@PostMapping(path = "/executor-pool/AddExecutor", consumes = {ExecutorJsonRepresentation.EXECUTOR_MEDIA_TYPE})
@PostMapping(path = "/executor-pool/executors", consumes = {ExecutorJsonRepresentation.EXECUTOR_MEDIA_TYPE})
public ResponseEntity<String> addNewExecutorToExecutorPool(@RequestBody ExecutorJsonRepresentation payload){
try {
AddNewExecutorToExecutorPoolCommand command = new AddNewExecutorToExecutorPoolCommand(

View File

@@ -19,7 +19,7 @@ public class GetAllExecutorsInExecutorPoolWebController {
this.getAllExecutorsInExecutorPoolUseCase = getAllExecutorsInExecutorPoolUseCase;
}
@GetMapping(path = "executor-pool/GetAllExecutorsinExecutorPool")
@GetMapping(path = "executor-pool/GetAllExecutorsInExecutorPool")
public ResponseEntity<String> getAllExecutorsInExecutorPool(){
List<ExecutorClass> executorClassList = getAllExecutorsInExecutorPoolUseCase.getAllExecutorsInExecutorPool();

View File

@@ -7,9 +7,7 @@ import ch.unisg.executorpool.domain.ExecutorClass;
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 java.net.URI;
@@ -23,10 +21,10 @@ public class RemoveExecutorFromExecutorPoolWebController {
this.removeExecutorFromExecutorPoolUseCase = removeExecutorFromExecutorPoolUseCase;
}
@PostMapping(path = "/executor-pool/RemoveExecutor", consumes = {ExecutorJsonRepresentation.EXECUTOR_MEDIA_TYPE})
public ResponseEntity<String> removeExecutorFromExecutorPool(@RequestBody ExecutorJsonRepresentation executorJsonRepresentation){
@DeleteMapping(path = "/executor-pool/executors/{executorUri}")
public ResponseEntity<String> removeExecutorFromExecutorPool(@PathVariable("executorUri") String executorUri){
RemoveExecutorFromExecutorPoolCommand command = new RemoveExecutorFromExecutorPoolCommand(
new ExecutorClass.ExecutorUri(URI.create(executorJsonRepresentation.getExecutorUri()))
new ExecutorClass.ExecutorUri(URI.create(executorUri))
);
Optional<ExecutorClass> removedExecutor = removeExecutorFromExecutorPoolUseCase.removeExecutorFromExecutorPool(command);

View File

@@ -1,6 +1,7 @@
server.port=8083
mqtt.broker.uri=tcp://localhost:1883
# mqtt.broker.uri=tcp://localhost:1883
mqtt.broker.uri=tcp://broker.hivemq.com
spring.data.mongodb.uri=mongodb://root:password@localhost:27017
spring.data.mongodb.database=tapas-executors

View File

@@ -18,6 +18,12 @@
<sonar.organization>scs-asse-fs21-group1</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
</properties>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -45,7 +51,42 @@
<artifactId>executor-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</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>master-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@@ -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();
}

View File

@@ -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.0/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;
}
}

View File

@@ -1,46 +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.InstructionToRobotPort;
@Component
@Primary
public class InstructionToRobotAdapter implements InstructionToRobotPort {
@Override
public boolean instructionToRobot(String key) {
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;
}
}

View File

@@ -1,12 +1,40 @@
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;
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;
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.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;
@@ -16,31 +44,198 @@ public class UserToRobotAdapter implements UserToRobotPort {
@Override
public String userToRobot() {
String postEndpoint = "https://api.interactions.ics.unisg.ch/leubot1/v1.3.0/user";
String inputJson = "{ \"name\":\"keanu rahimian\", \"email\":\"keanu.rahimian@student.unisg.ch\"}";
var request = HttpRequest.newBuilder()
.uri(URI.create(postEndpoint))
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 'leubot1' }";
var httpRequest = HttpRequest.newBuilder()
.uri(URI.create(endpoint))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(inputJson))
.POST(HttpRequest.BodyPublishers.ofString(input))
.build();
var client = HttpClient.newHttpClient();
try {
String description = client.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body();
String leubot1Uri = null;
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new InputSource(new StringReader(description)));
doc.getDocumentElement().normalize();
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<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.isEmpty()) {
// TODO implement logic if execution failed
return null;
}
Optional<Form> 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<DataSchema> 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<String, Object> elbowPayload = new HashMap<>();
elbowPayload.put("value", 400);
// Get the affordance "setElbow" from the TD
Optional<ActionAffordance> action = td.getActionByName("setElbow");
// Get the first form
if (action.isEmpty()) {
return false;
}
Optional<Form> 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<DataSchema> inputSchema = action.get().getInputSchema();
TDHttpRequest request = new TDHttpRequest(form.get(), TD.invokeAction);
if(inputSchema.isPresent()) {
request.setObjectPayload((ObjectSchema) inputSchema.get(), elbowPayload);
}
Optional<SecurityScheme> 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;
}
}

View File

@@ -1,5 +0,0 @@
package ch.unisg.executorrobot.executor.application.port.out;
public interface DeleteUserFromRobotPort {
boolean deleteUserFromRobot(String key);
}

View File

@@ -1,5 +0,0 @@
package ch.unisg.executorrobot.executor.application.port.out;
public interface InstructionToRobotPort {
boolean instructionToRobot(String key);
}

View File

@@ -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,8 @@ 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);
userToRobotPort.userToRobot();
return "";
}
}

View File

@@ -4,17 +4,20 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import ch.unisg.roster.roster.adapter.out.persistence.mongodb.RosterRepository;
import ch.unisg.roster.roster.application.port.in.LoadRosterItemPort;
import ch.unisg.roster.roster.application.service.GetExecutorsService;
import ch.unisg.roster.roster.domain.Roster;
import ch.unisg.roster.roster.domain.RosterItem;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.ConfigurableEnvironment;
import ch.unisg.roster.roster.adapter.common.clients.TapasMqttClient;
import ch.unisg.roster.roster.adapter.in.messaging.mqtt.ExecutorEventMqttListener;
import ch.unisg.roster.roster.adapter.in.messaging.mqtt.ExecutorEventsMqttDispatcher;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@@ -26,14 +29,16 @@ public class RosterApplication {
private static ConfigurableEnvironment ENVIRONMENT;
private static LoadRosterItemPort loadRosterItemPort;
@Autowired
private LoadRosterItemPort loadRosterItemPort;
public static void main(String[] args) {
SpringApplication rosterApp = new SpringApplication(RosterApplication.class);
ENVIRONMENT = rosterApp.run(args).getEnvironment();
bootstrapMarketplaceWithMqtt();
initialiseRoster();
var getExecutorsService = new GetExecutorsService();
getExecutorsService.getExecutorsFromExecutorPool();
}
/**
@@ -52,7 +57,8 @@ public class RosterApplication {
}
}
private static void initialiseRoster(){
@PostConstruct
private void initialiseRoster(){
List<RosterItem> rosterItemList = loadRosterItemPort.loadAllRosterItems();
Roster.getInstance().initialiseRoster(rosterItemList);
}

View File

@@ -18,8 +18,6 @@ public class ExecutorAddedEventListenerMqttAdapter extends ExecutorEventMqttList
@Override
public boolean handleEvent(MqttMessage message) {
System.out.println("New Executor added!");
String payload = new String(message.getPayload());
try {
@@ -30,6 +28,8 @@ public class ExecutorAddedEventListenerMqttAdapter extends ExecutorEventMqttList
String taskType = data.get("executorTaskType").asText();
String executorId = data.get("executorUri").asText();
LOGGER.info("Roster | New executor with type " + taskType + " added.");
ExecutorAddedEvent executorAddedEvent = new ExecutorAddedEvent(
new ExecutorURI(executorId),
new ExecutorType(taskType)

View File

@@ -1,11 +1,8 @@
package ch.unisg.roster.roster.adapter.in.web;
import ch.unisg.roster.roster.domain.Roster;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.json.JSONObject;
import org.springframework.http.HttpHeaders;
import java.util.logging.Logger;
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;
@@ -16,8 +13,6 @@ import ch.unisg.roster.roster.domain.ExecutorInfo;
import ch.unisg.roster.roster.domain.Task;
import org.springframework.web.server.ResponseStatusException;
import javax.validation.ConstraintViolationException;
@RestController
public class ApplyForTaskWebController {
private final ApplyForTaskUseCase applyForTaskUseCase;
@@ -26,14 +21,15 @@ public class ApplyForTaskWebController {
this.applyForTaskUseCase = applyForTaskUseCase;
}
// TODO fix return type
Logger logger = Logger.getLogger(ApplyForTaskWebController.class.getName());
/**
* Checks if task is available for the requesting executor.
* @return a task or null if no task found
* @return a task or 404 if no task available
**/
@PostMapping(path = "/task/apply", consumes = {"application/json"})
public ResponseEntity<String> applyForTask (@RequestBody ExecutorInfo executorInfo) {
public Task applyForTask (@RequestBody ExecutorInfo executorInfo) {
logger.info("Roster | Execuor applying for task");
ApplyForTaskCommand command = new ApplyForTaskCommand(executorInfo.getExecutorType(),
executorInfo.getExecutorURI());
@@ -43,23 +39,6 @@ public class ApplyForTaskWebController {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
try {
String executorType = command.getTaskType().getValue().toString();
String executorURI = command.getExecutorURI().getValue().toString();
String jsonPayLoad = new JSONObject()
.put("executorType", executorType)
.put("executorURI", executorURI)
.toString();
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add("Content-Type", "application/json");
return new ResponseEntity<>(jsonPayLoad, responseHeaders, HttpStatus.CREATED);
} catch (ConstraintViolationException e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
}
return task;
}
}

View File

@@ -1,14 +1,15 @@
package ch.unisg.roster.roster.adapter.in.web;
import java.util.logging.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import ch.unisg.roster.roster.application.port.in.DeleteTaskCommand;
import ch.unisg.roster.roster.application.port.in.DeleteTaskUseCase;
import ch.unisg.roster.roster.domain.Task;
@RestController
public class DeleteTaskController {
@@ -18,14 +19,16 @@ public class DeleteTaskController {
this.deleteTaskUseCase = deleteTaskUseCase;
}
Logger logger = Logger.getLogger(DeleteTaskController.class.getName());
/**
* Controller to delete a task
* @return 200 OK, 409 Conflict
**/
@DeleteMapping(path = "/task", consumes = {"application/task+json"})
public ResponseEntity<Void> applyForTask(@RequestBody Task task) {
DeleteTaskCommand command = new DeleteTaskCommand(task.getTaskID(), task.getTaskType());
@DeleteMapping(path = "/task/{taskId}")
public ResponseEntity<Void> deleteTask(@PathVariable("taskId") String taskId) {
logger.info("Roster | Delete task request.");
DeleteTaskCommand command = new DeleteTaskCommand(taskId);
if (deleteTaskUseCase.deleteTask(command)) {
return new ResponseEntity<>(HttpStatus.OK);

View File

@@ -2,11 +2,14 @@ package ch.unisg.roster.roster.adapter.in.web;
import java.util.logging.Logger;
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.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.function.ServerRequest.Headers;
import ch.unisg.roster.roster.application.port.in.NewTaskCommand;
import ch.unisg.roster.roster.application.port.in.NewTaskUseCase;
@@ -27,16 +30,33 @@ public class NewTaskController {
* @return 201 Create or 409 Conflict
**/
@PostMapping(path = "/task", consumes = {"application/task+json"})
public ResponseEntity<Void> newTaskController(@RequestBody Task task) {
public ResponseEntity<Void> newTaskController(@RequestBody Task task, @RequestHeader HttpHeaders header) {
logger.info("New task with id:" + task.getTaskID());
logger.info("Roster | New task with id:" + task.getTaskID());
NewTaskCommand command = new NewTaskCommand(task.getTaskID(), task.getTaskType(),
// Check if task URI is passed in body. (This happends when we handeling an external task) Else get task URI from header.
String taskUri = task.getTaskUri();
if (taskUri == null) {
if (header.containsKey("Link")) {
for (String location : header.get("Link")) {
if (location.contains("rel=\"task\"")) {
taskUri = location.split(">")[0].substring(1);
}
}
}
}
if (taskUri == null) {
logger.warning("Roster | TaskUri still null, something went wrong!");
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
NewTaskCommand command = new NewTaskCommand(task.getTaskID(), taskUri, task.getTaskType(),
task.getInputData());
boolean success = newTaskUseCase.addNewTaskToQueue(command);
logger.info("Could create task: " + success);
logger.info("Roster | Could create task: " + success);
if (success) {
return new ResponseEntity<>(HttpStatus.CREATED);

View File

@@ -0,0 +1,61 @@
package ch.unisg.roster.roster.adapter.out.web;
import ch.unisg.roster.roster.domain.ExecutorInfo;
import org.apache.logging.log4j.Level;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.http.HttpStatus;
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.LinkedList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class GetExecutorsInExecutorPoolWebAdapter {
private static final Logger LOGGER = LogManager.getLogger(GetExecutorsInExecutorPoolWebAdapter.class);
// TODO get from config
String server = "http://localhost:8083";
public List<ExecutorInfo> getExecutorsInExecutorPool(){
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create(server + "/executor-pool/GetAllExecutorsInExecutorPool"))
.GET()
.build();
try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if(response.statusCode() != HttpStatus.OK.value()){
LOGGER.log(Level.INFO, "Could not get executors from Executor Pool");
return null;
}
LOGGER.log(Level.INFO, "Executors received from ExecutorPool: " + response.body());
var jsonExecutorArray = new JSONArray(response.body());
var executorList = new LinkedList<ExecutorInfo>();
for(int i = 0; i < jsonExecutorArray.length(); i++){
var jsonExecutorObject = jsonExecutorArray.getJSONObject(i);
var executorURI = jsonExecutorObject.getString("executorUri");
var executorType = jsonExecutorObject.getString("executorTaskType");
executorList.add(new ExecutorInfo(executorURI, executorType));
}
return executorList;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,65 @@
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 java.util.logging.Level;
import java.util.logging.Logger;
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;
Logger logger = Logger.getLogger(LaunchAuctionEventAdapter.class.getName());
@Override
public void launchAuctionEvent(LaunchAuctionEvent launchAuctionEvent) {
var values = new HashMap<String, String>();
values.put("taskUri", launchAuctionEvent.taskUri);
values.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/auction+json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
try {
client.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException e) {
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
} catch (InterruptedException e) {
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
Thread.currentThread().interrupt();
}
}
}

View File

@@ -25,6 +25,12 @@ public class PublishNewTaskEventAdapter implements NewTaskEventPort {
@Value("${executor.computation.uri}")
private String server2;
@Value("${executor.humidity.uri}")
private String server3;
@Value("${executor.humidity.demo.uri}")
private String server4;
Logger logger = Logger.getLogger(PublishNewTaskEventAdapter.class.getName());
/**
@@ -34,21 +40,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 +71,38 @@ 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);
}
HttpClient client4 = HttpClient.newHttpClient();
HttpRequest request4 = HttpRequest.newBuilder()
.uri(URI.create(server4 + "/newtask/" + event.taskType.getValue()))
.GET()
.build();
try {
client4.send(request4, 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);
}
}
}

View File

@@ -1,7 +1,5 @@
package ch.unisg.roster.roster.application.port.in;
import ch.unisg.roster.roster.domain.RosterItem;
public interface DeleteRosterItem {
void deleteRosterItem(String taskId);

View File

@@ -2,7 +2,6 @@ package ch.unisg.roster.roster.application.port.in;
import javax.validation.constraints.NotNull;
import ch.unisg.roster.roster.domain.valueobject.ExecutorType;
import ch.unisg.common.validation.SelfValidating;
import lombok.EqualsAndHashCode;
import lombok.Value;
@@ -13,12 +12,8 @@ public class DeleteTaskCommand extends SelfValidating<ApplyForTaskCommand> {
@NotNull
private final String taskId;
@NotNull
private final ExecutorType taskType;
public DeleteTaskCommand(String taskId, ExecutorType taskType) {
public DeleteTaskCommand(String taskId) {
this.taskId = taskId;
this.taskType = taskType;
this.validateSelf();
}
}

View File

@@ -1,5 +1,7 @@
package ch.unisg.roster.roster.application.port.in;
import java.net.URI;
import javax.validation.constraints.NotNull;
import ch.unisg.roster.roster.domain.valueobject.ExecutorType;
@@ -17,11 +19,13 @@ public class NewTaskCommand extends SelfValidating<NewTaskCommand> {
@NotNull
private final ExecutorType taskType;
@NotNull
private final String inputData;
public NewTaskCommand(String taskID, ExecutorType taskType, String inputData) {
private final String taskUri;
public NewTaskCommand(String taskID, String taskUri, ExecutorType taskType, String inputData) {
this.taskID = taskID;
this.taskUri = taskUri;
this.taskType = taskType;
this.inputData = inputData;
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
public boolean deleteTask(DeleteTaskCommand command) {
Roster roster = Roster.getInstance();
return roster.deleteTask(command.getTaskId(), command.getTaskType());
return roster.deleteTask(command.getTaskId());
}
}

View File

@@ -0,0 +1,18 @@
package ch.unisg.roster.roster.application.service;
import ch.unisg.roster.roster.adapter.out.web.GetExecutorsInExecutorPoolWebAdapter;
import ch.unisg.roster.roster.domain.ExecutorRegistry;
// TODO should this implement a port in the Hexagonal architecture?
public class GetExecutorsService {
public boolean getExecutorsFromExecutorPool(){
var getExecutorsAdapter = new GetExecutorsInExecutorPoolWebAdapter();
var executors = getExecutorsAdapter.getExecutorsInExecutorPool();
if(executors == null){
return false;
}
var executorRegistry = ExecutorRegistry.getInstance();
return executorRegistry.addExecutors(executors);
}
}

View File

@@ -1,15 +1,19 @@
package ch.unisg.roster.roster.application.service;
import java.util.logging.Logger;
import javax.transaction.Transactional;
import org.springframework.stereotype.Component;
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.out.LaunchAuctionEventPort;
import ch.unisg.roster.roster.application.port.out.NewTaskEventPort;
import ch.unisg.roster.roster.domain.ExecutorRegistry;
import ch.unisg.roster.roster.domain.Roster;
import ch.unisg.roster.roster.domain.Task;
import ch.unisg.roster.roster.domain.event.LaunchAuctionEvent;
import ch.unisg.roster.roster.domain.event.NewTaskEvent;
import lombok.RequiredArgsConstructor;
@@ -20,6 +24,10 @@ public class NewTaskService implements NewTaskUseCase {
private final NewTaskEventPort newTaskEventPort;
private final LaunchAuctionEventPort launchAuctionEventPort;
Logger logger = Logger.getLogger(NewTaskService.class.getName());
/**
* 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.
@@ -31,9 +39,15 @@ public class NewTaskService implements NewTaskUseCase {
ExecutorRegistry executorRegistry = ExecutorRegistry.getInstance();
if (!executorRegistry.containsTaskType(command.getTaskType())) {
return false;
logger.info("Roster | Task with type " + command.getTaskType() + "can not be handled internaly. Send to auction house!");
LaunchAuctionEvent launchAuctionEvent = new LaunchAuctionEvent( command.getTaskUri(),
command.getTaskType());
launchAuctionEventPort.launchAuctionEvent(launchAuctionEvent);
return true;
}
logger.info("Roster | Task with type " + command.getTaskType() + " can be handled internaly.");
Task task = new Task(command.getTaskID(), command.getTaskType(), command.getInputData());
Roster.getInstance().addTaskToQueue(task);

View File

@@ -5,6 +5,8 @@ import ch.unisg.common.valueobject.ExecutorURI;
import lombok.Getter;
import lombok.Setter;
import java.net.URI;
public class ExecutorInfo {
@Getter
@Setter
@@ -13,4 +15,9 @@ public class ExecutorInfo {
@Getter
@Setter
private ExecutorType executorType;
public ExecutorInfo(String executorURI, String executorType){
this.executorURI = new ExecutorURI(executorURI);
this.executorType = new ExecutorType(executorType);
}
}

View File

@@ -30,8 +30,8 @@ public class ExecutorRegistry {
/**
* Adds an executor to the registry for a given task type.
*
* @param taskType the type of the task
* @param executorIdentifier the identifier of the executor (can be any string)
* @param executorType the type of the task
* @param executorURI the identifier of the executor (can be any string)
* @return true unless a runtime exception occurs
*/
public boolean addExecutor(ExecutorType executorType, ExecutorURI executorURI) {
@@ -44,6 +44,15 @@ public class ExecutorRegistry {
return true;
}
public boolean addExecutors(List<ExecutorInfo> executors){
for (var executor : executors) {
if(!addExecutor(executor.getExecutorType(), executor.getExecutorURI())){
return false;
}
}
return true;
}
/**
* Removes an executor from the registry. The executor is disassociated from all known task types.
*

View File

@@ -76,9 +76,14 @@ public class Roster {
* Deletes a task if it is still in the queue.
* @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);
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){

View File

@@ -12,6 +12,9 @@ public class Task {
@Getter
private ExecutorType taskType;
@Getter
private String taskUri;
@Getter
@Setter
private String inputData;
@@ -40,6 +43,12 @@ public class Task {
this.inputData = inputData;
}
public Task(String taskID, String taskUri, ExecutorType taskType) {
this.taskID = taskID;
this.taskUri = taskUri;
this.taskType = taskType;
}
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,8 +1,12 @@
server.port=8082
executor.robot.uri=http://127.0.0.1:8084
executor.computation.uri=http://127.0.0.1:8085
executor.humidity.uri=http://127.0.0.1:8087
executor.humidity.demo.uri=http://127.0.0.1:8088
auction.house.uri=http://127.0.0.1:8086
task.list.uri=http://127.0.0.1:8081
mqtt.broker.uri=tcp://localhost:1883
# mqtt.broker.uri=tcp://localhost:1883
mqtt.broker.uri=tcp://broker.hivemq.com
spring.data.mongodb.uri=mongodb://root:password@localhost:27017/
spring.data.mongodb.database=tapas-roster

View File

@@ -31,7 +31,7 @@ public class RosterTest {
assertThat(task.getTaskType().getValue().toString()).isEqualTo("TEST-TYPE");
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
//assertThat(empty_queue).isEqualTo(true);
//assertThat(queues.size()).isEqualTo(0);
@@ -44,8 +44,8 @@ public class RosterTest {
queues.clear();
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(queues.size()).isEqualTo(1);
}

View File

@@ -69,6 +69,12 @@
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.unisg</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View File

@@ -2,21 +2,21 @@ package ch.unisg.tapas;
import ch.unisg.tapas.auctionhouse.adapter.common.clients.TapasMqttClient;
import ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt.AuctionEventsMqttDispatcher;
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscovery;
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 ch.unisg.tapas.common.ConfigProperties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.ConfigurableEnvironment;
import java.net.URI;
import java.util.List;
import java.net.URISyntaxException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -28,34 +28,40 @@ import java.util.concurrent.TimeUnit;
public class TapasAuctionHouseApplication {
private static final Logger LOGGER = LogManager.getLogger(TapasAuctionHouseApplication.class);
public static String RESOURCE_DIRECTORY = "http://localhost:3500";
public static String DEFAULT_MQTT_BROKER = "tcp://broker.hivemq.com:1883";
private static ConfigurableEnvironment ENVIRONMENT;
public static void main(String[] args) {
SpringApplication tapasAuctioneerApp = new SpringApplication(TapasAuctionHouseApplication.class);
ENVIRONMENT = tapasAuctioneerApp.run(args).getEnvironment();
// TODO Set start up of message services with config
// We will use these bootstrap methods in Week 6:
bootstrapMarketplaceWithWebSub();
bootstrapMarketplaceWithMqtt();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(crawlerRunnable, 30, 30, TimeUnit.SECONDS);
var getExecutorsService = new GetExecutorsService();
getExecutorsService.getExecutorsFromExecutorPool();
}
/**
* Discovers auction houses and subscribes to WebSub notifications
*/
private static void bootstrapMarketplaceWithWebSub() {
WebSubSubscriber subscriber = new WebSubSubscriber(ENVIRONMENT.getProperty("auction.house.uri"));
try {
subscriber.subscribeToAuctionHouseEndpoint(new URI("https://tapas-auction-house.86-119-34-242.nip.io/websub-discovery"));
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
discoverAuctionHouseEndpoints();
// WebSubSubscriber subscriber = new WebSubSubscriber();
// for (String endpoint : auctionHouseEndpoints) {
// subscriber.subscribeToAuctionHouseEndpoint(URI.create(endpoint));
// for (AuctionHouseDiscoveryInformation endpoint : AuctionHouseDiscovery.getInstance().getAuctionHouseDiscoveryList()) {
// System.out.println(endpoint.getWebSubUri().getValue());
// if (!endpoint.getWebSubUri().getValue().toString().equalsIgnoreCase("https://tapas-auction-house.86-119-35-40.nip.io/websub/auctions")) {
// subscriber.subscribeToAuctionHouseEndpoint(endpoint.getWebSubUri().getValue());
// }
// }
}
@@ -82,21 +88,25 @@ public class TapasAuctionHouseApplication {
}
private static void discoverAuctionHouseEndpoints() {
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
URI.create(RESOURCE_DIRECTORY)
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);
}
private static Runnable crawlerRunnable = new Runnable() {
public void run() {
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
URI.create(RESOURCE_DIRECTORY)
);
// private static Runnable crawlerRunnable = new Runnable() {
// public void run() {
// AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
// URI.create(ENVIRONMENT.getProperty("discovery.endpoint.uri"))
// );
AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
}
};
// AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
// }
// };
}

View File

@@ -50,7 +50,6 @@ public class TapasMqttClient {
mqttClient = new org.eclipse.paho.client.mqttv3.MqttClient(brokerAddress, mqttClientId, new MemoryPersistence());
mqttClient.connect();
mqttClient.setCallback(messageReceivedCallback);
subscribeToAllTopics();
}

View File

@@ -2,9 +2,11 @@ package ch.unisg.tapas.auctionhouse.adapter.common.clients;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -18,25 +20,24 @@ import org.springframework.http.HttpStatus;
*/
public class WebSubSubscriber {
// TODO get this somehow from properties file. But on clue how to do this with static variables
static String WEBSUB_HUB_ENDPOINT = "http://localhost:3000";
static String AUCTION_HOUSE_ENDPOINT = "http://localhost:8086";
Logger logger = Logger.getLogger(WebSubSubscriber.class.getName());
public void subscribeToAuctionHouseEndpoint(URI endpoint) {
// TODO decide with other groups about auction house endpoint uri to discover websub topics
// and replace the hardcoded one with it
String topic = discoverWebSubTopic("http://localhost:3100/websub");
String AUCTION_HOUSE_ENDPOINT;
if (topic == null) {
public WebSubSubscriber(String AUCTION_HOUSE_ENDPOINT) {
this.AUCTION_HOUSE_ENDPOINT = AUCTION_HOUSE_ENDPOINT;
}
public void subscribeToAuctionHouseEndpoint(URI endpoint) {
HashMap<String, String> links = discoverWebSubTopic(endpoint);
if (links.isEmpty()) {
return;
}
subscribeToWebSub(topic);
subscribeToWebSub(links.get("hub"), links.get("self"));
// Shoudl be done :D
// TODO Subscribe to the auction house endpoint via WebSub:
// 1. Send a request to the auction house in order to discover the WebSub hub to subscribe to.
// The request URI should depend on the design of the Auction House HTTP API.
// 2. Send a subscription request to the discovered WebSub hub to subscribe to events relevant
@@ -52,23 +53,30 @@ public class WebSubSubscriber {
// - the implementation notes of the WebSub hub you are using to distribute events
}
private String discoverWebSubTopic(String endpoint) {
private HashMap<String, String> discoverWebSubTopic(URI endpoint) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(endpoint))
.uri(endpoint)
.header("Content-Type", "application/json")
.GET()
.build();
HashMap<String, String> links = new HashMap<>();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == HttpStatus.OK.value()) {
// TODO decide with other groups about response structure and replace the hardcoded
// uri with response uri
JSONObject jsonObject = new JSONObject(response.body());
System.out.println(jsonObject);
return jsonObject.getString("topic");
for (String link : response.headers().allValues("link")) {
if (link.contains("rel=\"hub\"")) {
String hub = link.split(">")[0];
links.put("hub", hub.substring(1));
} else if(link.contains("rel=\"self\"")) {
String self = link.split(">")[0];
links.put("self", self.substring(1));
}
System.out.println(link);
}
// TODO check for HTML tags second if links are not present in headers
} else {
logger.log(Level.SEVERE, "Could not find a websub uri");
}
@@ -78,24 +86,29 @@ public class WebSubSubscriber {
} catch (IOException e) {
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
return null;
return links;
}
private void subscribeToWebSub(String topic) {
private void subscribeToWebSub(String hub, String topic) {
HttpClient client = HttpClient.newHttpClient();
String body = new JSONObject()
.put("hub.callback", AUCTION_HOUSE_ENDPOINT + "/auction-started")
.put("hub.mode", "subscribe")
.put("hub.topic", topic)
.put("hub.ws", false)
.toString();
URI hubURI;
try {
hubURI = new URI(hub);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
System.out.println("HUB: " + hub);
System.out.println("TOPIC: " + topic);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(WEBSUB_HUB_ENDPOINT))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.uri(hubURI)
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("hub.mode=subscribe&hub.callback=" + AUCTION_HOUSE_ENDPOINT +
"/auction-started/74c72c7f-2739-4124-aa35-a3225171a97c" + "&hub.topic=" + topic))
.build();

View File

@@ -3,12 +3,16 @@ package ch.unisg.tapas.auctionhouse.adapter.common.formats;
import ch.unisg.tapas.auctionhouse.domain.Auction;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;
import java.net.URI;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Used to expose a representation of the state of an auction through an interface. This class is
@@ -60,4 +64,28 @@ public class AuctionJsonRepresentation {
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return mapper.writeValueAsString(representation);
}
public static Auction deserialize(String auctionJson) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(auctionJson);
Auction.AuctionId auctionId = new Auction.AuctionId(jsonNode.get("auctionId").asText());
Auction.AuctionHouseUri auctionHouseUri = new Auction.AuctionHouseUri(URI.create(jsonNode.get("auctionHouseUri").asText()));
Auction.AuctionedTaskUri taskUri = new Auction.AuctionedTaskUri(URI.create(jsonNode.get("taskUri").asText()));
Auction.AuctionedTaskType taskType = new Auction.AuctionedTaskType(jsonNode.get("taskType").asText());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date parsedDate;
try {
parsedDate = dateFormat.parse(jsonNode.get("deadline").toString());
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
Auction.AuctionDeadline deadline = new Auction.AuctionDeadline(timestamp);
Auction auction = new Auction(auctionId, auctionHouseUri, taskUri, taskType, deadline);
return auction;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}

View File

@@ -4,6 +4,7 @@ import ch.unisg.tapas.auctionhouse.application.handler.ExecutorAddedHandler;
import ch.unisg.tapas.auctionhouse.application.port.in.ExecutorAddedEvent;
import ch.unisg.tapas.auctionhouse.domain.Auction;
import ch.unisg.tapas.auctionhouse.domain.ExecutorRegistry;
import ch.unisg.common.valueobject.ExecutorURI;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -34,7 +35,7 @@ public class ExecutorAddedEventListenerMqttAdapter extends AuctionEventMqttListe
String executorTaskType = data.get("executorTaskType").asText();
ExecutorAddedEvent executorAddedEvent = new ExecutorAddedEvent(
new ExecutorRegistry.ExecutorUri(URI.create(executorUri)),
new ExecutorURI(executorUri),
new Auction.AuctionedTaskType(executorTaskType)
);

View File

@@ -2,6 +2,7 @@ package ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt;
import ch.unisg.tapas.auctionhouse.application.handler.ExecutorRemovedHandler;
import ch.unisg.tapas.auctionhouse.application.port.in.ExecutorRemovedEvent;
import ch.unisg.common.valueobject.ExecutorURI;
import ch.unisg.tapas.auctionhouse.domain.Auction;
import ch.unisg.tapas.auctionhouse.domain.ExecutorRegistry;
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -33,7 +34,7 @@ public class ExecutorRemovedEventListenerMqttAdapter extends AuctionEventMqttLis
String executorUri = data.get("executorUri").asText();
ExecutorRemovedEvent executorRemovedEvent = new ExecutorRemovedEvent(
new ExecutorRegistry.ExecutorUri(URI.create(executorUri))
new ExecutorURI(executorUri)
);
ExecutorRemovedHandler newExecutorHandler = new ExecutorRemovedHandler();

View File

@@ -13,26 +13,27 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Value;
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.sql.Timestamp;
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 taskListURI = "https://tapas-tasks.86-119-35-40.nip.io";
// String taskListURI = "http://e021-77-59-152-182.ngrok.io";
@Override
public boolean handleEvent(MqttMessage message){
String payload = new String(message.getPayload());
System.out.println("New auction");
try {
// Note: this message representation is provided only as an example. You should use a
// representation that makes sense in the context of your application.
@@ -46,6 +47,7 @@ public class ExternalAuctionStartedEventListenerMqttAdapter extends AuctionEvent
String deadline = data.get("deadline").asText();
var capable = ExecutorRegistry.getInstance().containsTaskType(new Auction.AuctionedTaskType(taskType));
System.out.println("Capable: " + capable);
// TODO check deadline
if(capable){
var bid = new Bid(

View File

@@ -1,20 +1,31 @@
package ch.unisg.tapas.auctionhouse.adapter.in.messaging.websub;
import ch.unisg.tapas.auctionhouse.adapter.common.formats.AuctionJsonRepresentation;
import ch.unisg.tapas.auctionhouse.adapter.common.formats.BidJsonRepresentation;
import ch.unisg.tapas.auctionhouse.application.handler.AuctionStartedHandler;
import ch.unisg.tapas.auctionhouse.application.port.in.AuctionStartedEvent;
import ch.unisg.tapas.auctionhouse.domain.Auction;
import ch.unisg.tapas.auctionhouse.domain.Bid;
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionDeadline;
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionHouseUri;
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionId;
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskType;
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskUri;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.Timestamp;
import java.util.Collection;
import java.util.Date;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -34,19 +45,88 @@ public class AuctionStartedEventListenerWebSubAdapter {
* @return 200 OK
* @throws URISyntaxException
**/
@PostMapping(path = "/auction-started")
public ResponseEntity<Void> handleExecutorAddedEvent(@RequestBody Collection<AuctionJsonRepresentation> payload) throws URISyntaxException {
// TODO generate a new capability ID instead of using a hardcoded one.
@PostMapping(path = "/auction-started/74c72c7f-2739-4124-aa35-a3225171a97c")
public ResponseEntity<Void> handleExecutorAddedEvent(@RequestBody String payload) throws URISyntaxException {
for (AuctionJsonRepresentation auction : payload) {
auctionStartedHandler.handleAuctionStartedEvent(
new AuctionStartedEvent(
new Auction(new AuctionId(auction.getAuctionId()),
new AuctionHouseUri(new URI(auction.getAuctionHouseUri())),
new AuctionedTaskUri(new URI(auction.getTaskUri())),
new AuctionedTaskType(auction.getTaskType()),
new AuctionDeadline(auction.getDeadline()))
));
}
System.out.println("new auctions :O");
System.out.println(payload);
JSONArray auctions = new JSONArray(payload);
if (auctions.length() > 0) {
JSONObject auction = auctions.getJSONObject(0);
System.out.print(auction);
// try {
// System.out.println(auction.getString("deadline"));
// System.out.println(AuctionJsonRepresentation.deserialize(auction.toString()));
// auctionStartedHandler.handleAuctionStartedEvent(
// new AuctionStartedEvent(AuctionJsonRepresentation.deserialize(auction.toString())));
// } catch (JsonProcessingException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
String auctionHouseURI = "https://tapas-auction-house.86-119-35-40.nip.io/";
// String auctionHouseURI = "http://b311-130-82-247-153.eu.ngrok.io";
String taskListURI = "https://tapas-tasks.86-119-35-40.nip.io";
// String taskListURI = "http://c64f-130-82-247-153.ngrok.io";
// TODO Sanitize URIs
String auctionId = auction.getString("auctionId");
String auctionHouseUri = auction.getString("auctionHouseUri");
String taskUri = auction.getString("taskUri");
String taskType = auction.getString("taskType");
String deadline = auction.getString("deadline");
var bid = new Bid(
new Auction.AuctionId(auctionId),
new Bid.BidderName("Group-1"),
new Bid.BidderAuctionHouseUri(URI.create(auctionHouseURI)),
new Bid.BidderTaskListUri(URI.create(taskListURI))
);
String body;
try {
body = BidJsonRepresentation.serialize(bid);
//LOGGER.info(body);
var postURI = URI.create(auctionHouseUri + "/bid");
HttpRequest postRequest = HttpRequest.newBuilder()
.uri(postURI)
.header("Content-Type", BidJsonRepresentation.MEDIA_TYPE)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpClient client = HttpClient.newHttpClient();
var postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString());
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//LOGGER.info(postResponse.statusCode());
};
// for (JSONObject auction : auctions) {
// auctionStartedHandler.handleAuctionStartedEvent(
// new AuctionStartedEvent(
// new Auction(new AuctionId(auction.getAuctionId()),
// new AuctionHouseUri(new URI(auction.getAuctionHouseUri())),
// new AuctionedTaskUri(new URI(auction.getTaskUri())),
// new AuctionedTaskType(auction.getTaskType()),
// new AuctionDeadline(auction.getDeadline()))
// ));
// }
return new ResponseEntity<>(HttpStatus.OK);
}

View File

@@ -0,0 +1,33 @@
package ch.unisg.tapas.auctionhouse.adapter.in.messaging.websub;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
/**
* This class is a template for handling auction started events received via WebSub
*/
@RestController
public class DiscoverWebSubAdapter {
@Value("${websub.hub.uri}")
private String webSubHubUri;
@Value("${auction.house.uri}")
private String auctionHouseUri;
/**
* Controller to discover our websub topic
* @return 200 OK
**/
@GetMapping(path = "/websub/auctions")
public ResponseEntity<String> handleDiscoverWebSubAuction() {
HttpHeaders header = new HttpHeaders();
header.add("link", "<" + auctionHouseUri + "/auctions/>; rel=\"self\"");
header.add("link", "<" + webSubHubUri + ">; rel=\"hub\"");
return ResponseEntity.ok().headers(header).body("");
}
}

View File

@@ -13,21 +13,9 @@ import org.springframework.web.bind.annotation.*;
@RestController
public class ValidateIntentWebSubAdapter {
@Value("${application.environment}")
private String environment;
@GetMapping(path = "/auction-started")
// TODO generate a new capability ID instead of using a hardcoded one.
@GetMapping(path = "/auction-started/74c72c7f-2739-4124-aa35-a3225171a97c")
public ResponseEntity<String> validateIntent(@RequestParam("hub.challenge") String challenge) {
// Different implementation depending on local development or production
if (environment.equalsIgnoreCase("development")) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
String body = new JSONObject()
.put("hub.challenge", challenge)
.toString();
return new ResponseEntity<>(body, headers, HttpStatus.OK);
} else {
return new ResponseEntity<>(challenge, HttpStatus.OK);
}
return new ResponseEntity<>(challenge, HttpStatus.OK);
}
}

View File

@@ -30,7 +30,7 @@ public class AuctionHouseDiscoveryWebController {
this.auctionHouseDiscoveryUseCase = auctionHouseDiscoveryUseCase;
}
@GetMapping(path="/discovery/", consumes = AuctionHouseDiscoveryJsonRepresentation.MEDIA_TYPE)
@GetMapping(path="/discovery/"/*, consumes = AuctionHouseDiscoveryJsonRepresentation.MEDIA_TYPE */)
public ResponseEntity<String> auctionHouseDiscovery() {
List<AuctionHouseDiscoveryInformation> auctionHouseDiscoveryInformation = auctionHouseDiscoveryUseCase.auctionHouseDiscovery();

View File

@@ -1,11 +1,6 @@
package ch.unisg.tapas.auctionhouse.adapter.in.web;
import ch.unisg.tapas.auctionhouse.adapter.common.formats.AuctionJsonRepresentation;
import ch.unisg.tapas.auctionhouse.adapter.common.formats.BidJsonRepresentation;
import ch.unisg.tapas.auctionhouse.adapter.common.formats.TaskJsonRepresentation;
import ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt.ExternalAuctionStartedEventListenerMqttAdapter;
import ch.unisg.tapas.auctionhouse.domain.Task;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
@@ -32,10 +27,12 @@ public class WinningBidWebController {
@PostMapping(path = "/taskwinner", consumes = TaskJsonRepresentation.MEDIA_TYPE)
public ResponseEntity<String> winningBid(@RequestBody TaskJsonRepresentation payload){
LOGGER.info("New Task Winner");
try {
var body = payload.serialize();
LOGGER.info(body);
var postURI = URI.create("https://tapas-tasks.86-119-35-40.nip.io/tasks/");
LOGGER.info("Task Winner body: " + body);
LOGGER.info("Task Winner taskListURI: " + taskListURI);
var postURI = URI.create(taskListURI + "/tasks/");
HttpRequest postRequest = HttpRequest.newBuilder()
.uri(postURI)
.header("Content-Type", TaskJsonRepresentation.MEDIA_TYPE)
@@ -45,11 +42,11 @@ 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();
return new ResponseEntity<>(responseHeaders, HttpStatus.NO_CONTENT);
return new ResponseEntity<>(responseHeaders, HttpStatus.ACCEPTED);
}
catch (
IOException | InterruptedException e) {

View File

@@ -6,9 +6,10 @@ import ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt.AuctionEventsMqttDi
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionStartedEventPort;
import ch.unisg.tapas.auctionhouse.domain.AuctionStartedEvent;
import ch.unisg.tapas.common.ConfigProperties;
import java.util.logging.Logger;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
@@ -18,19 +19,20 @@ import org.springframework.stereotype.Component;
@Primary
public class PublishAuctionStartedEventMqttAdapter implements AuctionStartedEventPort {
private static final Logger LOGGER = LogManager.getLogger(PublishAuctionStartedEventMqttAdapter.class);
Logger logger = Logger.getLogger(PublishAuctionStartedEventMqttAdapter.class.getName());
@Autowired
private ConfigProperties config;
@Override
public void publishAuctionStartedEvent(AuctionStartedEvent event) {
logger.info("AuctionHouse | Publish auction started over Mqtt!");
try{
var mqttClient = TapasMqttClient.getInstance(config.getMqttBrokerUri().toString(), new AuctionEventsMqttDispatcher());
mqttClient.publishMessage("ch/unisg/tapas/auctions", AuctionJsonRepresentation.serialize(event.getAuction()));
}
catch (MqttException | JsonProcessingException e){
LOGGER.error(e.getMessage(), e);
logger.severe(e.getMessage());
}
}
}

View File

@@ -1,41 +1,27 @@
package ch.unisg.tapas.auctionhouse.adapter.out.messaging.websub;
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionStartedEventPort;
import ch.unisg.tapas.auctionhouse.domain.Auction;
import ch.unisg.tapas.auctionhouse.domain.AuctionStartedEvent;
import ch.unisg.tapas.common.ConfigProperties;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* This class is a template for publishing auction started events via WebSub.
*/
@Component
// @Primary
public class PublishAuctionStartedEventWebSubAdapter implements AuctionStartedEventPort {
// You can use this object to retrieve properties from application.properties, e.g. the
// WebSub hub publish endpoint, etc.
@Autowired
private ConfigProperties config;
@Value("${auctionhouse.uri}")
@Value("${auction.house.uri}")
private String auctionHouseUri;
@Value("${websub.hub.uri}")
@@ -45,23 +31,23 @@ 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();
String body = new JSONObject()
.put("hub.url", auctionHouseUri + "/auctions")
.put("hub.mode", "publish")
.toString();
String body = "hub.url=" + auctionHouseUri + "/auctions/&hub.mode=publish";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(webSubHubUri))
.header("Content-Type", "application/json")
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
try {
client.send(request, HttpResponse.BodyHandlers.ofString());
logger.info("AuctionHouse | Publish auction over WebSub successfuly!");
} catch (InterruptedException e) {
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
Thread.currentThread().interrupt();

View File

@@ -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;
@@ -30,27 +31,34 @@ public class AuctionHouseDiscoveryHttpAdapter implements AuctionHouseDiscoveryPo
.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());
var arrayOfInformation = responseBody.getJSONArray("auctionHouseInfo");
var returnList = new LinkedList<AuctionHouseDiscoveryInformation>();
if (response.statusCode() == HttpStatus.OK.value() || response.statusCode() == HttpStatus.FOUND.value()) {
var responseBody = new JSONObject(response.body().toString());
// new JSON
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);
System.out.print(responseBody);
var arrayOfInformation = responseBody.getJSONArray("auctionHouseInfo");
var returnList = new LinkedList<AuctionHouseDiscoveryInformation>();
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 returnList;
return Collections.<AuctionHouseDiscoveryInformation>emptyList();
} catch (IOException e) {
e.printStackTrace();

View File

@@ -1,7 +1,6 @@
package ch.unisg.tapas.auctionhouse.adapter.out.web;
import ch.unisg.tapas.auctionhouse.adapter.common.formats.TaskJsonRepresentation;
import ch.unisg.tapas.auctionhouse.application.handler.AuctionStartedHandler;
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionWonEventPort;
import ch.unisg.tapas.auctionhouse.domain.AuctionRegistry;
import ch.unisg.tapas.auctionhouse.domain.AuctionWonEvent;
@@ -11,6 +10,7 @@ import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import java.io.IOException;
@@ -43,7 +43,12 @@ public class AuctionWonEventHttpAdapter implements AuctionWonEventPort {
.uri(auction.get().getTaskUri().getValue())
.GET()
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != HttpStatus.OK.value()) {
LOGGER.info("AuctionHouse | Could not get task from tasklist. Something went wrong...");
return;
}
LOGGER.info(response.body());
JSONObject responseBody = new JSONObject(response.body());

View File

@@ -0,0 +1,60 @@
package ch.unisg.tapas.auctionhouse.adapter.out.web;
import ch.unisg.tapas.auctionhouse.domain.ExecutorInfo;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.springframework.http.HttpStatus;
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.LinkedList;
import java.util.List;
public class GetExecutorsFromExecutorPoolWebAdapter {
private static final Logger LOGGER = LogManager.getLogger(GetExecutorsFromExecutorPoolWebAdapter.class);
// TODO get from config
String server = "http://localhost:8083";
public List<ExecutorInfo> getExecutorsInExecutorPool(){
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create(server + "/executor-pool/GetAllExecutorsInExecutorPool"))
.GET()
.build();
try {
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if(response.statusCode() != HttpStatus.OK.value()){
LOGGER.log(Level.INFO, "Could not get executors from Executor Pool");
return null;
}
LOGGER.log(Level.INFO, "Executors received from ExecutorPool: " + response.body());
var jsonExecutorArray = new JSONArray(response.body());
var executorList = new LinkedList<ExecutorInfo>();
for(int i = 0; i < jsonExecutorArray.length(); i++){
var jsonExecutorObject = jsonExecutorArray.getJSONObject(i);
var executorURI = jsonExecutorObject.getString("executorUri");
var executorType = jsonExecutorObject.getString("executorTaskType");
executorList.add(new ExecutorInfo(executorURI, executorType));
}
return executorList;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -2,7 +2,7 @@ package ch.unisg.tapas.auctionhouse.application.port.in;
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskType;
import ch.unisg.tapas.auctionhouse.domain.ExecutorRegistry;
import ch.unisg.tapas.auctionhouse.domain.ExecutorRegistry.ExecutorUri;
import ch.unisg.common.valueobject.ExecutorURI;
import ch.unisg.tapas.common.SelfValidating;
import lombok.Value;
@@ -14,7 +14,7 @@ import javax.validation.constraints.NotNull;
@Value
public class ExecutorAddedEvent extends SelfValidating<ExecutorAddedEvent> {
@NotNull
private final ExecutorRegistry.ExecutorUri executorUri;
private final ExecutorURI executorUri;
@NotNull
private final AuctionedTaskType taskType;
@@ -24,7 +24,7 @@ public class ExecutorAddedEvent extends SelfValidating<ExecutorAddedEvent> {
*
* @param executorUri the identifier of the executor that was added to this TAPAS application
*/
public ExecutorAddedEvent(ExecutorUri executorUri, AuctionedTaskType taskType) {
public ExecutorAddedEvent(ExecutorURI executorUri, AuctionedTaskType taskType) {
this.executorUri = executorUri;
this.taskType = taskType;

Some files were not shown because too many files have changed in this diff Show More