HTTP: Add multipart support with multiple files 28/79328/1
authorKanagaraj Manickam k00365106 <kanagaraj.manickam@huawei.com>
Thu, 28 Feb 2019 06:42:46 +0000 (12:12 +0530)
committerKanagaraj Manickam k00365106 <kanagaraj.manickam@huawei.com>
Thu, 28 Feb 2019 06:42:46 +0000 (12:12 +0530)
Issue-ID: CLI-129

Change-Id: I65a4d48bb7ce2922043739b83fdc13de7d2f584d
Signed-off-by: Kanagaraj Manickam k00365106 <kanagaraj.manickam@huawei.com>
profiles/http/src/main/java/org/onap/cli/fw/http/conf/OnapCommandHttpConstants.java
profiles/http/src/main/java/org/onap/cli/fw/http/connect/HttpInput.java
profiles/http/src/main/java/org/onap/cli/fw/http/connect/OnapHttpConnection.java
profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java
profiles/http/src/main/java/org/onap/cli/fw/http/utils/OnapCommandHttpUtils.java
profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml
profiles/http/src/test/java/org/onap/cli/fw/http/schema/ValidateSchemaTest.java [deleted file]
profiles/http/src/test/resources/open-cli-schema/sample-multipart-schema-http.yaml [new file with mode: 0644]

index e6d5e03..2d14bb8 100644 (file)
@@ -66,6 +66,7 @@ public class OnapCommandHttpConstants {
     public static final String RESULT_MAP = "result_map";
     public static final String SAMPLE_RESPONSE = "sample_response";
     public static final String MULTIPART_ENTITY_NAME = "multipart_entity_name";
+    public static final String MULTIPART = "multipart";
     public static final String HTTP_SECTION_EMPTY = "Http Section cann't be null or empty";
     public static final String HTTP_BODY_SECTION_EMPTY = "http body section under 'request:' cann't be null or empty";
     public static final String HTTP_BODY_FAILED_PARSING = "The http body json is failed to parse";
index f592279..9e0fc5f 100644 (file)
@@ -16,7 +16,9 @@
 
 package org.onap.cli.fw.http.connect;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -40,6 +42,32 @@ public class HttpInput {
 
     private Map<String, String> context = new HashMap<>();
 
+    private List<Part> multiparts = new ArrayList<>();
+
+    public static class Part {
+        private String name;
+        private String content;
+        private boolean binary;
+        public String getName() {
+            return name;
+        }
+        public void setName(String name) {
+            this.name = name;
+        }
+        public String getContent() {
+            return content;
+        }
+        public void setContent(String content) {
+            this.content = content;
+        }
+        public boolean isBinary() {
+            return binary;
+        }
+        public void setBinary(boolean binary) {
+            this.binary = binary;
+        }
+    }
+
     private boolean binaryData;
 
     public String getUri() {
@@ -142,4 +170,12 @@ public class HttpInput {
                 + this.getReqHeaders().toString() + "\nRequest Cookies: " + this.getReqCookies().toString()
                 + "\nbinaryData=" + this.binaryData + "\nContext=" + this.context;
     }
+
+    public List<Part> getMultiparts() {
+        return multiparts;
+    }
+
+    public void setMultiparts(List<Part> multiparts) {
+        this.multiparts = multiparts;
+    }
 }
index b86ef26..186383d 100644 (file)
@@ -56,6 +56,7 @@ import org.apache.http.conn.ssl.X509HostnameVerifier;
 import org.apache.http.cookie.Cookie;
 import org.apache.http.entity.ContentType;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.MultipartEntity;
 import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.impl.client.BasicCookieStore;
 import org.apache.http.impl.client.HttpClients;
@@ -292,7 +293,7 @@ public class OnapHttpConnection {
         HttpRequestBase requestBase = null;
         if ("post".equals(input.getMethod())) {
             HttpPost httpPost = new HttpPost();
-            if (input.isBinaryData()) {
+            if (input.isBinaryData() || input.getMultiparts().size() > 0) {
                 httpPost.setEntity(getMultipartEntity(input));
             } else {
                 httpPost.setEntity(this.getStringEntity(input));
@@ -365,13 +366,31 @@ public class OnapHttpConnection {
     }
 
     private HttpEntity getMultipartEntity(HttpInput input) {
-        String fileTag = input.getMultipartEntityName() != "" ? input.getMultipartEntityName() : "file";
-        File file = new File(input.getBody().trim());
-        HttpEntity multipartEntity = MultipartEntityBuilder
-                .create()
-                .addBinaryBody(fileTag, file, ContentType.create("application/octet-stream"), file.getName())
-                .build();
-        return multipartEntity;
+        if (input.getMultiparts().size() > 0) {
+            MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
+            for (HttpInput.Part part: input.getMultiparts()) {
+                if (part.isBinary()) {
+                     File file = new File(part.getContent());
+                     entityBuilder.addBinaryBody(
+                            part.getName(),
+                            file,
+                            ContentType.APPLICATION_OCTET_STREAM,
+                            file.getName());
+                } else {
+                    entityBuilder.addTextBody(part.getName(), part.getContent(), ContentType.APPLICATION_JSON);
+                }
+            }
+
+            return entityBuilder.build();
+        } else {
+            String fileTag = input.getMultipartEntityName() != "" ? input.getMultipartEntityName() : "file";
+            File file = new File(input.getBody().trim());
+            HttpEntity multipartEntity = MultipartEntityBuilder
+                    .create()
+                    .addBinaryBody(fileTag, file, ContentType.create("application/octet-stream"), file.getName())
+                    .build();
+            return multipartEntity;
+        }
     }
 
     @NotThreadSafe
index 5429b1a..aaca5c8 100644 (file)
@@ -36,6 +36,7 @@ import org.onap.cli.fw.error.OnapCommandNotFound;
 import org.onap.cli.fw.http.auth.OnapCommandHttpService;
 import org.onap.cli.fw.http.cmd.OnapHttpCommand;
 import org.onap.cli.fw.http.conf.OnapCommandHttpConstants;
+import org.onap.cli.fw.http.connect.HttpInput;
 import org.onap.cli.fw.http.error.OnapCommandHttpInvalidResultMap;
 import org.onap.cli.fw.registrar.OnapCommandRegistrar;
 import org.onap.cli.fw.schema.OnapCommandSchemaLoader;
@@ -127,7 +128,27 @@ public class OnapCommandSchemaHttpLoader {
                                             break;
                                         case OnapCommandHttpConstants.BODY:
                                             Object body = map.get(key2);
-                                            cmd.getInput().setBody(body.toString());
+
+                                            if (body instanceof String) {
+                                                cmd.getInput().setBody(body.toString());
+                                            } else {
+                                                //check for multipart
+                                                Map <String, Object> multipartBody = (Map<String, Object>) body;
+                                                List <Object> multiparts = (List<Object>) multipartBody.get(OnapCommandHttpConstants.MULTIPART);
+
+                                                for (Object part: multiparts ) {
+                                                    HttpInput.Part partO = new HttpInput.Part();
+                                                    Map<String, String> partMap = (Map<String, String>) part;
+                                                    partO.setName((String) partMap.get("name"));
+                                                    partO.setContent((String)partMap.get("content"));
+                                                    if (partMap.get("type") != null && ((String)partMap.get("type")).equalsIgnoreCase("file")) {
+                                                        partO.setBinary(true);
+                                                    }
+
+                                                    cmd.getInput().getMultiparts().add(partO);
+                                                }
+                                            }
+
                                             break;
                                         case OnapCommandHttpConstants.HEADERS:
                                             Map<String, String> head = (Map<String, String>) map.get(key2);
index a0c96ca..3afb196 100644 (file)
@@ -75,6 +75,14 @@ public class OnapCommandHttpUtils {
         }
         inp.setMultipartEntityName(input.getMultipartEntityName());
         inp.setBody(OnapCommandUtils.replaceLineFromInputParameters(input.getBody(), params));
+
+        if (input.getMultiparts().size() > 0) {
+            for (HttpInput.Part part: input.getMultiparts()) {
+                part.setContent(OnapCommandUtils.replaceLineFromInputParameters(part.getContent(), params));
+            }
+        }
+        inp.setMultiparts(input.getMultiparts());
+
         inp.setUri(OnapCommandUtils.replaceLineFromInputParameters(input.getUri(), params));
         inp.setMethod(input.getMethod().toLowerCase());
         for (String h : input.getReqHeaders().keySet()) {
index 585aebb..80a7e56 100644 (file)
@@ -22,7 +22,7 @@ parameters:
     long_option: host-username
     default_value: $s{env:OPEN_CLI_HOST_USERNAME}
     is_optional: false
-    is_default_param: true
+    is_default_param: false
   - name: host-password
     type: string
     description: Host user password
@@ -31,7 +31,7 @@ parameters:
     default_value: $s{env:OPEN_CLI_HOST_PASSWORD}
     is_secured: true
     is_optional: false
-    is_default_param: true
+    is_default_param: false
   - name: host-url
     type: url
     description: host url in http(s)
@@ -39,7 +39,7 @@ parameters:
     long_option: host-url
     is_optional: false
     default_value: $s{env:OPEN_CLI_HOST_URL}
-    is_default_param: true
+    is_default_param: false
   - name: no-auth
     type: bool
     description: Whether to authenticate user or not
@@ -62,4 +62,5 @@ parameters:
        To enable the verification of samples in real time, set DISABLE_MOCKING=true in the context parameter.
     default_value: false
     is_include: true
-    is_optional: true
\ No newline at end of file
+    is_optional: true
+    is_default_param: true
\ No newline at end of file
diff --git a/profiles/http/src/test/java/org/onap/cli/fw/http/schema/ValidateSchemaTest.java b/profiles/http/src/test/java/org/onap/cli/fw/http/schema/ValidateSchemaTest.java
deleted file mode 100644 (file)
index 0bf073e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 Huawei Technologies Co., Ltd.
- *
- * 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
- *
- *     http://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.
- */
-
-package org.onap.cli.fw.http.schema;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.onap.cli.fw.cmd.OnapCommand;
-import org.onap.cli.fw.error.OnapCommandException;
-import org.onap.cli.fw.registrar.OnapCommandRegistrar;
-import org.onap.cli.fw.schema.OnapCommandSchemaLoader;
-import org.onap.cli.main.OnapCli;
-
-public class ValidateSchemaTest {
-    @Test
-    public void validateTest() throws OnapCommandException {
-
-        OnapCommand cmd1 = new OnapCommand() {
-            @Override
-            protected void run() throws OnapCommandException {}
-        };
-        List<String> errorList1 = OnapCommandSchemaLoader.loadSchema(cmd1, "schema-validate-http.yaml", true, true);
-        assertTrue(errorList1.size() > 0);
-    }
-
-    @Test
-    public void testVerify() throws OnapCommandException {
-        OnapCommandRegistrar.getRegistrar().setEnabledProductVersion("open-cli");
-        OnapCli onapCli = new OnapCli(new String[]{"sample-test-verify", "--verify"});
-        onapCli.handle();
-
-        //mrkanag though it pass, when ran alone, It fails during mvn test phase, check it
-    }
-}
diff --git a/profiles/http/src/test/resources/open-cli-schema/sample-multipart-schema-http.yaml b/profiles/http/src/test/resources/open-cli-schema/sample-multipart-schema-http.yaml
new file mode 100644 (file)
index 0000000..baf49ae
--- /dev/null
@@ -0,0 +1,68 @@
+# Copyright 2019 Huawei Technologies Co., Ltd.
+#
+# 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
+#
+#     http://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.
+
+open_cli_schema_version: 1.0
+name: sample-test-multipart
+description: Multipart sample test command
+
+info:
+  product: open-cli
+  service: test
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+parameters:
+  - name: file1
+    type: binary
+    description: file1
+    short_option: b
+    long_option: file1
+    is_optional: false
+  - name: file2
+    type: binary
+    description: file 2
+    short_option: x
+    long_option: file2
+    is_optional: false
+  - name: entity1
+    type: string
+    description: entity1
+    long_option: entity1
+    short_option: c
+    is_optional: false
+  - name: entity2
+    type: string
+    description: entity2
+    long_option: entity2
+    short_option: y
+    is_optional: false
+http:
+  request:
+    uri: /
+    method: POST
+    body:
+      multipart:
+        - name: file
+          content: ${file1}
+          type: file
+        - name: file
+          content: ${file2}
+          type: file
+        - name: executions
+          content: '{"id":"${entity1}"}'
+        - name: entity2
+          content: '{"id":"${entity2}"}'
+  success_codes:
+    - 201
+    - 200