Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDirk Fauth2020-10-13 09:18:39 +0000
committerDirk Fauth2020-10-13 09:18:39 +0000
commitd6ad7e69fc0131d0f5a3f2f3476945642b164e33 (patch)
tree18f787a4ec8e974d80b06d8168d1a4b605abb062
parent4e5b2bc9f1f71ff8e3ecd1f23bde9f5432361d19 (diff)
downloadorg.eclipse.app4mc.cloud-d6ad7e69fc0131d0f5a3f2f3476945642b164e33.tar.gz
org.eclipse.app4mc.cloud-d6ad7e69fc0131d0f5a3f2f3476945642b164e33.tar.xz
org.eclipse.app4mc.cloud-d6ad7e69fc0131d0f5a3f2f3476945642b164e33.zip
Added handling of configuration parameter
Change-Id: I1f8b52c321528ddd40a1b9079234017665cae64e Signed-off-by: Dirk Fauth <Dirk.Fauth@de.bosch.com>
-rw-r--r--manager/pom.xml2
-rw-r--r--manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfiguration.java39
-rw-r--r--manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfigurationParameter.java85
-rw-r--r--manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowController.java117
-rw-r--r--manager/src/main/java/org/eclipse/app4mc/cloud/manager/WorkflowStatus.java24
-rw-r--r--manager/src/main/resources/templates/selectedServices.html46
-rw-r--r--manager/src/main/resources/templates/workflow.html15
-rw-r--r--org.eclipse.app4mc.validation.cloud/org.eclipse.app4mc.validation.cloud.http/src/org/eclipse/app4mc/validation/cloud/http/ValidationServlet.java39
8 files changed, 318 insertions, 49 deletions
diff --git a/manager/pom.xml b/manager/pom.xml
index bec8421..52b57cf 100644
--- a/manager/pom.xml
+++ b/manager/pom.xml
@@ -62,7 +62,7 @@
<dependency>
<groupId>com.konghq</groupId>
<artifactId>unirest-java</artifactId>
- <version>3.7.04</version>
+ <version>3.11.01</version>
</dependency>
<dependency>
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfiguration.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfiguration.java
new file mode 100644
index 0000000..1f21f09
--- /dev/null
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfiguration.java
@@ -0,0 +1,39 @@
+/*********************************************************************************
+ * Copyright (c) 2020 Robert Bosch GmbH and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Robert Bosch GmbH - initial API and implementation
+ ********************************************************************************
+ */
+package org.eclipse.app4mc.cloud.manager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ServiceConfiguration {
+
+ private final String serviceName;
+ private ArrayList<ServiceConfigurationParameter> parameter = new ArrayList<>();
+
+ public ServiceConfiguration(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void addParameter(ServiceConfigurationParameter param) {
+ this.parameter.add(param);
+ }
+
+ public List<ServiceConfigurationParameter> getParameterList() {
+ return this.parameter;
+ }
+}
diff --git a/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfigurationParameter.java b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfigurationParameter.java
new file mode 100644
index 0000000..a96ebbf
--- /dev/null
+++ b/manager/src/main/java/org/eclipse/app4mc/cloud/manager/ServiceConfigurationParameter.java
@@ -0,0 +1,85 @@
+/*********************************************************************************
+ * Copyright (c) 2020 Robert Bosch GmbH and others.
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Robert Bosch GmbH - initial API and implementation
+ ********************************************************************************
+ */
+package org.eclipse.app4mc.cloud.manager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ServiceConfigurationParameter {
+
+ private String name;
+ private String key;
+ private String value;
+ private String type;
+ private String cardinality = "single";
+ private boolean mandatory = false;
+ private List<String> possibleValues = new ArrayList<>();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getCardinality() {
+ return cardinality;
+ }
+
+ public void setCardinality(String cardinality) {
+ this.cardinality = cardinality;
+ }
+
+ public boolean isMandatory() {
+ return mandatory;
+ }
+
+ public void setMandatory(boolean mandatory) {
+ this.mandatory = mandatory;
+ }
+
+ public List<String> getPossibleValues() {
+ return possibleValues;
+ }
+
+ public void setPossibleValues(List<String> possibleValues) {
+ this.possibleValues = possibleValues;
+ }
+
+}
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 8766f29..efa796f 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
@@ -20,7 +20,9 @@ import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
import org.apache.http.HttpStatus;
import org.eclipse.app4mc.cloud.manager.administration.CloudServiceDefinition;
@@ -47,6 +49,7 @@ import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import kong.unirest.HttpResponse;
+import kong.unirest.MultipartBody;
import kong.unirest.Unirest;
@Controller
@@ -65,28 +68,6 @@ public class WorkflowController {
@GetMapping("/workflow")
public String workflow(Model model) {
-
- // TODO move this to a configuration resource mechanism
- CloudServiceDefinition csd = this.cloudServiceDefinitions.stream()
- .filter(sd -> sd.getName().equals("Validation"))
- .findFirst()
- .orElse(null);
-
- List<?> allProfiles = new ArrayList<>();
- if (csd != null) {
- try {
- String baseUrl = csd.getBaseUrl();
- if (!baseUrl.endsWith("/")) {
- baseUrl += "/";
- }
- allProfiles = Unirest.get(baseUrl + "profiles").asJson().getBody().getArray().toList();
- } catch (Exception e) {
- // do nothing, we will handle configurations in a different way in the future
- }
- }
-
- model.addAttribute("allProfiles", allProfiles);
-
// render the form view
return "workflow";
}
@@ -104,8 +85,65 @@ public class WorkflowController {
ws.addSelectedService(selected);
- // TODO init service configuration
-
+ 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
+ }
+
+ 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);
+ }
+ }
+ } else if ("RTC Analysis".equals(selected)) {
+ ServiceConfiguration config = new ServiceConfiguration(selected);
+
+ ServiceConfigurationParameter ascPriorities = new ServiceConfigurationParameter();
+ ascPriorities.setName("Ascending priorities");
+ ascPriorities.setKey("analysis-ascending-priorities");
+ ascPriorities.setType("boolean");
+ config.addParameter(ascPriorities);
+
+ ServiceConfigurationParameter enableFlows = new ServiceConfigurationParameter();
+ enableFlows.setName("Include flow analysis");
+ enableFlows.setKey("analysis-enable-flows");
+ enableFlows.setType("boolean");
+ config.addParameter(enableFlows);
+
+ ServiceConfigurationParameter timeUnit = new ServiceConfigurationParameter();
+ timeUnit.setName("Time unit");
+ timeUnit.setKey("analysis-time-unit");
+ timeUnit.setType("String");
+ timeUnit.setPossibleValues(Arrays.asList("s", "ms", "us", "ns"));
+ config.addParameter(timeUnit);
+
+ ws.addConfiguration(selected, config);
+ }
// render the form view
return "workflow";
@@ -118,6 +156,8 @@ public class WorkflowController {
ws.removeSelectedService(selected);
+ ws.removeConfiguration(selected);
+
// render the form view
return "workflow";
}
@@ -149,12 +189,13 @@ public class WorkflowController {
@PostMapping("/workflow")
public String handleFileUpload(
@RequestParam("file") MultipartFile file,
- @RequestParam(name = "profiles", required = false) String[] validationProfiles,
Model model,
@ModelAttribute WorkflowStatus ws) {
if (ws == null) {
ws = new WorkflowStatus();
+ } else {
+ ws.clearResults();
}
final WorkflowStatus workflowStatus = ws;
@@ -249,9 +290,28 @@ public class WorkflowController {
}
// upload to service
- HttpResponse<?> uploadResponse = Unirest.post(baseUrl)
+ MultipartBody multipartBody = Unirest.post(baseUrl)
.field("file", Files.newInputStream(inputFile), originalFilename)
- .asEmpty();
+ .field("values", Arrays.asList("value1", "value2"));
+
+ ServiceConfiguration config = workflowStatus.getConfiguration(serviceName);
+ if (config != null) {
+ config.getParameterList().forEach(param -> {
+ if (!StringUtils.isEmpty(param.getValue())) {
+ if ("multiple".equals(param.getCardinality())) {
+ // TODO remove query string once equinox multipart is fixed
+ multipartBody.queryString(param.getKey(), Arrays.asList(param.getValue().split(",")));
+ multipartBody.field(param.getKey(), Arrays.asList(param.getValue().split(",")));
+ } else {
+ // TODO remove query string once equinox multipart is fixed
+ multipartBody.queryString(param.getKey(), param.getValue());
+ multipartBody.field(param.getKey(), param.getValue());
+ }
+ }
+ });
+ }
+
+ HttpResponse<?> uploadResponse = multipartBody.asEmpty();
// extract status link from result
String statusUrl = null;
@@ -396,7 +456,8 @@ public class WorkflowController {
"serveFile",
workflowStatus.getUuid(),
"_" + serviceName.toLowerCase(),
- migrationError.getFileName().toString()).build().toUri().toString());
+ migrationError.getFileName().toString(),
+ null).build().toUri().toString());
// extract delete
deleteUrl = getUrlFromLink(errorResponse.getHeaders().get("Link"), "delete", baseUrl);
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 1e7eae3..1f972ae 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
@@ -21,6 +21,7 @@ public class WorkflowStatus {
private String uuid;
private ArrayList<String> selectedServices = new ArrayList<>();
+ private HashMap<String, ServiceConfiguration> serviceConfigurations = new LinkedHashMap<>();
private ArrayList<String> messages = new ArrayList<>();
private ArrayList<String> errors = new ArrayList<>();
private HashMap<String, String> results = new LinkedHashMap<>();
@@ -45,6 +46,22 @@ public class WorkflowStatus {
this.selectedServices.remove(service);
}
+ public ServiceConfiguration getConfiguration(String key) {
+ return this.serviceConfigurations.get(key);
+ }
+
+ public HashMap<String, ServiceConfiguration> getConfigurations() {
+ return this.serviceConfigurations;
+ }
+
+ public void addConfiguration(String key, ServiceConfiguration config) {
+ this.serviceConfigurations.put(key, config);
+ }
+
+ public void removeConfiguration(String key) {
+ this.serviceConfigurations.remove(key);
+ }
+
public ArrayList<String> getMessages() {
return messages;
}
@@ -69,8 +86,15 @@ public class WorkflowStatus {
this.results.put(key, resultFile);
}
+ public void clearResults() {
+ this.messages.clear();
+ this.errors.clear();
+ this.results.clear();
+ }
+
public void clear() {
this.selectedServices.clear();
+ this.serviceConfigurations.clear();
this.messages.clear();
this.errors.clear();
this.results.clear();
diff --git a/manager/src/main/resources/templates/selectedServices.html b/manager/src/main/resources/templates/selectedServices.html
index 71058a5..60fc357 100644
--- a/manager/src/main/resources/templates/selectedServices.html
+++ b/manager/src/main/resources/templates/selectedServices.html
@@ -5,7 +5,7 @@
</head>
<body>
- <div th:fragment="servicesList" id="selectedServices">
+ <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">
<p class="p-0 m-0 flex-grow-1" th:text="${selected}">Service</p>
@@ -21,6 +21,50 @@
th:selected="${service.name == selected}">
</option>
</select><br>
+
+ <div th:if="not *{configurations.isEmpty()}">
+ <div th:each="config : *{configurations}" class="mb-3">
+ <h4 th:text="${config.key + ' Configuration'}">Config</h4>
+ <div th:each="parameter, parameterStatus : ${config.value.parameterList}">
+ <!-- multiple possible values + cardinality multiple = checkboxes -->
+ <div th:if="${parameter.cardinality == 'multiple' and parameter.possibleValues.size() > 1}">
+ <label th:text="${parameter.name}">Label</label>
+ <div th:each="pv : ${parameter.possibleValues}" class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ th:field="*{configurations[__${config.key}__].parameterList[__${parameterStatus.index}__].value}"
+ th:value="${pv}">
+ <label class="form-check-label" th:text="${pv}">Profile</label>
+ </div>
+ </div>
+ <!-- multiple possible values + cardinality single = combobox -->
+ <div th:if="${parameter.cardinality == 'single' and parameter.possibleValues.size() > 1}">
+ <label th:text="${parameter.name}">Label</label>
+ <select
+ class="custom-select"
+ th:field="*{configurations[__${config.key}__].parameterList[__${parameterStatus.index}__].value}">
+ <option value=""></option>
+ <option
+ th:each="pv : ${parameter.possibleValues}"
+ th:text="${pv}"
+ th:value="${pv}">
+ </option>
+ </select>
+ </div>
+ <!-- single boolean value -->
+ <div th:if="${parameter.cardinality == 'single' and parameter.type == 'boolean'}" class="form-check">
+ <input
+ class="form-check-input"
+ type="checkbox"
+ th:field="*{configurations[__${config.key}__].parameterList[__${parameterStatus.index}__].value}"
+ value="true">
+ <label class="form-check-label" th:text="${parameter.name}" th:for="${parameter.key}">Label</label>
+ </div>
+ </div>
+ </div>
+ </div>
+
</div>
</body>
</html>
diff --git a/manager/src/main/resources/templates/workflow.html b/manager/src/main/resources/templates/workflow.html
index fdb7fef..08100a5 100644
--- a/manager/src/main/resources/templates/workflow.html
+++ b/manager/src/main/resources/templates/workflow.html
@@ -61,7 +61,7 @@ $(document).ready(function(){
</div>
</div>
- <form method="POST" enctype="multipart/form-data" action="/workflow">
+ <form method="POST" enctype="multipart/form-data" action="/workflow" th:object="${workflowStatus}">
<div class="form-row mb-3">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile" name="file">
@@ -85,19 +85,6 @@ $(document).ready(function(){
</div>
</div>
</div>
- <table>
- <tr th:if="${allProfiles != null and not allProfiles.isEmpty()}">
- <td valign="top">Select validations to perform:</td>
- <td>
- <ul>
- <li th:each="profile : ${allProfiles}">
- <input type="checkbox" name="profiles" th:value="${profile}" />
- <label th:text="${profile}">Amalthea</label>
- </li>
- </ul>
- </td>
- </tr>
- </table>
<div class="form-row">
<div class="col text-center">
<input type="submit" value="Start workflow" class="btn btn-primary mt-2"/>
diff --git a/org.eclipse.app4mc.validation.cloud/org.eclipse.app4mc.validation.cloud.http/src/org/eclipse/app4mc/validation/cloud/http/ValidationServlet.java b/org.eclipse.app4mc.validation.cloud/org.eclipse.app4mc.validation.cloud.http/src/org/eclipse/app4mc/validation/cloud/http/ValidationServlet.java
index 82c54e8..8d02b69 100644
--- a/org.eclipse.app4mc.validation.cloud/org.eclipse.app4mc.validation.cloud.http/src/org/eclipse/app4mc/validation/cloud/http/ValidationServlet.java
+++ b/org.eclipse.app4mc.validation.cloud/org.eclipse.app4mc.validation.cloud.http/src/org/eclipse/app4mc/validation/cloud/http/ValidationServlet.java
@@ -13,16 +13,19 @@
*/
package org.eclipse.app4mc.validation.cloud.http;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@@ -141,6 +144,8 @@ public class ValidationServlet extends HttpServlet {
ServletContext context = getServletContext();
Map<String, String> registry = getRegistry(context);
registry.put(uuid, PROGRESS_MARKER);
+
+ List<String> selectedProfiles = getSelectedProfiles(request);
// trigger asynchronous processing
executor.execute(() -> {
@@ -155,10 +160,6 @@ public class ValidationServlet extends HttpServlet {
return;
}
- // get profile selection out of request
- String[] profiles = request.getParameterValues("profiles");
- List<String> selectedProfiles = profiles != null ? Arrays.asList(profiles) : Arrays.asList("Amalthea Standard Validations");
-
// get selected profiles from profile manager
List<Class<? extends IProfile>> profileList = manager.getRegisteredValidationProfiles().values().stream()
.filter(profile -> selectedProfiles.contains(profile.getName()))
@@ -214,6 +215,34 @@ public class ValidationServlet extends HttpServlet {
return;
}
+ private List<String> getSelectedProfiles(HttpServletRequest request) throws IOException, ServletException {
+
+ // first check if the profiles are sent as query parameter
+ String[] profiles = request.getParameterValues("profiles");
+ if (profiles != null) {
+ return Arrays.asList(profiles);
+ } else {
+ // check if the profiles are sent as post parameter in the multipart request
+ List<String> collected = new ArrayList<>();
+ for (Part supportPart : request.getParts()) {
+ if (supportPart.getName().equals("profiles")) {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(supportPart.getInputStream()))) {
+ List<String> collect = reader.lines().collect(Collectors.toList());
+ if (collect != null && !collect.isEmpty()) {
+ collected.addAll(collect);
+ }
+ }
+ }
+ }
+ if (!collected.isEmpty()) {
+ return collected;
+ }
+ }
+
+ // neither query parameter nor multipart post parameter found, return default
+ return Arrays.asList("Amalthea Standard Validations");
+ }
+
// GET /app4mc/validation/profiles
// GET /app4mc/validation/{id}
// GET /app4mc/validation/{id}/download
@@ -222,7 +251,7 @@ public class ValidationServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
-
+
response.addHeader("Link", "<" + request.getRequestURL() + ">;rel=\"self\"");
String[] splitPath = validatePath(request.getPathInfo());

Back to the top