58fe7df6d3309bc81dbb8e10e8d36a951c145941
[cli.git] / framework / src / main / java / org / onap / cli / fw / utils / OnapCommandUtils.java
1 /*
2  * Copyright 2017 Huawei Technologies Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.cli.fw.utils;
18
19 import static org.onap.cli.fw.conf.OnapCommandConstants.BOOLEAN_TRUE;
20 import static org.onap.cli.fw.conf.OnapCommandConstants.BOOLEAN_VALUE;
21 import static org.onap.cli.fw.conf.OnapCommandConstants.IS_INCLUDE;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Set;
32 import java.util.UUID;
33
34 import org.apache.commons.codec.binary.Base64;
35 import org.apache.commons.codec.digest.DigestUtils;
36 import org.apache.commons.io.FileUtils;
37 import org.onap.cli.fw.cmd.OnapCommand;
38 import org.onap.cli.fw.conf.OnapCommandConfig;
39 import org.onap.cli.fw.conf.OnapCommandConstants;
40 import org.onap.cli.fw.error.OnapCommandException;
41 import org.onap.cli.fw.error.OnapCommandInvalidParameterValue;
42 import org.onap.cli.fw.error.OnapCommandParameterNotFound;
43 import org.onap.cli.fw.error.OnapCommandResultEmpty;
44 import org.onap.cli.fw.input.OnapCommandParameter;
45 import org.onap.cli.fw.input.OnapCommandParameterType;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 import com.google.gson.Gson;
50 import com.google.gson.GsonBuilder;
51 import com.jayway.jsonpath.JsonPath;
52
53
54 /**
55  * Provides helper method to parse Yaml files and produce required objects.
56  *
57  */
58 public class OnapCommandUtils {
59
60     static Logger log = LoggerFactory.getLogger(OnapCommandUtils.class);
61     private static Gson gson = new GsonBuilder().serializeNulls().create();
62
63     /**
64      * Private constructor.
65      */
66     private OnapCommandUtils() {
67
68     }
69
70     public static void throwOrCollect(OnapCommandException ex, List<String> list, boolean shouldCollectException)
71             throws OnapCommandException {
72         if (shouldCollectException) {
73             list.add(ex.getMessage());
74         } else {
75             throw ex;
76         }
77     }
78
79     public static void validateTags(List<String> schemaErrors, Map<String, ?> yamlMap, List<String> totalParams,
80             List<String> mandatoryParams, String section) {
81         // mrkanag capture invalid entries as well
82         for (String param : totalParams) {
83             boolean isMandatory = mandatoryParams.contains(param);
84             boolean isYamlContains = yamlMap.containsKey(param);
85             boolean isInclude = yamlMap.containsKey(IS_INCLUDE) && yamlMap.get(IS_INCLUDE).toString().equals(BOOLEAN_TRUE);
86             if (isMandatory) {
87                 if (!isYamlContains && isInclude) {
88                     schemaErrors.add("Mandatory attribute '" + param + "' is missing under '" + section + "'");
89                 } else {
90                     String value = String.valueOf(yamlMap.get(param));
91                     if (value == null || value.isEmpty()) {
92                         schemaErrors.add("Mandatory attribute '" + param + "' under '" + section
93                                 + "' shouldn't be null or empty");
94                     }
95                 }
96             }
97         }
98     }
99
100     /**
101      * Validate Boolean.
102      *
103      * @param toValidate
104      *            string
105      * @return boolean
106      */
107     public static boolean validateBoolean(String toValidate) {
108         return OnapCommandConfig.getCommaSeparatedList(BOOLEAN_VALUE).contains(toValidate.toLowerCase());
109     }
110
111     public static String emptySection(String section) {
112         return "The section '" + section + ":' cann't be null or empty";
113     }
114
115     public static String invalidBooleanValueMessage(String section, String attribute, String value) {
116         return "The value '" + value + "' of '" + attribute + "' present under '" + section + "' should be boolean";
117     }
118
119     public static void parseParameters(String line, Set<String> paramNames) {
120
121         int currentIdx = 0;
122         while (currentIdx < line.length()) {
123             int idxS = line.indexOf("${", currentIdx);
124             if (idxS == -1) {
125                 break;
126             }
127             int idxE = line.indexOf('}', idxS);
128             String paramName = line.substring(idxS + 2, idxE);
129             paramNames.add(paramName.trim());
130
131             currentIdx = idxE + 1;
132         }
133
134     }
135
136     /**
137      * Create Dict from list of Parameters.
138      *
139      * @param inputs
140      *            list of parameters
141      * @return map
142      */
143     public static Map<String, OnapCommandParameter> getInputMap(Set<OnapCommandParameter> inputs) {
144         Map<String, OnapCommandParameter> map = new HashMap<>();
145         for (OnapCommandParameter param : inputs) {
146             map.put(param.getName(), param);
147         }
148         return map;
149     }
150
151     /**
152      * sort the set.
153      *
154      * @param col
155      *            set
156      * @return list
157      */
158     public static List<String> sort(Set<String> col) {
159         List<String> results = new ArrayList<>();
160         results.addAll(col);
161         Collections.sort(results);
162         return results;
163     }
164
165     /**
166      * Flatten the json list.
167      *
168      * @param jsons
169      *            list json strings
170      * @return list
171      */
172     public static List<String> jsonFlatten(List<String> jsons) {
173         List<String> results = new ArrayList<>();
174         for (String json : jsons) {
175             try {
176                 results.add(JsonPath.parse(json).jsonString());
177             } catch (Exception e) { // NOSONAR
178                 results.add(json);
179             }
180         }
181
182         return results;
183     }
184
185     /**
186      * There are unique values like uuid is supported, so when input, output (default) values has
187      * these special entries, then it will get replaced with it's value
188      *
189      * @param lineSpl
190      * @return
191      */
192     public static String replaceLineForSpecialValues(String lineSpl) {
193         return replaceLineForSpecialValues(lineSpl, new HashMap<String, String>());
194     }
195
196     /**
197      *
198      * @param lineSpl
199      * @param values Value for the given entry already known by the caller.
200      * @return
201      */
202     public static String replaceLineFromResults(String line, Map <String, String> values) {
203         StringBuilder resultLine = new StringBuilder();
204
205         if (!line.contains("$r{")) {
206             return line;
207         }
208
209         int currentIdx = 0;
210         while (currentIdx < line.length()) {
211             int idxS = line.indexOf("$r{", currentIdx);
212             if (idxS == -1) {
213                 resultLine.append(line.substring(currentIdx));
214                 break;
215             }
216             int idxE = line.indexOf('}', idxS);
217             String attr = line.substring(idxS + 3, idxE);
218             attr = attr.trim();
219
220             String value = "";
221
222             if (values.get(attr) != null) {
223                 value = values.get(attr);
224             } else {
225                 value = attr;
226             }
227
228             resultLine.append(line.substring(currentIdx, idxS) + value);
229             currentIdx = idxE + 1;
230         }
231
232         return resultLine.toString();
233     }
234
235     public static String replaceLineForSpecialValues(String lineSpl, Map <String, String> values) {
236         StringBuilder resultSpl = new StringBuilder();
237
238         if (!lineSpl.contains("$s{")) {
239             return lineSpl;
240         }
241
242         int currentIdx = 0;
243         while (currentIdx < lineSpl.length()) {
244             int idxS = lineSpl.indexOf("$s{", currentIdx);
245             if (idxS == -1) {
246                 resultSpl.append(lineSpl.substring(currentIdx));
247                 break;
248             }
249             int idxE = lineSpl.indexOf('}', idxS);
250             String splEntry = lineSpl.substring(idxS + 3, idxE);
251             splEntry = splEntry.trim();
252
253             String value = "";
254
255             if (OnapCommandConstants.SPL_ENTRY_UUID.equals(splEntry)) {
256                     value = UUID.randomUUID().toString();
257             }
258                 else{
259                     if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_ENV)) {
260                         //start to read after env:ENV_VAR_NAME
261                         String envVarName = splEntry.substring(4);
262                         value = System.getenv(envVarName); //NOSONAR
263                         if (value == null) {
264                             //when env is not defined, assign the same env:ENV_VAR_NAME
265                             //so that it will given hit to user that ENV_VAR_NAME to be
266                             //defined.
267                             value = splEntry;
268                         }
269                     } else if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_FILE)) {
270                         //start to read after file:filepath
271                         String fileName = splEntry.substring(5);
272                         try {
273                             value = FileUtils.readFileToString(new File(fileName));
274                         } catch (IOException e) {
275                             //when file is not found, assign the same file:FILE_PATH
276                             //so that it will given hit to user that FILE_PATH to be
277                             //exist.
278                             value = "";
279                         }
280                     } else if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_MD5)) {
281                             //start to read after md5:entryname
282                             String entryName = splEntry.substring(4);
283                             String content = values.get(entryName);
284                             if (content != null)
285                                 value = OnapCommandUtils.md5(content);
286                             else
287                                 value = splEntry;
288                     } else {
289                         if (values.get(splEntry) != null) {
290                             value = values.get(splEntry);
291                         } else {
292                             value = splEntry;
293                         }
294                     }
295             }
296
297             resultSpl.append(lineSpl.substring(currentIdx, idxS) + value);
298             currentIdx = idxE + 1;
299         }
300
301         return resultSpl.toString();
302     }
303
304     public static String replaceLineFromInputParameters(String line, Map<String, OnapCommandParameter> params)
305             throws OnapCommandException {
306         StringBuilder result = new StringBuilder();
307
308         if (!line.contains("${")) {
309             return line;
310         }
311
312         int currentIdx = 0;
313         while (currentIdx < line.length()) {
314             int idxS = line.indexOf("${", currentIdx);
315             if (idxS == -1) {
316                 result.append(line.substring(currentIdx));
317                 break;
318             }
319             int idxE = line.indexOf('}', idxS);
320             String paramName = line.substring(idxS + 2, idxE);
321             paramName = paramName.trim();
322             if (!params.containsKey(paramName)) {
323                 throw new OnapCommandParameterNotFound(paramName);
324             }
325
326             OnapCommandParameter param = params.get(paramName);
327             if (OnapCommandParameterType.ARRAY.equals(param.getParameterType())
328                     || OnapCommandParameterType.JSON.equals(param.getParameterType())
329                     || OnapCommandParameterType.YAML.equals(param.getParameterType())) {
330                 // ignore the front and back double quotes in json body
331                 String value = params.get(paramName).getValue().toString();
332                 if (idxS > 0)
333                     result.append(line.substring(currentIdx, idxS - 1) + value);
334                 else
335                     result.append(value);
336                 currentIdx = idxE + 2;
337             } else if (OnapCommandParameterType.MAP.equals(param.getParameterType())) {
338                 try {
339                     String value = gson.toJson(params.get(paramName).getValue());
340                     if ((idxS == 0) && (currentIdx == 0)) {
341                         result.replace(0, result.length(), value);
342                     } else {
343                         result.append(line.substring(currentIdx, idxS - 1) + value);
344                     }
345                 } catch (Exception e) {  // NOSONAR
346                     //never occur as map is coverted to json string here
347                 }
348
349                 currentIdx = idxE + 2;
350             }else {
351                 result.append(line.substring(currentIdx, idxS) + params.get(paramName).getValue().toString());
352                 currentIdx = idxE + 1;
353             }
354         }
355
356         return result.toString();
357     }
358
359     /**
360      * Populate result from input parameters.
361      *
362      * @param resultMap
363      *            map
364      * @param params
365      *            Map<String, OnapCommandParameter>
366      * @return map
367      * @throws OnapCommandException
368      */
369     public static Map<String, ArrayList<String>> populateOutputsFromInputParameters(
370             Map<String, ArrayList<String>> resultMap,
371             Map<String, OnapCommandParameter> params)
372             throws OnapCommandException {
373         Map<String, ArrayList<String>> resultsProcessed = new HashMap<>();
374
375         for (Entry<String, ArrayList<String>> entry : resultMap.entrySet()) {
376             String key = entry.getKey();
377             resultsProcessed.put(key, new ArrayList<>());
378             for (String value: entry.getValue()) {
379                 try {
380                     value = replaceLineFromInputParameters(value, params);
381                 } catch(OnapCommandResultEmpty e) {  // NOSONAR
382                     // pass
383                 }
384                 resultsProcessed.get(key).add(value);
385             }
386         }
387
388         return resultsProcessed;
389     }
390
391     /**
392      * Copy the parameters across the commands, mainly used for catalog, login and logout commands
393      *
394      * @throws OnapCommandInvalidParameterValue
395      */
396     public static void copyParamsFrom(OnapCommand from, OnapCommand to, Map<String, String> paramOverride) throws OnapCommandInvalidParameterValue {
397         for (OnapCommandParameter param: to.getParameters()) {
398
399             OnapCommandParameter fromParam = from.getParametersMap().get(param.getName());
400
401             if (fromParam != null) {
402                 param.setValue(fromParam.getValue());
403                 param.setDefaultValue(fromParam.getDefaultValue());
404             }
405
406             if (paramOverride.containsKey(param.getName())) {
407                  param.setValue(paramOverride.get(param.getName()));
408             }
409         }
410     }
411
412     public static void copyParamsFrom(OnapCommand from, OnapCommand to) throws OnapCommandInvalidParameterValue {
413         copyParamsFrom(from, to, new HashMap<String, String>());
414     }
415
416     /**
417      * Copy param schema from source command to destination command, useful in adding login command params into command
418      * @param from
419      * @param to
420      * @throws OnapCommandException
421      */
422     public static void copyParamSchemasFrom(OnapCommand from, OnapCommand to) {
423         for (OnapCommandParameter param: from.getParameters()) {
424             if (!to.getParametersMap().containsKey(param.getName())) {
425                 to.getParameters().add(param);
426             }
427         }
428     }
429
430     public static String md5(String content) {
431         String md5 = DigestUtils.md5Hex(content); //NOSONAR
432
433         byte[] encodeBase64 = Base64.encodeBase64(md5.getBytes());
434         return new String(encodeBase64);
435     }
436 }
437
438
439