Added tooltips on selected services
Change-Id: I8558301bd178cdc53000d38bdf24c764d1f1af4f
Signed-off-by: Dirk Fauth <Dirk.Fauth@de.bosch.com>
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ProcessLog.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ProcessLog.java
index ba97da5..30c2412 100644
--- a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ProcessLog.java
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ProcessLog.java
@@ -24,6 +24,7 @@
private Action action;
private String message;
+ private String uuid;
public ProcessLog() {
}
@@ -53,4 +54,12 @@
this.message = message;
}
+ public ProcessLog withUuid(String uuid) {
+ this.uuid = uuid;
+ return this;
+ }
+
+ public String getUuid() {
+ return this.uuid;
+ }
}
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowController.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowController.java
index d183bcc..d5f0040 100644
--- a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowController.java
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowController.java
@@ -66,14 +66,15 @@
private final StorageService storageService;
private ExecutorService executor = Executors.newCachedThreadPool();
-
- private HashMap<String, WorkflowStatus> workflowStatusMap = new HashMap<>();
private DateFormat formatter = DateFormat.getDateTimeInstance(
DateFormat.SHORT,
DateFormat.SHORT,
Locale.ENGLISH);
+ @javax.annotation.Resource(name = "workflowStatusMap")
+ private HashMap<String, WorkflowStatus> workflowStatusMap;
+
@javax.annotation.Resource(name = "cloudServiceDefinitions")
List<CloudServiceDefinition> cloudServiceDefinitions;
@@ -87,14 +88,17 @@
@GetMapping("/workflow")
public String workflow(
- Model model,
+ Model model,
+ @ModelAttribute WorkflowStatus workflowStatus,
@RequestParam(name = "uuid", required = false) String uuid) {
if (!StringUtils.isEmpty(uuid)) {
WorkflowStatus existing = this.workflowStatusMap.get(uuid);
if (existing == null) {
- existing = WorkflowStatusHelper.loadWorkflowStatus(storageService.load(uuid, "workflowstatus.json").toFile());
+ existing = WorkflowStatusHelper.loadWorkflowStatus(
+ this.storageService.load(uuid, "workflowstatus.json").toFile(),
+ this.cloudServiceDefinitions);
if (existing != null) {
// we could load, so we store it in the local map to avoid loading it again
this.workflowStatusMap.put(uuid, existing);
@@ -103,9 +107,11 @@
}
}
model.addAttribute("workflowStatus", existing);
+ } else if (workflowStatus == null || workflowStatus.isDone()) {
+ // only create a new WorkflowStatus in case the current instance is done
+ model.addAttribute("workflowStatus", new WorkflowStatus());
}
-
// render the form view
return "workflow";
}
@@ -131,7 +137,7 @@
String uuid = storageService.store(file);
workflowStatus.setUuid(uuid);
- workflowStatus.setName(file.getOriginalFilename() + " - " + formatter.format(new Date()));
+ workflowStatus.setName(uuid + " - " + file.getOriginalFilename() + " - " + formatter.format(new Date()));
workflowStatus.addMessage(file.getOriginalFilename() + " successfully uploaded!");
this.workflowStatusMap.put(uuid, workflowStatus);
@@ -190,42 +196,45 @@
@PathVariable(name = "selected") String selected,
@ModelAttribute WorkflowStatus ws) {
- ws.addSelectedService(selected);
+ CloudServiceDefinition csd = this.cloudServiceDefinitions.stream()
+ .filter(sd -> sd.getName().equals(selected))
+ .findFirst()
+ .orElse(null);
+
+ if (csd == null) {
+ return "workflow";
+ }
+
+ ws.addSelectedService(csd);
if ("Validation".equals(selected)) {
// TODO general: check if the selected service has a configuration URL
// TODO build configuration based on provided service configuration
- CloudServiceDefinition csd = this.cloudServiceDefinitions.stream()
- .filter(sd -> sd.getName().equals("Validation"))
- .findFirst()
- .orElse(null);
- if (csd != null) {
- List<String> allProfiles = new ArrayList<>();
- try {
- String baseUrl = csd.getBaseUrl();
- if (!baseUrl.endsWith("/")) {
- baseUrl += "/";
- }
- List<?> jsonResult = Unirest.get(baseUrl + "profiles").asJson().getBody().getArray().toList();
- allProfiles = jsonResult.stream().map(Object::toString).collect(Collectors.toList());
- } catch (Exception e) {
- // do nothing, we will handle configurations in a different way in the future
+ List<String> allProfiles = new ArrayList<>();
+ try {
+ String baseUrl = csd.getBaseUrl();
+ if (!baseUrl.endsWith("/")) {
+ baseUrl += "/";
}
+ List<?> jsonResult = Unirest.get(baseUrl + "profiles").asJson().getBody().getArray().toList();
+ allProfiles = jsonResult.stream().map(Object::toString).collect(Collectors.toList());
+ } catch (Exception e) {
+ // do nothing, we will handle configurations in a different way in the future
+ }
+
+ if (allProfiles != null && !allProfiles.isEmpty()) {
+ ServiceConfiguration config = new ServiceConfiguration(selected);
- if (allProfiles != null && !allProfiles.isEmpty()) {
- ServiceConfiguration config = new ServiceConfiguration(selected);
-
- ServiceConfigurationParameter validationProfiles = new ServiceConfigurationParameter();
- validationProfiles.setName("Validation profiles");
- validationProfiles.setKey("profiles");
- validationProfiles.setType("String");
- validationProfiles.setCardinality("multiple");
- validationProfiles.setPossibleValues(allProfiles);
- config.addParameter(validationProfiles);
-
- ws.addConfiguration(selected, config);
- }
+ ServiceConfigurationParameter validationProfiles = new ServiceConfigurationParameter();
+ validationProfiles.setName("Validation profiles");
+ validationProfiles.setKey("profiles");
+ validationProfiles.setType("String");
+ validationProfiles.setCardinality("multiple");
+ validationProfiles.setPossibleValues(allProfiles);
+ config.addParameter(validationProfiles);
+
+ ws.addConfiguration(selected, config);
}
} else if ("RTC Analysis".equals(selected)) {
ServiceConfiguration config = new ServiceConfiguration(selected);
@@ -290,9 +299,15 @@
@PathVariable(name = "selected") String selected,
@ModelAttribute WorkflowStatus ws) {
- ws.removeSelectedService(selected);
-
- ws.removeConfiguration(selected);
+ CloudServiceDefinition csd = this.cloudServiceDefinitions.stream()
+ .filter(sd -> sd.getName().equals(selected))
+ .findFirst()
+ .orElse(null);
+
+ if (csd != null) {
+ ws.removeSelectedService(csd);
+ ws.removeConfiguration(selected);
+ }
// render the form view
return "workflow";
@@ -404,7 +419,7 @@
public void run() {
try {
Path inputFile = storageService.load(uuid, originalFilename);
- for (String service : workflowStatus.getSelectedServices()) {
+ for (CloudServiceDefinition service : workflowStatus.getSelectedServices()) {
if (StringUtils.isEmpty(service)) {
continue;
}
@@ -427,8 +442,10 @@
}
} finally {
workflowStatus.done();
- WorkflowStatusHelper.saveWorkflowStatus(workflowStatus, storageService.load(this.uuid, "workflowstatus.json").toFile());
- messagingTemplate.convertAndSend("/topic/process-updates", new ProcessLog(Action.DONE));
+ WorkflowStatusHelper.saveWorkflowStatus(
+ this.workflowStatus,
+ storageService.load(this.uuid, "workflowstatus.json").toFile());
+ messagingTemplate.convertAndSend("/topic/process-updates", new ProcessLog(Action.DONE).withUuid(this.uuid));
// TODO send to session and not broadcast
// messagingTemplate.convertAndSendToUser(
// this.uuid,
@@ -438,20 +455,10 @@
}
}
- private Path executeCloudService(String serviceName, WorkflowStatus workflowStatus, Path inputFile) {
+ private Path executeCloudService(CloudServiceDefinition csd, WorkflowStatus workflowStatus, Path inputFile) {
try {
- CloudServiceDefinition csd = cloudServiceDefinitions.stream()
- .filter(sd -> sd.getName().equals(serviceName))
- .findFirst()
- .orElse(null);
-
- String baseUrl = "";
- if (csd != null) {
- baseUrl = csd.getBaseUrl();
- } else {
- workflowStatus.addError("No service with name " + serviceName + " found! Workflow stopped!");
- return null;
- }
+ String serviceName = csd.getName();
+ String baseUrl = csd.getBaseUrl();
// upload to service
MultipartBody multipartBody = Unirest.post(baseUrl)
@@ -661,7 +668,7 @@
return result;
} catch (Exception e) {
- throw new ProcessingFailedException("Error in " + serviceName + " workflow: " + e.getMessage(), e);
+ throw new ProcessingFailedException("Error in " + csd.getName() + " workflow: " + e.getMessage(), e);
}
}
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowResultController.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowResultController.java
index 3b0418d..f598978 100644
--- a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowResultController.java
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowResultController.java
@@ -13,8 +13,12 @@
*/
package org.eclipse.app4mc.cloud.manager;
+import java.util.List;
import java.util.stream.Collectors;
+import javax.annotation.Resource;
+
+import org.eclipse.app4mc.cloud.manager.administration.CloudServiceDefinition;
import org.eclipse.app4mc.cloud.manager.storage.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@@ -28,6 +32,9 @@
@Autowired
private StorageService storageService;
+ @Resource(name = "cloudServiceDefinitions")
+ List<CloudServiceDefinition> cloudServiceDefinitions;
+
@GetMapping("/workflowResults")
public String workflowResults(Model model) {
@@ -35,12 +42,15 @@
.map(path -> path.toString().substring(path.toString().lastIndexOf('_') + 1))
.collect(Collectors.toMap(
uuid -> {
- WorkflowStatus status = WorkflowStatusHelper.loadWorkflowStatus(storageService.load(uuid, "workflowstatus.json").toFile());
+ WorkflowStatus status = WorkflowStatusHelper.loadWorkflowStatus(
+ this.storageService.load(uuid, "workflowstatus.json").toFile(),
+ this.cloudServiceDefinitions);
return (status != null && status.getName() != null) ? status.getName() : uuid;
},
uuid -> MvcUriComponentsBuilder.fromMethodName(WorkflowController.class,
"workflow",
model,
+ null,
uuid).build().toUri().toString()))
);
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatus.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatus.java
index 551c5a7..8ad7488 100644
--- a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatus.java
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatus.java
@@ -17,11 +17,13 @@
import java.util.HashMap;
import java.util.LinkedHashMap;
+import org.eclipse.app4mc.cloud.manager.administration.CloudServiceDefinition;
+
public class WorkflowStatus {
private String name;
private String uuid;
- private ArrayList<String> selectedServices = new ArrayList<>();
+ private ArrayList<CloudServiceDefinition> selectedServices = new ArrayList<>();
private HashMap<String, ServiceConfiguration> serviceConfigurations = new LinkedHashMap<>();
private ArrayList<String> messages = new ArrayList<>();
private ArrayList<String> errors = new ArrayList<>();
@@ -46,15 +48,15 @@
this.uuid = uuid;
}
- public ArrayList<String> getSelectedServices() {
+ public ArrayList<CloudServiceDefinition> getSelectedServices() {
return selectedServices;
}
- public void addSelectedService(String service) {
+ public void addSelectedService(CloudServiceDefinition service) {
this.selectedServices.add(service);
}
- public void removeSelectedService(String service) {
+ public void removeSelectedService(CloudServiceDefinition service) {
this.selectedServices.remove(service);
}
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatusHelper.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatusHelper.java
index 3a02bc8..23bf33f 100644
--- a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatusHelper.java
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatusHelper.java
@@ -14,11 +14,22 @@
package org.eclipse.app4mc.cloud.manager;
import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import org.eclipse.app4mc.cloud.manager.administration.CloudServiceDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
public final class WorkflowStatusHelper {
@@ -31,6 +42,11 @@
public static void saveWorkflowStatus(WorkflowStatus ws, File file) {
try {
ObjectMapper mapper = new ObjectMapper();
+
+ SimpleModule module = new SimpleModule();
+ module.addSerializer(CloudServiceDefinition.class, new CloudServiceDefinitionSerializer());
+ mapper.registerModule(module);
+
mapper.writerWithDefaultPrettyPrinter().writeValue(file, ws);
} catch (Exception e) {
LOG.error("Failed to serialize workflow status", e);
@@ -38,10 +54,15 @@
}
- public static WorkflowStatus loadWorkflowStatus(File file) {
+ public static WorkflowStatus loadWorkflowStatus(File file, List<CloudServiceDefinition> cloudServiceDefinitions) {
try {
if (file.exists()) {
ObjectMapper mapper = new ObjectMapper();
+
+ SimpleModule module = new SimpleModule();
+ module.addDeserializer(CloudServiceDefinition.class, new CloudServiceDefinitionDeserializer(cloudServiceDefinitions));
+ mapper.registerModule(module);
+
return mapper.readValue(file, WorkflowStatus.class);
}
} catch (Exception e) {
@@ -49,4 +70,54 @@
}
return null;
}
+
+ private static class CloudServiceDefinitionSerializer extends StdSerializer<CloudServiceDefinition> {
+
+ private static final long serialVersionUID = 6323664165957974486L;
+
+ public CloudServiceDefinitionSerializer() {
+ this(null);
+ }
+
+ public CloudServiceDefinitionSerializer(Class<CloudServiceDefinition> t) {
+ super(t);
+ }
+
+ @Override
+ public void serialize(CloudServiceDefinition value, JsonGenerator gen, SerializerProvider provider) throws IOException {
+ gen.writeString(value.getName());
+ }
+ }
+
+ private static class CloudServiceDefinitionDeserializer extends StdDeserializer<CloudServiceDefinition> {
+
+ private static final long serialVersionUID = -272147724534718705L;
+
+ private List<CloudServiceDefinition> cloudServiceDefinitions;
+
+ public CloudServiceDefinitionDeserializer(List<CloudServiceDefinition> cloudServiceDefinitions) {
+ this(null, cloudServiceDefinitions);
+ }
+
+ public CloudServiceDefinitionDeserializer(Class<?> vc, List<CloudServiceDefinition> cloudServiceDefinitions) {
+ super(vc);
+ this.cloudServiceDefinitions = cloudServiceDefinitions;
+ }
+
+ @Override
+ public CloudServiceDefinition deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+ String name = jp.getText();
+
+ CloudServiceDefinition csd = this.cloudServiceDefinitions.stream()
+ .filter(sd -> sd.getName().equals(name))
+ .findFirst()
+ .orElse(null);
+
+ if (csd != null) {
+ return csd;
+ } else {
+ return new CloudServiceDefinition(name, null, null);
+ }
+ }
+ }
}
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/administration/ApplicationConfig.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/administration/ApplicationConfig.java
index ef8f86b..7e20b88 100644
--- a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/administration/ApplicationConfig.java
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/administration/ApplicationConfig.java
@@ -19,9 +19,12 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
+import org.eclipse.app4mc.cloud.manager.WorkflowStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
@@ -32,6 +35,12 @@
@Bean
@ApplicationScope
+ public Map<String, WorkflowStatus> workflowStatusMap() {
+ return new HashMap<>();
+ }
+
+ @Bean
+ @ApplicationScope
public List<CloudServiceDefinition> cloudServiceDefinitions() {
ArrayList<CloudServiceDefinition> definitions = new ArrayList<>();
diff --git a/manager/src/main/resources/services.txt b/manager/src/main/resources/services.txt
index 076f805..94f4582 100644
--- a/manager/src/main/resources/services.txt
+++ b/manager/src/main/resources/services.txt
@@ -1,13 +1,13 @@
-Migration;http://localhost:8080/app4mc/converter/;Model Migration Service
-Validation;http://localhost:8181/app4mc/validation/;Model Validation Service
-RTC Analysis;http://localhost:8081/app4mc/analysis/;RTC Analysis Service
-RTC Interpreter;http://localhost:8082/app4mc/interpreter/rtc/;RTC Interpreter Service
-Label per Core Interpreter;http://localhost:8084/app4mc/interpreter/label-per-core/;Label per Core Interpreter Service
-Label per Memory Interpreter;http://localhost:8084/app4mc/interpreter/label-per-memory/;Label per Memory Interpreter Service
-Label per Task Interpreter;http://localhost:8084/app4mc/interpreter/label-per-task/;Label per Task Interpreter Service
-Label Size Interpreter;http://localhost:8084/app4mc/interpreter/label-size/;Label Size Interpreter Service
-Chart Visualizer;http://localhost:8083/app4mc/visualization/barchart/;Chart Visualizer Service
-Amalthea 2 INCHRON;https://am2inc.dev1.inchron.de/projects;Amalthea to INCHRON Transformation Service
-Amalthea 2 SystemC;http://localhost:8282/app4mc/amlt2systemc/;Amalthea to SystemC Transformation Service
-APP4MC.Sim;http://139.30.201.29:2323/app4mc/simulation/;APP4MC SystemC Simulation Service
-INCHRON BTF Trace Visualization;https://trace.dev1.inchron.de/traces/;INCHRON BTF Trace Visualization Service
\ No newline at end of file
+Migration;http://localhost:8080/app4mc/converter/;Migrates an input model file to model version 0.9.9
+Validation;http://localhost:8181/app4mc/validation/;Validates the input model file
+RTC Analysis;http://localhost:8081/app4mc/analysis/;Executes Real-Time Calculus (RTC) techniques on a provided Amalthea model to analyse timing properties of heterogeneous embedded systems
+RTC Interpreter;http://localhost:8082/app4mc/interpreter/rtc/;Converts the results of a RTC Analysis into an input for the Chart Visualizer
+Label per Core Interpreter;http://localhost:8084/app4mc/interpreter/label-per-core/;Parses an Amalthea model to inspect label access operations per core
+Label per Memory Interpreter;http://localhost:8084/app4mc/interpreter/label-per-memory/;Parses an Amalthea model to inspect label access operations per memory
+Label per Task Interpreter;http://localhost:8084/app4mc/interpreter/label-per-task/;Parses an Amalthea model to inspect label access operations per task
+Label Size Interpreter;http://localhost:8084/app4mc/interpreter/label-size/;Parses an Amalthea model to inspect the number of labels grouped by size
+Chart Visualizer;http://localhost:8083/app4mc/visualization/barchart/;Visualization of interpreter results
+Amalthea 2 INCHRON;https://am2inc.dev1.inchron.de/projects;Transforms an Amalthea model to an INCHRON model
+Amalthea 2 SystemC;http://localhost:8282/app4mc/amlt2systemc/;Transforms an Amalthea model to simulation code
+APP4MC.Sim;http://139.30.201.29:2323/app4mc/simulation/;Executes simulation and generates a BTF traces
+INCHRON BTF Trace Visualization;https://trace.dev1.inchron.de/traces/;Visualization of trace data provided by INCHRON
\ No newline at end of file
diff --git a/manager/src/main/resources/services_online.txt b/manager/src/main/resources/services_online.txt
index a7649d3..fe5f257 100644
--- a/manager/src/main/resources/services_online.txt
+++ b/manager/src/main/resources/services_online.txt
@@ -1,13 +1,13 @@
-Migration;https://app4mc.eclipseprojects.io/app4mc/converter/;Model Migration Service
-Validation;https://app4mc.eclipseprojects.io/app4mc/validation/;Model Validation Service
-RTC Analysis;https://app4mc.eclipseprojects.io/app4mc/analysis/;RTC Analysis Service
-RTC Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/rtc/;RTC Interpreter Service
-Label per Core Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-per-core/;Label per Core Interpreter Service
-Label per Memory Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-per-memory/;Label per Memory Interpreter Service
-Label per Task Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-per-task/;Label per Task Interpreter Service
-Label Size Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-size/;Label Size Interpreter Service
-Chart Visualizer;https://app4mc.eclipseprojects.io/app4mc/visualization/barchart/;Chart Visualizer Service
-Amalthea 2 INCHRON;https://am2inc.dev1.inchron.de/projects;Amalthea to INCHRON Transformation Service
-Amalthea 2 SystemC;https://app4mc.eclipseprojects.io/app4mc/amlt2systemc/;Amalthea to SystemC Transformation Service
-APP4MC.Sim;http://139.30.201.29:2323/app4mc/simulation/;APP4MC SystemC Simulation Service
-INCHRON BTF Trace Visualization;https://trace.dev1.inchron.de/traces/;INCHRON BTF Trace Visualization Service
\ No newline at end of file
+Migration;https://app4mc.eclipseprojects.io/app4mc/converter/;Migrates an input model file to model version 0.9.9
+Validation;https://app4mc.eclipseprojects.io/app4mc/validation/;Validates the input model file
+RTC Analysis;https://app4mc.eclipseprojects.io/app4mc/analysis/;Executes Real-Time Calculus (RTC) techniques on a provided Amalthea model to analyse timing properties of heterogeneous embedded systems
+RTC Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/rtc/;Converts the results of a RTC Analysis into an input for the Chart Visualizer
+Label per Core Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-per-core/;Parses an Amalthea model to inspect label access operations per core
+Label per Memory Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-per-memory/;Parses an Amalthea model to inspect label access operations per memory
+Label per Task Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-per-task/;Parses an Amalthea model to inspect label access operations per task
+Label Size Interpreter;https://app4mc.eclipseprojects.io/app4mc/interpreter/label-size/;Parses an Amalthea model to inspect the number of labels grouped by size
+Chart Visualizer;https://app4mc.eclipseprojects.io/app4mc/visualization/barchart/;Visualization of interpreter results
+Amalthea 2 INCHRON;https://am2inc.dev1.inchron.de/projects;Transforms an Amalthea model to an INCHRON model
+Amalthea 2 SystemC;https://app4mc.eclipseprojects.io/app4mc/amlt2systemc/;Transforms an Amalthea model to simulation code
+APP4MC.Sim;http://139.30.201.29:2323/app4mc/simulation/;Executes simulation and generates a BTF traces
+INCHRON BTF Trace Visualization;https://trace.dev1.inchron.de/traces/;Visualization of trace data provided by INCHRON
\ No newline at end of file
diff --git a/manager/src/main/resources/static/js/workflow.js b/manager/src/main/resources/static/js/workflow.js
index 585fa27..e1730a2 100644
--- a/manager/src/main/resources/static/js/workflow.js
+++ b/manager/src/main/resources/static/js/workflow.js
@@ -24,6 +24,7 @@
url: '/select/' + service,
success: function(result) {
$('#selectedServicesBlock').load('/selectedServices');
+ $('[data-toggle="tooltip"]').tooltip();
}
});
}
@@ -59,6 +60,9 @@
// load the fragments to be able to update via ajax in later steps
loadFragments();
+ // enable all tooltips in the document
+ $('[data-toggle="tooltip"]').tooltip();
+
// initialize and bind the form for ajax submission
var options = {
beforeSubmit: function() {
@@ -125,12 +129,13 @@
//'/user/queue/process-updates',
function (processLog) {
var action = JSON.parse(processLog.body).action;
+ var uuid = JSON.parse(processLog.body).uuid;
if (action == 'UPDATE') {
$('#messagesBlock').load('/messages');
$('#errorsBlock').load('/errors');
} else if (action == 'DONE') {
disconnect();
- window.location.href = window.location.href.split("?")[0];
+ window.location.href = window.location.href.split("?")[0] + '?uuid=' + uuid;
}
}
);
diff --git a/manager/src/main/resources/templates/selectedServices.html b/manager/src/main/resources/templates/selectedServices.html
index d87b196..a7794c1 100644
--- a/manager/src/main/resources/templates/selectedServices.html
+++ b/manager/src/main/resources/templates/selectedServices.html
@@ -8,10 +8,15 @@
<div th:fragment="servicesList" id="selectedServices" th:object="${workflowStatus}">
<ul class="list-group">
<li th:each="selected : ${workflowStatus.selectedServices}" class="list-group-item d-flex justify-content-between" th:classappend="*{uuid != null} ? disabled_service : ''">
- <p class="p-0 flex-grow-1 plist" th:text="${selected}" th:classappend="*{uuid != null} ? disabled_service : ''">Service</p>
+ <p
+ class="p-0 flex-grow-1 plist"
+ th:text="${selected.name}"
+ th:title="${selected.description}"
+ data-toggle="tooltip"
+ th:classappend="*{uuid != null} ? disabled_service : ''">Service</p>
<a
th:if="*{uuid == null}"
- th:attr="onclick=|removeSelectedServices('${selected}')|"
+ th:attr="onclick=|removeSelectedServices('${selected.name}')|"
class="btn btn-primary btn-sm btn-rmv">
<i class="fas fa-times"></i>
</a>
diff --git a/manager/src/main/resources/templates/status.html b/manager/src/main/resources/templates/status.html
index 07ac487..6bd5880 100644
--- a/manager/src/main/resources/templates/status.html
+++ b/manager/src/main/resources/templates/status.html
@@ -28,17 +28,33 @@
<p class="p-0 m-0 flex-grow-1" th:text="${result.key}">Result</p>
<a class="btn btn-primary btn-sm mr-1"
th:if="${not #strings.endsWith(result.value, 'zip')}"
- th:href="@{/{uuid}/files/{resultValue}(uuid=${workflowStatus.uuid},resultValue=${result.value})}"><i class="fas fa-eye"></i></a>
+ th:href="@{/{uuid}/files/{resultValue}(uuid=${workflowStatus.uuid},resultValue=${result.value})}"
+ title="View the result in the browser"
+ data-toggle="tooltip"><i class="fas fa-eye"></i></a>
<a class="btn btn-secondary btn-sm"
- th:href="@{/{uuid}/files/{resultValue}?download=true(uuid=${workflowStatus.uuid},resultValue=${result.value})}"><i class="fas fa-download"></i></a>
+ th:href="@{/{uuid}/files/{resultValue}?download=true(uuid=${workflowStatus.uuid},resultValue=${result.value})}"
+ title="Download the processing result"
+ data-toggle="tooltip"><i class="fas fa-download"></i></a>
</li>
</ul>
<div class="row mt-4 mb-4">
<div class="col">
- <a th:href="@{/{uuid}/delete(uuid=${workflowStatus.uuid})}" class="btn btn-danger">Delete</a>
- <a th:href="@{workflow?uuid={uuid}(uuid=${workflowStatus.uuid})}" class="btn btn-info" onclick="copy(this);return false;">Permanent Link</a>
+ <a th:href="@{/{uuid}/delete(uuid=${workflowStatus.uuid})}"
+ class="btn btn-danger"
+ title="Delete the processing result"
+ data-toggle="tooltip">Delete</a>
+ <a th:href="@{workflow?uuid={uuid}(uuid=${workflowStatus.uuid})}"
+ class="btn btn-info"
+ title="Copy the permanent link of this execution to the clipboard"
+ data-toggle="tooltip"
+ onclick="copy(this);return false;">Permanent Link</a>
<div>
- <div class="toast" role="alert" aria-live="assertive" aria-atomic="true" style="position:relative;bottom:60px;left:200px;">
+ <div
+ class="toast"
+ role="alert"
+ aria-live="assertive"
+ aria-atomic="true"
+ style="position:relative;bottom:60px;left:200px;">
<div class="toast-body">
Permanent link copied to clipboard
</div>
diff --git a/manager/src/main/resources/templates/workflowResults.html b/manager/src/main/resources/templates/workflowResults.html
index 46cce37..b4addea 100644
--- a/manager/src/main/resources/templates/workflowResults.html
+++ b/manager/src/main/resources/templates/workflowResults.html
@@ -19,7 +19,7 @@
</div>
<div class="row" th:each="workflow : ${workflows}">
<div class="col text-center">
- <a th:href="${workflow.value}" th:text="${workflow.key}"></a>
+ <a th:href="${workflow.value}" th:text="${#strings.substringAfter(workflow.key, ' - ')}"></a>
</div>
</div>
<div sec:authorize="isAuthenticated()" class="row mt-5">