From c9f4e87e86c166ca5ba641dbb99d8a6a5f759e3a Mon Sep 17 00:00:00 2001 From: Kanagaraj Manickam k00365106 Date: Thu, 28 Feb 2019 12:12:46 +0530 Subject: HTTP: Add multipart support with multiple files Issue-ID: CLI-129 Change-Id: I65a4d48bb7ce2922043739b83fdc13de7d2f584d Signed-off-by: Kanagaraj Manickam k00365106 --- .../cli/fw/http/conf/OnapCommandHttpConstants.java | 1 + .../org/onap/cli/fw/http/connect/HttpInput.java | 36 ++++++++++++ .../cli/fw/http/connect/OnapHttpConnection.java | 35 ++++++++--- .../http/schema/OnapCommandSchemaHttpLoader.java | 23 +++++++- .../cli/fw/http/utils/OnapCommandHttpUtils.java | 8 +++ .../http/default_input_parameters_http.yaml | 9 +-- .../cli/fw/http/schema/ValidateSchemaTest.java | 50 ---------------- .../sample-multipart-schema-http.yaml | 68 ++++++++++++++++++++++ 8 files changed, 167 insertions(+), 63 deletions(-) delete mode 100644 profiles/http/src/test/java/org/onap/cli/fw/http/schema/ValidateSchemaTest.java create mode 100644 profiles/http/src/test/resources/open-cli-schema/sample-multipart-schema-http.yaml (limited to 'profiles/http') diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/conf/OnapCommandHttpConstants.java b/profiles/http/src/main/java/org/onap/cli/fw/http/conf/OnapCommandHttpConstants.java index e6d5e031..2d14bb88 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/conf/OnapCommandHttpConstants.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/conf/OnapCommandHttpConstants.java @@ -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"; diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/connect/HttpInput.java b/profiles/http/src/main/java/org/onap/cli/fw/http/connect/HttpInput.java index f5922796..9e0fc5f6 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/connect/HttpInput.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/connect/HttpInput.java @@ -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 context = new HashMap<>(); + private List 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 getMultiparts() { + return multiparts; + } + + public void setMultiparts(List multiparts) { + this.multiparts = multiparts; + } } diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/connect/OnapHttpConnection.java b/profiles/http/src/main/java/org/onap/cli/fw/http/connect/OnapHttpConnection.java index b86ef26b..186383d9 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/connect/OnapHttpConnection.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/connect/OnapHttpConnection.java @@ -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 diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java b/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java index 5429b1af..aaca5c87 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java @@ -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 multipartBody = (Map) body; + List multiparts = (List) multipartBody.get(OnapCommandHttpConstants.MULTIPART); + + for (Object part: multiparts ) { + HttpInput.Part partO = new HttpInput.Part(); + Map partMap = (Map) 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 head = (Map) map.get(key2); diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/utils/OnapCommandHttpUtils.java b/profiles/http/src/main/java/org/onap/cli/fw/http/utils/OnapCommandHttpUtils.java index a0c96cad..3afb1961 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/utils/OnapCommandHttpUtils.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/utils/OnapCommandHttpUtils.java @@ -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()) { diff --git a/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml b/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml index 585aebbe..80a7e562 100644 --- a/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml +++ b/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml @@ -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 index 0bf073e7..00000000 --- a/profiles/http/src/test/java/org/onap/cli/fw/http/schema/ValidateSchemaTest.java +++ /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 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 index 00000000..baf49aea --- /dev/null +++ b/profiles/http/src/test/resources/open-cli-schema/sample-multipart-schema-http.yaml @@ -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 -- cgit 1.2.3-korg