2 * Copyright 2017 Huawei Technologies Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onap.cli.fw.utils;
19 import static org.onap.cli.fw.conf.Constants.API;
20 import static org.onap.cli.fw.conf.Constants.ATTRIBUTES;
21 import static org.onap.cli.fw.conf.Constants.AUTH;
22 import static org.onap.cli.fw.conf.Constants.AUTH_VALUES;
23 import static org.onap.cli.fw.conf.Constants.BODY;
24 import static org.onap.cli.fw.conf.Constants.BOOLEAN_VALUE;
25 import static org.onap.cli.fw.conf.Constants.CLIENT;
26 import static org.onap.cli.fw.conf.Constants.COMMAND_TYPE_VALUES;
27 import static org.onap.cli.fw.conf.Constants.DATA_DIRECTORY;
28 import static org.onap.cli.fw.conf.Constants.DATA_PATH_JSON_PATTERN;
29 import static org.onap.cli.fw.conf.Constants.DEAFULT_PARAMETER_PASSWORD;
30 import static org.onap.cli.fw.conf.Constants.DEAFULT_PARAMETER_USERNAME;
31 import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETER_FILE_NAME;
32 import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETER_HTTP_FILE_NAME;
33 import static org.onap.cli.fw.conf.Constants.DEFAULT_PARAMETER_NO_AUTH;
34 import static org.onap.cli.fw.conf.Constants.DEFAULT_VALUE;
35 import static org.onap.cli.fw.conf.Constants.DESCRIPTION;
36 import static org.onap.cli.fw.conf.Constants.DIRECTION;
37 import static org.onap.cli.fw.conf.Constants.DISCOVERY_FILE;
38 import static org.onap.cli.fw.conf.Constants.ENTITY;
39 import static org.onap.cli.fw.conf.Constants.EXCEPTION;
40 import static org.onap.cli.fw.conf.Constants.EXECUTOR;
41 import static org.onap.cli.fw.conf.Constants.HEADERS;
42 import static org.onap.cli.fw.conf.Constants.HTTP;
43 import static org.onap.cli.fw.conf.Constants.HTTP_BODY_FAILED_PARSING;
44 import static org.onap.cli.fw.conf.Constants.HTTP_BODY_JSON_EMPTY;
45 import static org.onap.cli.fw.conf.Constants.HTTP_MANDATORY_SECTIONS;
46 import static org.onap.cli.fw.conf.Constants.HTTP_METHODS;
47 import static org.onap.cli.fw.conf.Constants.HTTP_REQUEST_MANDATORY_PARAMS;
48 import static org.onap.cli.fw.conf.Constants.HTTP_REQUEST_PARAMS;
49 import static org.onap.cli.fw.conf.Constants.HTTP_SECTIONS;
50 import static org.onap.cli.fw.conf.Constants.HTTP_SUCCESS_CODE_INVALID;
51 import static org.onap.cli.fw.conf.Constants.INFO;
52 import static org.onap.cli.fw.conf.Constants.INFO_AUTHOR;
53 import static org.onap.cli.fw.conf.Constants.INFO_PARAMS_LIST;
54 import static org.onap.cli.fw.conf.Constants.INFO_PARAMS_MANDATORY_LIST;
55 import static org.onap.cli.fw.conf.Constants.INFO_PRODUCT;
56 import static org.onap.cli.fw.conf.Constants.INFO_SERVICE;
57 import static org.onap.cli.fw.conf.Constants.INFO_TYPE;
58 import static org.onap.cli.fw.conf.Constants.INPUT_PARAMS_LIST;
59 import static org.onap.cli.fw.conf.Constants.INPUT_PARAMS_MANDATORY_LIST;
60 import static org.onap.cli.fw.conf.Constants.IS_INCLUDE;
61 import static org.onap.cli.fw.conf.Constants.IS_OPTIONAL;
62 import static org.onap.cli.fw.conf.Constants.IS_SECURED;
63 import static org.onap.cli.fw.conf.Constants.LONG_OPTION;
64 import static org.onap.cli.fw.conf.Constants.METHOD;
65 import static org.onap.cli.fw.conf.Constants.METHOD_TYPE;
66 import static org.onap.cli.fw.conf.Constants.MODE;
67 import static org.onap.cli.fw.conf.Constants.MODE_VALUES;
68 import static org.onap.cli.fw.conf.Constants.MULTIPART_ENTITY_NAME;
69 import static org.onap.cli.fw.conf.Constants.NAME;
70 import static org.onap.cli.fw.conf.Constants.OPEN_CLI_SCHEMA_VERSION;
71 import static org.onap.cli.fw.conf.Constants.PARAMETERS;
72 import static org.onap.cli.fw.conf.Constants.QUERIES;
73 import static org.onap.cli.fw.conf.Constants.REQUEST;
74 import static org.onap.cli.fw.conf.Constants.RESULTS;
75 import static org.onap.cli.fw.conf.Constants.RESULT_MAP;
76 import static org.onap.cli.fw.conf.Constants.RESULT_PARAMS_LIST;
77 import static org.onap.cli.fw.conf.Constants.RESULT_PARAMS_MANDATORY_LIST;
78 import static org.onap.cli.fw.conf.Constants.SAMPLE_RESPONSE;
79 import static org.onap.cli.fw.conf.Constants.SCHEMA_DIRECTORY;
80 import static org.onap.cli.fw.conf.Constants.SCHEMA_FILE_NOT_EXIST;
81 import static org.onap.cli.fw.conf.Constants.SCHEMA_FILE_WRONG_EXTN;
82 import static org.onap.cli.fw.conf.Constants.SCHEMA_PATH_PATERN;
83 import static org.onap.cli.fw.conf.Constants.SCOPE;
84 import static org.onap.cli.fw.conf.Constants.SERVICE;
85 import static org.onap.cli.fw.conf.Constants.SERVICE_PARAMS_LIST;
86 import static org.onap.cli.fw.conf.Constants.SERVICE_PARAMS_MANDATORY_LIST;
87 import static org.onap.cli.fw.conf.Constants.SHORT_OPTION;
88 import static org.onap.cli.fw.conf.Constants.SUCCESS_CODES;
89 import static org.onap.cli.fw.conf.Constants.TOP_LEVEL_MANDATORY_LIST;
90 import static org.onap.cli.fw.conf.Constants.TOP_LEVEL_PARAMS_LIST;
91 import static org.onap.cli.fw.conf.Constants.TYPE;
92 import static org.onap.cli.fw.conf.Constants.URI;
93 import static org.onap.cli.fw.conf.Constants.VERSION;
96 import java.io.FileInputStream;
97 import java.io.FileNotFoundException;
98 import java.io.IOException;
99 import java.io.InputStream;
100 import java.util.ArrayList;
101 import java.util.Arrays;
102 import java.util.Collections;
103 import java.util.HashMap;
104 import java.util.HashSet;
105 import java.util.List;
106 import java.util.Map;
107 import java.util.Map.Entry;
108 import java.util.ServiceLoader;
109 import java.util.Set;
110 import java.util.UUID;
111 import java.util.jar.Attributes;
112 import java.util.jar.JarFile;
113 import java.util.jar.Manifest;
114 import java.util.stream.Collectors;
116 import org.onap.cli.fw.OnapCommand;
117 import org.onap.cli.fw.ad.OnapService;
118 import org.onap.cli.fw.cmd.CommandType;
119 import org.onap.cli.fw.cmd.OnapHttpCommand;
120 import org.onap.cli.fw.cmd.OnapSwaggerCommand;
121 import org.onap.cli.fw.conf.Constants;
122 import org.onap.cli.fw.conf.OnapCommandConfg;
123 import org.onap.cli.fw.error.OnapCommandDiscoveryFailed;
124 import org.onap.cli.fw.error.OnapCommandException;
125 import org.onap.cli.fw.error.OnapCommandHelpFailed;
126 import org.onap.cli.fw.error.OnapCommandHttpHeaderNotFound;
127 import org.onap.cli.fw.error.OnapCommandHttpInvalidResponseBody;
128 import org.onap.cli.fw.error.OnapCommandHttpInvalidResultMap;
129 import org.onap.cli.fw.error.OnapCommandInvalidParameterType;
130 import org.onap.cli.fw.error.OnapCommandInvalidParameterValue;
131 import org.onap.cli.fw.error.OnapCommandInvalidPrintDirection;
132 import org.onap.cli.fw.error.OnapCommandInvalidResultAttributeScope;
133 import org.onap.cli.fw.error.OnapCommandInvalidSchema;
134 import org.onap.cli.fw.error.OnapCommandInvalidSchemaVersion;
135 import org.onap.cli.fw.error.OnapCommandLoadProfileFailed;
136 import org.onap.cli.fw.error.OnapCommandParameterNameConflict;
137 import org.onap.cli.fw.error.OnapCommandParameterNotFound;
138 import org.onap.cli.fw.error.OnapCommandParameterOptionConflict;
139 import org.onap.cli.fw.error.OnapCommandPersistProfileFailed;
140 import org.onap.cli.fw.error.OnapCommandResultEmpty;
141 import org.onap.cli.fw.error.OnapCommandResultMapProcessingFailed;
142 import org.onap.cli.fw.error.OnapCommandSchemaNotFound;
143 import org.onap.cli.fw.http.HttpInput;
144 import org.onap.cli.fw.http.HttpResult;
145 import org.onap.cli.fw.info.OnapCommandInfo;
146 import org.onap.cli.fw.input.OnapCommandParameter;
147 import org.onap.cli.fw.input.ParameterType;
148 import org.onap.cli.fw.input.cache.Param;
149 import org.onap.cli.fw.output.OnapCommandResult;
150 import org.onap.cli.fw.output.OnapCommandResultAttribute;
151 import org.onap.cli.fw.output.OnapCommandResultAttributeScope;
152 import org.onap.cli.fw.output.PrintDirection;
153 import org.onap.cli.fw.output.ResultType;
154 import org.onap.cli.fw.run.OnapCommandExecutor;
155 import org.slf4j.Logger;
156 import org.slf4j.LoggerFactory;
157 import org.springframework.core.io.Resource;
158 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
159 import org.springframework.core.io.support.ResourcePatternResolver;
160 import org.yaml.snakeyaml.Yaml;
162 import com.fasterxml.jackson.databind.ObjectMapper;
163 import com.jayway.jsonpath.JsonPath;
165 import net.minidev.json.JSONArray;
166 import net.minidev.json.JSONObject;
169 * Provides helper method to parse Yaml files and produce required objects.
172 public class OnapCommandUtils {
174 private static Logger LOG = LoggerFactory.getLogger(OnapCommandUtils.class);
176 * Private constructor.
178 private OnapCommandUtils() {
183 * Validates schema version.
185 * @param schemaName schema name
186 * @param version schema version
188 * @throws OnapCommandInvalidSchemaVersion invalid schema version exception
189 * @throws OnapCommandInvalidSchema invalid schema
190 * @throws OnapCommandSchemaNotFound schema not found
192 public static Map<String, ?> validateSchemaVersion(String schemaName, String version) throws OnapCommandException {
193 InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName);
196 Resource resource = findResource(schemaName, SCHEMA_PATH_PATERN);
198 if (resource != null) {
199 inputStream = resource.getInputStream();
202 } catch (IOException e) {
203 throw new OnapCommandSchemaNotFound(schemaName, e);
205 if (inputStream == null) {
206 inputStream = loadSchemaFromFile(schemaName);
209 Map<String, ?> values = null;
211 values = (Map<String, ?>) new Yaml().load(inputStream);
212 } catch (Exception e) {
213 throw new OnapCommandInvalidSchema(schemaName, e);
215 String schemaVersion = "";
216 if (values.keySet().contains(OPEN_CLI_SCHEMA_VERSION)) {
217 Object obj = values.get(OPEN_CLI_SCHEMA_VERSION);
218 schemaVersion = obj.toString();
221 if (!version.equals(schemaVersion)) {
222 throw new OnapCommandInvalidSchemaVersion(schemaVersion);
228 private static InputStream loadSchemaFromFile(String schemaLocation) throws OnapCommandInvalidSchema {
229 File schemaFile = new File(schemaLocation);
231 FileInputStream inputFileStream = new FileInputStream(schemaFile);
232 if (!schemaFile.isFile()) {
233 throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_NOT_EXIST);
236 if (!schemaFile.getName().endsWith(".yaml")) {
237 throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_WRONG_EXTN);
239 return inputFileStream;
240 }catch (FileNotFoundException e) {
241 throw new OnapCommandInvalidSchema(schemaFile.getName(), e);
246 * Retrieve OnapCommand from schema.
248 * @param cmd OnapCommand
249 * @param schemaName schema name
250 * @param includeDefault include if default
251 * @param validateSchema flag to represent validation
252 * @throws OnapCommandException on error
254 public static List<String> loadSchema(OnapCommand cmd, String schemaName, boolean includeDefault,
255 boolean validateSchema) throws OnapCommandException {
257 List<String> errors = new ArrayList<>();
258 if (includeDefault) {
259 Map<String, ?> defaultParameterMap = includeDefault ?
260 validateSchemaVersion(DEFAULT_PARAMETER_FILE_NAME, cmd.getSchemaVersion()) : new HashMap<>();
261 errors.addAll(parseSchema(cmd, defaultParameterMap, validateSchema));
264 Map<String, List<Map<String, String>>> commandYamlMap =
265 (Map<String, List<Map<String, String>>>)validateSchemaVersion(schemaName, cmd.getSchemaVersion());
267 errors.addAll(parseSchema(cmd, commandYamlMap, validateSchema));
270 } catch (OnapCommandException e) {
272 } catch (Exception e) {
273 throw new OnapCommandInvalidSchema(schemaName, e);
278 public static List<String> loadHttpSchema(OnapHttpCommand cmd, String schemaName, boolean includeDefault,
279 boolean validateSchema) throws OnapCommandException {
281 List<String> errors = new ArrayList<>();
282 if (includeDefault) {
283 Map<String, ?> defaultParameterMap = includeDefault ?
284 validateSchemaVersion(DEFAULT_PARAMETER_HTTP_FILE_NAME, cmd.getSchemaVersion()) : new HashMap<>();
285 errors.addAll(parseSchema(cmd, defaultParameterMap, validateSchema));
288 Map<String, List<Map<String, String>>> commandYamlMap =
289 (Map<String, List<Map<String, String>>>)validateSchemaVersion(schemaName, cmd.getSchemaVersion());
291 errors.addAll(parseHttpSchema(cmd, commandYamlMap, validateSchema));
295 } catch (OnapCommandException e) {
297 } catch (Exception e) {
298 throw new OnapCommandInvalidSchema(schemaName, e);
302 private static List<String> parseSchema(OnapCommand cmd,
303 final Map<String, ?> values,
304 boolean validate) throws OnapCommandException {
306 List<String> exceptionList = new ArrayList<>();
307 List<String> shortOptions = new ArrayList<>();
308 List<String> longOptions = new ArrayList<>();
311 validateTags(exceptionList, (Map<String, Object>) values, OnapCommandConfg.getSchemaAttrInfo(TOP_LEVEL_PARAMS_LIST),
312 OnapCommandConfg.getSchemaAttrInfo(TOP_LEVEL_MANDATORY_LIST), "root level");
316 List<String> sections = Arrays.asList(NAME, DESCRIPTION, INFO, PARAMETERS, RESULTS);
318 for (String key : sections) {
322 Object val = values.get(key);
324 cmd.setName(val.toString());
329 Object description = values.get(key);
330 if (description != null) {
331 cmd.setDescription(description.toString());
336 Map<String, String> infoMap = (Map<String, String>) values.get(key);
338 if (infoMap != null) {
340 validateTags(exceptionList, (Map<String, Object>) values.get(key),
341 OnapCommandConfg.getSchemaAttrInfo(INFO_PARAMS_LIST),
342 OnapCommandConfg.getSchemaAttrInfo(INFO_PARAMS_MANDATORY_LIST), INFO);
344 HashMap<String, String> validationMap = new HashMap<>();
345 validationMap.put(INFO_TYPE, COMMAND_TYPE_VALUES);
347 for (String secKey : validationMap.keySet()) {
348 if (infoMap.containsKey(secKey)) {
349 Object obj = infoMap.get(secKey);
351 exceptionList.add("Attribute '" + secKey + "' under '" + INFO + "' is empty");
353 String value = String.valueOf(obj);
354 if (!OnapCommandConfg.getSchemaAttrInfo(validationMap.get(secKey)).contains(value)) {
355 exceptionList.add("Attribute '" + secKey + "' contains invalid value. Valide values are "
356 + OnapCommandConfg.getSchemaAttrInfo(validationMap.get(key))); //
363 OnapCommandInfo info = new OnapCommandInfo();
365 for (Map.Entry<String, String> entry1 : infoMap.entrySet()) {
366 String key1 = entry1.getKey();
370 info.setProduct(infoMap.get(key1));
374 info.setService(infoMap.get(key1).toString());
378 Object obj = infoMap.get(key1);
379 info.setCommandType(CommandType.get(obj.toString()));
383 Object mode = infoMap.get(key1);
384 info.setAuthor(mode.toString());
395 List<Map<String, String>> parameters = (List) values.get(key);
397 if (parameters != null) {
398 Set<String> names = new HashSet<>();
400 //To support overriding of the parameters, if command is already
401 //having the same named parameters, means same parameter is
402 //Overridden from included template into current template
403 Set<String> existingParamNames = cmd.getParametersMap().keySet();
405 for (Map<String, String> parameter : parameters) {
406 boolean isOverriding = false;
407 OnapCommandParameter param = new OnapCommandParameter();
409 //Override the parameters from its base such as default parameters list
410 if (existingParamNames.contains(parameter.getOrDefault(NAME, ""))) {
411 param = cmd.getParametersMap().get(parameter.getOrDefault(NAME, ""));
416 validateTags(exceptionList, parameter, OnapCommandConfg.getSchemaAttrInfo(INPUT_PARAMS_LIST),
417 OnapCommandConfg.getSchemaAttrInfo(INPUT_PARAMS_MANDATORY_LIST), PARAMETERS);
420 for (Map.Entry<String, String> entry1 : parameter.entrySet()) {
421 String key2 = entry1.getKey();
425 if (names.contains(parameter.get(key2))) {
426 throwOrCollect(new OnapCommandParameterNameConflict(parameter.get(key2)), exceptionList, validate);
428 names.add(parameter.get(key2));
431 param.setName(parameter.get(key2));
435 param.setDescription(parameter.get(key2));
439 if (shortOptions.contains(parameter.get(key2))) {
440 throwOrCollect(new OnapCommandParameterOptionConflict(parameter.get(key2)), exceptionList, validate);
442 shortOptions.add(parameter.get(key2));
443 param.setShortOption(parameter.get(key2));
447 if (longOptions.contains(parameter.get(key2))) {
448 throwOrCollect(new OnapCommandParameterOptionConflict(parameter.get(key2)), exceptionList, validate);
450 longOptions.add(parameter.get(key2));
451 param.setLongOption(parameter.get(key2));
455 Object obj = parameter.get(key2);
456 param.setDefaultValue(obj.toString());
461 param.setParameterType(ParameterType.get(parameter.get(key2)));
462 } catch (OnapCommandException ex) {
463 throwOrCollect(ex, exceptionList, validate);
469 if (!validateBoolean(String.valueOf(parameter.get(key2)))) {
470 exceptionList.add(invalidBooleanValueMessage(parameter.get(NAME),
471 IS_SECURED, parameter.get(key2)));
474 if ("true".equalsIgnoreCase(String.valueOf(parameter.get(key2)))) {
475 param.setOptional(true);
477 param.setOptional(false);
483 if (!validateBoolean(String.valueOf(parameter.get(key2)))) {
484 exceptionList.add(invalidBooleanValueMessage(parameter.get(NAME),
485 IS_SECURED, parameter.get(key2)));
489 if ("true".equalsIgnoreCase(String.valueOf(parameter.get(key2)))) {
490 param.setSecured(true);
492 param.setSecured(false);
498 if (!validateBoolean(String.valueOf(parameter.get(key2)))) {
499 exceptionList.add(invalidBooleanValueMessage(parameter.get(NAME),
500 IS_INCLUDE, parameter.get(key2)));
504 if ("true".equalsIgnoreCase(String.valueOf(parameter.get(key2)))) {
505 param.setInclude(true);
507 param.setInclude(false);
513 if ( !isOverriding) {
514 cmd.getParameters().add(param);
516 cmd.getParametersMap().replace(param.getName(), param);
523 Map<String, ?> valueMap = (Map<String, ?>) values.get(key);
524 if (valueMap != null) {
525 OnapCommandResult result = new OnapCommandResult();
526 for (Map.Entry<String, ?> entry1 : valueMap.entrySet()) {
527 String key3 = entry1.getKey();
532 result.setPrintDirection(PrintDirection.get((String) valueMap.get(key3)));
533 } catch (OnapCommandException ex) {
534 throwOrCollect(ex, exceptionList, validate);
539 List<Map<String, String>> attrs = (ArrayList) valueMap.get(key3);
541 for (Map<String, String> map : attrs) {
542 OnapCommandResultAttribute attr = new OnapCommandResultAttribute();
544 validateTags(exceptionList, map, OnapCommandConfg.getSchemaAttrInfo(RESULT_PARAMS_LIST),
545 OnapCommandConfg.getSchemaAttrInfo(RESULT_PARAMS_MANDATORY_LIST), ATTRIBUTES);
548 Set<String> resultParamNames = new HashSet<>();
550 for (Map.Entry<String, String> entry4 : map.entrySet()) {
551 String key4 = entry4.getKey();
555 if (resultParamNames.contains(map.get(key4))) {
556 exceptionList.add("Attribute name='" + map.get(key4) + "' under '"
557 + ATTRIBUTES + ":' is already used, Take different one.");
560 attr.setName(map.get(key4));
561 resultParamNames.add(map.get(key4));
566 attr.setDescription(map.get(key4));
571 attr.setScope(OnapCommandResultAttributeScope.get(map.get(key4)));
572 } catch (OnapCommandException ex) {
573 throwOrCollect(ex, exceptionList, validate);
579 attr.setType(ParameterType.get(map.get(key4)));
580 } catch (OnapCommandException ex) {
581 throwOrCollect(ex, exceptionList, validate);
586 Object obj = map.get(key4);
587 attr.setDefaultValue(obj.toString());
592 if (!validateBoolean(String.valueOf(map.get(key4)))) {
593 exceptionList.add(invalidBooleanValueMessage(ATTRIBUTES,
594 IS_SECURED, map.get(key4)));
597 if ("true".equals(String.valueOf(map.get(key4)))) {
598 attr.setSecured(true);
600 attr.setSecured(false);
606 result.getRecords().add(attr);
611 cmd.setResult(result);
616 return exceptionList;
623 * OnapSwaggerBasedCommand
626 * @throws OnapCommandParameterNameConflict
627 * param name conflict exception
628 * @throws OnapCommandParameterOptionConflict
629 * param option conflict exception
630 * @throws OnapCommandInvalidParameterType
631 * invalid param type exception
632 * @throws OnapCommandInvalidPrintDirection
633 * invalid print direction exception
634 * @throws OnapCommandInvalidResultAttributeScope
635 * invalid scope exception
636 * @throws OnapCommandSchemaNotFound
638 * @throws OnapCommandInvalidSchema
640 * @throws OnapCommandInvalidSchemaVersion
641 * invalid schema version
643 public static void loadSchema(OnapSwaggerCommand cmd, String schemaName) throws OnapCommandException {
645 Map<String, ?> values = (Map<String, ?>) validateSchemaVersion(schemaName, cmd.getSchemaVersion());
646 Map<String, String> valueMap = (Map<String, String>) values.get(EXECUTOR);
647 OnapCommandExecutor exec = new OnapCommandExecutor();
649 for (Map.Entry<String, String> entry1 : valueMap.entrySet()) {
650 String key1 = entry1.getKey();
652 if (API.equals(key1)) {
653 exec.setApi(valueMap.get(key1));
654 } else if (CLIENT.equals(key1)) {
655 exec.setClient(valueMap.get(key1));
656 } else if (ENTITY.equals(key1)) {
657 exec.setEntity(valueMap.get(key1));
658 } else if (EXCEPTION.equals(key1)) {
659 exec.setException(valueMap.get(key1));
660 } else if (METHOD.equals(key1)) {
661 exec.setMethod(valueMap.get(key1));
665 cmd.setExecutor(exec);
666 } catch (OnapCommandException e) {
668 } catch (Exception e) {
669 throw new OnapCommandInvalidSchema(schemaName, e);
680 * @throws OnapCommandException
683 private static ArrayList<String> parseHttpSchema(OnapHttpCommand cmd,
684 final Map<String, ?> values,
685 boolean validate) throws OnapCommandException {
686 ArrayList<String> errorList = new ArrayList<>();
688 Map<String, ?> valMap = (Map<String, ?>) values.get(HTTP);
690 if (valMap != null) {
692 validateTags(errorList, valMap, OnapCommandConfg.getSchemaAttrInfo(HTTP_SECTIONS),
693 OnapCommandConfg.getSchemaAttrInfo(HTTP_MANDATORY_SECTIONS), PARAMETERS);
694 errorList.addAll(validateHttpSchemaSection(values));
696 for (Map.Entry<String, ?> entry1 : valMap.entrySet()) {
697 String key1 = entry1.getKey();
701 Map<String, ?> map = (Map<String, ?>) valMap.get(key1);
703 for (Map.Entry<String, ?> entry2 : map.entrySet()) {
705 String key2 = entry2.getKey();
709 Object obj = map.get(key2);
710 cmd.getInput().setUri(obj.toString());
713 Object method = map.get(key2);
714 cmd.getInput().setMethod(method.toString());
717 Object body = map.get(key2);
718 cmd.getInput().setBody(body.toString());
721 Map<String, String> head = (Map<String, String>) map.get(key2);
722 cmd.getInput().setReqHeaders(head);
725 Map<String, String> query = (Map<String, String>) map.get(key2);
727 cmd.getInput().setReqQueries(query);
729 case MULTIPART_ENTITY_NAME:
730 Object multipartEntityName = map.get(key2);
731 cmd.getInput().setMultipartEntityName(multipartEntityName.toString());
734 }catch (Exception ex) {
735 throwOrCollect(new OnapCommandInvalidSchema(cmd.getSchemaName(), ex), errorList, validate);
741 Map<String, String> serviceMap = (Map<String, String>) valMap.get(key1);
743 if (serviceMap != null) {
745 validateTags(errorList, (Map<String, Object>) valMap.get(key1),
746 OnapCommandConfg.getSchemaAttrInfo(SERVICE_PARAMS_LIST),
747 OnapCommandConfg.getSchemaAttrInfo(SERVICE_PARAMS_MANDATORY_LIST), SERVICE);
749 HashMap<String, String> validationMap = new HashMap<>();
750 validationMap.put(AUTH, AUTH_VALUES);
751 validationMap.put(MODE, MODE_VALUES);
753 for (String secKey : validationMap.keySet()) {
754 if (serviceMap.containsKey(secKey)) {
755 Object obj = serviceMap.get(secKey);
757 errorList.add("Attribute '" + secKey + "' under '" + SERVICE + "' is empty");
759 String value = String.valueOf(obj);
760 if (!OnapCommandConfg.getSchemaAttrInfo(validationMap.get(secKey)).contains(value)) {
761 errorList.add("Attribute '" + secKey + "' contains invalid value. Valide values are "
762 + OnapCommandConfg.getSchemaAttrInfo(validationMap.get(key1))); //
769 OnapService srv = new OnapService();
771 for (Map.Entry<String, String> entry : serviceMap.entrySet()) {
772 String key = entry.getKey();
776 srv.setName(serviceMap.get(key));
780 srv.setVersion(serviceMap.get(key).toString());
784 Object obj = serviceMap.get(key);
785 srv.setAuthType(obj.toString());
787 //On None type, username, password and no_auth are invalid
788 if (srv.isNoAuth()) {
789 cmd.getParametersMap().get(DEAFULT_PARAMETER_USERNAME).setInclude(false);
790 cmd.getParametersMap().get(DEAFULT_PARAMETER_PASSWORD).setInclude(false);
791 cmd.getParametersMap().get(DEFAULT_PARAMETER_NO_AUTH).setInclude(false);
796 Object mode = serviceMap.get(key);
797 srv.setMode(mode.toString());
807 validateHttpSccessCodes(errorList, (List<Object>) valMap.get(key1));
809 cmd.setSuccessStatusCodes((ArrayList) valMap.get(key1));
814 validateHttpResultMap(errorList, values);
816 cmd.setResultMap((Map<String, String>) valMap.get(key1));
819 case SAMPLE_RESPONSE:
820 // (mrkanag) implement sample response handling
825 }catch (OnapCommandException e) {
826 throwOrCollect(e, errorList, validate);
832 private static void throwOrCollect(OnapCommandException ex, List<String> list, boolean shouldCollectException)
833 throws OnapCommandException {
834 if (shouldCollectException) {
835 list.add(ex.getMessage());
841 private static void validateTags(List<String> schemaErrors, Map<String, ?> yamlMap, List<String> totalParams,
842 List<String> mandatoryParams, String section) {
843 // mrkanag capture invalid entries as well
844 for (String param : totalParams) {
845 boolean isMandatory = mandatoryParams.contains(param);
846 boolean isYamlContains = yamlMap.containsKey(param);
848 if (!isYamlContains) {
849 schemaErrors.add("Mandatory attribute '" + param + "' is missing under '" + section + "'");
851 String value = String.valueOf(yamlMap.get(param));
852 if (value == null || value.isEmpty()) {
853 schemaErrors.add("Mandatory attribute '" + param + "' under '" + section
854 + "' shouldn't be null or empty");
868 protected static boolean validateBoolean(String toValidate) {
869 return OnapCommandConfg.getSchemaAttrInfo(BOOLEAN_VALUE).contains(toValidate.toLowerCase());
872 private static String emptySection(String section) {
873 return "The section '" + section + ":' cann't be null or empty";
876 private static String invalidBooleanValueMessage(String section, String attribute, String value) {
877 return "The value '" + value + "' of '" + attribute + "' present under '" + section + "' should be boolean";
880 private static Set<String> validateHttpQueries(Map<String, Object> requestMap) {
881 Map<String, Object> queries = (Map<String, Object>) requestMap.get(QUERIES);
882 Set<String> queryParamNames = new HashSet<>();
883 if (queries != null) {
884 for (Entry<String, Object> entry : queries.entrySet()) {
885 parseParameters(String.valueOf(entry.getValue()), queryParamNames);
888 return queryParamNames;
892 private static Set<String> validateHttpHeaders(Map<String, Object> requestMap) {
894 Map<String, Object> headers = (Map<String, Object>) requestMap.get(HEADERS);
895 Set<String> headerParamNames = new HashSet<>();
896 if (headers != null) {
897 for (Entry<String, Object> entry : headers.entrySet()) {
898 parseParameters(String.valueOf(entry.getValue()), headerParamNames);
901 return headerParamNames;
904 private static Set<String> validateHttpBody(List<String> errorList, Map<String, Object> requestMap) {
905 Set<String> bodyParamNames = new HashSet<>();
906 Object bodyString = requestMap.get(BODY);
907 if (bodyString == null) {
908 return bodyParamNames;
911 String body = String.valueOf(bodyString);
912 JSONObject obj = null;
914 obj = new ObjectMapper().readValue(body, JSONObject.class);
915 } catch (IOException e1) { // NOSONAR
916 errorList.add(HTTP_BODY_FAILED_PARSING);
918 if (obj == null || "".equals(obj.toString())) {
919 errorList.add(HTTP_BODY_JSON_EMPTY);
921 parseParameters(body, bodyParamNames);
923 return bodyParamNames;
926 private static Set<String> validateHttpUri(List<String> errorList, Map<String, Object> requestMap) {
927 Set<String> uriParamNames = new HashSet<>();
928 String uri = (String) requestMap.get(URI);
929 if (uri == null || uri.isEmpty()) {
930 errorList.add(emptySection(URI));
931 return uriParamNames;
933 parseParameters(uri, uriParamNames);
934 return uriParamNames;
937 private static void parseParameters(String line, Set<String> paramNames) {
940 while (currentIdx < line.length()) {
941 int idxS = line.indexOf("${", currentIdx);
945 int idxE = line.indexOf("}", idxS);
946 String paramName = line.substring(idxS + 2, idxE);
947 paramNames.add(paramName.trim());
949 currentIdx = idxE + 1;
954 private static Set<String> getRequestParams(Map<String, ?> yamlMap) {
956 Set<String> set = new HashSet<>();
958 @SuppressWarnings("unchecked")
959 List<Map<String, Object>> inputParams = (List<Map<String, Object>>) yamlMap.get(PARAMETERS);
961 if (inputParams != null) {
962 for (Map<String, Object> map : inputParams) {
963 for (Entry<String, Object> entry : map.entrySet()) {
964 Object key = entry.getKey();
966 if (NAME.equals(key)) {
967 set.add(String.valueOf(entry.getValue()));
977 private static void validateHttpResultMap(List<String> errorList, Map<String, ?> values) throws OnapCommandException {
978 Map<String, ?> valMap = (Map<String, ?>) values.get(HTTP);
979 List<Map<String, String>> attributes = (List<Map<String, String>>) ((Map<String, ?>)values.get(RESULTS)).get(ATTRIBUTES);
980 Set<String> resultMapParams = ((Map<String, String>) valMap.get(RESULT_MAP)).keySet();
982 Set<String> resultAttNames = attributes.stream().map(map -> map.get(NAME))
983 .collect(Collectors.toSet());
985 List<String> invaliResultMapParams = resultMapParams.stream()
986 .filter(p -> !resultAttNames.contains(p)).collect(Collectors.toList());
988 if (!invaliResultMapParams.isEmpty()) {
989 throwOrCollect(new OnapCommandHttpInvalidResultMap(invaliResultMapParams), errorList, true);
993 private static void validateHttpSccessCodes(List<String> errorList, List<Object> requestSuccessCodes) {
995 if (requestSuccessCodes == null || requestSuccessCodes.isEmpty()) {
996 errorList.add(HTTP_SUCCESS_CODE_INVALID);
1000 for (Object successCode : requestSuccessCodes) {
1001 Integer code = (Integer) successCode;
1002 if (code < 200 || code >= 300) {
1004 errorList.add(HTTP_SUCCESS_CODE_INVALID);
1012 private static ArrayList<String> validateHttpSchemaSection(Map<String, ?> values) {
1014 ArrayList<String> errorList = new ArrayList<>();
1015 Map<String, ?> map = (Map<String, ?>) values.get(HTTP);
1016 Map<String, Object> requestMap = (Map<String, Object>) map.get(REQUEST);
1018 if (requestMap != null && !requestMap.isEmpty()) {
1019 validateTags(errorList, requestMap, OnapCommandConfg.getSchemaAttrInfo(HTTP_REQUEST_PARAMS),
1020 OnapCommandConfg.getSchemaAttrInfo(HTTP_REQUEST_MANDATORY_PARAMS), REQUEST);
1021 String method = (String) requestMap.get(METHOD);
1022 if (method != null && !method.isEmpty()) {
1023 if (!OnapCommandConfg.getSchemaAttrInfo(HTTP_METHODS).contains(method.toLowerCase())) {
1024 errorList.add("Attribute '" + METHOD + "' under '" + REQUEST + "' is invalid, correct types are "
1025 + OnapCommandConfg.getSchemaAttrInfo(HTTP_METHODS).toString());
1028 errorList.add("Http request method cann't be null or empty");
1031 Set<String> requestParams = getRequestParams(values);
1033 Set<String> uriParams = validateHttpUri(errorList, requestMap);
1035 Set<String> bodyParams = validateHttpBody(errorList, requestMap);
1037 Set<String> headerParams = validateHttpHeaders(requestMap);
1039 Set<String> queryParams = validateHttpQueries(requestMap);
1041 HashSet<String> totoalParams = new HashSet<>(uriParams);
1042 totoalParams.addAll(bodyParams);
1043 totoalParams.addAll(headerParams);
1044 totoalParams.addAll(queryParams);
1046 List<String> nonDeclaredParams = totoalParams.stream().filter(param -> !requestParams.contains(param))
1047 .collect(Collectors.toList());
1049 nonDeclaredParams.stream().forEach(p -> errorList.add("The parameter '" + p
1050 + "' declared under 'parameters:' section is not mapped into request section."));
1052 errorList.add(emptySection(REQUEST));
1063 * @return help string
1064 * @throws OnapCommandHelpFailed
1065 * help failed exception
1067 public static String help(OnapCommand cmd) throws OnapCommandHelpFailed {
1069 String help = "usage: oclip " + cmd.getName();
1072 help += "\n\n" + cmd.getDescription();
1075 help += "\n\nService: " + cmd.getInfo().getService();
1077 // Add whole command
1078 String commandOptions = "";
1081 OnapCommandResult paramTable = new OnapCommandResult();
1082 paramTable.setPrintDirection(PrintDirection.LANDSCAPE);
1083 paramTable.setType(ResultType.TABLE);
1084 paramTable.setIncludeTitle(false);
1085 paramTable.setIncludeSeparator(false);
1087 OnapCommandResultAttribute attrName = new OnapCommandResultAttribute();
1088 attrName.setName(NAME);
1089 attrName.setDescription(NAME);
1090 attrName.setScope(OnapCommandResultAttributeScope.SHORT);
1091 paramTable.getRecords().add(attrName);
1093 OnapCommandResultAttribute attrDescription = new OnapCommandResultAttribute();
1094 attrDescription.setName(DESCRIPTION);
1095 attrDescription.setDescription(DESCRIPTION);
1096 attrDescription.setScope(OnapCommandResultAttributeScope.SHORT);
1097 paramTable.getRecords().add(attrDescription);
1099 int newLineOptions = 0;
1100 for (OnapCommandParameter param : cmd.getParameters()) {
1101 if (!param.isInclude()) {
1105 // First column Option or positional args
1107 if (newLineOptions == 3) {
1109 commandOptions += "\n";
1112 if (param.getShortOption() != null || param.getLongOption() != null) {
1113 optFirstCol = OnapCommandParameter.printShortOption(param.getShortOption()) + " | "
1114 + OnapCommandParameter.printLongOption(param.getLongOption());
1115 commandOptions += " [" + optFirstCol + "]";
1117 optFirstCol = param.getName();
1118 commandOptions += " <" + optFirstCol + ">";
1123 attrName.getValues().add(" " + optFirstCol);
1125 // Second column description
1126 String optSecondCol = param.getDescription().trim();
1127 if (!optSecondCol.endsWith(".")) {
1128 optSecondCol += ".";
1130 optSecondCol += " It is of type " + param.getParameterType().name() + ".";
1132 if (param.getParameterType().equals(ParameterType.JSON)
1133 || param.getParameterType().equals(ParameterType.YAML)) {
1134 optSecondCol += " It's recommended to input the complete path of the file, which is having the value for it.";
1136 if (param.isOptional()) {
1137 optSecondCol += " It is optional.";
1140 String defaultMsg = " By default, it is ";
1141 if (param.isRawDefaultValueAnEnv()) {
1142 optSecondCol += defaultMsg + "read from environment variable " + param.getEnvVarNameFromrRawDefaultValue()
1144 } else if (param.getDefaultValue() != null && !((String)param.getDefaultValue()).isEmpty()) {
1145 optSecondCol += defaultMsg + param.getDefaultValue() + ".";
1148 if (param.isSecured()) {
1149 optSecondCol += " Secured.";
1151 // (mrkanag) Add help msg for reading default value from env
1152 attrDescription.getValues().add(optSecondCol);
1156 help += "\n\nOptions::\n\n" + commandOptions + "\n\nwhere::\n\n" + paramTable.print();
1157 } catch (OnapCommandException e) {
1158 throw new OnapCommandHelpFailed(e);
1162 OnapCommandResult resultTable = new OnapCommandResult();
1163 resultTable.setPrintDirection(PrintDirection.PORTRAIT);
1164 resultTable.setType(ResultType.TABLE);
1165 resultTable.setIncludeTitle(false);
1166 resultTable.setIncludeSeparator(false);
1168 for (OnapCommandResultAttribute attr : cmd.getResult().getRecords()) {
1169 OnapCommandResultAttribute attrHelp = new OnapCommandResultAttribute();
1170 attrHelp.setName(" " + attr.getName());
1171 attrHelp.setDescription(attr.getDescription());
1172 String msg = attr.getDescription() + " and is of type " + attr.getType().name() + ".";
1173 if (attr.isSecured()) {
1174 msg += " It is secured.";
1176 attrHelp.getValues().add(msg);
1177 attrHelp.setType(attr.getType());
1178 resultTable.getRecords().add(attrHelp);
1181 if (cmd.getResult().getRecords().size() > 0) {
1183 help += "\n\nResults::\n\n" + resultTable.print();
1184 } catch (OnapCommandException e) {
1185 throw new OnapCommandHelpFailed(e);
1190 help += "\n\nError::\n\n On error, it prints <HTTP STATUS CODE>::<ERROR CODE>::<ERROR MESSAGE>\n";
1195 * Create Dict from list of Parameters.
1198 * list of parameters
1201 public static Map<String, OnapCommandParameter> getInputMap(List<OnapCommandParameter> inputs) {
1202 Map<String, OnapCommandParameter> map = new HashMap<>();
1203 for (OnapCommandParameter param : inputs) {
1204 map.put(param.getName(), param);
1210 * Discover the Oclip commands.
1214 public static List<Class<OnapCommand>> discoverCommandPlugins() {
1215 ServiceLoader<OnapCommand> loader = ServiceLoader.load(OnapCommand.class);
1216 List<Class<OnapCommand>> clss = new ArrayList<>();
1217 for (OnapCommand implClass : loader) {
1218 clss.add((Class<OnapCommand>) implClass.getClass());
1231 public static List<String> sort(Set<String> col) {
1232 List<String> results = new ArrayList<>();
1233 results.addAll(col);
1234 Collections.sort(results);
1239 * Flatten the json list.
1245 public static List<String> jsonFlatten(List<String> jsons) {
1246 List<String> results = new ArrayList<>();
1247 for (String json : jsons) {
1249 results.add(JsonPath.parse(json).jsonString());
1250 } catch (Exception e) { // NOSONAR
1259 * Construct method name.
1267 public static String formMethodNameFromAttributeName(String name, String prefix) {
1268 if (name == null || name.isEmpty()) {
1272 String methodName = prefix;
1273 for (String tk : name.split("-")) {
1274 methodName += Character.toString(tk.charAt(0)).toUpperCase();
1275 methodName += tk.substring(1);
1281 * There are unique values like uuid is supported, so when input, output (default) values has
1282 * these special entries, then it will get replaced with it's value
1287 public static String replaceLineForSpecialValues(String line) {
1290 if (!line.contains("$s{")) {
1295 while (currentIdx < line.length()) {
1296 int idxS = line.indexOf("$s{", currentIdx);
1298 result += line.substring(currentIdx);
1301 int idxE = line.indexOf("}", idxS);
1302 String splEntry = line.substring(idxS + 3, idxE);
1303 splEntry = splEntry.trim();
1308 case Constants.SPL_ENTRY_UUID:
1309 value = UUID.randomUUID().toString();
1314 if (splEntry.startsWith(Constants.SPL_ENTRY_ENV)) {
1315 //start to read after env:ENV_VAR_NAME
1316 String envVarName = splEntry.substring(4);
1317 value = System.getenv(envVarName);
1318 if (value == null) {
1319 //when env is not defined, assign the same env:ENV_VAR_NAME
1320 //so that it will given hit to user that ENV_VAR_NAME to be
1329 result += line.substring(currentIdx, idxS) + value;
1330 currentIdx = idxE + 1;
1336 public static String replaceLineFromInputParameters(String line, Map<String, OnapCommandParameter> params)
1337 throws OnapCommandException {
1340 if (!line.contains("${")) {
1345 while (currentIdx < line.length()) {
1346 int idxS = line.indexOf("${", currentIdx);
1348 result += line.substring(currentIdx);
1351 int idxE = line.indexOf("}", idxS);
1352 String paramName = line.substring(idxS + 2, idxE);
1353 paramName = paramName.trim();
1354 if (!params.containsKey(paramName)) {
1355 throw new OnapCommandParameterNotFound(paramName);
1358 String value = params.get(paramName).getValue().toString();
1360 OnapCommandParameter param = params.get(paramName);
1361 if (ParameterType.ARRAY.equals(param.getParameterType())
1362 || ParameterType.MAP.equals(param.getParameterType())
1363 || ParameterType.JSON.equals(param.getParameterType())
1364 || ParameterType.YAML.equals(param.getParameterType())) {
1365 // ignore the front and back double quotes in json body
1366 result += line.substring(currentIdx, idxS - 1) + value;
1367 currentIdx = idxE + 2;
1369 result += line.substring(currentIdx, idxS) + value;
1370 currentIdx = idxE + 1;
1377 private static ArrayList<String> replaceLineFromOutputResults(String line, HttpResult resultHttp)
1378 throws OnapCommandHttpHeaderNotFound, OnapCommandHttpInvalidResponseBody,
1379 OnapCommandResultMapProcessingFailed, OnapCommandResultEmpty {
1380 String headerProcessedLine = "";
1382 ArrayList<String> result = new ArrayList<>();
1383 if (!line.contains("$b{") && !line.contains("$h{")) {
1389 * In case of empty response body [] or {}
1391 if (resultHttp.getBody().length() <= 2) {
1396 * Process headers macros : line: $h{abc}-$b{$.[*].xyz} , After processing line will be [abc's
1397 * value]-$b{$.[*].xyz}
1400 while (currentIdx < line.length()) {
1401 int idxS = line.indexOf("$h{", currentIdx);
1403 headerProcessedLine += line.substring(currentIdx);
1406 int idxE = line.indexOf("}", idxS);
1407 String headerName = line.substring(idxS + 3, idxE);
1408 headerName = headerName.trim();
1409 if (!resultHttp.getRespHeaders().containsKey(headerName)) {
1410 throw new OnapCommandHttpHeaderNotFound(headerName);
1412 String value = resultHttp.getRespHeaders().get(headerName);
1414 headerProcessedLine += line.substring(currentIdx, idxS) + value;
1415 currentIdx = idxE + 1;
1418 // Process body jsonpath macros
1419 List<Object> values = new ArrayList<>();
1420 String bodyProcessedPattern = "";
1422 int maxRows = 1; // in normal case, only one row will be there
1423 while (currentIdx < headerProcessedLine.length()) {
1424 int idxS = headerProcessedLine.indexOf("$b{", currentIdx);
1426 bodyProcessedPattern += headerProcessedLine.substring(currentIdx);
1429 int idxE = headerProcessedLine.indexOf("}", idxS);
1430 String jsonPath = headerProcessedLine.substring(idxS + 3, idxE);
1431 jsonPath = jsonPath.trim();
1433 // JSONArray or String
1434 Object value = JsonPath.read(resultHttp.getBody(), jsonPath);
1435 if (value instanceof JSONArray) {
1436 JSONArray arr = (JSONArray) value;
1437 if (arr.size() > maxRows) {
1438 maxRows = arr.size();
1441 bodyProcessedPattern += headerProcessedLine.substring(currentIdx, idxS) + "%s";
1443 currentIdx = idxE + 1;
1444 } catch (Exception e) {
1445 throw new OnapCommandHttpInvalidResponseBody(jsonPath, e);
1449 if (bodyProcessedPattern.isEmpty()) {
1450 result.add(headerProcessedLine);
1453 for (int i = 0; i < maxRows; i++) {
1455 String bodyProcessedLine = "";
1456 int positionalIdx = 0; // %s positional idx
1457 while (currentIdx < bodyProcessedPattern.length()) {
1458 int idxS = bodyProcessedPattern.indexOf("%s", currentIdx);
1460 bodyProcessedLine += bodyProcessedPattern.substring(currentIdx);
1463 int idxE = idxS + 2; // %s
1465 Object value = values.get(positionalIdx);
1466 String valueS = String.valueOf(value);
1467 if (value instanceof JSONArray) {
1468 JSONArray arr = (JSONArray) value;
1469 if (!arr.isEmpty()) {
1470 valueS = arr.get(i).toString();
1472 throw new OnapCommandResultEmpty();
1476 bodyProcessedLine += bodyProcessedPattern.substring(currentIdx, idxS) + valueS;
1479 } catch (OnapCommandResultEmpty e) {
1481 } catch (Exception e) {
1482 throw new OnapCommandResultMapProcessingFailed(line, e);
1485 result.add(bodyProcessedLine);
1493 * Set argument to param value.
1500 * @throws OnapCommandParameterNotFound
1502 * @throws OnapCommandInvalidParameterValue
1505 public static HttpInput populateParameters(Map<String, OnapCommandParameter> params, HttpInput input)
1506 throws OnapCommandException {
1507 HttpInput inp = new HttpInput();
1508 for (OnapCommandParameter param : params.values()) {
1509 if (ParameterType.BINARY.equals(param.getParameterType())) {
1510 inp.setBinaryData(true);
1514 inp.setBody(replaceLineFromInputParameters(input.getBody(), params));
1515 inp.setUri(replaceLineFromInputParameters(input.getUri(), params));
1516 inp.setMethod(input.getMethod().toLowerCase());
1517 for (String h : input.getReqHeaders().keySet()) {
1518 String value = input.getReqHeaders().get(h);
1519 inp.getReqHeaders().put(h, replaceLineFromInputParameters(value, params));
1522 for (String h : input.getReqQueries().keySet()) {
1523 String value = input.getReqQueries().get(h);
1524 inp.getReqQueries().put(h, replaceLineFromInputParameters(value, params));
1538 * @throws OnapCommandHttpHeaderNotFound
1539 * header not found exception
1540 * @throws OnapCommandHttpInvalidResponseBody
1541 * invalid response body exception
1542 * @throws OnapCommandResultMapProcessingFailed
1543 * map processing failed exception
1545 public static Map<String, ArrayList<String>> populateOutputs(Map<String, String> resultMap, HttpResult resultHttp)
1546 throws OnapCommandException {
1547 Map<String, ArrayList<String>> resultsProcessed = new HashMap<>();
1549 for (Entry<String, String> entry : resultMap.entrySet()) {
1550 String key = entry.getKey();
1552 resultsProcessed.put(key, replaceLineFromOutputResults(resultMap.get(key), resultHttp));
1553 } catch(OnapCommandResultEmpty e) {
1558 return resultsProcessed;
1562 * Populate result from input parameters.
1567 * Map<String, OnapCommandParameter>
1569 * @throws OnapCommandHttpHeaderNotFound
1570 * header not found exception
1571 * @throws OnapCommandHttpInvalidResponseBody
1572 * invalid response body exception
1573 * @throws OnapCommandResultMapProcessingFailed
1574 * map processing failed exception
1576 public static Map<String, ArrayList<String>> populateOutputsFromInputParameters(
1577 Map<String, ArrayList<String>> resultMap,
1578 Map<String, OnapCommandParameter> params)
1579 throws OnapCommandException {
1580 Map<String, ArrayList<String>> resultsProcessed = new HashMap<>();
1582 for (Entry<String, ArrayList<String>> entry : resultMap.entrySet()) {
1583 String key = entry.getKey();
1584 resultsProcessed.put(key, new ArrayList<>());
1585 for (String value: entry.getValue()) {
1587 value = replaceLineFromInputParameters(value, params);
1588 } catch(OnapCommandResultEmpty e) {
1591 resultsProcessed.get(key).add(value);
1595 return resultsProcessed;
1599 * Find external schema files.
1601 * @return list ExternalSchema
1602 * @throws OnapCommandDiscoveryFailed
1604 * @throws OnapCommandInvalidSchema
1607 public static List<SchemaInfo> discoverSchemas() throws OnapCommandException {
1608 List<SchemaInfo> extSchemas = new ArrayList<>();
1610 Resource[] res = findResources(SCHEMA_PATH_PATERN);
1611 if (res != null && res.length > 0) {
1612 Map<String, ?> resourceMap;
1614 for (Resource resource : res) {
1616 resourceMap = loadSchema(resource);
1617 } catch (OnapCommandException e) {
1618 LOG.error("Invalid schema " + resource.getURI().toString(), e);
1622 if (resourceMap != null && resourceMap.size() > 0) {
1623 SchemaInfo schema = new SchemaInfo();
1625 schema.setSchemaURI(resource.getURI().toString());
1627 Object obj = resourceMap.get(OPEN_CLI_SCHEMA_VERSION);
1628 schema.setVersion(obj.toString());
1630 if (!schema.getVersion().equalsIgnoreCase(Constants.OPEN_CLI_SCHEMA_VERSION_VALUE_1_0)) {
1631 LOG.info("Unsupported Schema version found " + schema.getSchemaURI());
1635 schema.setSchemaName(resource.getFilename());
1636 schema.setCmdName((String) resourceMap.get(NAME));
1638 Map<String, ?> infoMap = (Map<String, ?>) resourceMap.get(Constants.INFO);
1639 if (infoMap != null && infoMap.get(Constants.INFO_TYPE) != null) {
1640 schema.setType(infoMap.get(Constants.INFO_TYPE).toString());
1643 if (infoMap != null && infoMap.get(Constants.INFO_PRODUCT) != null) {
1644 schema.setProduct(infoMap.get(Constants.INFO_PRODUCT).toString());
1647 schema.setSchemaProfile(identitySchemaProfileType(resourceMap));
1649 extSchemas.add(schema);
1653 } catch (IOException e) {
1654 throw new OnapCommandDiscoveryFailed(SCHEMA_DIRECTORY, e);
1660 private static String identitySchemaProfileType(Map<String, ?> schemaYamlMap) {
1661 if (schemaYamlMap.get(Constants.HTTP) != null) {
1662 return Constants.HTTP_SCHEMA_PROFILE;
1665 return Constants.BASIC_SCHEMA_PROFILE;
1669 * Returns all resources available under certain directory in class-path.
1673 * @return resources found resources
1674 * @throws IOException
1677 public static Resource[] findResources(String pattern) throws IOException {
1678 ClassLoader cl = OnapCommandUtils.class.getClassLoader();
1679 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);
1680 return resolver.getResources("classpath*:" + pattern);
1684 * Returns a resource available under certain directory in class-path.
1688 * @return found resource
1689 * @throws IOException
1692 public static Resource findResource(String fileName, String pattern) throws IOException {
1693 Resource[] resources = findResources(pattern);
1694 if (resources != null && resources.length > 0) {
1695 for (Resource res : resources) {
1696 if (res.getFilename().equals(fileName)) {
1711 * @throws OnapCommandInvalidSchema
1714 public static Map<String, ?> loadSchema(Resource resource) throws OnapCommandInvalidSchema {
1715 Map<String, ?> values = null;
1717 values = (Map<String, ?>) new Yaml().load(resource.getInputStream());
1718 } catch (Exception e) {
1719 throw new OnapCommandInvalidSchema(resource.getFilename(), e);
1725 * Persist the external schema details.
1729 * @throws OnapCommandDiscoveryFailed
1732 public static void persistSchemaInfo(List<SchemaInfo> schemas) throws OnapCommandDiscoveryFailed {
1733 if (schemas != null) {
1735 Resource[] resources = findResources(DATA_DIRECTORY);
1736 if (resources != null && resources.length == 1) {
1737 String path = resources[0].getURI().getPath();
1738 File file = new File(path + File.separator + DISCOVERY_FILE);
1739 ObjectMapper mapper = new ObjectMapper();
1740 mapper.writerWithDefaultPrettyPrinter().writeValue(file, schemas);
1742 } catch (IOException e1) {
1743 throw new OnapCommandDiscoveryFailed(DATA_DIRECTORY,
1744 DISCOVERY_FILE, e1);
1749 public static void persistProfile(List<Param> params, String profileName) throws OnapCommandPersistProfileFailed {
1750 if (params != null) {
1752 Resource[] resources = findResources(DATA_DIRECTORY);
1753 if (resources != null && resources.length == 1) {
1754 String path = resources[0].getURI().getPath();
1755 File file = new File(path + File.separator + profileName + ".json");
1756 ObjectMapper mapper = new ObjectMapper();
1757 mapper.writerWithDefaultPrettyPrinter().writeValue(file, params);
1759 } catch (IOException e1) {
1760 throw new OnapCommandPersistProfileFailed(e1);
1766 * Check if json file discovered or not.
1769 * @throws OnapCommandDiscoveryFailed
1772 public static boolean isAlreadyDiscovered() throws OnapCommandDiscoveryFailed {
1773 Resource resource = null;
1775 resource = findResource(DISCOVERY_FILE,
1776 DATA_PATH_JSON_PATTERN);
1777 if (resource != null) {
1780 } catch (IOException e) {
1781 throw new OnapCommandDiscoveryFailed(DATA_DIRECTORY,
1789 * Load the previous discovered json file.
1792 * @throws OnapCommandInvalidSchema
1794 * @throws OnapCommandDiscoveryFailed
1797 public static List<SchemaInfo> discoverOrLoadSchemas() throws OnapCommandException {
1798 List<SchemaInfo> schemas = new ArrayList<>();
1799 if (OnapCommandConfg.isDiscoverAlways() || !isAlreadyDiscovered()) {
1800 schemas = discoverSchemas();
1801 if (!schemas.isEmpty()) {
1802 persistSchemaInfo(schemas);
1806 Resource resource = findResource(DISCOVERY_FILE,
1807 DATA_PATH_JSON_PATTERN);
1808 if (resource != null) {
1809 File file = new File(resource.getURI().getPath());
1810 ObjectMapper mapper = new ObjectMapper();
1811 SchemaInfo[] list = mapper.readValue(file, SchemaInfo[].class);
1812 schemas.addAll(Arrays.asList(list));
1814 } catch (IOException e) {
1815 throw new OnapCommandDiscoveryFailed(DATA_DIRECTORY,
1823 public static List<Param> loadParamFromCache(String profileName) throws OnapCommandLoadProfileFailed {
1824 List<Param> params = new ArrayList<>();
1827 Resource resource = findResource(profileName + ".json",
1828 DATA_PATH_JSON_PATTERN);
1829 if (resource != null) {
1830 File file = new File(resource.getURI().getPath());
1831 ObjectMapper mapper = new ObjectMapper();
1832 Param[] list = mapper.readValue(file, Param[].class);
1833 params.addAll(Arrays.asList(list));
1835 } catch (IOException e) {
1836 throw new OnapCommandLoadProfileFailed(e);
1843 * Fetch a particular schema details.
1847 * @return ExternalSchema obj
1848 * @throws OnapCommandInvalidSchema
1850 * @throws OnapCommandDiscoveryFailed
1853 public static SchemaInfo getSchemaInfo(String cmd, String version) throws OnapCommandException {
1854 List<SchemaInfo> list = discoverOrLoadSchemas();
1855 SchemaInfo schemaStr = null;
1857 for (SchemaInfo schema : list) {
1858 if (cmd.equals(schema.getCmdName()) && version.equals(schema.getProduct())) {
1868 * Copy the parameters across the commands, mainly used for catalog, login and logout commands
1870 * @throws OnapCommandInvalidParameterValue
1872 public static void copyParamsFrom(OnapHttpCommand from, OnapCommand to) throws OnapCommandInvalidParameterValue {
1873 for (OnapCommandParameter param: to.getParameters()) {
1875 OnapCommandParameter fromParam = from.getParametersMap().get(param.getName());
1877 if (fromParam != null) {
1878 param.setValue(fromParam.getValue());
1879 param.setDefaultValue(fromParam.getDefaultValue());
1880 } else if (param.getName().equalsIgnoreCase(Constants.CATALOG_SERVICE_NAME)) { // for catalog cmd
1881 param.setValue(from.getService().getName());
1882 } else if (param.getName().equalsIgnoreCase(Constants.CATALOG_SERVICE_VERSION)) { // for catalog cmd
1883 param.setValue(from.getService().getVersion());
1889 * Returns the build time from manifest.mf
1891 public static String findLastBuildTime() {
1892 String impBuildDate = "";
1895 String path = OnapCommandUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath();
1896 JarFile jar = new JarFile(path);
1897 Manifest manifest = jar.getManifest();
1900 Attributes attributes = manifest.getMainAttributes();
1902 impBuildDate = attributes.getValue("Build-Time");
1904 catch (IOException e)
1906 //Ignore it as it will never occur
1909 return impBuildDate;