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;
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;
}
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.
*
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;
/**
* 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<>();
}
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;
/**
*
*/
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<>();
for (OnapCommandSchemaInfo schema : schemas) {
if (schema.isIgnore()) {
+ LOG.info("Ignoring schema " + schema.getSchemaURI());
continue;
}
} 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());
}
}
}
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;
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;
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);
}
}
- if ( !isOverriding) {
- cmd.getParameters().add(param);
- } else {
- cmd.getParametersMap().replace(param.getName(), param);
- }
+ cmd.getParameters().add(param);
}
}
break;
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
+
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;
open_cli_schema_version: 1.0
-info:
- product: open-cli
- service: default-param
- ignore: true
-
parameters:
- name: help
type: bool
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
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() {
--- /dev/null
+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
private OnapCommandHttpService oclipService = new OnapCommandHttpService();
+ public OnapHttpCommand() {
+ super.addDefaultSchemas(OnapCommandHttpConstants.DEFAULT_PARAMETER_HTTP_FILE_NAME);
+ }
+
public void setInput(HttpInput input) {
this.input = input;
}
}
@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
* @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<>();
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();
open_cli_schema_version: 1.0
-info:
- product: open-cli
- service: default-param
- ignore: true
-
parameters:
- name: host-username
type: string
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");
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"});