Merge "Added non-vulnerable version for log4j"
[vnfsdk/refrepo.git] / vnfmarket-be / vnf-sdk-marketplace / src / main / java / org / onap / vtp / scenario / VTPScenarioResource.java
index fda50ca..274cacd 100644 (file)
 
 package org.onap.vtp.scenario;
 
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -30,7 +39,16 @@ import javax.ws.rs.QueryParam;
 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.FileUtil;
+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;
@@ -43,8 +61,9 @@ import org.onap.vtp.scenario.model.VTPTestCase.VTPTestCaseOutput;
 import org.onap.vtp.scenario.model.VTPTestScenario.VTPTestScenarioList;
 import org.onap.vtp.scenario.model.VTPTestSuite.VTPTestSuiteList;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -55,30 +74,42 @@ import io.swagger.annotations.ApiResponses;
 @Path("/vtp")
 @Api(tags = {"VTP Scenario"})
 public class VTPScenarioResource extends VTPResource{
-    public VTPTestScenarioList listTestScenariosHandler() throws VTPException, IOException{
+    private static final String DESCRIPTION = "description";
+    private static final String PRODUCT_ARG="--product";
+    private static final String OPEN_CLI="open-cli";
+    private static final String FORMAT="--format";
+    private static final String IO_EXCEPTION_OCCURS ="IOException occurs";
+    private static final String SERVICE="service";
+    public VTPTestScenarioList listTestScenariosHandler() throws VTPException {
         List<String> args = new ArrayList<>();
 
-        args.addAll(Arrays.asList(new String[] {
-                "--product", "open-cli", "product-list", "--format", "json"
-                }));
+        args.addAll(Arrays.asList(
+                PRODUCT_ARG, OPEN_CLI, "product-list", FORMAT, "json"
+        ));
 
-        JsonNode results = this.makeRpcAndGetJson(args);
+
+        JsonElement results = null;
+        try {
+            results = this.makeRpcAndGetJson(args);
+        } catch (IOException e) {
+            LOG.error(IO_EXCEPTION_OCCURS,e);
+        }
 
         VTPTestScenarioList list = new VTPTestScenarioList();
 
-        if (results != null && results.isArray()) {
-            ArrayNode resultsArray = (ArrayNode)results;
-            if (resultsArray.size() >= 0) {
-                for (Iterator<JsonNode> it = resultsArray.iterator(); it.hasNext();) {
-                    JsonNode n = it.next();
-                    if (n.elements().hasNext()) {
-                        String name = n.get("product").asText();
+        if (results != null && results.isJsonArray() && results.getAsJsonArray().size()>0) {
+            JsonArray resultsArray = results.getAsJsonArray();
+            for (Iterator<JsonElement> it = resultsArray.iterator(); it.hasNext();) {
+                JsonElement jsonElement = it.next();
+                JsonObject n = jsonElement.getAsJsonObject();
+                if (n.entrySet().iterator().hasNext()) {
+                    String name = n.get("product").getAsString();
 
-                        if (name.equalsIgnoreCase("open-cli")) continue;
+                    if (OPEN_CLI.equalsIgnoreCase(name))
+                        continue;
 
-                        list.getScenarios().add(new VTPTestScenario().setName(name).setDescription(
-                                n.get("description").asText()));
-                    }
+                    list.getScenarios().add(new VTPTestScenario().setName(name).setDescription(
+                            n.get(DESCRIPTION).getAsString()));
                 }
             }
         }
@@ -94,30 +125,34 @@ public class VTPScenarioResource extends VTPResource{
             @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
                     message = "Failed to perform the operation",
                     response = VTPError.class) })
-    public Response listTestScenarios() throws VTPException, IOException {
+    public Response listTestScenarios() throws VTPException {
         return Response.ok(this.listTestScenariosHandler().getScenarios().toString(), MediaType.APPLICATION_JSON).build();
     }
 
-    public VTPTestSuiteList listTestSutiesHandler(String scenario) throws VTPException, IOException{
+    public VTPTestSuiteList listTestSutiesHandler(String scenario) throws VTPException {
         List<String> args = new ArrayList<>();
 
-        args.addAll(Arrays.asList(new String[] {
-                "--product", "open-cli", "service-list", "--product", scenario, "--format", "json"
-                }));
+        args.addAll(Arrays.asList(
+                PRODUCT_ARG, OPEN_CLI, "service-list", PRODUCT_ARG, scenario, FORMAT, "json"
+        ));
 
-        JsonNode results = this.makeRpcAndGetJson(args);
+        JsonElement results = null;
+        try {
+            results = this.makeRpcAndGetJson(args);
+        } catch (IOException e) {
+            LOG.error(IO_EXCEPTION_OCCURS,e);
+        }
 
         VTPTestSuiteList list = new VTPTestSuiteList();
 
-        if (results != null && results.isArray()) {
-            ArrayNode resultsArray = (ArrayNode)results;
-            if (resultsArray.size() >= 0) {
-                for (Iterator<JsonNode> it = resultsArray.iterator(); it.hasNext();) {
-                    JsonNode n = it.next();
-                    if (n.elements().hasNext()) {
-                        list.getSuites().add(new VTPTestSuite().setName(n.get("service").asText()).setDescription(
-                                n.get("description").asText()));
-                    }
+        if (results != null && results.isJsonArray() && results.getAsJsonArray().size()>0) {
+            JsonArray resultsArray = results.getAsJsonArray();
+            for (Iterator<JsonElement> it = resultsArray.iterator(); it.hasNext();) {
+                JsonElement jsonElement = it.next();
+                JsonObject n = jsonElement.getAsJsonObject();
+                if (n.entrySet().iterator().hasNext()) {
+                    list.getSuites().add(new VTPTestSuite().setName(n.get(SERVICE).getAsString()).setDescription(
+                            n.get(DESCRIPTION).getAsString()));
                 }
             }
         }
@@ -134,37 +169,41 @@ public class VTPScenarioResource extends VTPResource{
                     message = "Failed to perform the operation",
                     response = VTPError.class) })
     public Response listTestSuties(
-            @ApiParam("Test scenario name") @PathParam("scenario") String scenario) throws VTPException, IOException {
+            @ApiParam("Test scenario name") @PathParam("scenario") String scenario) throws VTPException {
 
         return Response.ok(this.listTestSutiesHandler(scenario).getSuites().toString(), MediaType.APPLICATION_JSON).build();
     }
 
-    public VTPTestCaseList listTestcasesHandler(String testSuiteName, String scenario) throws VTPException, IOException{
+    public VTPTestCaseList listTestcasesHandler(String testSuiteName, String scenario) throws VTPException {
         List<String> args = new ArrayList<>();
 
-        args.addAll(Arrays.asList(new String[] {
-                "--product", "open-cli", "schema-list", "--product", scenario, "--format", "json"
-                }));
+        args.addAll(Arrays.asList(
+                PRODUCT_ARG, OPEN_CLI, "schema-list", PRODUCT_ARG, scenario, FORMAT, "json"
+        ));
         if (testSuiteName != null) {
             args.add("--service");
             args.add(testSuiteName);
         }
 
-        JsonNode results = this.makeRpcAndGetJson(args);
+        JsonElement results = null;
+        try {
+            results = this.makeRpcAndGetJson(args);
+        } catch (IOException e) {
+            LOG.error(IO_EXCEPTION_OCCURS,e);
+        }
 
         VTPTestCaseList list = new VTPTestCaseList();
 
-        if (results != null && results.isArray()) {
-            ArrayNode resultsArray = (ArrayNode)results;
-            if (resultsArray.size() >= 0) {
-                for (Iterator<JsonNode> it = resultsArray.iterator(); it.hasNext();) {
-                    JsonNode n = it.next();
-                    if (n.elements().hasNext())
-                        list.getTestCases().add(
-                                new VTPTestCase().setTestCaseName(
-                                        n.get("command").asText()).setTestSuiteName(
-                                                n.get("service").asText()));
-                }
+        if (results != null && results.isJsonArray() && results.getAsJsonArray().size()>0) {
+            JsonArray resultsArray = results.getAsJsonArray();
+            for (Iterator<JsonElement> it = resultsArray.iterator(); it.hasNext();) {
+                JsonElement jsonElement = it.next();
+                JsonObject n = jsonElement.getAsJsonObject();
+                if (n.entrySet().iterator().hasNext())
+                    list.getTestCases().add(
+                            new VTPTestCase().setTestCaseName(
+                                    n.get("command").getAsString()).setTestSuiteName(
+                                    n.get(SERVICE).getAsString()));
             }
         }
 
@@ -180,41 +219,47 @@ public class VTPScenarioResource extends VTPResource{
                     message = "Failed to perform the operation",
                     response = VTPError.class) })
     public Response listTestcases(
-             @ApiParam("Test scenario name") @PathParam("scenario") String scenario,
-             @ApiParam("Test suite name") @QueryParam("testSuiteName") String testSuiteName
-             ) throws VTPException, IOException {
+            @ApiParam("Test scenario name") @PathParam("scenario") String scenario,
+            @ApiParam("Test suite name") @QueryParam("testSuiteName") String testSuiteName
+    ) throws VTPException {
 
         return Response.ok(this.listTestcasesHandler(testSuiteName, scenario).getTestCases().toString(), MediaType.APPLICATION_JSON).build();
     }
 
-    public VTPTestCase getTestcaseHandler(String scenario, String testSuiteName, String testCaseName) throws VTPException, IOException {
+    public VTPTestCase getTestcaseHandler(String scenario, String testSuiteName, String testCaseName) throws VTPException {
         List<String> args = new ArrayList<>();
-        args.addAll(Arrays.asList(new String[] {
-                 "--product", "open-cli", "schema-show", "--product", scenario, "--service", testSuiteName, "--command", testCaseName , "--format", "json"
-                }));
-        JsonNode results = this.makeRpcAndGetJson(args);
+        args.addAll(Arrays.asList(
+                PRODUCT_ARG, OPEN_CLI, "schema-show", PRODUCT_ARG, scenario, "--service", testSuiteName, "--command", testCaseName , FORMAT, "json"
+        ));
+        JsonElement results = null;
+        try {
+            results = this.makeRpcAndGetJson(args);
+        } catch (IOException e) {
+            LOG.error(IO_EXCEPTION_OCCURS,e);
+        }
 
-        JsonNode schema = results.get("schema");
+        JsonObject schema = results.getAsJsonObject().getAsJsonObject("schema");
 
         VTPTestCase tc = new VTPTestCase();
-        tc.setTestCaseName(schema.get("name").asText());
-        tc.setDescription(schema.get("description").asText());
-        tc.setTestSuiteName(schema.get("service").asText());
-        tc.setAuthor(schema.get("author").asText());
-        JsonNode inputsJson = schema.get("inputs");
-        if (inputsJson != null && inputsJson.isArray()) {
-            for (final JsonNode inputJson: inputsJson) {
+        tc.setTestCaseName(schema.get("name").getAsString());
+        tc.setDescription(schema.get(DESCRIPTION).getAsString());
+        tc.setTestSuiteName(schema.get(SERVICE).getAsString());
+        tc.setAuthor(schema.get("author").getAsString());
+        JsonElement inputsJson = schema.get("inputs");
+        if (inputsJson != null && inputsJson.isJsonArray()) {
+            for (final JsonElement jsonElement: inputsJson.getAsJsonArray()) {
+                JsonObject inputJson  = jsonElement.getAsJsonObject();
                 VTPTestCaseInput input = new VTPTestCaseInput();
 
-                input.setName(inputJson.get("name").asText());
-                input.setDescription(inputJson.get("description").asText());
-                input.setType(inputJson.get("type").asText());
+                input.setName(inputJson.get("name").getAsString());
+                input.setDescription(inputJson.get(DESCRIPTION).getAsString());
+                input.setType(inputJson.get("type").getAsString());
 
                 if (inputJson.get("is_optional") != null)
-                    input.setIsOptional(inputJson.get("is_optional").asBoolean());
+                    input.setIsOptional(inputJson.get("is_optional").getAsBoolean());
 
                 if (inputJson.get("default_value") != null)
-                    input.setDefaultValue(inputJson.get("default_value").asText());
+                    input.setDefaultValue(inputJson.get("default_value").getAsString());
 
                 if (inputJson.get("metadata") != null)
                     input.setMetadata(inputJson.get("metadata"));
@@ -223,13 +268,14 @@ public class VTPScenarioResource extends VTPResource{
             }
         }
 
-        JsonNode outputsJson = schema.get("outputs");
-        if (outputsJson != null && outputsJson.isArray()) {
-            for (final JsonNode outputJson: outputsJson) {
+        JsonElement outputsJson = schema.get("outputs");
+        if (outputsJson != null && outputsJson.isJsonArray() && outputsJson.getAsJsonArray().size()>0) {
+            for (final JsonElement jsonElement: outputsJson.getAsJsonArray()) {
+                JsonObject outputJson = jsonElement.getAsJsonObject();
                 VTPTestCaseOutput output = new VTPTestCaseOutput();
-                output.setName(outputJson.get("name").asText());
-                output.setDescription(outputJson.get("description").asText());
-                output.setType(outputJson.get("type").asText());
+                output.setName(outputJson.get("name").getAsString());
+                output.setDescription(outputJson.get(DESCRIPTION).getAsString());
+                output.setType(outputJson.get("type").getAsString());
 
                 tc.getOutputs().add(output);
             }
@@ -251,8 +297,148 @@ public class VTPScenarioResource extends VTPResource{
             @ApiParam("Test scenario name") @PathParam("scenario") String scenario,
             @ApiParam(value = "Test case name") @PathParam("testSuiteName") String testSuiteName,
             @ApiParam(value = "Test case name") @PathParam("testCaseName") String testCaseName)
-                    throws IOException, VTPException {
+            throws VTPException {
 
         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.forceMkdir(scenarioDir);
+                FileUtils.copyInputStreamToFile(entity.getInputStream(), yamlFile);
+            } 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 (!source.isFile()) {
+                            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 =  FileUtil.searchFiles(scenarioDir, CommonConstant.YAML_SUFFIX);
+        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();
+    }
+}
\ No newline at end of file