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.schema;
19 import static org.onap.cli.fw.conf.OnapCommandConstants.ATTRIBUTES;
20 import static org.onap.cli.fw.conf.OnapCommandConstants.BOOLEAN_TRUE;
21 import static org.onap.cli.fw.conf.OnapCommandConstants.COMMAND_TYPE_VALUES;
22 import static org.onap.cli.fw.conf.OnapCommandConstants.DEFAULT_PARAMETER_FILE_NAME;
23 import static org.onap.cli.fw.conf.OnapCommandConstants.DEFAULT_VALUE;
24 import static org.onap.cli.fw.conf.OnapCommandConstants.DESCRIPTION;
25 import static org.onap.cli.fw.conf.OnapCommandConstants.DIRECTION;
26 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO;
27 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_AUTHOR;
28 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_IGNORE;
29 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_PARAMS_LIST;
30 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_PARAMS_MANDATORY_LIST;
31 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_PRODUCT;
32 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_SERVICE;
33 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_STATE;
34 import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_TYPE;
35 import static org.onap.cli.fw.conf.OnapCommandConstants.INPUT_PARAMS_LIST;
36 import static org.onap.cli.fw.conf.OnapCommandConstants.INPUT_PARAMS_MANDATORY_LIST;
37 import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_ATTR;
38 import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_PARAM;
39 import static org.onap.cli.fw.conf.OnapCommandConstants.IS_INCLUDE;
40 import static org.onap.cli.fw.conf.OnapCommandConstants.IS_OPTIONAL;
41 import static org.onap.cli.fw.conf.OnapCommandConstants.IS_SECURED;
42 import static org.onap.cli.fw.conf.OnapCommandConstants.LONG_OPTION;
43 import static org.onap.cli.fw.conf.OnapCommandConstants.NAME;
44 import static org.onap.cli.fw.conf.OnapCommandConstants.OPEN_CLI_SCHEMA_VERSION;
45 import static org.onap.cli.fw.conf.OnapCommandConstants.PARAMETERS;
46 import static org.onap.cli.fw.conf.OnapCommandConstants.RESULTS;
47 import static org.onap.cli.fw.conf.OnapCommandConstants.RESULT_PARAMS_LIST;
48 import static org.onap.cli.fw.conf.OnapCommandConstants.RESULT_PARAMS_MANDATORY_LIST;
49 import static org.onap.cli.fw.conf.OnapCommandConstants.SCHEMA_FILE_NOT_EXIST;
50 import static org.onap.cli.fw.conf.OnapCommandConstants.SCHEMA_FILE_WRONG_EXTN;
51 import static org.onap.cli.fw.conf.OnapCommandConstants.SCHEMA_PATH_PATERN;
52 import static org.onap.cli.fw.conf.OnapCommandConstants.SCOPE;
53 import static org.onap.cli.fw.conf.OnapCommandConstants.SHORT_OPTION;
54 import static org.onap.cli.fw.conf.OnapCommandConstants.TOP_LEVEL_MANDATORY_LIST;
55 import static org.onap.cli.fw.conf.OnapCommandConstants.TOP_LEVEL_PARAMS_LIST;
56 import static org.onap.cli.fw.conf.OnapCommandConstants.TYPE;
59 import java.io.FileInputStream;
60 import java.io.FileNotFoundException;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import java.util.ArrayList;
64 import java.util.Arrays;
65 import java.util.HashMap;
66 import java.util.HashSet;
67 import java.util.List;
71 import org.onap.cli.fw.cmd.OnapCommand;
72 import org.onap.cli.fw.cmd.OnapCommandType;
73 import org.onap.cli.fw.conf.OnapCommandConfig;
74 import org.onap.cli.fw.conf.OnapCommandConstants;
75 import org.onap.cli.fw.error.OnapCommandException;
76 import org.onap.cli.fw.error.OnapCommandInvalidSchema;
77 import org.onap.cli.fw.error.OnapCommandInvalidSchemaVersion;
78 import org.onap.cli.fw.error.OnapCommandParameterNameConflict;
79 import org.onap.cli.fw.error.OnapCommandParameterOptionConflict;
80 import org.onap.cli.fw.error.OnapCommandSchemaNotFound;
81 import org.onap.cli.fw.info.OnapCommandInfo;
82 import org.onap.cli.fw.info.OnapCommandState;
83 import org.onap.cli.fw.input.OnapCommandParameter;
84 import org.onap.cli.fw.input.OnapCommandParameterType;
85 import org.onap.cli.fw.output.OnapCommandPrintDirection;
86 import org.onap.cli.fw.output.OnapCommandResultAttribute;
87 import org.onap.cli.fw.output.OnapCommandResultAttributeScope;
88 import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils;
89 import org.onap.cli.fw.utils.OnapCommandUtils;
90 import org.springframework.core.io.Resource;
92 public class OnapCommandSchemaLoader {
94 private OnapCommandSchemaLoader() {
95 // As per the java guidelines
99 * Validates schema version.
101 * @param schemaName schema name
102 * @param version schema version
104 * @throws OnapCommandInvalidSchemaVersion invalid schema version exception
105 * @throws OnapCommandInvalidSchema invalid schema
106 * @throws OnapCommandSchemaNotFound schema not found
108 public static Map<String, Object> validateSchemaVersion(String schemaName, String version) throws OnapCommandException {
109 Map<String, Object> values = null;
111 InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName);
113 Resource resource = OnapCommandDiscoveryUtils.findResource(schemaName, SCHEMA_PATH_PATERN);
115 if (resource != null) {
116 inputStream = resource.getInputStream();
119 if (inputStream == null) {
120 inputStream = loadSchemaFromFile(schemaName);
123 values = loadSchema(inputStream, schemaName);
124 String schemaVersion = "";
125 if (values.keySet().contains(OPEN_CLI_SCHEMA_VERSION)) {
126 Object obj = values.get(OPEN_CLI_SCHEMA_VERSION);
127 schemaVersion = obj.toString();
130 if (!version.equals(schemaVersion)) {
131 throw new OnapCommandInvalidSchemaVersion(schemaVersion);
134 } catch (IOException e) {
135 throw new OnapCommandSchemaNotFound(schemaName, e);
141 * Retrieve OnapCommand from schema.
143 * @param cmd OnapCommand
144 * @param schemaName schema name
145 * @param includeDefault include if default
146 * @param validateSchema flag to represent validation
147 * @throws OnapCommandException on error
149 public static List<String> loadSchema(OnapCommand cmd, String schemaName, boolean includeDefault,
150 boolean validateSchema) throws OnapCommandException {
152 List<String> errors = new ArrayList<>();
153 if (includeDefault) {
154 Map<String, ?> defaultParameterMap = validateSchemaVersion(DEFAULT_PARAMETER_FILE_NAME, cmd.getSchemaVersion());
155 //mrkanag default_parameter is supported only for parameters.
156 if (defaultParameterMap.containsKey(INFO)) {
157 defaultParameterMap.remove(OnapCommandConstants.INFO);
160 errors.addAll(parseSchema(cmd, defaultParameterMap, validateSchema));
163 Map<String, Object> commandYamlMap = validateSchemaVersion(schemaName, cmd.getSchemaVersion());
165 errors.addAll(parseSchema(cmd, commandYamlMap, validateSchema));
168 } catch (OnapCommandException e) {
170 } catch (Exception e) {
171 throw new OnapCommandInvalidSchema(schemaName, e);
175 public static List<String> parseSchema(OnapCommand cmd,
176 final Map<String, ?> values,
177 boolean validate) throws OnapCommandException {
179 List<String> exceptionList = new ArrayList<>();
180 List<String> shortOptions = new ArrayList<>();
181 List<String> longOptions = new ArrayList<>();
184 OnapCommandUtils.validateTags(exceptionList, (Map<String, Object>) values, OnapCommandConfig.getCommaSeparatedList(TOP_LEVEL_PARAMS_LIST),
185 OnapCommandConfig.getCommaSeparatedList(TOP_LEVEL_MANDATORY_LIST), "root level");
189 List<String> sections = Arrays.asList(NAME, DESCRIPTION, INFO, PARAMETERS, RESULTS);
191 for (String key : sections) {
195 Object val = values.get(key);
197 cmd.setName(val.toString());
202 Object description = values.get(key);
203 if (description != null) {
204 cmd.setDescription(description.toString());
209 Map<String, String> infoMap = (Map<String, String>) values.get(key);
211 if (infoMap != null) {
213 OnapCommandUtils.validateTags(exceptionList, (Map<String, Object>) values.get(key),
214 OnapCommandConfig.getCommaSeparatedList(INFO_PARAMS_LIST),
215 OnapCommandConfig.getCommaSeparatedList(INFO_PARAMS_MANDATORY_LIST), INFO);
217 HashMap<String, String> validationMap = new HashMap<>();
218 validationMap.put(INFO_TYPE, COMMAND_TYPE_VALUES);
220 for (Map.Entry<String,String> entry : validationMap.entrySet()) {
221 String secKey=entry.getKey();
222 if (infoMap.containsKey(secKey)) {
223 String value = infoMap.get(secKey);
225 exceptionList.add("Attribute '" + secKey + "' under '" + INFO + "' is empty");
227 if (!OnapCommandConfig.getCommaSeparatedList(validationMap.get(secKey)).contains(value)) {
228 exceptionList.add("Attribute '" + secKey + "' contains invalid value. Valide values are "
229 + OnapCommandConfig.getCommaSeparatedList(validationMap.get(key))); //
236 OnapCommandInfo info = new OnapCommandInfo();
238 for (Map.Entry<String, String> entry1 : infoMap.entrySet()) {
239 String key1 = entry1.getKey();
243 info.setProduct(infoMap.get(key1));
247 info.setService(infoMap.get(key1));
251 Object obj = infoMap.get(key1);
252 info.setCommandType(OnapCommandType.get(obj.toString()));
256 Object state = infoMap.get(key1);
257 info.setState(OnapCommandState.get(state.toString()));
261 Object mode = infoMap.get(key1);
262 info.setAuthor(mode.toString());
266 Object ignore = infoMap.get(key1);
267 info.setIgnore(ignore.toString().equalsIgnoreCase(OnapCommandConstants.BOOLEAN_TRUE));
269 default : // Do nothing
279 List<Map<String, String>> parameters = (List) values.get(key);
281 if (parameters != null) {
282 Set<String> names = new HashSet<>();
284 for (Map<String, String> parameter : parameters) {
285 OnapCommandParameter param = new OnapCommandParameter();
288 OnapCommandUtils.validateTags(exceptionList, parameter, OnapCommandConfig.getCommaSeparatedList(INPUT_PARAMS_LIST),
289 OnapCommandConfig.getCommaSeparatedList(INPUT_PARAMS_MANDATORY_LIST), PARAMETERS);
292 for (Map.Entry<String, String> entry1 : parameter.entrySet()) {
293 String key2 = entry1.getKey();
297 if (names.contains(parameter.get(key2))) {
298 OnapCommandUtils.throwOrCollect(new OnapCommandParameterNameConflict(parameter.get(key2)), exceptionList, validate);
300 names.add(parameter.get(key2));
303 param.setName(parameter.get(key2));
307 param.setDescription(parameter.get(key2));
311 if (shortOptions.contains(parameter.get(key2))) {
312 OnapCommandUtils.throwOrCollect(new OnapCommandParameterOptionConflict(
314 parameter.get(key2)), exceptionList, validate);
316 shortOptions.add(parameter.get(key2));
317 param.setShortOption(parameter.get(key2));
321 if (longOptions.contains(parameter.get(key2))) {
322 OnapCommandUtils.throwOrCollect(new OnapCommandParameterOptionConflict(
324 parameter.get(key2)), exceptionList, validate);
326 longOptions.add(parameter.get(key2));
327 param.setLongOption(parameter.get(key2));
331 Object obj = parameter.get(key2);
332 param.setRawDefaultValue(obj.toString());
337 param.setParameterType(OnapCommandParameterType.get(parameter.get(key2)));
338 } catch (OnapCommandException ex) {
339 OnapCommandUtils.throwOrCollect(ex, exceptionList, validate);
344 if (validate && !OnapCommandUtils.validateBoolean(String.valueOf(parameter.get(key2)))) {
345 exceptionList.add(OnapCommandUtils.invalidBooleanValueMessage(parameter.get(NAME),
346 IS_OPTIONAL, String.valueOf(parameter.get(key2))));
349 param.setOptional(BOOLEAN_TRUE.equalsIgnoreCase(String.valueOf(parameter.get(key2))));
353 if (validate && !OnapCommandUtils.validateBoolean(String.valueOf(parameter.get(key2)))) {
354 exceptionList.add(OnapCommandUtils.invalidBooleanValueMessage(parameter.get(NAME),
355 IS_SECURED, String.valueOf(parameter.get(key2))));
358 param.setSecured(BOOLEAN_TRUE.equalsIgnoreCase(String.valueOf(parameter.get(key2))));
362 if (validate && !OnapCommandUtils.validateBoolean(String.valueOf(parameter.get(key2)))) {
363 exceptionList.add(OnapCommandUtils.invalidBooleanValueMessage(parameter.get(NAME),
364 IS_INCLUDE, String.valueOf(parameter.get(key2))));
367 param.setInclude(BOOLEAN_TRUE.equalsIgnoreCase(String.valueOf(parameter.get(key2))));
370 case IS_DEFAULT_PARAM:
371 if (validate && !OnapCommandUtils.validateBoolean(String.valueOf(parameter.get(key2)))) {
372 exceptionList.add(OnapCommandUtils.invalidBooleanValueMessage(parameter.get(NAME),
373 IS_DEFAULT_PARAM, String.valueOf(parameter.get(key2))));
376 param.setDefaultParam(BOOLEAN_TRUE.equalsIgnoreCase(String.valueOf(parameter.get(key2))));
378 default : // Do nothing
382 cmd.getParameters().add(param);
388 Map<String, ?> valueMap = (Map<String, ?>) values.get(key);
389 if (valueMap != null) {
390 for (Map.Entry<String, ?> entry1 : valueMap.entrySet()) {
391 String key3 = entry1.getKey();
396 cmd.getResult().setPrintDirection(OnapCommandPrintDirection.get((String) valueMap.get(key3)));
397 } catch (OnapCommandException ex) {
398 OnapCommandUtils.throwOrCollect(ex, exceptionList, validate);
403 List<Map<String, String>> attrs = (ArrayList) valueMap.get(key3);
405 for (Map<String, String> map : attrs) {
406 OnapCommandResultAttribute attr = new OnapCommandResultAttribute();
408 OnapCommandUtils.validateTags(exceptionList, map, OnapCommandConfig.getCommaSeparatedList(RESULT_PARAMS_LIST),
409 OnapCommandConfig.getCommaSeparatedList(RESULT_PARAMS_MANDATORY_LIST), ATTRIBUTES);
412 Set<String> resultParamNames = new HashSet<>();
414 for (Map.Entry<String, String> entry4 : map.entrySet()) {
415 String key4 = entry4.getKey();
419 if (resultParamNames.contains(map.get(key4))) {
420 exceptionList.add("Attribute name='" + map.get(key4) + "' under '"
421 + ATTRIBUTES + ":' is already used, Take different one.");
424 attr.setName(map.get(key4));
425 resultParamNames.add(map.get(key4));
430 attr.setDescription(map.get(key4));
435 attr.setScope(OnapCommandResultAttributeScope.get(map.get(key4)));
436 } catch (OnapCommandException ex) {
437 OnapCommandUtils.throwOrCollect(ex, exceptionList, validate);
443 attr.setType(OnapCommandParameterType.get(map.get(key4)));
444 } catch (OnapCommandException ex) {
445 OnapCommandUtils.throwOrCollect(ex, exceptionList, validate);
450 Object obj = map.get(key4);
451 attr.setDefaultValue(obj.toString());
455 if (validate && !OnapCommandUtils.validateBoolean(String.valueOf(map.get(key4)))) {
456 exceptionList.add(OnapCommandUtils.invalidBooleanValueMessage(ATTRIBUTES,
457 IS_SECURED, String.valueOf(map.get(key4))));
459 attr.setSecured(BOOLEAN_TRUE.equals(String.valueOf(map.get(key4))));
462 case IS_DEFAULT_ATTR:
463 if (validate && !OnapCommandUtils.validateBoolean(String.valueOf(map.get(key4)))) {
464 exceptionList.add(OnapCommandUtils.invalidBooleanValueMessage(ATTRIBUTES,
465 IS_DEFAULT_ATTR, String.valueOf(map.get(key4))));
467 attr.setDefaultAttr(BOOLEAN_TRUE.equals(String.valueOf(map.get(key4))));
469 default : // Do nothing
473 cmd.getResult().getRecords().add(attr);
476 default : // Do nothing
481 default : // Do nothing
485 return exceptionList;
488 public static InputStream loadSchemaFromFile(String schemaLocation) throws OnapCommandInvalidSchema {
489 File schemaFile = new File(schemaLocation);
491 FileInputStream inputFileStream = new FileInputStream(schemaFile); // NOSONAR
492 if (!schemaFile.isFile()) {
493 throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_NOT_EXIST);
496 if (!schemaFile.getName().endsWith(".yaml")) {
497 throw new OnapCommandInvalidSchema(schemaFile.getName(), SCHEMA_FILE_WRONG_EXTN);
499 return inputFileStream;
500 }catch (FileNotFoundException e) {
501 throw new OnapCommandInvalidSchema(schemaFile.getName(), e);
511 * @throws OnapCommandInvalidSchema
514 public static Map<String, Object> loadSchema(InputStream stream, String schemaName) throws OnapCommandInvalidSchema { //NOSONAR
515 return OnapCommandDiscoveryUtils.loadYaml(stream);