7148aa104e64fda4cc864581e3c75573d0c11604
[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         String resultLine = "";
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 += 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 += line.substring(currentIdx, idxS) + value;
229             currentIdx = idxE + 1;
230         }
231
232         return resultLine;
233     }
234
235     public static String replaceLineForSpecialValues(String lineSpl, Map <String, String> values) {
236         String resultSpl = "";
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 += 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             switch (splEntry) {
256                 case OnapCommandConstants.SPL_ENTRY_UUID:
257                     value = UUID.randomUUID().toString();
258                     break;
259
260                 default:
261
262                     if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_ENV)) {
263                         //start to read after env:ENV_VAR_NAME
264                         String envVarName = splEntry.substring(4);
265                         value = System.getenv(envVarName); //NOSONAR
266                         if (value == null) {
267                             //when env is not defined, assign the same env:ENV_VAR_NAME
268                             //so that it will given hit to user that ENV_VAR_NAME to be
269                             //defined.
270                             value = splEntry;
271                         }
272                     } else if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_FILE)) {
273                         //start to read after file:filepath
274                         String fileName = splEntry.substring(5);
275                         try {
276                             value = FileUtils.readFileToString(new File(fileName));
277                         } catch (IOException e) {
278                             //when file is not found, assign the same file:FILE_PATH
279                             //so that it will given hit to user that FILE_PATH to be
280                             //exist.
281                             value = "";
282                         }
283                     } else if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_MD5)) {
284                             //start to read after md5:entryname
285                             String entryName = splEntry.substring(4);
286                             String content = values.get(entryName);
287                             if (content != null)
288                                 value = OnapCommandUtils.md5(content);
289                             else
290                                 value = splEntry;
291                     } else {
292                         if (values.get(splEntry) != null) {
293                             value = values.get(splEntry);
294                         } else {
295                             value = splEntry;
296                         }
297                     }
298             }
299
300             resultSpl += lineSpl.substring(currentIdx, idxS) + value;
301             currentIdx = idxE + 1;
302         }
303
304         return resultSpl;
305     }
306
307     public static String replaceLineFromInputParameters(String line, Map<String, OnapCommandParameter> params)
308             throws OnapCommandException {
309         String result = "";
310
311         if (!line.contains("${")) {
312             return line;
313         }
314
315         int currentIdx = 0;
316         while (currentIdx < line.length()) {
317             int idxS = line.indexOf("${", currentIdx);
318             if (idxS == -1) {
319                 result += line.substring(currentIdx);
320                 break;
321             }
322             int idxE = line.indexOf("}", idxS);
323             String paramName = line.substring(idxS + 2, idxE);
324             paramName = paramName.trim();
325             if (!params.containsKey(paramName)) {
326                 throw new OnapCommandParameterNotFound(paramName);
327             }
328
329             OnapCommandParameter param = params.get(paramName);
330             if (OnapCommandParameterType.ARRAY.equals(param.getParameterType())
331                     || OnapCommandParameterType.JSON.equals(param.getParameterType())
332                     || OnapCommandParameterType.YAML.equals(param.getParameterType())) {
333                 // ignore the front and back double quotes in json body
334                 String va_ = params.get(paramName).getValue().toString();
335                 if (idxS > 0)
336                     result += line.substring(currentIdx, idxS - 1) + va_;
337                 else
338                     result += va_;
339                 currentIdx = idxE + 2;
340             } else if (OnapCommandParameterType.MAP.equals(param.getParameterType())) {
341                 try {
342                     String value = gson.toJson(params.get(paramName).getValue());
343                     if ((idxS == 0) && (currentIdx == 0)) {
344                         result = value;
345                     } else {
346                         result += line.substring(currentIdx, idxS - 1) + value;
347                     }
348                 } catch (Exception e) {  // NOSONAR
349                     //never occur as map is coverted to json string here
350                 }
351
352                 currentIdx = idxE + 2;
353             }else {
354                 result += line.substring(currentIdx, idxS) + params.get(paramName).getValue().toString();
355                 currentIdx = idxE + 1;
356             }
357         }
358
359         return result;
360     }
361
362     /**
363      * Populate result from input parameters.
364      *
365      * @param resultMap
366      *            map
367      * @param params
368      *            Map<String, OnapCommandParameter>
369      * @return map
370      * @throws OnapCommandException
371      */
372     public static Map<String, ArrayList<String>> populateOutputsFromInputParameters(
373             Map<String, ArrayList<String>> resultMap,
374             Map<String, OnapCommandParameter> params)
375             throws OnapCommandException {
376         Map<String, ArrayList<String>> resultsProcessed = new HashMap<>();
377
378         for (Entry<String, ArrayList<String>> entry : resultMap.entrySet()) {
379             String key = entry.getKey();
380             resultsProcessed.put(key, new ArrayList<>());
381             for (String value: entry.getValue()) {
382                 try {
383                     value = replaceLineFromInputParameters(value, params);
384                 } catch(OnapCommandResultEmpty e) {  // NOSONAR
385                     // pass
386                 }
387                 resultsProcessed.get(key).add(value);
388             }
389         }
390
391         return resultsProcessed;
392     }
393
394     /**
395      * Copy the parameters across the commands, mainly used for catalog, login and logout commands
396      *
397      * @throws OnapCommandInvalidParameterValue
398      */
399     public static void copyParamsFrom(OnapCommand from, OnapCommand to, Map<String, String> paramOverride) throws OnapCommandInvalidParameterValue {
400         for (OnapCommandParameter param: to.getParameters()) {
401
402             OnapCommandParameter fromParam = from.getParametersMap().get(param.getName());
403
404             if (fromParam != null) {
405                 param.setValue(fromParam.getValue());
406                 param.setDefaultValue(fromParam.getDefaultValue());
407             }
408
409             if (paramOverride.containsKey(param.getName())) {
410                  param.setValue(paramOverride.get(param.getName()));
411             }
412         }
413     }
414
415     public static void copyParamsFrom(OnapCommand from, OnapCommand to) throws OnapCommandInvalidParameterValue {
416         copyParamsFrom(from, to, new HashMap<String, String>());
417     }
418
419     /**
420      * Copy param schema from source command to destination command, useful in adding login command params into command
421      * @param from
422      * @param to
423      * @throws OnapCommandException
424      */
425     public static void copyParamSchemasFrom(OnapCommand from, OnapCommand to) {
426         for (OnapCommandParameter param: from.getParameters()) {
427             if (!to.getParametersMap().containsKey(param.getName())) {
428                 to.getParameters().add(param);
429             }
430         }
431     }
432
433     public static String md5(String content) {
434         String md5 = DigestUtils.md5Hex(content);
435
436         byte[] encodeBase64 = Base64.encodeBase64(md5.getBytes());
437         return new String(encodeBase64);
438     }
439 }
440
441
442