summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCooper.Wu <wutuo@chinamobile.com>2020-09-01 16:11:48 +0800
committerCooper.Wu <wutuo@chinamobile.com>2020-09-01 16:12:10 +0800
commit0c15423accb26f152167fd89cf3dc9ad1b504d61 (patch)
treedbd1865225250d0cfbce39a8e70c0f47a31df3d7
parent6ede5a7097df3122af7ddf9c850db737afa1e664 (diff)
Scenario active management
Issue-ID: VNFSDK-613 Change-Id: I0d89a53d5aa5c31137b25e1a65075fdb1e3504da Signed-off-by: Cooper.Wu <wutuo@chinamobile.com>
-rw-r--r--vnfmarket-be/vnf-sdk-marketplace/pom.xml5
-rw-r--r--vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vnfsdk/marketplace/common/CommonConstant.java4
-rw-r--r--vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/VTPResource.java18
-rw-r--r--vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/scenario/VTPScenarioResource.java174
-rw-r--r--vnfmarket-be/vnf-sdk-marketplace/src/main/resources/vtp.properties6
5 files changed, 195 insertions, 12 deletions
diff --git a/vnfmarket-be/vnf-sdk-marketplace/pom.xml b/vnfmarket-be/vnf-sdk-marketplace/pom.xml
index 3dcda1a9..3fbfb22c 100644
--- a/vnfmarket-be/vnf-sdk-marketplace/pom.xml
+++ b/vnfmarket-be/vnf-sdk-marketplace/pom.xml
@@ -121,6 +121,11 @@
<artifactId>snakeyaml</artifactId>
<version>1.26</version>
</dependency>
+ <dependency>
+ <groupId>cn.hutool</groupId>
+ <artifactId>hutool-all</artifactId>
+ <version>5.3.10</version>
+ </dependency>
<!-- jersey -->
<!-- excluded jetty-util and added invulnerable version -->
<dependency>
diff --git a/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vnfsdk/marketplace/common/CommonConstant.java b/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vnfsdk/marketplace/common/CommonConstant.java
index 60d2a22a..cc3cbe9d 100644
--- a/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vnfsdk/marketplace/common/CommonConstant.java
+++ b/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vnfsdk/marketplace/common/CommonConstant.java
@@ -53,6 +53,8 @@ public class CommonConstant {
public static final String CSAR_SUFFIX = ".csar";
+ public static final String YAML_SUFFIX = ".yaml";
+
public static final String HTTP_HEADER_CONTENT_RANGE = "Content-Range";
public static final String CATALOG_CSAR_DIR_NAME = "/csar";
@@ -103,6 +105,8 @@ public class CommonConstant {
public static final String MEDIA_TYPE_JSON = "application/json;charset=UTF-8";
+ public static final String MEDIA_TYPE_YAML = "text/yaml";
+
public static final String URL = "url";
public static final String METHOD_TYPE = "methodType";
diff --git a/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/VTPResource.java b/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/VTPResource.java
index 0d813c74..9e1a9c80 100644
--- a/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/VTPResource.java
+++ b/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/VTPResource.java
@@ -39,6 +39,8 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
public class VTPResource {
@@ -50,6 +52,8 @@ public class VTPResource {
protected static String VTP_ARTIFACT_STORE; // NOSONAR
protected static String VTP_EXECUTION_TEMP_STORE; // NOSONAR
protected static int VTP_EXECUTION_GRPC_TIMEOUT; // NOSONAR
+ protected static String VTP_YAML_STORE; // NOSONAR
+ protected static String VTP_SCRIPT_STORE; // NOSONAR
protected static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US); // NOSONAR
@@ -64,6 +68,8 @@ public class VTPResource {
VTP_ARTIFACT_STORE = prp.getProperty("vtp.artifact.store");
VTP_EXECUTION_TEMP_STORE = prp.getProperty("vtp.file.store");
VTP_EXECUTION_GRPC_TIMEOUT = Integer.parseInt(prp.getProperty("vtp.grpc.timeout")) * 1000 ;
+ VTP_YAML_STORE = prp.getProperty("vtp.yaml.store");
+ VTP_SCRIPT_STORE = prp.getProperty("vtp.script.store");
} catch (Exception e) { // NOSONAR
LOG.error(e.getMessage());
}
@@ -138,4 +144,16 @@ public class VTPResource {
return output;
}
+
+ /**
+ * Build SnakeYaml instance
+ * @return
+ */
+ protected Yaml snakeYaml() {
+ DumperOptions dumperOptions = new DumperOptions();
+ dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
+ dumperOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
+ dumperOptions.setPrettyFlow(false);
+ return new Yaml(dumperOptions);
+ }
}
diff --git a/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/scenario/VTPScenarioResource.java b/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/scenario/VTPScenarioResource.java
index 4b319328..2eff61f8 100644
--- a/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/scenario/VTPScenarioResource.java
+++ b/vnfmarket-be/vnf-sdk-marketplace/src/main/java/org/onap/vtp/scenario/VTPScenarioResource.java
@@ -16,21 +16,24 @@
package org.onap.vtp.scenario;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
+import java.io.*;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+
+import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import com.google.common.collect.Maps;
+import org.apache.commons.io.FileUtils;
+import org.apache.cxf.common.util.CollectionUtils;
import org.eclipse.jetty.http.HttpStatus;
+import org.glassfish.jersey.media.multipart.BodyPartEntity;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
+import org.glassfish.jersey.media.multipart.FormDataParam;
+import org.onap.vnfsdk.marketplace.common.CommonConstant;
+import org.onap.vnfsdk.marketplace.common.ToolUtil;
import org.onap.vtp.VTPResource;
import org.onap.vtp.error.VTPError;
import org.onap.vtp.error.VTPError.VTPException;
@@ -283,4 +286,153 @@ public class VTPScenarioResource extends VTPResource{
return Response.ok(this.getTestcaseHandler(scenario, testSuiteName, testCaseName).toString(), MediaType.APPLICATION_JSON).build();
}
+
+ @Path("/scenarios")
+ @POST
+ @ApiOperation(tags = "VTP Scenario", value = "Create Scenario")
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Failed to perform the operation", response = VTPError.class)})
+ public Response storageScenarios(@ApiParam(value = "file form data body parts", required = true)
+ @FormDataParam("files") List<FormDataBodyPart> bodyParts) throws VTPException {
+ bodyParts.forEach(bodyPart -> {
+ BodyPartEntity entity = (BodyPartEntity) bodyPart.getEntity();
+ String fileName = bodyPart.getContentDisposition().getFileName();
+ if (!ToolUtil.isYamlFile(new File(fileName))) {
+ LOG.error("The fileName {} is not yaml !!!", fileName);
+ return;
+ }
+ String scenario = fileName.substring(0, fileName.indexOf("-registry"));
+ File scenarioDir = new File(VTP_YAML_STORE, scenario);
+ File yamlFile = new File(VTP_YAML_STORE, fileName);
+
+ // 1、store the scenario yaml file and create the scenario dir
+ try {
+ FileUtils.deleteQuietly(yamlFile);
+ FileUtils.deleteDirectory(scenarioDir);
+ FileUtils.copyInputStreamToFile(entity.getInputStream(), yamlFile);
+ FileUtils.forceMkdir(scenarioDir);
+ } catch (IOException e) {
+ LOG.error("Save yaml {} failed", fileName, e);
+ }
+
+ // 2、create the testsuits dir and copy the testcase to current scenarios by commands
+ try {
+ Map<String, Object> yamlInfos = Maps.newHashMap();
+ try (FileReader fileReader = new FileReader(yamlFile)) {
+ yamlInfos = snakeYaml().load(fileReader);
+ }
+ for (Object service : (List) yamlInfos.get("services")) {
+ Map<String, Object> serviceMap = (Map<String, Object>) service;
+ String testsuite = serviceMap.get("name").toString();
+ File testsuiteDir = new File(scenarioDir, testsuite);
+ FileUtils.forceMkdir(testsuiteDir);
+ if (!serviceMap.containsKey("commands")) {
+ continue;
+ }
+ for (Object cmd : (List) serviceMap.get("commands")) {
+ File source = new File(VTP_YAML_STORE, cmd.toString().replaceAll("::", Matcher.quoteReplacement(File.separator)));
+ if (!cn.hutool.core.io.FileUtil.isFile(source)) {
+ LOG.error("Source {} is not a yaml file !!!", source.getName());
+ continue;
+ }
+ File dest = new File(testsuiteDir, cmd.toString().substring(cmd.toString().lastIndexOf("::") + 2));
+ FileUtils.copyFile(source, dest);
+
+ // 3、modify the testcase scenario and testsuite
+ Map<String, Object> result = Maps.newHashMap();
+ try (FileReader fileReader = new FileReader(dest)) {
+ result = snakeYaml().load(fileReader);
+ }
+ Map<String, Object> info = (Map<String, Object>) result.get("info");
+ info.put("product", scenario);
+ info.put("service", testsuite);
+ try (FileWriter fileWriter = new FileWriter(dest)) {
+ snakeYaml().dump(result, fileWriter);
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Parse testcase yaml failed !!!", e);
+ }
+ });
+ return Response.ok("Save yaml success", MediaType.APPLICATION_JSON).build();
+ }
+
+
+ @Path("/scenarios/{scenarioName}")
+ @DELETE
+ @ApiOperation(tags = "VTP Scenario", value = "Delete yaml string")
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Failed to perform the operation", response = VTPError.class)})
+ public Response deleteScenario(@ApiParam("Test scenario yaml") @PathParam("scenarioName") String scenarioName) throws VTPException {
+ String scenario = scenarioName.substring(0, scenarioName.indexOf("-registry"));
+ File scenarioDir = new File(VTP_YAML_STORE, scenario);
+ List<File> yamls = cn.hutool.core.io.FileUtil.loopFiles(scenarioDir, new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ final String path = pathname.getPath();
+ if (null != path && path.endsWith(CommonConstant.YAML_SUFFIX)) {
+ return true;
+ }
+ return false;
+ }
+ });
+ if (!CollectionUtils.isEmpty(yamls)) {
+ LOG.error("The scenario yaml {} has sub testcase yamls, delete failed", scenarioName);
+ throw new VTPException(
+ new VTPError().setMessage(MessageFormat.format("The scenario yaml {0} has sub testcase yamls, delete failed !!!", scenarioName))
+ .setHttpStatus(HttpStatus.INTERNAL_SERVER_ERROR_500));
+ }
+
+ try {
+ FileUtils.deleteQuietly(new File(VTP_YAML_STORE, scenarioName));
+ FileUtils.deleteDirectory(scenarioDir);
+ } catch (IOException e) {
+ LOG.error("Delete scenario yaml {} failed", scenarioName, e);
+ throw new VTPException(
+ new VTPError().setMessage("Delete yaml failed !!!").setHttpStatus(HttpStatus.INTERNAL_SERVER_ERROR_500));
+ }
+ return Response.ok("Delete yaml success", MediaType.APPLICATION_JSON).build();
+ }
+
+ @Path("/testcases")
+ @POST
+ @ApiOperation(tags = "VTP Scenario", value = "Create test case")
+ @Consumes(MediaType.MULTIPART_FORM_DATA)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500, message = "Failed to perform the operation", response = VTPError.class)})
+ public Response storageTestcases(@ApiParam(value = "file form data body parts", required = true)
+ @FormDataParam("files") List<FormDataBodyPart> bodyParts) throws VTPException {
+ bodyParts.forEach(bodyPart -> {
+ BodyPartEntity entity = (BodyPartEntity) bodyPart.getEntity();
+ String fileName = bodyPart.getContentDisposition().getFileName();
+ if (ToolUtil.isYamlFile(new File(fileName))) {
+ // 1、store the testcase yaml file
+ Map<String, Object> result = snakeYaml().load(entity.getInputStream());
+ Map<String, Object> info = (Map<String, Object>) result.get("info");
+
+ File yamlFile = new File(VTP_YAML_STORE, info.get("product") + File.separator + info.get("service") + File.separator + fileName);
+ try {
+ FileUtils.deleteQuietly(yamlFile);
+ FileUtils.copyInputStreamToFile(entity.getInputStream(), yamlFile);
+ } catch (IOException e) {
+ LOG.error("Save testcase yaml {} failed", yamlFile.getName(), e);
+ }
+ } else {
+ // 2、store the testcase script file
+ File scriptFile = new File(VTP_SCRIPT_STORE, fileName);
+ try {
+ FileUtils.deleteQuietly(scriptFile);
+ FileUtils.copyInputStreamToFile(entity.getInputStream(), scriptFile);
+ } catch (IOException e) {
+ LOG.error("Save testcase script {} failed", scriptFile.getName(), e);
+ }
+ }
+ });
+ return Response.ok("Save success", MediaType.APPLICATION_JSON).build();
+ }
}
diff --git a/vnfmarket-be/vnf-sdk-marketplace/src/main/resources/vtp.properties b/vnfmarket-be/vnf-sdk-marketplace/src/main/resources/vtp.properties
index d0e89d81..f7a579da 100644
--- a/vnfmarket-be/vnf-sdk-marketplace/src/main/resources/vtp.properties
+++ b/vnfmarket-be/vnf-sdk-marketplace/src/main/resources/vtp.properties
@@ -17,4 +17,8 @@ vtp.grpc.port = 50051
vtp.artifact.store = /tmp/data/vtp-artifacts
vtp.file.store = /tmp/data/vtp-tmp-files
#60 seconds
-vtp.grpc.timeout = 60 \ No newline at end of file
+vtp.grpc.timeout = 60
+
+#scenariotestsuittestcase store
+vtp.yaml.store = /opt/oclip/open-cli-schema/vtp
+vtp.script.store = /opt/oclip/script/vtp \ No newline at end of file