diff options
14 files changed, 223 insertions, 40 deletions
diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommand.java index 5479b51b..8db3ab79 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommand.java @@ -33,6 +33,7 @@ import org.onap.cli.fw.output.OnapCommandResultAttribute; import org.onap.cli.fw.output.OnapCommandResultAttributeScope; import org.onap.cli.fw.output.OnapCommandResultType; import org.onap.cli.fw.schema.OnapCommandSchemaLoader; +import org.onap.cli.fw.schema.OnapCommandSchemaMerger; import org.onap.cli.fw.utils.OnapCommandHelperUtils; import org.onap.cli.fw.utils.OnapCommandUtils; import org.slf4j.Logger; @@ -58,8 +59,21 @@ public abstract class OnapCommand { private OnapCommandResult cmdResult = new OnapCommandResult(); + private List<String> defaultSchemas = new ArrayList<>(); + protected boolean isInitialzied = false; + protected OnapCommand() { + this.addDefaultSchemas(OnapCommandConstants.DEFAULT_PARAMETER_FILE_NAME); + } + + public List<String> getSchemas() throws OnapCommandException { + List<String> schemas = new ArrayList<>(); + schemas.addAll(this.defaultSchemas); + schemas.add(this.getSchemaName()); + return schemas; + } + public String getSchemaVersion() { return OnapCommandConstants.OPEN_CLI_SCHEMA_VERSION_VALUE_1_0; } @@ -116,6 +130,14 @@ public abstract class OnapCommand { this.cmdSchemaName = schemaName; } + protected void addDefaultSchemas(String schema) { + this.defaultSchemas.add(schema); + } + + public List<String> getDefaultSchema() { + return this.defaultSchemas; + } + /** * Initialize this command from command schema and assumes schema is already validated. * @@ -127,11 +149,13 @@ public abstract class OnapCommand { return this.initializeSchema(schema, false); } + public List<String> initializeSchema(String schema, boolean validate) throws OnapCommandException { this.setSchemaName(schema); - List<String> errors = OnapCommandSchemaLoader.loadSchema(this, schema, true, validate); - errors.addAll(this.initializeProfileSchema(validate)); + Map<String, ?> schemaMap = OnapCommandSchemaMerger.mergeSchemas(this); + List<String> errors = OnapCommandSchemaLoader.parseSchema(this, schemaMap, validate); + errors.addAll(this.initializeProfileSchema(schemaMap, validate)); this.isInitialzied = true; return errors; @@ -139,7 +163,7 @@ public abstract class OnapCommand { /** * Any additional profile based such as http schema could be initialized. */ - protected List<String> initializeProfileSchema(boolean validate) throws OnapCommandException { + protected List<String> initializeProfileSchema(Map<String, ?> schemaMap, boolean validate) throws OnapCommandException { return new ArrayList<>(); } diff --git a/framework/src/main/java/org/onap/cli/fw/registrar/OnapCommandRegistrar.java b/framework/src/main/java/org/onap/cli/fw/registrar/OnapCommandRegistrar.java index e9dc288b..19dc3f56 100644 --- a/framework/src/main/java/org/onap/cli/fw/registrar/OnapCommandRegistrar.java +++ b/framework/src/main/java/org/onap/cli/fw/registrar/OnapCommandRegistrar.java @@ -45,6 +45,8 @@ import org.onap.cli.fw.schema.OnapCommandSchemaInfo; import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; import org.onap.cli.fw.utils.OnapCommandHelperUtils; import org.onap.cli.fw.utils.OnapCommandUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** @@ -53,6 +55,9 @@ import org.onap.cli.fw.utils.OnapCommandUtils; * */ public class OnapCommandRegistrar { + + private static Logger LOG = LoggerFactory.getLogger(OnapCommandRegistrar.class); + private Map<String, Class<? extends OnapCommand>> registry = new HashMap<>(); private Map<String, Class<? extends OnapCommand>> registryProfilePlugins = new HashMap<>(); @@ -271,6 +276,7 @@ public class OnapCommandRegistrar { for (OnapCommandSchemaInfo schema : schemas) { if (schema.isIgnore()) { + LOG.info("Ignoring schema " + schema.getSchemaURI()); continue; } @@ -280,7 +286,7 @@ public class OnapCommandRegistrar { } else if (plugins.containsKey(schema.getSchemaProfile())) { this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaProfile())); } else { - throw new OnapUnsupportedSchemaProfile(schema.getSchemaURI()); + LOG.info("Ignoring schema " + schema.getSchemaURI()); } } } diff --git a/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaLoader.java b/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaLoader.java index 0c4af809..bcf93269 100644 --- a/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaLoader.java +++ b/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaLoader.java @@ -33,11 +33,11 @@ import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_SERVICE; import static org.onap.cli.fw.conf.OnapCommandConstants.INFO_TYPE; import static org.onap.cli.fw.conf.OnapCommandConstants.INPUT_PARAMS_LIST; import static org.onap.cli.fw.conf.OnapCommandConstants.INPUT_PARAMS_MANDATORY_LIST; +import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_ATTR; +import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_PARAM; import static org.onap.cli.fw.conf.OnapCommandConstants.IS_INCLUDE; import static org.onap.cli.fw.conf.OnapCommandConstants.IS_OPTIONAL; import static org.onap.cli.fw.conf.OnapCommandConstants.IS_SECURED; -import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_ATTR; -import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_PARAM; import static org.onap.cli.fw.conf.OnapCommandConstants.LONG_OPTION; import static org.onap.cli.fw.conf.OnapCommandConstants.NAME; import static org.onap.cli.fw.conf.OnapCommandConstants.OPEN_CLI_SCHEMA_VERSION; @@ -81,7 +81,6 @@ import org.onap.cli.fw.info.OnapCommandInfo; import org.onap.cli.fw.input.OnapCommandParameter; import org.onap.cli.fw.input.OnapCommandParameterType; import org.onap.cli.fw.output.OnapCommandPrintDirection; -import org.onap.cli.fw.output.OnapCommandResult; import org.onap.cli.fw.output.OnapCommandResultAttribute; import org.onap.cli.fw.output.OnapCommandResultAttributeScope; import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; @@ -272,21 +271,9 @@ public class OnapCommandSchemaLoader { if (parameters != null) { Set<String> names = new HashSet<>(); - //To support overriding of the parameters, if command is already - //having the same named parameters, means same parameter is - //Overridden from included template into current template - Set<String> existingParamNames = cmd.getParametersMap().keySet(); - for (Map<String, String> parameter : parameters) { - boolean isOverriding = false; OnapCommandParameter param = new OnapCommandParameter(); - //Override the parameters from its base such as default parameters list - if (existingParamNames.contains(parameter.getOrDefault(NAME, ""))) { - param = cmd.getParametersMap().get(parameter.getOrDefault(NAME, "")); - isOverriding = true; - } - if (validate) { OnapCommandUtils.validateTags(exceptionList, parameter, OnapCommandConfig.getCommaSeparatedList(INPUT_PARAMS_LIST), OnapCommandConfig.getCommaSeparatedList(INPUT_PARAMS_MANDATORY_LIST), PARAMETERS); @@ -404,11 +391,7 @@ public class OnapCommandSchemaLoader { } } - if ( !isOverriding) { - cmd.getParameters().add(param); - } else { - cmd.getParametersMap().replace(param.getName(), param); - } + cmd.getParameters().add(param); } } break; diff --git a/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaMerger.java b/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaMerger.java new file mode 100644 index 00000000..97ca4c15 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaMerger.java @@ -0,0 +1,146 @@ +/* + * Copyright 2017 Huawei Technologies Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.cli.fw.schema; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.conf.OnapCommandConstants; +import org.onap.cli.fw.error.OnapCommandException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Helps to merge two yaml schemas + * + */ +public class OnapCommandSchemaMerger { + + static Logger LOG = LoggerFactory.getLogger(OnapCommandSchemaMerger.class); + + public static Map<String, ?> mergeSchemas(OnapCommand cmd) throws OnapCommandException { + Map<String, Object> mergedResult = new LinkedHashMap<String, Object>(); + + for (String schema: cmd.getSchemas()) { + Map<String , Object> schemaMap = (Map<String, Object>) OnapCommandSchemaLoader.validateSchemaVersion(schema, cmd.getSchemaVersion()); + mergeYamlMap(mergedResult, schemaMap); + } + + return mergedResult; + + } + + public static void mergeYamlMap(Map<String, Object> mergedResult, Map<String, Object> yamlContents) { + if (yamlContents == null) return; + + for (String key : yamlContents.keySet()) { + + Object yamlValue = yamlContents.get(key); + if (yamlValue == null) { + mergedResult.put(key, yamlValue); + continue; + } + + Object existingValue = mergedResult.get(key); + if (existingValue != null) { + if (yamlValue instanceof Map) { + if (existingValue instanceof Map) { + mergeYamlMap((Map<String, Object>) existingValue, (Map<String, Object>) yamlValue); + } else if (existingValue instanceof String) { + throw new IllegalArgumentException("Cannot merge complex element into a simple element: "+key); + } else { + throw unknownValueType(key, yamlValue); + } + } else if (yamlValue instanceof List) { + mergeYamlLists(mergedResult, key, yamlValue); + + } else if (yamlValue instanceof String + || yamlValue instanceof Boolean + || yamlValue instanceof Double + || yamlValue instanceof Integer) { + mergedResult.put(key, yamlValue); + + } else { + throw unknownValueType(key, yamlValue); + } + + } else { + if (yamlValue instanceof Map + || yamlValue instanceof List + || yamlValue instanceof String + || yamlValue instanceof Boolean + || yamlValue instanceof Integer + || yamlValue instanceof Double) { + mergedResult.put(key, yamlValue); + } else { + throw unknownValueType(key, yamlValue); + } + } + } + } + + private static IllegalArgumentException unknownValueType(String key, Object yamlValue) { + final String msg = "Cannot merge element of unknown type: " + key + ": " + yamlValue.getClass().getName(); + return new IllegalArgumentException(msg); + } + + @SuppressWarnings("unchecked") + private static void mergeYamlLists(Map<String, Object> mergedResult, String key, Object yamlValue) { + if (! (yamlValue instanceof List && mergedResult.get(key) instanceof List)) { + throw new IllegalArgumentException("Cannot merge a list with a non-list: "+key); + } + + List<Object> originalList = (List<Object>) mergedResult.get(key); + + for (Object o: (List<Object>) yamlValue) { + Map<String, Object> oN = (Map) o; + String nameN = (String)oN.getOrDefault(OnapCommandConstants.NAME, null); + + //Name should be existing in the map, otherwise continue as don't know how to compare + if (nameN == null) { + continue; + } + + boolean existing = false; + for (Object e: originalList) { + Map<String, Object> oE = (Map) e; + String nameE = (String)oE.getOrDefault(OnapCommandConstants.NAME, null); + + //Name should be existing in the map, otherwise continue as don't know how to compare + if (nameE == null) { + continue; + } + + if (nameN.equals(nameE)) { + for (Entry<String, Object> oNe : oN.entrySet()) { + oE.put(oNe.getKey(), oNe.getValue()); + } + existing = true; + break; + } + } + + if (!existing) { + originalList.add(o); + } + } + } +} + diff --git a/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandDiscoveryUtils.java b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandDiscoveryUtils.java index 7d305a86..30a7ac62 100644 --- a/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandDiscoveryUtils.java +++ b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandDiscoveryUtils.java @@ -30,9 +30,11 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.ServiceLoader; +import java.util.Map.Entry; import org.onap.cli.fw.cmd.OnapCommand; import org.onap.cli.fw.conf.OnapCommandConfig; diff --git a/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java index 383a5b99..93a34577 100644 --- a/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java +++ b/framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java @@ -336,5 +336,6 @@ public class OnapCommandUtils { } } } + } diff --git a/framework/src/main/resources/open-cli-schema/default_input_parameters.yaml b/framework/src/main/resources/open-cli-schema/default_input_parameters.yaml index 44c71e53..bb35ac26 100644 --- a/framework/src/main/resources/open-cli-schema/default_input_parameters.yaml +++ b/framework/src/main/resources/open-cli-schema/default_input_parameters.yaml @@ -1,10 +1,5 @@ open_cli_schema_version: 1.0 -info: - product: open-cli - service: default-param - ignore: true - parameters: - name: help type: bool diff --git a/framework/src/main/resources/open-cli.properties b/framework/src/main/resources/open-cli.properties index 0e8b2af5..2ae1b146 100644 --- a/framework/src/main/resources/open-cli.properties +++ b/framework/src/main/resources/open-cli.properties @@ -3,7 +3,7 @@ cli.version=1.0 cli.discover_always=false #schema validation -cli.schema.top_level_params_list=open_cli_schema_version,name,description,parameters,results,http,info +cli.schema.top_level_params_list=open_cli_schema_version,name,description,parameters,results,info cli.schema.top_level_mandatory_list=open_cli_schema_version cli.schema.info_params_list=product,service,type,author,ignore diff --git a/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java b/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java index 8153b6db..a33b785c 100644 --- a/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java +++ b/framework/src/test/java/org/onap/cli/fw/schema/ValidateSchemaTest.java @@ -37,6 +37,17 @@ public class ValidateSchemaTest { OnapCommandSchemaLoader.loadSchema(cmd, "fdsfds.yaml", true, true); } + + @Test + public void validateTestMerge() throws OnapCommandException { + + OnapCommand cmd = new OnapCommand() { + @Override + protected void run() throws OnapCommandException {} + }; + cmd.initializeSchema("test-command-to-valdiate-merge.yaml", true); + } + @Test(expected = OnapCommandInvalidSchema.class) public void invalidateTest2() throws OnapCommandException { OnapCommand cmd = new OnapCommand() { diff --git a/framework/src/test/resources/test-command-to-valdiate-merge.yaml b/framework/src/test/resources/test-command-to-valdiate-merge.yaml new file mode 100644 index 00000000..1a381a46 --- /dev/null +++ b/framework/src/test/resources/test-command-to-valdiate-merge.yaml @@ -0,0 +1,15 @@ +open_cli_schema_version: 1.0 + +name: test-command-to-valdiate-merge + +description: cli catalog command to find the base path for service. + +info: + product: open-cli + service: test + type: cmd + author: Kanagaraj Manickam kanagaraj.manickam@huawei.com + +parameters: + - name: help + is_include: false diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/cmd/OnapHttpCommand.java b/profiles/http/src/main/java/org/onap/cli/fw/http/cmd/OnapHttpCommand.java index 12309341..17d9c731 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/cmd/OnapHttpCommand.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/cmd/OnapHttpCommand.java @@ -61,6 +61,10 @@ public class OnapHttpCommand extends OnapCommand { private OnapCommandHttpService oclipService = new OnapCommandHttpService(); + public OnapHttpCommand() { + super.addDefaultSchemas(OnapCommandHttpConstants.DEFAULT_PARAMETER_HTTP_FILE_NAME); + } + public void setInput(HttpInput input) { this.input = input; } @@ -102,8 +106,8 @@ public class OnapHttpCommand extends OnapCommand { } @Override - protected List<String> initializeProfileSchema(boolean validate) throws OnapCommandException { - return OnapCommandSchemaHttpLoader.loadHttpSchema(this, this.getSchemaName(), true, validate); + protected List<String> initializeProfileSchema(Map<String, ?> schemaMap, boolean validate) throws OnapCommandException { + return OnapCommandSchemaHttpLoader.parseHttpSchema(this, schemaMap, validate); } @Override diff --git a/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java b/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java index 08a70782..6dd15884 100644 --- a/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java +++ b/profiles/http/src/main/java/org/onap/cli/fw/http/schema/OnapCommandSchemaHttpLoader.java @@ -87,7 +87,7 @@ public class OnapCommandSchemaHttpLoader { * @throws OnapCommandException * on error */ - static ArrayList<String> parseHttpSchema(OnapHttpCommand cmd, + public static ArrayList<String> parseHttpSchema(OnapHttpCommand cmd, final Map<String, ?> values, boolean validate) throws OnapCommandException { ArrayList<String> errorList = new ArrayList<>(); @@ -98,6 +98,7 @@ public class OnapCommandSchemaHttpLoader { if (validate) { OnapCommandUtils.validateTags(errorList, valMap, OnapCommandConfig.getCommaSeparatedList(OnapCommandHttpConstants.HTTP_SECTIONS), OnapCommandConfig.getCommaSeparatedList(OnapCommandHttpConstants.HTTP_MANDATORY_SECTIONS), OnapCommandHttpConstants.HTTP); + errorList.addAll(validateHttpSchemaSection(values)); } for (Map.Entry<String, ?> entry1 : valMap.entrySet()) { String key1 = entry1.getKey(); diff --git a/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml b/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml index 9029e273..69e82b3b 100644 --- a/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml +++ b/profiles/http/src/main/resources/open-cli-schema/http/default_input_parameters_http.yaml @@ -1,10 +1,5 @@ open_cli_schema_version: 1.0 -info: - product: open-cli - service: default-param - ignore: true - parameters: - name: host-username type: string diff --git a/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java b/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java index d8e26329..6f84c953 100644 --- a/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java +++ b/validate/validation/src/test/java/org/onap/cli/validation/OnapValidationTest.java @@ -53,7 +53,7 @@ public class OnapValidationTest { if (sch.isIgnore()) { continue; } - if (sch.getProduct().equals(version)) { + if (sch.getProduct() != null && sch.getProduct().equals(version)) { System.out.println( "************************* validate '" + sch.getCmdName() + "' *******************************"); OnapCommandRegistrar.getRegistrar().setEnabledProductVersion("open-cli"); @@ -74,7 +74,7 @@ public class OnapValidationTest { if (sch.isIgnore()) { continue; } - if (sch.getProduct().equals(version)) { + if (sch.getProduct() != null && sch.getProduct().equals(version)) { System.out.println("[" + i++ + "] " + sch.getCmdName()); System.out.println("-----------------------------------------------\n\n"); this.handle(new String[] { sch.getCmdName(), "-h"}); |