AT&T 1712 and 1802 release code
[so.git] / bpmn / MSOCoreBPMN / src / test / java / org / openecomp / mso / bpmn / core / JsonUtilsTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 /*- 
22  * ============LICENSE_START======================================================= 
23  * ONAP - SO 
24  * ================================================================================ 
25  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. 
26  * ================================================================================ 
27  * Licensed under the Apache License, Version 2.0 (the "License"); 
28  * you may not use this file except in compliance with the License. 
29  * You may obtain a copy of the License at 
30  * 
31  *      http://www.apache.org/licenses/LICENSE-2.0 
32  * 
33  * Unless required by applicable law or agreed to in writing, software 
34  * distributed under the License is distributed on an "AS IS" BASIS, 
35  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
36  * See the License for the specific language governing permissions and 
37  * limitations under the License. 
38  * ============LICENSE_END========================================================= 
39  */ 
40
41 package org.openecomp.mso.bpmn.core;
42
43
44
45 import static org.assertj.core.api.Assertions.assertThat;
46
47 import java.io.File;
48 import java.io.IOException;
49 import java.nio.charset.StandardCharsets;
50 import java.nio.file.Files;
51
52 import org.json.JSONObject;
53 import org.junit.Assert;
54 import org.junit.BeforeClass;
55 import org.junit.Test;
56 import org.openecomp.mso.apihandler.common.ValidationException;
57 import org.openecomp.mso.bpmn.core.json.JsonUtils;
58 import org.openecomp.mso.bpmn.core.xml.XmlTool;
59 import org.xmlunit.builder.DiffBuilder;
60 import org.xmlunit.diff.DefaultNodeMatcher;
61 import org.xmlunit.diff.Diff;
62 import org.xmlunit.diff.ElementSelectors;
63
64 /**
65  * @version 1.0
66  */
67 public class JsonUtilsTest {
68
69     private static final String EOL = "\n";
70     private static final String XML_REQ =
71                     "<vnf-request xmlns=\"http://org.openecomp/mso/infra/vnf-request/v1\">" + EOL +
72                     "  <request-info>" + EOL +
73                     "    <request-id>DEV-VF-0021</request-id>" + EOL +
74                     "    <action>CREATE_VF_MODULE</action>" + EOL +
75                     "    <source>PORTAL</source>" + EOL +
76                     "  </request-info>" + EOL +
77                     "  <vnf-inputs>" + EOL +
78                     "    <vnf-id>a27ce5a9-29c4-4c22-a017-6615ac73c721</vnf-id>" + EOL +
79                     "    <vnf-name>STMTN5MMSC21</vnf-name>" + EOL +
80                     "    <vnf-type>asc_heat-int</vnf-type>" + EOL +
81                     "    <vf-module-name>STMTN5MMSC21-MMSC::module-0-0</vf-module-name>" + EOL +
82                     "    <vf-module-model-name>STMTN5MMSC21-MMSC::model-1-0</vf-module-model-name>" + EOL +
83                     "    <is-base-module>true</is-base-module>" + EOL +
84                     "    <persona-model-id>00000000-0000-0000-0000-000000000000</persona-model-id>" + EOL +
85                     "    <persona-model-version>1.0</persona-model-version>" + EOL +
86                     "    <vnf-persona-model-id>999999999-0000-0000-0000-000000000000</vnf-persona-model-id>" + EOL +
87                     "    <vnf-persona-model-version>1.5</vnf-persona-model-version>" + EOL +
88                     "    <service-id>00000000-0000-0000-0000-000000000000</service-id>" + EOL +
89                     "    <service-type>SDN-ETHERNET-INTERNET</service-type>" + EOL +
90                     "    <tenant-id>fba1bd1e195a404cacb9ce17a9b2b421</tenant-id>" + EOL +
91                     "    <orchestration-status>pending-delete</orchestration-status>" + EOL +
92                     "    <aic-cloud-region>RDM2WAGPLCP</aic-cloud-region>" + EOL +
93                     "    <asdc-service-model-version>1</asdc-service-model-version>" + EOL +
94                     "  </vnf-inputs>" + EOL +
95                     "  <vnf-params xmlns:tns=\"http://org.openecomp/mso/infra/vnf-request/v1\">" + EOL +
96                     "    <param name=\"network\">network1111</param>" + EOL +
97                     "    <param name=\"server\">server1111</param>" + EOL +
98                     "  </vnf-params> " + EOL +
99                     "</vnf-request>" + EOL;
100     
101     private static final String XML_REQ_NO_ATTRS =
102                     "<vnf-request xmlns=\"http://org.openecomp/mso/infra/vnf-request/v1\">" + EOL +
103                     "  <request-info>" + EOL +
104                     "    <action>DELETE_VF_MODULE</action>" + EOL +
105                     "    <source>PORTAL</source>" + EOL +
106                     "  </request-info>" + EOL +
107                     "  <vnf-inputs>" + EOL +
108                     "    <vnf-id>a27ce5a9-29c4-4c22-a017-6615ac73c721</vnf-id>" + EOL +
109                     "    <vnf-name>STMTN5MMSC21</vnf-name>" + EOL +
110                     "    <vnf-type>asc_heat-int</vnf-type>" + EOL +
111                     "    <vf-module-id>973ed047-d251-4fb9-bf1a-65b8949e0a73</vf-module-id>" + EOL +
112                     "    <vf-module-name>STMTN5MMSC21-MMSC::module-0-0</vf-module-name>" + EOL +
113                     "    <service-id>00000000-0000-0000-0000-000000000000</service-id>" + EOL +
114                     "    <service-type>SDN-ETHERNET-INTERNET</service-type>" + EOL +
115                     "    <tenant-id>fba1bd1e195a404cacb9ce17a9b2b421</tenant-id>" + EOL +
116                     "    <orchestration-status>pending-delete</orchestration-status>" + EOL +
117                     "    <aic-cloud-region>RDM2WAGPLCP</aic-cloud-region>" + EOL +
118                     "  </vnf-inputs>" + EOL +
119                     "  <vnf-params xmlns:tns=\"http://org.openecomp/mso/infra/vnf-request/v1\"/>" + EOL +
120                     "</vnf-request>" + EOL;
121
122     private static final String XML_ARRAY_REQ =
123                     "<ucpeInfo>" + EOL +
124                     "       <outOfBandManagementModem>BROADBAND</outOfBandManagementModem>" + EOL +
125                 "   <internetTopology>IVLAN</internetTopology>" + EOL +
126                 "   <ucpeAliasHostName>SHELLUCPE31</ucpeAliasHostName>" + EOL +
127                 "   <wanList>" + EOL +
128                 "           <wanInfo>" + EOL +
129                 "                   <wanType>AVPN</wanType>" + EOL +
130                 "                   <interfaceType>1000BASE-T</interfaceType>" + EOL +
131                 "                   <transportProviderName>ATT</transportProviderName>" + EOL +
132                 "                   <circuitId>BT/SLIR/70911</circuitId>" + EOL +
133                 "                   <dualMode>Active</dualMode>" + EOL +
134                 "                   <wanPortNumber>WAN1</wanPortNumber>" + EOL +
135                 "                   <transportManagementOption>ATT</transportManagementOption>" + EOL +
136                 "                   <transportVendorTotalBandwidth>100</transportVendorTotalBandwidth>" + EOL +
137                 "                   <mediaType>ELECTRICAL</mediaType>" + EOL +
138                 "           </wanInfo>" + EOL +
139                 "           <wanInfo>" + EOL +
140                 "                   <wanType>AVPN</wanType>" + EOL +
141                 "                   <interfaceType>10/100/1000BASE-T</interfaceType>" + EOL +
142                 "                   <transportProviderName>ATT</transportProviderName>" + EOL +
143                 "                   <circuitId>AS/KRFN/34611</circuitId>" + EOL +
144                 "                   <dualMode>Active</dualMode>" + EOL +
145                 "                   <wanPortNumber>WAN2</wanPortNumber>" + EOL +
146                 "                   <transportManagementOption>ATT</transportManagementOption>" + EOL +
147                 "                   <transportVendorTotalBandwidth>10000</transportVendorTotalBandwidth>" + EOL +
148                 "                   <mediaType>MMF</mediaType>" + EOL +
149                 "           </wanInfo>" + EOL +
150                 "   </wanList>" + EOL +
151                 "   <ucpeActivationCode>ASD-987-M31</ucpeActivationCode>" + EOL +
152                 "   <ucpeHostName>USOSTCDALTX0101UJZZ31</ucpeHostName>" + EOL +
153                 "   <ucpePartNumber>FG-VM00*</ucpePartNumber>" + EOL +
154                     "</ucpeInfo>";
155
156     // JSON request w/ embedded XML will be read from a file
157     private static String jsonReq;
158     private static String jsonReqArray;
159     
160     @BeforeClass
161     public static void initialize() throws Exception {
162         jsonReq = readFileToString("src/test/resources/request.json");
163         jsonReqArray = readFileToString("src/test/resources/requestArray.json");
164                     }
165     
166     private static String readFileToString(String path) throws IOException {
167         File file = new File(path);
168         return new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
169     }
170
171     @Test
172     public void shouldConvertXmlToJsonAndBackToSameXml() throws Exception {
173             // Note: the current version of the JsonUtils.json2xml() method
174             // does not support converting the JSONObject representation
175             // of XML attributes (JSONArray) back to XML. So this test will
176             // only succeed if the original XML does not contain attributes
177             
178         // given
179         String xmlIn = XmlTool.removeNamespaces(XML_REQ_NO_ATTRS);
180         // when
181         String json = JsonUtils.xml2json(XML_REQ_NO_ATTRS);
182             String xmlOut = JsonUtils.json2xml(json);
183         // then
184         Diff diffXml = DiffBuilder.compare(xmlIn).withTest(xmlOut).ignoreWhitespace()
185                 .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)).checkForSimilar().build();
186
187         assertThat(diffXml.hasDifferences()).withFailMessage(diffXml.toString()).isFalse();
188     }
189
190     @Test
191     public void shouldReadValuesForAbsoluteJsonPaths() throws Exception {
192         // given
193         String json = JsonUtils.xml2json(XML_REQ);
194         // when, then
195         assertThat(JsonUtils.getJsonValue(json, "vnf-request.vnf-inputs.vnf-name")).isEqualTo("STMTN5MMSC21");
196         assertThat(JsonUtils.getJsonValue(json, "vnf-request.request-info.action")).isEqualTo("CREATE_VF_MODULE");
197         assertThat(JsonUtils.getJsonValue(json, "vnf-request.vnf-inputs.persona-model-version")).isEqualTo("1");
198         assertThat(JsonUtils.getJsonValue(json, "vnf-request.vnf-inputs.vnf-persona-model-version")).isEqualTo("1.5");
199         assertThat(JsonUtils.getJsonValue(json, "vnf-request.vnf-inputs.is-base-module")).isEqualTo("true");
200     }
201
202     @Test
203     public void shouldReturnValueForJsonKey() throws Exception {
204         // given
205         String json = JsonUtils.xml2json(XML_REQ);
206         // when, then
207         assertThat(JsonUtils.getJsonValueForKey(json, "source")).isEqualTo("PORTAL");
208     }
209
210     @Test
211     public void shouldReturnNullForNonexistentJsonNode() throws Exception {
212         // given
213         String json = JsonUtils.xml2json(XML_REQ);
214         // when, then
215         assertThat(JsonUtils.getJsonValueForKey(json, "nonexistent-node")).isNull();
216     }
217
218     @Test
219     public void shouldReturnNullForNonExistentParameter() throws Exception {
220         // given
221         String json = JsonUtils.xml2json(XML_REQ);
222         // when, then
223         assertThat(JsonUtils.getJsonValue(json, "vnf-request.vnf-inputs.bad")).isNull();
224     }
225
226     @Test
227     public void shouldGetJasonParametersFromArray() throws Exception {
228         // given
229         String json = JsonUtils.xml2json(XML_REQ);
230         // when, then
231         assertThat(JsonUtils.getJsonParamValue(json, "vnf-request.vnf-params.param", "name")).isEqualTo("network");
232         assertThat(JsonUtils.getJsonParamValue(json, "vnf-request.vnf-params.param", "content"))
233                 .isEqualTo("network1111");
234         assertThat(JsonUtils.getJsonParamValue(json, "vnf-request.vnf-params.param", "name", 1)).isEqualTo("server");
235         assertThat(JsonUtils.getJsonParamValue(json, "vnf-request.vnf-params.param", "content", 1))
236                 .isEqualTo("server1111");
237         assertThat(JsonUtils.getJsonParamValue(json, "vnf-request.vnf-params.param", "badParam"))
238                 .withFailMessage("Expected null for nonexistent param").isNull();
239         assertThat(JsonUtils.getJsonParamValue(json, "vnf-request.vnf-params.param", "name", 2))
240                 .withFailMessage("Expected null for index out of bound").isNull();
241     }
242             
243     @Test
244     public void shouldAddJsonValue() throws Exception {
245         // given
246         String json = JsonUtils.xml2json(XML_REQ);
247         String key = "vnf-request.request-info.comment";
248         String value = "Some comment";
249         // when
250         String jsonUpd = JsonUtils.addJsonValue(json, key, value);
251         // then
252         String extractedValue = JsonUtils.getJsonValue(jsonUpd, key);
253         assertThat(extractedValue).isEqualTo(value);
254     }
255
256     @Test
257     public void shouldIgnoreAddIfFieldAlreadyExists() throws Exception {
258         // given
259         String json = JsonUtils.xml2json(XML_REQ);
260         String key = "vnf-request.vnf-inputs.vnf-name";
261         String newValue = "STMTN5MMSC22";
262         String oldValue = JsonUtils.getJsonValue(json, key);
263         // when
264         String jsonUpd = JsonUtils.addJsonValue(json, key, newValue);
265         // then
266         String extractedValue = JsonUtils.getJsonValue(jsonUpd, key);
267         assertThat(extractedValue).isEqualTo(oldValue).isNotEqualTo(newValue);
268             }
269
270     @Test
271     public void shouldUpdateValueInJson() throws Exception {
272         // given
273         String json = JsonUtils.xml2json(XML_REQ);
274         String key = "vnf-request.vnf-inputs.vnf-name";
275         String newValue = "STMTN5MMSC22";
276         String oldValue = JsonUtils.getJsonValue(json, key);
277         // when
278         String jsonUpd = JsonUtils.updJsonValue(json, key, newValue);
279         // then
280         String extractedValue = JsonUtils.getJsonValue(jsonUpd, key);
281         assertThat(extractedValue).isNotEqualTo(oldValue).isEqualTo(newValue);
282     }
283
284     @Test
285     public void shouldDeleteValue() throws Exception {
286         // given
287         String json = JsonUtils.xml2json(XML_REQ);
288         String key = "vnf-request.vnf-inputs.vnf-name";
289         String oldValue = JsonUtils.getJsonValue(json, key);
290         // when
291         String jsonUpd = JsonUtils.delJsonValue(json, key);
292         // then
293         String extractedValue = JsonUtils.getJsonValue(jsonUpd, key);
294         assertThat(extractedValue).isNotEqualTo(oldValue).isNull();
295                         JSONObject jsonObj = new JSONObject(json);
296             Integer intValue = JsonUtils.getJsonIntValueForKey(jsonObj, "persona-model-version");
297             Assert.assertTrue(intValue == 1);
298             Boolean boolValue = JsonUtils.getJsonBooleanValueForKey(jsonObj, "is-base-module");
299             Assert.assertTrue(boolValue);
300     }
301
302     @Test
303     public void shouldReturnOriginalJsonWhenTryingToRemoveNonexistentField() throws Exception {
304         // given
305         String json = JsonUtils.xml2json(XML_REQ);
306         String key = "vnf-request.vnf-inputs.does-not-exist";
307         // when
308         String jsonUpd = JsonUtils.delJsonValue(json, key);
309         // then
310         assertThat(jsonUpd).isEqualTo(json);
311     }
312     
313     @Test
314     public void shouldConvertXmlToJsonAndBackToSameXmlExtractedFromTheRequest() throws Exception {
315         // given
316                     String value = JsonUtils.getJsonValue(jsonReq, "variables.bpmnRequest.value");
317                     String xmlReq = XmlTool.removeNamespaces(XmlTool.normalize(value));
318         // when
319                     String json = JsonUtils.xml2json(xmlReq);
320                     String xmlOut = JsonUtils.json2xml(json);
321         // then
322         Diff diffXml = DiffBuilder.compare(xmlReq).withTest(xmlOut).ignoreWhitespace()
323                 .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)).checkForSimilar().build();
324         assertThat(diffXml.hasDifferences()).withFailMessage(diffXml.toString()).isFalse();
325                     }
326                     
327     @Test
328     public void shouldConvertJsonContainingArrayToXml() throws Exception {
329         // when
330                     String jsonParm = JsonUtils.getJsonNodeValue(jsonReqArray, "requestDetails.requestParameters.ucpeInfo");
331                     String xmlOut = JsonUtils.json2xml(jsonParm);
332         // then
333         Diff diffXml = DiffBuilder.compare(XML_ARRAY_REQ).withTest(xmlOut).ignoreWhitespace()
334                 .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)).checkForSimilar().build();
335         assertThat(diffXml.hasDifferences()).withFailMessage(diffXml.toString()).isFalse();
336     }
337
338     @Test
339     // Tests the jsonSchemaValidation() method
340     public void testJsonSchemaValidation() {
341         try {
342             String myReqArray = jsonReqArray;
343                         String result = JsonUtils.jsonSchemaValidation(myReqArray, "src/test/resources/requestSchema.json");
344                         System.out.println("Schema Validation Result: " + result);
345                         Assert.assertTrue(result.contains("success"));
346                         // remove a required parameter from the JSON doc so that validation fails
347                         myReqArray = JsonUtils.delJsonValue(myReqArray, "requestDetails.requestParameters.ucpeInfo.ucpeHostName");
348                         result = JsonUtils.jsonSchemaValidation(myReqArray, "src/test/resources/requestSchema.json");
349                         System.out.println("Schema Validation Result: " + result);                      
350                         Assert.assertTrue(result.contains("failure"));
351                         Assert.assertTrue(result.contains("error: object has missing required properties ([\"ucpeHostName\"])"));
352                 } catch (ValidationException e) {
353                         e.printStackTrace();
354                 }
355     }
356 }