diff options
author | 2019-02-28 10:02:37 +0000 | |
---|---|---|
committer | 2019-02-28 10:02:37 +0000 | |
commit | adfc77d913cb8e54750d8fe167fde2bb4ffc57ef (patch) | |
tree | 91d238a78898420633991803b66db792b7d1a254 /framework/src/main/java/org/onap | |
parent | c5bd732f37c9b8b06c802cfe38dcf9ec64228341 (diff) | |
parent | 73747e103b5ce41abe253af5d9b55994375eaa86 (diff) |
Merge changes I60285973,I612ecfe2
* changes:
CVC: Add support for execution, schema, product
CMD: Enhace command profile with additional macros
Diffstat (limited to 'framework/src/main/java/org/onap')
33 files changed, 2113 insertions, 198 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 f9066efa..dbd24630 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 @@ -17,6 +17,7 @@ package org.onap.cli.fw.cmd; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -28,17 +29,24 @@ import org.onap.cli.fw.error.OnapCommandHelpFailed; import org.onap.cli.fw.error.OnapCommandNotInitialized; 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.OnapCommandResult; 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.OnapCommandSchemaInfo; import org.onap.cli.fw.schema.OnapCommandSchemaLoader; import org.onap.cli.fw.schema.OnapCommandSchemaMerger; +import org.onap.cli.fw.store.OnapCommandArtifactStore; +import org.onap.cli.fw.store.OnapCommandArtifactStore.Artifact; import org.onap.cli.fw.utils.OnapCommandHelperUtils; import org.onap.cli.fw.utils.OnapCommandUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + /** * Oclip Command. * @@ -63,6 +71,16 @@ public abstract class OnapCommand { protected boolean isInitialzied = false; + private boolean isRpc = false; + + public boolean isRpc() { + return isRpc; + } + + public void setRpc(boolean isRpc) { + this.isRpc = isRpc; + } + protected OnapCommand() { this.addDefaultSchemas(OnapCommandConstants.DEFAULT_PARAMETER_FILE_NAME); } @@ -138,6 +156,33 @@ public abstract class OnapCommand { return this.defaultSchemas; } + public List<String> getArgs() { + List <String> args = new ArrayList<>(); + for (OnapCommandParameter param: this.getParameters()) { + args.add(OnapCommandParameter.printLongOption(param.getName())); + args.add(param.getValue().toString()); + } + + return args; + } + + public String getArgsJson(boolean ignoreDefaults) { + Map <String, String> args = new HashMap<>(); + + for (OnapCommandParameter param: this.getParameters()) { + if (ignoreDefaults && param.isDefaultParam()) + continue; + + args.put(param.getName(), param.getValue().toString()); + } + + try { + return new ObjectMapper().writeValueAsString(args); + } catch (JsonProcessingException e) { + return "{}"; + } + } + /** * Initialize this command from command schema and assumes schema is already validated. * @@ -149,6 +194,10 @@ public abstract class OnapCommand { return this.initializeSchema(schema, false); } + public List<String> initializeSchema(OnapCommandSchemaInfo schema) throws OnapCommandException { + return this.initializeSchema(schema.getSchemaName(), false); + } + public List<String> initializeSchema(String schema, boolean validate) throws OnapCommandException { this.setSchemaName(schema); @@ -216,6 +265,19 @@ public abstract class OnapCommand { return this.cmdResult; } + //set the artifact content path. + for (OnapCommandParameter param: this.getParameters()) { + if (!param.getParameterType().equals(OnapCommandParameterType.BINARY)) + continue; + + if (param.getValue().toString().matches("artifact://*:*")) { + String categoryAndName = param.getValue().toString().replaceFirst("artifact://", ""); + String[] categoryAndNameTokens = categoryAndName.split(":"); + Artifact a = OnapCommandArtifactStore.getStore().getArtifact(categoryAndNameTokens[1], categoryAndNameTokens[0]); + param.setValue(a.getPath()); + } + } + // validate this.validate(); diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommandType.java b/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommandType.java index e874a14e..34ccc760 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommandType.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/OnapCommandType.java @@ -27,7 +27,8 @@ public enum OnapCommandType { AUTH, CATALOG, - CMD; + CMD, + SYSTEM; /** * Get parameter type. @@ -45,6 +46,8 @@ public enum OnapCommandType { return CATALOG; } else if (CMD.name().equalsIgnoreCase(name)) { return CMD; + } else if (SYSTEM.name().equalsIgnoreCase(name)) { + return SYSTEM; } else { throw new OnapCommandInvalidCommandType(name); } diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/dummy/OnapCommandDummy.java b/framework/src/main/java/org/onap/cli/fw/cmd/dummy/OnapCommandDummy.java new file mode 100644 index 00000000..aed9224a --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/dummy/OnapCommandDummy.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019 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.cmd.dummy; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.schema.OnapCommandSchema; + +/** + * List available schemas. + * + */ +@OnapCommandSchema(type = "dummy") +public class OnapCommandDummy extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionListCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionListCommand.java new file mode 100644 index 00000000..5470472c --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionListCommand.java @@ -0,0 +1,64 @@ +/* + * Copyright 2019 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.cmd.execution; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.store.OnapCommandExecutionStore; + +/** + * List available schemas. + * + */ +@OnapCommandSchema(schema = "execution-list.yaml") +public class OnapCommandExceutionListCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + Map<String, String> map = new HashMap<>(); + for (String input: Arrays.asList(new String []{"request-id", "product", "service", "command", "profile", "start-time", "end-time"})) { + String value = getParametersMap().get(input).getValue().toString(); + if (value != null && !value.isEmpty()) { + map.put(input, value); + } + } + + List<OnapCommandExecutionStore.Execution> executions = OnapCommandExecutionStore.getStore().listExecutions(map); + + for (OnapCommandExecutionStore.Execution e : executions) { + this.getResult().getRecordsMap().get("product").getValues().add(e.getProduct()); + this.getResult().getRecordsMap().get("service").getValues().add(e.getService()); + this.getResult().getRecordsMap().get("command").getValues().add(e.getCommand()); + this.getResult().getRecordsMap().get("profile").getValues().add(e.getProfile()); + this.getResult().getRecordsMap().get("execution-id").getValues().add(e.getId()); + this.getResult().getRecordsMap().get("request-id").getValues().add(e.getRequestId()); + this.getResult().getRecordsMap().get("status").getValues().add(e.getStatus()); + this.getResult().getRecordsMap().get("start-time").getValues().add(e.getStartTime()); + this.getResult().getRecordsMap().get("end-time").getValues().add(e.getEndTime()); + this.getResult().getRecordsMap().get("input").getValues().add(e.getInput()); + this.getResult().getRecordsMap().get("output").getValues().add(e.getOutput()); + } + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionShowCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionShowCommand.java new file mode 100644 index 00000000..8d29c03f --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionShowCommand.java @@ -0,0 +1,86 @@ +/* + * Copyright 2019 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.cmd.execution; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandExecutionNotFound; +import org.onap.cli.fw.output.OnapCommandResultType; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.store.OnapCommandExecutionStore; +import org.onap.cli.fw.store.OnapCommandExecutionStore.Execution; + +/** + * List available schemas. + * + */ +@OnapCommandSchema(schema = "execution-show.yaml") +public class OnapCommandExceutionShowCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + String requestId = getParametersMap().get("execution-id").getValue().toString(); + + OnapCommandExecutionStore.Execution e= OnapCommandExecutionStore.getStore().getExecution(requestId); + + this.getResult().getRecordsMap().get("product").getValues().add(e.getProduct()); + this.getResult().getRecordsMap().get("service").getValues().add(e.getService()); + this.getResult().getRecordsMap().get("command").getValues().add(e.getCommand()); + this.getResult().getRecordsMap().get("profile").getValues().add(e.getProfile()); + this.getResult().getRecordsMap().get("input").getValues().add(String.valueOf(e.getInput())); + this.getResult().getRecordsMap().get("request-id").getValues().add(e.getId()); + this.getResult().getRecordsMap().get("status").getValues().add(e.getStatus()); + this.getResult().getRecordsMap().get("start-time").getValues().add(e.getStartTime()); + this.getResult().getRecordsMap().get("end-time").getValues().add(e.getEndTime()); + this.getResult().getRecordsMap().get("output").getValues().add(String.valueOf(e.getOutput())); + + if (this.getResult().getType().equals(OnapCommandResultType.TEXT)) { + List<Execution> list = new ArrayList<>(); + list.add(e); + this.getResult().setOutput(this.printExecution(list)); + } + } + + + public String printExecution(List<OnapCommandExecutionStore.Execution> executions) throws OnapCommandExecutionNotFound { + String msg = "<oclip-execution-list>\n"; + for (OnapCommandExecutionStore.Execution e: executions) { + msg += "<oclip-execution>\n"; + if ( e.getId() != null) + msg += "<oclip-request-id>\n" + e.getId() + "</oclip-request-id>\n"; + msg += "<oclip-request-product>\n" + e.getProduct() + "</oclip-request-product>\n"; + msg += "<oclip-request-service>\n" + e.getService() + "</oclip-request-service>\n"; + msg += "<oclip-request-command>\n" + e.getCommand() + "</oclip-request-command>\n"; + if ( e.getProfile() != null) + msg += "<oclip-request-profile>\n" + e.getProfile() + "</oclip-request-profile>\n"; + msg += "<oclip-request-input>\n" + e.getInput() + "</oclip-request-input>\n"; + if ( e.getOutput() != null) + msg += "<oclip-request-output>\n" + e.getOutput() + "</oclip-request-output>\n"; + msg += "<oclip-request-start-time>\n" + e.getStartTime() + "</oclip-request-start-time>\n"; + msg += "<oclip-request-end-time>\n" + e.getEndTime() + "</oclip-request-end-time>\n"; + msg += "<oclip-request-status>\n" + e.getStatus() + "</oclip-request-status>\n"; + msg += "</oclip-execution>"; + } + msg += "</oclip-execution-list>"; + + return msg; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/product/OnapProductsListCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/product/OnapProductsListCommand.java new file mode 100644 index 00000000..d0788c16 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/product/OnapProductsListCommand.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018 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.cmd.product; + +import java.io.InputStream; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.conf.OnapCommandConstants; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.schema.OnapCommandSchemaInfo; +import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; +import org.yaml.snakeyaml.Yaml; + +/** + * Product list. + * + */ +@OnapCommandSchema(schema = "product-list.yaml") +public class OnapProductsListCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(false); + + Set<String> rslt = new HashSet<>(); + + for (OnapCommandSchemaInfo schema : schemas) { + if (schema.isIgnore()) { + continue; + } + + rslt.add(schema.getProduct()); + } + + for (String product : rslt) { + this.getResult().getRecordsMap().get("product").getValues().add(product); + + InputStream stream = this.getClass().getResourceAsStream("/" + OnapCommandConstants.SCHEMA_DIRECTORY + + "/" + product + OnapCommandConstants.PRODUCT_REGISTRY_YAML); + + if (stream != null) { + Map<String, ?> map = (Map<String, ?>) new Yaml().load(stream); + Map<String, String> productMap = (Map<String, String>) map.get("product"); + String description = (String) productMap.get(OnapCommandConstants.DESCRIPTION); + this.getResult().getRecordsMap().get("description").getValues().add(description.trim()); + } else { + this.getResult().getRecordsMap().get("description").getValues().add(""); + } + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/product/OnapServiceListCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/product/OnapServiceListCommand.java new file mode 100644 index 00000000..8cbfa36c --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/product/OnapServiceListCommand.java @@ -0,0 +1,81 @@ +/* + * Copyright 2018 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.cmd.product; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.conf.OnapCommandConstants; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.schema.OnapCommandSchemaInfo; +import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; +import org.yaml.snakeyaml.Yaml; + +/** + * Service list. + * + */ +@OnapCommandSchema(schema = "service-list.yaml") +public class OnapServiceListCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + String product = getParametersMap().get("product").getValue().toString(); + + List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(false); + Map<String, Set<String>> rslt = new HashMap<>(); + + for (OnapCommandSchemaInfo schema : schemas) { + if (schema.isIgnore()) { + continue; + } + + if (!rslt.containsKey(schema.getProduct())) { + rslt.put(schema.getProduct(), new HashSet<String>()); + } + rslt.get(schema.getProduct()).add(schema.getService()); + } + + InputStream stream = this.getClass().getResourceAsStream("/" +OnapCommandConstants.SCHEMA_DIRECTORY + + "/" + product + OnapCommandConstants.PRODUCT_REGISTRY_YAML); + + Map<String, String> serviceDescs = new HashMap<>(); + if (stream != null) { + Map<String, ?> map = (Map<String, ?>) new Yaml().load(stream); + if (map.containsKey("services")) { + List<Map<String, String>> services = (List) map.get("services"); + + for (Map<String, String> service: services ) { + serviceDescs.put(service.get("name"), service.get("description")); + } + } + } + + for (String service : rslt.get(product)) { + this.getResult().getRecordsMap().get("service").getValues().add(service); + this.getResult().getRecordsMap().get("description").getValues().add( + serviceDescs.containsKey(service) ? serviceDescs.get(service) : ""); + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaListCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaListCommand.java index bbd350b7..ef22e4af 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaListCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaListCommand.java @@ -14,17 +14,18 @@ * limitations under the License. */ -package org.onap.cli.fw.cmd; +package org.onap.cli.fw.cmd.schema; import java.util.List; +import org.onap.cli.fw.cmd.OnapCommand; import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.schema.OnapCommandSchema; import org.onap.cli.fw.schema.OnapCommandSchemaInfo; import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; /** - * Refresh external schema. + * List available schemas. * */ @OnapCommandSchema(schema = "schema-list.yaml") @@ -34,21 +35,29 @@ public class OnapSchemaListCommand extends OnapCommand { protected void run() throws OnapCommandException { String product = getParametersMap().get("product").getValue().toString(); + String service = getParametersMap().get("service").getValue().toString(); List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(true); - int i = 0; for (OnapCommandSchemaInfo schema : schemas) { if (schema.isIgnore()) { continue; } if (schema.getProduct().equalsIgnoreCase(product)) { - i++; - - this.getResult().getRecordsMap().get("sr.no").getValues().add(String.valueOf(i)); + if (service.length() > 0 && !service.equalsIgnoreCase(schema.getService())) { + continue; + } this.getResult().getRecordsMap().get("command").getValues().add(schema.getCmdName()); this.getResult().getRecordsMap().get("schema").getValues().add(schema.getSchemaName()); + this.getResult().getRecordsMap().get("service").getValues().add(schema.getService()); this.getResult().getRecordsMap().get("ocs-version").getValues().add(schema.getVersion()); + this.getResult().getRecordsMap().get("enabled").getValues().add("" + !Boolean.parseBoolean(schema.getIgnore())); + + String rpc = ""; + if (schema.isRpc()) { + rpc = schema.getRpcHost() + ":" + schema.getRpcPort(); + } + this.getResult().getRecordsMap().get("rpc").getValues().add(rpc); this.getResult().getRecordsMap().get("type").getValues().add(schema.getSchemaProfile()); } diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaRefreshCommand.java index 2458a141..075a237c 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaRefreshCommand.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.onap.cli.fw.cmd; +package org.onap.cli.fw.cmd.schema; import java.util.List; +import org.onap.cli.fw.cmd.OnapCommand; import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.schema.OnapCommandSchema; import org.onap.cli.fw.schema.OnapCommandSchemaInfo; @@ -34,19 +35,16 @@ public class OnapSchemaRefreshCommand extends OnapCommand { protected void run() throws OnapCommandException { List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(true); - int i = 0; for (OnapCommandSchemaInfo schema : schemas) { - if (schema.isIgnore()) { - continue; - } + //ignore those RPC schemas, schema-list would provide this information + if (schema.isRpc()) continue; - i++; - this.getResult().getRecordsMap().get("sr.no").getValues().add(String.valueOf(i)); this.getResult().getRecordsMap().get("command").getValues().add(schema.getCmdName()); this.getResult().getRecordsMap().get("schema").getValues().add(schema.getSchemaName()); this.getResult().getRecordsMap().get("ocs-version").getValues().add(schema.getVersion()); this.getResult().getRecordsMap().get("product").getValues().add(schema.getProduct()); this.getResult().getRecordsMap().get("type").getValues().add(schema.getSchemaProfile()); + this.getResult().getRecordsMap().get("enabled").getValues().add("" + !Boolean.parseBoolean(schema.getIgnore())); } } diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaShowCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaShowCommand.java new file mode 100644 index 00000000..b7c027f7 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaShowCommand.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018 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.cmd.schema; + +import java.util.HashMap; +import java.util.Map; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.error.OnapCommandNotFound; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.schema.OnapCommandSchemaInfo; +import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; + +import net.minidev.json.JSONObject; + +/** + * Refresh external schema. + * + */ +@OnapCommandSchema(schema = "schema-show.yaml") +public class OnapSchemaShowCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + + String cmd = getParametersMap().get("command").getValue().toString(); + String product = getParametersMap().get("product").getValue().toString(); + String service = getParametersMap().get("service").getValue().toString(); + + OnapCommandSchemaInfo info = OnapCommandDiscoveryUtils.getSchemaInfo(cmd, product); + if (!service.isEmpty() && !info.getService().equalsIgnoreCase(service)) { + throw new OnapCommandNotFound(cmd, product, service); + } + + Map <String, Object> ioMap = new HashMap<String, Object>(); + ioMap.put("name", info.getCmdName()); + ioMap.put("author", info.getAuthor()); + ioMap.put("description", info.getDescription()); + ioMap.put("service", info.getService()); + ioMap.put("inputs", info.getInputs()); + ioMap.put("outputs", info.getOutputs()); + + String schema = new JSONObject(ioMap).toString(); + this.getResult().setOutput(schema); + this.getResult().getRecordsMap().get("schema").getValues().add(schema); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaSwitchCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaSwitchCommand.java new file mode 100644 index 00000000..ea5c8289 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaSwitchCommand.java @@ -0,0 +1,58 @@ +/* + * 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.cmd.schema; + +import java.util.List; +import java.util.Map; + +import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.error.OnapCommandException; +import org.onap.cli.fw.input.OnapCommandParameter; +import org.onap.cli.fw.registrar.OnapCommandRegistrar; +import org.onap.cli.fw.schema.OnapCommandSchema; +import org.onap.cli.fw.schema.OnapCommandSchemaInfo; +import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; + +/** + * Validate schema command. + */ +@OnapCommandSchema(schema = "schema-switch.yaml") +public class OnapSchemaSwitchCommand extends OnapCommand { + + @Override + protected void run() throws OnapCommandException { + Map<String, OnapCommandParameter> paramMap = getParametersMap(); + + OnapCommandParameter nameParam = paramMap.get("name"); + String name = String.valueOf(nameParam.getValue()); + + OnapCommandParameter productParam = paramMap.get("product"); + String product = String.valueOf(productParam.getValue()); + + List<OnapCommandSchemaInfo> list = OnapCommandDiscoveryUtils.loadSchemas(); + for (OnapCommandSchemaInfo info: list) { + if (info.getProduct().equals(product) && info.getCmdName().equals(name)) { + info.setIgnore(!info.isIgnore()); + break; + } + } + + OnapCommandDiscoveryUtils.persistSchemaInfo(list); + OnapCommandRegistrar.getRegistrar().resync(); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaValidateCommand.java index 70148bc5..71267ec3 100644 --- a/framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java +++ b/framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaValidateCommand.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.onap.cli.fw.cmd; +package org.onap.cli.fw.cmd.schema; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.onap.cli.fw.cmd.OnapCommand; import org.onap.cli.fw.conf.OnapCommandConstants; import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.input.OnapCommandParameter; @@ -67,11 +68,7 @@ public class OnapSchemaValidateCommand extends OnapCommand { } List<String> error = cmd.initializeSchema(location, true); - List<String> slNumber = new ArrayList<>(); - for (int i = 1; i <= error.size(); i++) { - slNumber.add(String.valueOf(i)); - } - this.getResult().getRecordsMap().get("sl-no").setValues(slNumber); + this.getResult().getRecordsMap().get("error").setValues(error); } diff --git a/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConstants.java b/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConstants.java index 71c44ac7..7d169d5e 100644 --- a/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConstants.java +++ b/framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConstants.java @@ -41,6 +41,8 @@ public class OnapCommandConstants { public static final String SCHEMA_TYPES_SUPPORTED = "cli.schema.profile.available"; public static final String OPEN_CLI_PRODUCT_NAME = "cli.product_name"; public static final String OPEN_CLI_PLUGIN_PRPS = "cli.schema.profile.confs"; + public static final String OPEN_CLI_DATA_DIR = "cli.data.dir"; + public static final String OPEN_CLI_ARTIFACT_DIR = "cli.artifact.dir"; //schema public static final String OPEN_CLI_SCHEMA_VERSION = "open_cli_schema_version"; @@ -50,6 +52,7 @@ public class OnapCommandConstants { public static final String DESCRIPTION = "description"; //Info + public static final String OPEN_CLI = "open-cli"; public static final String INFO = "info"; public static final String INFO_PRODUCT = "product"; public static final String OPEN_CLI_PRODUCT_IN_USE_ENV_NAME = "OPEN_CLI_PRODUCT_IN_USE"; @@ -81,7 +84,8 @@ public class OnapCommandConstants { public static final String PARAMETER_TYPE_BINARY = "binary"; public static final String PARAMETER_TYPE_MAP = "map"; - public static final String DEFAULT_PARAMETER_FILE_NAME = "default_input_parameters.yaml"; + public static final String DEAFULT_INPUT_PARAMETERS_NAME = "default_input_parameters"; + public static final String DEFAULT_PARAMETER_FILE_NAME = DEAFULT_INPUT_PARAMETERS_NAME + ".yaml"; public static final String DEFAULT_PARAMETER_HELP = "help"; public static final String DEFAULT_PARAMETER_VERSION = "version"; public static final String DEFAULT_PARAMETER_DEBUG = "debug"; @@ -111,16 +115,20 @@ public class OnapCommandConstants { //discovery public static final String SCHEMA_DIRECTORY = "open-cli-schema"; public static final String YAML_PATTERN = "/**/*.yaml"; + public static final String DEFAULT_YAML_PATTERN = "/**/" + DEAFULT_INPUT_PARAMETERS_NAME + "_*.yaml"; public static final String JSON_PATTERN = "/**/*.json"; public static final String SCHEMA_PATH_PATERN = SCHEMA_DIRECTORY + YAML_PATTERN; + public static final String DEFAULT_SCHEMA_PATH_PATERN = SCHEMA_DIRECTORY + DEFAULT_YAML_PATTERN; public static final String DATA_DIRECTORY = "data"; - public static final String DISCOVERY_FILE = "cli-schema.json"; + public static final String DISCOVERY_FILE = "schemas.json"; public static final String DATA_PATH_JSON_PATTERN = DATA_DIRECTORY + JSON_PATTERN; public static final String DATA_PATH_PROFILE_JSON = "-profile.json"; public static final String DATA_PATH_PROFILE_JSON_PATTERN = DATA_DIRECTORY + "/**/*" + DATA_PATH_PROFILE_JSON; public static final String DISCOVER_ALWAYS = "discover_always"; public static final String PARAM_CACHE_FILE_NAME = "default"; + public static final String OCLIP_GLOBAL_PROFILE = "OCLIP-GLOBAL-PROFILE"; + public static final String PRODUCT_REGISTRY_YAML = "-registry.yaml"; //normal public static final String BASIC_SCHEMA_PROFILE = "basic"; public static final String EXCEPTION = "exception"; @@ -141,6 +149,7 @@ public class OnapCommandConstants { public static final String SPL_ENTRY_UUID = "uuid"; public static final String SPL_ENTRY_ENV = "env:"; + public static final String SPL_ENTRY_FILE = "file:"; public static final String VERSION_INFO = "version.info"; public static final String VERSION_INFO_PLACE_HOLDER_VERSION = "__VERSION__"; @@ -167,7 +176,20 @@ public class OnapCommandConstants { public static final String VERIFY_RESULT_FAIL = "fail"; public static final String VERIFY_CONTEXT_PARAM = "context"; - + public static final String RPC_HOST = "rpc-host"; + public static final String RPC_PORT = "rpc-port"; + public static final String RPC_PORT_DEFAULT = "50051"; + public static final String RPC_CMD = "command"; + public static final String RPC_REQID = "request-id"; + public static final String RPC_ARGS = "arg"; + public static final String RPC_PRODUCT = "product"; + public static final String RPC_PROFILE = "profile"; + public static final String RPC_SCHEMAS = "commands"; + public static final String RPC_MODE = "mode"; + public static final String RPC_MODE_RUN_CLI = "cli"; + public static final String RPC_MODE_RUN_RPC = "rpc"; + public static final String RPC_MODE_RSYNC_SRC = "rsync_src"; + public static final String RPC_MODE_RSYNC_DST = "rsync_dst"; public static final String VERIFY_LONG_OPTION = "--verify"; public static final String VERIFY_SHORT_OPTION = "-V"; @@ -178,3 +200,5 @@ public class OnapCommandConstants { } + + diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactAlreadyExist.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactAlreadyExist.java new file mode 100644 index 00000000..6db8042a --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactAlreadyExist.java @@ -0,0 +1,31 @@ +/* + * 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.error; + +/** + * Artifact already exist at given path. + * + */ +public class OnapCommandArtifactAlreadyExist extends OnapCommandException { + private static final long serialVersionUID = 488775545436993019L; + + private static final String ERROR_CODE = "0x21002"; + + public OnapCommandArtifactAlreadyExist(String name, String category) { + super(ERROR_CODE, "Artifact already exists with given name " + name + " under category " + category); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentChecksumNotMatch.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentChecksumNotMatch.java new file mode 100644 index 00000000..823b5b01 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentChecksumNotMatch.java @@ -0,0 +1,31 @@ +/* + * 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.error; + +/** + * Artifact content does not exist at given path. + * + */ +public class OnapCommandArtifactContentChecksumNotMatch extends OnapCommandException { + private static final long serialVersionUID = 488775545436993019L; + + private static final String ERROR_CODE = "0x21004"; + + public OnapCommandArtifactContentChecksumNotMatch(String path) { + super(ERROR_CODE, "Artifact content checksum does not match for " + path); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentNotExist.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentNotExist.java new file mode 100644 index 00000000..a2e4dbd6 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentNotExist.java @@ -0,0 +1,31 @@ +/* + * 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.error; + +/** + * Artifact content does not exist at given path. + * + */ +public class OnapCommandArtifactContentNotExist extends OnapCommandException { + private static final long serialVersionUID = 488775545436993019L; + + private static final String ERROR_CODE = "0x21001"; + + public OnapCommandArtifactContentNotExist(String path) { + super(ERROR_CODE, "Artifact content does not exist at " + path); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactNotFound.java new file mode 100644 index 00000000..05b0eb55 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactNotFound.java @@ -0,0 +1,31 @@ +/* + * 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.error; + +/** + * Artifact does not exist at given path. + * + */ +public class OnapCommandArtifactNotFound extends OnapCommandException { + private static final long serialVersionUID = 488775545436993019L; + + private static final String ERROR_CODE = "0x21003"; + + public OnapCommandArtifactNotFound(String name, String category) { + super(ERROR_CODE, "Artifact does not exists with given name " + name + " under category " + category); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionNotFound.java new file mode 100644 index 00000000..1174946f --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionNotFound.java @@ -0,0 +1,32 @@ +/* + * 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.error; + +/** + * Command execution not found. + * + */ +public class OnapCommandExecutionNotFound extends OnapCommandException { + private static final long serialVersionUID = 488775545436993019L; + + private static final String ERROR_CODE = "0x6009"; + + + public OnapCommandExecutionNotFound(String requestId) { + super(ERROR_CODE, "Execution instance " + requestId + " does not exist"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java index e34136d8..f5aa7b5a 100644 --- a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java @@ -27,4 +27,8 @@ public class OnapCommandNotFound extends OnapCommandException { public OnapCommandNotFound(String cmdName, String version) { super("0x6003", "Command " + cmdName + " is not available for product version " + version); } + + public OnapCommandNotFound(String cmdName, String version, String service) { + super("0x6003", "Command " + cmdName + " is not available for product version " + version + "under service " + service); + } } diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoadProfileFailed.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileLoadFailed.java index 029da5b4..12be9a29 100644 --- a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoadProfileFailed.java +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileLoadFailed.java @@ -20,7 +20,7 @@ package org.onap.cli.fw.error; * Command profile persistence failed. * */ -public class OnapCommandLoadProfileFailed extends OnapCommandException { +public class OnapCommandProfileLoadFailed extends OnapCommandException { private static final long serialVersionUID = 8580121615330415123L; @@ -30,11 +30,11 @@ public class OnapCommandLoadProfileFailed extends OnapCommandException { /** * Command result empty. */ - public OnapCommandLoadProfileFailed(String error) { + public OnapCommandProfileLoadFailed(String error) { super(ERROR_CODE, ERROR_MSG + ", " + error); } - public OnapCommandLoadProfileFailed(Throwable error) { + public OnapCommandProfileLoadFailed(Throwable error) { super(ERROR_CODE, ERROR_MSG, error); } diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileNotFound.java b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileNotFound.java new file mode 100644 index 00000000..efc7b36c --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileNotFound.java @@ -0,0 +1,36 @@ +/* + * Copyright 2019 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.error; + +/** + * Profile does not exist. + * + */ +public class OnapCommandProfileNotFound extends OnapCommandException { + + private static final long serialVersionUID = 8580121615330415123L; + + private static final String ERROR_CODE = "0xc002"; + + private static final String ERROR_MSG = "Profile does not exist"; + /** + * Profile does not exist. + */ + public OnapCommandProfileNotFound(String profile) { + super(ERROR_CODE, "Profile " + profile + " does not exist"); + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/error/OnapSchemaSyncFailure.java b/framework/src/main/java/org/onap/cli/fw/error/OnapSchemaSyncFailure.java new file mode 100644 index 00000000..de90979f --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/error/OnapSchemaSyncFailure.java @@ -0,0 +1,33 @@ +/* + * 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.error; + +/** + * Command schema not found. + * + */ +public class OnapSchemaSyncFailure extends OnapCommandException { + + private static final long serialVersionUID = -3919580583845280200L; + + private static final String ERROR_CODE = "0xb006"; + + public OnapSchemaSyncFailure(String host, String fromHost) { + super(ERROR_CODE, "Schema sync failed on " + host + " from " + fromHost); + } + +} diff --git a/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java index 0b9f9be7..ca0f04e7 100644 --- a/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java +++ b/framework/src/main/java/org/onap/cli/fw/output/OnapCommandResult.java @@ -42,7 +42,7 @@ public class OnapCommandResult { * * if type=TEXT, then it holds the result in text format such as help message */ - private Object output; + private Object output = new String(""); /* * Type requested by user @@ -84,6 +84,13 @@ public class OnapCommandResult { */ private boolean isDebug = false; + /** + * Command passed/failed + * @return + */ + + private boolean passed = true; + public OnapCommandPrintDirection getPrintDirection() { return printDirection; } @@ -192,43 +199,41 @@ public class OnapCommandResult { * exception */ public String print() throws OnapCommandException { - if (this.getRecords().isEmpty()) { - return ""; - } else if (this.getType().equals(OnapCommandResultType.TEXT)) { - return this.getOutput().toString(); + if (this.getType().equals(OnapCommandResultType.TEXT)) { + return this.getOutput().toString(); } OnapCommandPrint print = new OnapCommandPrint(); print.setPrintTitle(this.isIncludeTitle()); - if (this.getPrintDirection().equals(OnapCommandPrintDirection.LANDSCAPE)) { - for (OnapCommandResultAttribute record : this.getScopedRecords()) { - if (record.getType().equals(OnapCommandParameterType.JSON)) { - print.addColumn(record.getName(), OnapCommandUtils.jsonFlatten(record.getValues())); - } else { + print.setDirection(this.printDirection); + + if (!this.getRecords().isEmpty()) { + if (this.getPrintDirection().equals(OnapCommandPrintDirection.LANDSCAPE)) { + for (OnapCommandResultAttribute record : this.getScopedRecords()) { print.addColumn(record.getName(), record.getValues()); } - } - } else { - // Add property column - OnapCommandResultAttribute prp = new OnapCommandResultAttribute(); - prp.setName(OnapCommandConstants.PORTRAINT_COLUMN_NAME_PROPERTY); - prp.setScope(OnapCommandResultAttributeScope.SHORT); - // Add value column - OnapCommandResultAttribute val = new OnapCommandResultAttribute(); - val.setName(OnapCommandConstants.PORTRAINT_COLUMN_NAME_VALUE); - val.setScope(OnapCommandResultAttributeScope.SHORT); - - for (OnapCommandResultAttribute record : this.getScopedRecords()) { - prp.getValues().add(record.getName()); - if (record.getValues().size() == 1) { - val.getValues().add(record.getValues().get(0)); - } else { - val.getValues().add(record.getValues().toString()); + } else { + // Add property column + OnapCommandResultAttribute prp = new OnapCommandResultAttribute(); + prp.setName(OnapCommandConstants.PORTRAINT_COLUMN_NAME_PROPERTY); + prp.setScope(OnapCommandResultAttributeScope.SHORT); + // Add value column + OnapCommandResultAttribute val = new OnapCommandResultAttribute(); + val.setName(OnapCommandConstants.PORTRAINT_COLUMN_NAME_VALUE); + val.setScope(OnapCommandResultAttributeScope.SHORT); + + for (OnapCommandResultAttribute record : this.getScopedRecords()) { + prp.getValues().add(record.getName()); + if (record.getValues().size() == 1) { + val.getValues().add(record.getValues().get(0)); + } else { + val.getValues().add(record.getValues().toString()); + } } - } - print.addColumn(prp.getName(), prp.getValues()); - print.addColumn(val.getName(), val.getValues()); + print.addColumn(prp.getName(), prp.getValues()); + print.addColumn(val.getName(), val.getValues()); + } } if (this.getType().equals(OnapCommandResultType.JSON)) { @@ -255,4 +260,12 @@ public class OnapCommandResult { return recordList; } + + public boolean isPassed() { + return passed; + } + + public void setPassed(boolean passed) { + this.passed = passed; + } } diff --git a/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java b/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java index 614ef5d1..834dea06 100644 --- a/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java +++ b/framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java @@ -37,6 +37,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; +import net.minidev.json.JSONValue; /** * Oclip Command Table print. * @@ -236,28 +237,48 @@ public class OnapCommandPrint { } } + public Object getJsonNodeOrString(String value) { + try { + return (JSONObject) JSONValue.parse(value); + } catch (Exception e) { + return value; + } + } + public String printJson() { List<List<Object>> rows = this.formRows(false); - JSONArray array = new JSONArray(); + if (this.direction.equals(OnapCommandPrintDirection.PORTRAIT)) { + JSONObject result = new JSONObject(); + for (int i=1; i<rows.size(); i++) { + if (rows.get(i).get(1) != null) + result.put(rows.get(i).get(0).toString(), this.getJsonNodeOrString(rows.get(i).get(1).toString())); + } + return result.toJSONString(); + } else { + JSONArray array = new JSONArray(); - //skip first row title - List<Object> titleRow = rows.get(0); + //skip first row title + List<Object> titleRow = rows.get(0); - for (int i=1; i<rows.size(); i++) { - JSONObject rowO = new JSONObject(); + for (int i=1; i<rows.size(); i++) { + JSONObject rowO = new JSONObject(); - for (int j=0; j<titleRow.size(); j++) { - if (rows.get(i).get(j) != null) - rowO.put(titleRow.get(j).toString(), rows.get(i).get(j).toString()); + for (int j=0; j<titleRow.size(); j++) { + if (rows.get(i).get(j) != null) + rowO.put(titleRow.get(j).toString(), this.getJsonNodeOrString(rows.get(i).get(j).toString())); + } + + array.add(rowO); + } + try { + return new ObjectMapper().readTree(array.toJSONString()).toString(); + } catch (IOException e) { + // TODO Auto-generated catch block + return array.toJSONString(); } - array.add(rowO); } - - JSONObject json = new JSONObject(); - json.put(OnapCommandConstants.RESULTS, array); - return json.toJSONString(); } public String printYaml() throws OnapCommandOutputPrintingFailed { 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 07c2dbe1..d7937527 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 @@ -16,18 +16,24 @@ package org.onap.cli.fw.registrar; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + import org.apache.commons.io.IOUtils; import org.onap.cli.fw.cmd.OnapCommand; +import org.onap.cli.fw.cmd.dummy.OnapCommandDummy; import org.onap.cli.fw.conf.OnapCommandConfig; import org.onap.cli.fw.conf.OnapCommandConstants; import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.error.OnapCommandHelpFailed; -import org.onap.cli.fw.error.OnapCommandInvalidRegistration; import org.onap.cli.fw.error.OnapCommandNotFound; import org.onap.cli.fw.error.OnapCommandProductVersionInvalid; import org.onap.cli.fw.error.OnapCommandRegistrationProductInfoMissing; import org.onap.cli.fw.error.OnapUnsupportedSchemaProfile; -import org.onap.cli.fw.input.cache.OnapCommandParameterCache; import org.onap.cli.fw.output.OnapCommandPrintDirection; import org.onap.cli.fw.output.OnapCommandResult; import org.onap.cli.fw.output.OnapCommandResultAttribute; @@ -35,19 +41,13 @@ import org.onap.cli.fw.output.OnapCommandResultAttributeScope; import org.onap.cli.fw.output.OnapCommandResultType; import org.onap.cli.fw.schema.OnapCommandSchema; import org.onap.cli.fw.schema.OnapCommandSchemaInfo; +import org.onap.cli.fw.store.OnapCommandProfileStore; 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; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * Oclip Command registrar provides a common place, where every command would get registered automatically when its @@ -68,7 +68,11 @@ public class OnapCommandRegistrar { private boolean isInteractiveMode = false; - private OnapCommandParameterCache paramCache = OnapCommandParameterCache.getInstance(); + private String host; + + private int port; + + private OnapCommandProfileStore paramCache = OnapCommandProfileStore.getInstance(); public boolean isInteractiveMode() { return isInteractiveMode; @@ -79,7 +83,11 @@ public class OnapCommandRegistrar { } public Map<String, String> getParamCache() { - return paramCache.getParams(this.getEnabledProductVersion()); + return this.getParamCache(this.getEnabledProductVersion()); + } + + public Map<String, String> getParamCache(String product) { + return paramCache.getParams(product); } public void addParamCache(String paramName, String paramValue) { @@ -90,7 +98,7 @@ public class OnapCommandRegistrar { paramCache.remove(this.getEnabledProductVersion(), paramName); } - public void setProfile(String profileName, List<String> includes, List<String> excludes) { + public void setProfile(String profileName, List<String> includes, List<String> excludes) throws OnapCommandException { this.paramCache.setProfile(profileName); for (String profile : includes) { @@ -145,12 +153,16 @@ public class OnapCommandRegistrar { public static OnapCommandRegistrar getRegistrar() throws OnapCommandException { if (registrar == null) { registrar = new OnapCommandRegistrar(); - registrar.autoDiscoverSchemas(); + registrar.autoDiscoverSchemas(true); } return registrar; } + public void resync() throws OnapCommandException { + registrar.autoDiscoverSchemas(false); + } + /** * Get the list of discovered commands by registrar. * @@ -244,8 +256,10 @@ public class OnapCommandRegistrar { } OnapCommand cmd = OnapCommandDiscoveryUtils.loadCommandClass(cls); - String schemaName = OnapCommandDiscoveryUtils.getSchemaInfo(cmdName, version).getSchemaName(); - cmd.initializeSchema(schemaName); + + OnapCommandSchemaInfo info = OnapCommandDiscoveryUtils.getSchemaInfo(cmdName, version); + + cmd.initializeSchema(info); return cmd; } @@ -271,8 +285,8 @@ public class OnapCommandRegistrar { return map; } - private void autoDiscoverSchemas() throws OnapCommandException { - List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(true); + private void autoDiscoverSchemas(boolean refresh) throws OnapCommandException { + List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(refresh); Map<String, Class<OnapCommand>> plugins = this.autoDiscoverCommandPlugins(); @@ -282,13 +296,16 @@ public class OnapCommandRegistrar { continue; } - //First check if there is an specific plugin exist, otherwise check for profile plugin - if (plugins.containsKey(schema.getSchemaName())) { + //First check if there is an specific plug-in exist, otherwise check for profile plug-in + if (schema.isRpc()) { + //proxy the schema by using rpc schema, when the schema is marked with rpc + this.register(schema.getCmdName(), schema.getProduct(), plugins.get("schema-rpc.yaml")); + } else if (plugins.containsKey(schema.getSchemaName())) { this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaName())); } else if (plugins.containsKey(schema.getSchemaProfile())) { this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaProfile())); } else { - log.info("Ignoring schema " + schema.getSchemaURI()); + this.register(schema.getCmdName(), schema.getProduct(), OnapCommandDummy.class); } } } @@ -394,6 +411,11 @@ public class OnapCommandRegistrar { attr.getValues().add(cmdName); } + //don't expose system commands for user usage + //if (cmd.getInfo().getCommandType().name().equalsIgnoreCase(OnapCommandType.SYSTEM.name())) { + // continue; + //} + attrSrv.getValues().add(cmd.getInfo().getService()); attrDesc.getValues().add(cmd.getDescription()); attrState.getValues().add(cmd.getInfo().getState().name()); @@ -412,4 +434,20 @@ public class OnapCommandRegistrar { public List<Map<String, ?>> getTestSuite(String cmd) throws OnapCommandException { return OnapCommandDiscoveryUtils.createTestSuite(cmd, enabledProductVersion); } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } } diff --git a/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaInfo.java b/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaInfo.java index a4703256..c1a6412e 100644 --- a/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaInfo.java +++ b/framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaInfo.java @@ -24,10 +24,13 @@ import org.onap.cli.fw.cmd.OnapCommandType; import org.onap.cli.fw.conf.OnapCommandConstants; import org.onap.cli.fw.info.OnapCommandState; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + /** * OnapCommandSchemaInfo is used in discovery caching. * */ +@JsonIgnoreProperties(ignoreUnknown = true) public class OnapCommandSchemaInfo implements Comparable<OnapCommandSchemaInfo> { /** @@ -59,6 +62,54 @@ public class OnapCommandSchemaInfo implements Comparable<OnapCommandSchemaInfo> private String state = OnapCommandState.STABLE.name(); + //deployment info + private String rpcHost; + + private String rpcPort; + + private List<Object> inputs = new ArrayList<>(); + + private List<Object> outputs = new ArrayList<>(); + + private String description; + + private String service; + + private String author; + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + + public List<Object> getInputs() { + return inputs; + } + + public void setInputs(List<Object> inputs) { + this.inputs = inputs; + } + + public List<Object> getOutputs() { + return outputs; + } + + public void setOutputs(List<Object> outputs) { + this.outputs = outputs; + } + public String getSchemaName() { return schemaName; } @@ -127,6 +178,10 @@ public class OnapCommandSchemaInfo implements Comparable<OnapCommandSchemaInfo> this.ignore = ignore; } + public void setIgnore(boolean ignore) { + this.ignore = Boolean.toString(ignore); + } + public List<String> getSampleFiles() { return sampleFiles; } @@ -160,4 +215,33 @@ public class OnapCommandSchemaInfo implements Comparable<OnapCommandSchemaInfo> public int hashCode() { return Objects.hashCode(this.cmdName); } + + public String getRpcHost() { + return rpcHost; + } + + public void setRpcHost(String rpcHost) { + this.rpcHost = rpcHost; + } + + public String getRpcPort() { + return rpcPort; + } + + public void setRpcPort(String rpcPort) { + this.rpcPort = rpcPort; + } + + public boolean isRpc() { + return this.getRpcHost() != null && !this.getRpcHost().isEmpty() && + this.getRpcPort() != null && !this.getRpcPort().isEmpty(); + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } } 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 a5c0826d..fe191f5b 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 @@ -107,33 +107,34 @@ public class OnapCommandSchemaLoader { * @throws OnapCommandSchemaNotFound schema not found */ public static Map<String, ?> validateSchemaVersion(String schemaName, String version) throws OnapCommandException { - InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName); - + Map<String, ?> values = null; try { + InputStream inputStream = OnapCommandUtils.class.getClassLoader().getResourceAsStream(schemaName); + Resource resource = OnapCommandDiscoveryUtils.findResource(schemaName, SCHEMA_PATH_PATERN); if (resource != null) { inputStream = resource.getInputStream(); } - } catch (IOException e) { - throw new OnapCommandSchemaNotFound(schemaName, e); - } - if (inputStream == null) { - inputStream = loadSchemaFromFile(schemaName); - } + if (inputStream == null) { + inputStream = loadSchemaFromFile(schemaName); + } - Map<String, ?> values = loadSchema(inputStream, schemaName); - String schemaVersion = ""; - if (values.keySet().contains(OPEN_CLI_SCHEMA_VERSION)) { - Object obj = values.get(OPEN_CLI_SCHEMA_VERSION); - schemaVersion = obj.toString(); - } + values = loadSchema(inputStream, schemaName); + String schemaVersion = ""; + if (values.keySet().contains(OPEN_CLI_SCHEMA_VERSION)) { + Object obj = values.get(OPEN_CLI_SCHEMA_VERSION); + schemaVersion = obj.toString(); + } - if (!version.equals(schemaVersion)) { - throw new OnapCommandInvalidSchemaVersion(schemaVersion); + if (!version.equals(schemaVersion)) { + throw new OnapCommandInvalidSchemaVersion(schemaVersion); + } + inputStream.close(); + } catch (IOException e) { + throw new OnapCommandSchemaNotFound(schemaName, e); } - return values; } diff --git a/framework/src/main/java/org/onap/cli/fw/store/OnapCommandArtifactStore.java b/framework/src/main/java/org/onap/cli/fw/store/OnapCommandArtifactStore.java new file mode 100644 index 00000000..f01f9a21 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/store/OnapCommandArtifactStore.java @@ -0,0 +1,321 @@ +/* + * Copyright 2019 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.store; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import javax.xml.bind.DatatypeConverter; + +import org.apache.commons.io.FileUtils; +import org.onap.cli.fw.conf.OnapCommandConfig; +import org.onap.cli.fw.conf.OnapCommandConstants; +import org.onap.cli.fw.error.OnapCommandArtifactAlreadyExist; +import org.onap.cli.fw.error.OnapCommandArtifactContentChecksumNotMatch; +import org.onap.cli.fw.error.OnapCommandArtifactContentNotExist; +import org.onap.cli.fw.error.OnapCommandArtifactNotFound; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class OnapCommandArtifactStore { + private static Logger log = LoggerFactory.getLogger(OnapCommandArtifactStore.class); + + private static boolean storeReady = false; + + private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US); + + static { + dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + private static String SEPARATOR = "__"; + + public static class Artifact { + private String name; + private String description; + private String categoty; + private String checksum; + private long size; + private String createAt; + private String lastUpdatedAt; + private String path; + private Map<String, String> metadata = new HashMap<>(); + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getChecksum() { + return checksum; + } + public void setChecksum(String checksum) { + this.checksum = checksum; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getCategoty() { + return categoty; + } + public void setCategoty(String categoty) { + this.categoty = categoty; + } + + public long getSize() { + return size; + } + public void setSize(long l) { + this.size = l; + } + public String getCreateAt() { + return createAt; + } + public void setCreateAt(String createAt) { + this.createAt = createAt; + } + public String getLastUpdatedAt() { + return lastUpdatedAt; + } + public void setLastUpdatedAt(String lastUpdatedAt) { + this.lastUpdatedAt = lastUpdatedAt; + } + public String getPath() { + return path; + } + public void setPath(String path) { + this.path = path; + } + public Map<String, String> getMetadata() { + return metadata; + } + public void setMetadata(Map<String, String> metadata) { + this.metadata = metadata; + } + + } + static { + try { + FileUtils.forceMkdir(new File(getBasePath())); + storeReady = true; + } catch (IOException e) { + log.error("Failed to create the data store results"); + } + } + + private static OnapCommandArtifactStore store = null; + + private OnapCommandArtifactStore() { + + } + + public static OnapCommandArtifactStore getStore() { + if (store == null) { + store = new OnapCommandArtifactStore(); + } + + return store; + } + + private static String getBasePath() { + return OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_DATA_DIR) + + File.separator + "artifacts"; + } + + private static String getArtifactPath(String name, String category) { + return getBasePath() + File.separator + name + SEPARATOR + category + ".json"; + } + + private String getChecksum(String storePath) throws IOException, NoSuchAlgorithmException { + byte[] b = Files.readAllBytes(Paths.get(storePath)); + byte[] hash = MessageDigest.getInstance("MD5").digest(b); + return DatatypeConverter.printHexBinary(hash); + } + + public Artifact createArtifact(Artifact artifact) throws OnapCommandArtifactContentNotExist, OnapCommandArtifactAlreadyExist, OnapCommandArtifactContentChecksumNotMatch { + if (!new File(artifact.getPath()).exists()) { + throw new OnapCommandArtifactContentNotExist(artifact.getPath()); + } + + String storePath = getArtifactPath(artifact.getName(), artifact.getCategoty()); + File aFile = new File(storePath); + if (aFile.exists()) { + throw new OnapCommandArtifactAlreadyExist(artifact.getName(), artifact.getCategoty()); + } + + try { + String actual = this.getChecksum(artifact.getPath()); + artifact.setChecksum(actual); + + artifact.setSize(new File(artifact.getPath()).length() / 1024); + + artifact.setCreateAt(dateFormatter.format(new Date())); + artifact.setLastUpdatedAt(artifact.getCreateAt()); + + FileUtils.writeStringToFile(new File(storePath), new ObjectMapper().writeValueAsString(artifact)); + } catch (NoSuchAlgorithmException | IOException e) { + //It is expected that this never occurs + log.error("Failed to store the artifact at " + storePath); + } + + return artifact; + } + + public Artifact getArtifact(String name, String category) throws OnapCommandArtifactNotFound { + String storePath = getArtifactPath(name, category); + File aFile = new File(storePath); + if (!aFile.exists()) { + throw new OnapCommandArtifactNotFound(name, category); + } + + try { + return new ObjectMapper().readValue(FileUtils.readFileToString(aFile), Artifact.class); + } catch (IOException e) { + //It is expected that this never occurs + log.error("Failed to retrieve the artifact at " + storePath); + } + return null; + } + + + public List<Artifact> listArtifact(String category, String namePattern) throws OnapCommandArtifactNotFound { + List<Artifact> artifacts = new ArrayList<>(); + + String searchPattern = ""; + if (namePattern != null && !namePattern.isEmpty()) { + searchPattern += namePattern; + } else { + searchPattern += "*"; + } + + searchPattern += SEPARATOR; + + if (category != null && !namePattern.isEmpty()) { + searchPattern += category; + } else { + searchPattern += "*"; + } + + searchPattern += ".json"; + + final String SP = searchPattern; + + for (File file: new File(getBasePath()).listFiles(/*new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.matches(SP); + } + }*/)) { + try { + artifacts.add(new ObjectMapper().readValue(file, Artifact.class)); + } catch (IOException e) { + //It is expected that this never occurs + log.error("While seraching Failed to retrieve the artifact at " + file.getAbsolutePath()); + } + } + + return artifacts; + } + + public void deleteArtifact(String name, String category) throws OnapCommandArtifactNotFound { + String storePath = getArtifactPath(name, category); + File aFile = new File(storePath); + if (!aFile.exists()) { + throw new OnapCommandArtifactNotFound(name, category); + } + aFile.delete(); + } + + public Artifact updateArtifact(String name, String category, Artifact artifact) throws OnapCommandArtifactNotFound, OnapCommandArtifactContentNotExist, OnapCommandArtifactAlreadyExist { + Artifact existing = this.getArtifact(name, category); + String existingStorePath = getArtifactPath(name, category); + + String newStorePath = getArtifactPath(artifact.getName(), artifact.getCategoty()); + if ( !existingStorePath.equalsIgnoreCase(newStorePath) && new File(newStorePath).exists()) { + throw new OnapCommandArtifactAlreadyExist(artifact.getName(), artifact.getCategoty()); + } + + try { + if (artifact.getName() == null) { + artifact.setName(existing.getName()); + } + + if (artifact.getDescription() == null) { + artifact.setDescription(existing.getDescription()); + } + + if (artifact.getCategoty() == null) { + artifact.setCategoty(existing.getCategoty()); + } + + if (artifact.getPath()!= null) { + if (!new File(artifact.getPath()).exists()) { + throw new OnapCommandArtifactContentNotExist(artifact.getPath()); + } + String actual = this.getChecksum(artifact.getPath()); + if (!existing.getChecksum().equals(actual)) { + artifact.setChecksum(actual); + artifact.setSize(new File(artifact.getPath()).length() / 1024); + } + } else { + artifact.setPath(existing.getPath()); + } + + artifact.setCreateAt(existing.getCreateAt()); + artifact.setLastUpdatedAt(dateFormatter.format(new Date())); + if (artifact.getMetadata().size() > 0) { + //update to existing one + for (Map.Entry<String, String> entry: artifact.getMetadata().entrySet()) { + if (entry.getValue() == null || entry.getValue().isEmpty() || entry.getValue().equalsIgnoreCase("null")) { + existing.getMetadata().remove(entry.getKey()); + } else + existing.getMetadata().put(entry.getKey(), entry.getValue()); + } + + artifact.setMetadata(existing.getMetadata()); + } + + FileUtils.writeStringToFile(new File(newStorePath), new ObjectMapper().writeValueAsString(artifact)); + + if (!newStorePath.equalsIgnoreCase(existingStorePath)) { + this.deleteArtifact(name, category); + } + } catch (NoSuchAlgorithmException | IOException e) { + //It is expected that this never occurs + log.error("Failed to update the artifact at " + existingStorePath); + } + return artifact; + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/store/OnapCommandExecutionStore.java b/framework/src/main/java/org/onap/cli/fw/store/OnapCommandExecutionStore.java new file mode 100644 index 00000000..71cd245f --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/store/OnapCommandExecutionStore.java @@ -0,0 +1,371 @@ +/* + * Copyright 2019 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.store; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.onap.cli.fw.conf.OnapCommandConfig; +import org.onap.cli.fw.conf.OnapCommandConstants; +import org.onap.cli.fw.error.OnapCommandExecutionFailed; +import org.onap.cli.fw.error.OnapCommandExecutionNotFound; +import org.onap.cli.fw.utils.ProcessRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OnapCommandExecutionStore { + private static Logger log = LoggerFactory.getLogger(OnapCommandExecutionStore.class); + + private static boolean storeReady = false; + + private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US); + + static { + dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + private static String SEPARATOR = "__"; + + private enum SearchMode { + find, + file //for developer mode + } + private static SearchMode SEARCH_MODE = SearchMode.file; + + public static class ExecutionStoreContext { + + private String executionId; + private String storePath; + public String getExecutionId() { + return executionId; + } + public ExecutionStoreContext setExecutionId(String executionId) { + this.executionId = executionId; + return this; + } + public String getStorePath() { + return storePath; + } + public ExecutionStoreContext setStorePath(String storePath) { + this.storePath = storePath; + return this; + } + } + + public static class Execution { + private String id; + private String requestId; + private String status; + private String startTime; + private String endTime; + private String input; + private String output; + private String profile; + private String command; + private String product; + private String service; + + public String getInput() { + return input; + } + public void setInput(String input) { + this.input = input; + } + public String getOutput() { + return output; + } + public void setOutput(String output) { + this.output = output; + } + public String getProfile() { + return profile; + } + public void setProfile(String profile) { + this.profile = profile; + } + public String getCommand() { + return command; + } + public void setCommand(String command) { + this.command = command; + } + public String getProduct() { + return product; + } + public void setProduct(String product) { + this.product = product; + } + public String getService() { + return service; + } + public void setService(String service) { + this.service = service; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getEndTime() { + return endTime; + } + public void setEndTime(String endTime) { + this.endTime = endTime; + } + public void setStartTime(String timeOfExecution) { + this.startTime = timeOfExecution; + } + public String getStartTime() { + return startTime; + } + public String getStatus() { + return status; + } + public void setStatus(String status) { + this.status = status; + } + public String getRequestId() { + return requestId; + } + public void setRequestId(String requestId) { + this.requestId = requestId; + } + } + + static { + try { + FileUtils.forceMkdir(new File(getBasePath())); + storeReady = true; + } catch (IOException e) { + log.error("Failed to create the data store results"); + } + } + + private static OnapCommandExecutionStore store = null; + + private OnapCommandExecutionStore() { + + } + + public static OnapCommandExecutionStore getStore() { + if (store == null) { + store = new OnapCommandExecutionStore(); + } + + return store; + } + + private static String getBasePath() { + return OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_DATA_DIR) + + File.separator + "executions"; + } + + public ExecutionStoreContext storeExectutionStart( + String requestId, String product, String service, String cmd, String profile, String input) { + + String executionId = requestId + "-" + System.currentTimeMillis(); + + String storePath = getBasePath() + File.separator + executionId + SEPARATOR + product + + SEPARATOR + service + + SEPARATOR + cmd + + (profile != null ? (SEPARATOR + profile) : "" ); + try { + File dir = new File(storePath); + FileUtils.forceMkdir(dir); + + if (product != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "product"), product); + if (service != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "service"), service); + if (cmd != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "command"), cmd); + + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "requestId"), requestId); + + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "executionId"), executionId); + + if (input != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "input"), input); + if (profile != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "profile"), profile); + FileUtils.touch(new File(dir.getAbsolutePath() + File.separator + "in-progress")); + } catch (IOException e) { + log.error("Failed to store the execution start details " + storePath); + } + + return new ExecutionStoreContext().setExecutionId(executionId).setStorePath(storePath); + } + + public void storeExectutionEnd( + ExecutionStoreContext execContext, + String output, String error, boolean passed) { + + try { + File dir = new File(execContext.getStorePath()); + FileUtils.forceMkdir(dir); + + if (output != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "output"), output); + if (error != null) + FileUtils.writeStringToFile(new File(dir.getAbsolutePath() + File.separator + "error"), error); + + if (passed) + FileUtils.touch(new File(dir.getAbsolutePath() + File.separator + "completed")); + else + FileUtils.touch(new File(dir.getAbsolutePath() + File.separator + "failed")); + + new File(dir.getAbsolutePath() + File.separator + "in-progress").delete(); + } catch (IOException e) { + log.error("Failed to store the execution end details " + execContext.storePath); + } + } + + public List<OnapCommandExecutionStore.Execution> listExecutions(Map<String, String> search) throws OnapCommandExecutionFailed { + List <OnapCommandExecutionStore.Execution> list = new ArrayList<>(); + + try { + List <String> dirs = new ArrayList<>(); + if (SEARCH_MODE.equals(SearchMode.file)) { + for (File f: new File(getBasePath()).listFiles()) + dirs.add(f.getAbsolutePath()); + } else { + //find results -type d -newermt '2019-02-11 10:00:00' ! -newermt '2019-02-11 15:10:00' -name "*__*__profile-list*" + //find 'results' -type d -newermt '2019-02-11T10:00:00.000' ! -newermt '2019-02-11T15:10:00.000' -name "*__*__profile*" + + String searchString = "find '" + new File(getBasePath()).getAbsolutePath() + "' -type d "; + + String startTime = search.get("startTime"); + if (startTime != null) { + searchString += " -newermt " + startTime ; + } + + String endTime = search.get("endTime"); + if (endTime != null) { + searchString += " ! -newermt " + endTime ; + } + + searchString += " -name '"; + + if(search.containsKey("execution-id")) { + searchString += search.get("execution-id"); + } else if(search.containsKey("request-id")) { + searchString += search.get("request-id") + "*"; + } else { + searchString += "*"; + } + + for (String term: Arrays.asList(new String []{"product", "service", "command", "profile"})) { + searchString += "__"; + if (search.get(term) != null) { + searchString += search.get(term); + } else { + searchString += "*"; + } + } + if (!searchString.endsWith("*")) + searchString += "*"; + + searchString += "'"; + + ProcessRunner pr = new ProcessRunner(new String [] {searchString}, null, "."); + pr.overrideToUnix(); + pr.run(); + if (pr.getExitCode() != 0) { + throw new OnapCommandExecutionFailed("System failed to search the executions with error " + pr.getError()); + } + + dirs = Arrays.asList(pr.getOutput().split("\\r?\\n")); + } + + for (String dir: dirs) { + list.add(this.makeExecution(dir)); + } + } catch (IOException e) { + throw new OnapCommandExecutionFailed(e, "Failed to search the executions"); + } catch (InterruptedException e) { + throw new OnapCommandExecutionFailed(e, "Failed to search the executions"); + } + + return list; + } + + private Execution makeExecution(String executionStorePath) throws IOException { + OnapCommandExecutionStore.Execution exectuion = new OnapCommandExecutionStore.Execution(); + if (new File(executionStorePath + File.separator + "requestId").exists()) + exectuion.setRequestId(FileUtils.readFileToString(new File(executionStorePath + File.separator + "requestId"))); + if (new File(executionStorePath + File.separator + "executionId").exists()) + exectuion.setId(FileUtils.readFileToString(new File(executionStorePath + File.separator + "executionId"))); + exectuion.setProduct(FileUtils.readFileToString(new File(executionStorePath + File.separator + "product"))); + exectuion.setService(FileUtils.readFileToString(new File(executionStorePath + File.separator + "service"))); + exectuion.setCommand(FileUtils.readFileToString(new File(executionStorePath + File.separator + "command"))); + if (new File(executionStorePath + File.separator + "profile").exists()) + exectuion.setProfile(FileUtils.readFileToString(new File(executionStorePath + File.separator + "profile"))); + + exectuion.setInput(FileUtils.readFileToString(new File(executionStorePath + File.separator + "input"))); + exectuion.setStartTime(dateFormatter.format(new File(executionStorePath + File.separator + "input").lastModified())); + + if (new File(executionStorePath + File.separator + "in-progress").exists()) { + exectuion.setStatus("in-progress"); + } else if (new File(executionStorePath + File.separator + "completed").exists()) { + exectuion.setStatus("completed"); + if (new File(executionStorePath + File.separator + "output").exists()) { + exectuion.setOutput(FileUtils.readFileToString(new File(executionStorePath + File.separator + "output"))); + exectuion.setEndTime(dateFormatter.format(new File(executionStorePath + File.separator + "output").lastModified())); + } + } else if (new File(executionStorePath + File.separator + "failed").exists()) { + exectuion.setStatus("failed"); + if (new File(executionStorePath + File.separator + "error").exists()) { + exectuion.setOutput(FileUtils.readFileToString(new File(executionStorePath + File.separator + "error"))); + exectuion.setEndTime(dateFormatter.format(new File(executionStorePath + File.separator + "error").lastModified())); + } + } + + return exectuion; + } + public Execution getExecution(String executionId) throws OnapCommandExecutionNotFound, OnapCommandExecutionFailed { + File []f = new File(getBasePath()).listFiles(new FilenameFilter() { + + @Override + public boolean accept(File dir, String name) { + if (name.startsWith(executionId)) return true; + return false; + } + }); + + if (f.length == 0) { + throw new OnapCommandExecutionNotFound(executionId); + } + + try { + return this.makeExecution(f[0].getAbsolutePath()); + } catch (IOException e) { + throw new OnapCommandExecutionFailed(e, "Failed to retrieve the execution"); + } + } +} diff --git a/framework/src/main/java/org/onap/cli/fw/input/cache/OnapCommandParameterCache.java b/framework/src/main/java/org/onap/cli/fw/store/OnapCommandProfileStore.java index ade5c998..4be5bcd8 100644 --- a/framework/src/main/java/org/onap/cli/fw/input/cache/OnapCommandParameterCache.java +++ b/framework/src/main/java/org/onap/cli/fw/store/OnapCommandProfileStore.java @@ -14,14 +14,12 @@ * limitations under the License. */ -package org.onap.cli.fw.input.cache; +package org.onap.cli.fw.store; -import static org.onap.cli.fw.conf.OnapCommandConstants.DATA_DIRECTORY; -import static org.onap.cli.fw.conf.OnapCommandConstants.DATA_PATH_JSON_PATTERN; import static org.onap.cli.fw.conf.OnapCommandConstants.DATA_PATH_PROFILE_JSON; -import static org.onap.cli.fw.conf.OnapCommandConstants.DATA_PATH_PROFILE_JSON_PATTERN; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -29,40 +27,52 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.io.FileUtils; +import org.onap.cli.fw.conf.OnapCommandConfig; import org.onap.cli.fw.conf.OnapCommandConstants; -import org.onap.cli.fw.error.OnapCommandLoadProfileFailed; +import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.error.OnapCommandPersistProfileFailed; -import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils; -import org.springframework.core.io.Resource; +import org.onap.cli.fw.error.OnapCommandProfileLoadFailed; +import org.onap.cli.fw.error.OnapCommandProfileNotFound; +import org.onap.cli.fw.input.cache.OnapCommandParamEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper; -public class OnapCommandParameterCache { - +public class OnapCommandProfileStore { + private static Logger log = LoggerFactory.getLogger(OnapCommandProfileStore.class); private Map<String, Map<String, String>> paramCache = new HashMap<>(); - private static OnapCommandParameterCache single = null; + private static OnapCommandProfileStore single = null; private String profileName = OnapCommandConstants.PARAM_CACHE_FILE_NAME; - private OnapCommandParameterCache() { + static { + try { + FileUtils.forceMkdir(new File(getDataStorePath())); + } catch (IOException e) { + log.error("Failed to create the data store profile"); + } + } + private OnapCommandProfileStore() { } - public static OnapCommandParameterCache getInstance() { + public static OnapCommandProfileStore getInstance() { if (single == null) { - single = new OnapCommandParameterCache(); + single = new OnapCommandProfileStore(); } - single.load(); + //single.load(); return single; } - public void includeProfile(String profile) { + public void includeProfile(String profile) throws OnapCommandException { this.load(profile, true); } - public void excludeProfile(String profile) { + public void excludeProfile(String profile) throws OnapCommandException { this.load(profile, false); } @@ -88,11 +98,18 @@ public class OnapCommandParameterCache { } public Map<String, String> getParams(String productVersion) { + //default profile used across products, set in profile-set command + Map<String, String> map = new HashMap<>(); + + if (paramCache.containsKey(OnapCommandConstants.OCLIP_GLOBAL_PROFILE)) { + map = this.paramCache.get(OnapCommandConstants.OCLIP_GLOBAL_PROFILE); + } + if (paramCache.containsKey(productVersion)) { - return this.paramCache.get(productVersion); - } else { - return new HashMap<>(); + map.putAll(this.paramCache.get(productVersion)); } + + return map; } private void persist() { @@ -117,17 +134,13 @@ public class OnapCommandParameterCache { } } - private void load() { + private void load() throws OnapCommandException { this.load(this.profileName, true); } - private void load(String profileName, boolean include) { + private void load(String profileName, boolean include) throws OnapCommandException { List<OnapCommandParamEntity> params= new ArrayList<>(); - try { - params = this.loadParamFromCache(profileName); - } catch (OnapCommandLoadProfileFailed e) { - throw new RuntimeException(e); // NOSONAR - } + params = this.loadParamFromCache(profileName); for (OnapCommandParamEntity p : params) { if (include) { @@ -138,62 +151,69 @@ public class OnapCommandParameterCache { } } - public void setProfile(String profileName) { + public void setProfile(String profileName) throws OnapCommandException { this.profileName = profileName; this.paramCache.clear(); this.load(); } - private void persistProfile(List<OnapCommandParamEntity> params, String profileName) throws OnapCommandPersistProfileFailed { + public static String getDataStorePath() { + return OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_DATA_DIR) + + File.separator + "profiles"; + } + + public void persistProfile(List<OnapCommandParamEntity> params, String profileName) throws OnapCommandPersistProfileFailed { if (params != null) { + String dataDir = getDataStorePath(); try { - Resource[] resources = OnapCommandDiscoveryUtils.findResources(DATA_DIRECTORY); - if (resources != null && resources.length == 1) { - String path = resources[0].getURI().getPath(); - File file = new File(path + File.separator + profileName + DATA_PATH_PROFILE_JSON); - ObjectMapper mapper = new ObjectMapper(); - mapper.writerWithDefaultPrettyPrinter().writeValue(file, params); - } + File file = new File(dataDir + File.separator + profileName + DATA_PATH_PROFILE_JSON); + ObjectMapper mapper = new ObjectMapper(); + mapper.writerWithDefaultPrettyPrinter().writeValue(file, params); } catch (IOException e1) { throw new OnapCommandPersistProfileFailed(e1); } } } - private List<OnapCommandParamEntity> loadParamFromCache(String profileName) throws OnapCommandLoadProfileFailed { + public List<OnapCommandParamEntity> loadParamFromCache(String profileName) throws OnapCommandException { List<OnapCommandParamEntity> params = new ArrayList<>(); - + String dataDir = getDataStorePath(); try { - Resource resource = OnapCommandDiscoveryUtils.findResource(profileName + DATA_PATH_PROFILE_JSON, - DATA_PATH_JSON_PATTERN); - if (resource != null) { - File file = new File(resource.getURI().getPath()); + File file = new File(dataDir + File.separator + profileName + DATA_PATH_PROFILE_JSON); + if (file.exists()) { ObjectMapper mapper = new ObjectMapper(); OnapCommandParamEntity[] list = mapper.readValue(file, OnapCommandParamEntity[].class); params.addAll(Arrays.asList(list)); + } else { + throw new OnapCommandProfileNotFound(profileName); } } catch (IOException e) { - throw new OnapCommandLoadProfileFailed(e); + throw new OnapCommandProfileLoadFailed(e); } return params; } + public void removeProfile(String profile) { + String dataDir = getDataStorePath(); + File file = new File(dataDir + File.separator + profile + DATA_PATH_PROFILE_JSON); + if (file.exists()) { + file.delete(); + } + } + public List<String> getProfiles() { List<String> profiles = new ArrayList<>(); - Resource[] resources; - try { - resources = OnapCommandDiscoveryUtils.findResources(DATA_PATH_PROFILE_JSON_PATTERN); - } catch (IOException e) { - throw new RuntimeException(e); // NOSONAR - } - - if (resources != null && resources.length > 0) { - for (Resource res : resources) { - String profile = res.getFilename().substring(0, res.getFilename().indexOf(DATA_PATH_PROFILE_JSON)); - profiles.add(profile); + String dataDir = getDataStorePath(); + for (File file: new File(dataDir).listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(DATA_PATH_PROFILE_JSON); } + })) { + String profile = file.getName().substring(0, file.getName().indexOf(DATA_PATH_PROFILE_JSON)); + profiles.add(profile); } return profiles; 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 26d49650..8c97bd30 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 @@ -16,14 +16,19 @@ package org.onap.cli.fw.utils; -import static org.onap.cli.fw.conf.OnapCommandConstants.DATA_DIRECTORY; -import static org.onap.cli.fw.conf.OnapCommandConstants.DATA_PATH_JSON_PATTERN; +import static org.onap.cli.fw.conf.OnapCommandConstants.ATTRIBUTES; +import static org.onap.cli.fw.conf.OnapCommandConstants.DESCRIPTION; import static org.onap.cli.fw.conf.OnapCommandConstants.DISCOVERY_FILE; import static org.onap.cli.fw.conf.OnapCommandConstants.NAME; import static org.onap.cli.fw.conf.OnapCommandConstants.OPEN_CLI_SAMPLE_VERSION; import static org.onap.cli.fw.conf.OnapCommandConstants.OPEN_CLI_SCHEMA_VERSION; +import static org.onap.cli.fw.conf.OnapCommandConstants.PARAMETERS; +import static org.onap.cli.fw.conf.OnapCommandConstants.RESULTS; import static org.onap.cli.fw.conf.OnapCommandConstants.SCHEMA_DIRECTORY; import static org.onap.cli.fw.conf.OnapCommandConstants.SCHEMA_PATH_PATERN; +import static org.onap.cli.fw.conf.OnapCommandConstants.DEFAULT_SCHEMA_PATH_PATERN; +import static org.onap.cli.fw.conf.OnapCommandConstants.DEAFULT_INPUT_PARAMETERS_NAME; +import static org.onap.cli.fw.conf.OnapCommandConstants.IS_DEFAULT_PARAM; import java.io.File; import java.io.IOException; @@ -46,6 +51,7 @@ import org.onap.cli.fw.error.OnapCommandException; import org.onap.cli.fw.error.OnapCommandInstantiationFailed; import org.onap.cli.fw.error.OnapCommandInvalidSample; import org.onap.cli.fw.error.OnapCommandInvalidSchema; +import org.onap.cli.fw.error.OnapCommandNotFound; import org.onap.cli.fw.schema.OnapCommandSchemaInfo; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @@ -78,6 +84,10 @@ public class OnapCommandDiscoveryUtils { } } } + + if (schemaInfo == null) + throw new OnapCommandNotFound(cmd, version); + return schemaInfo; } @@ -96,22 +106,55 @@ public class OnapCommandDiscoveryUtils { || !OnapCommandDiscoveryUtils.isAlreadyDiscovered()) { schemas = OnapCommandDiscoveryUtils.discoverSchemas(); if (!schemas.isEmpty()) { + //merge the existing RPC schema with discovered ones + List<OnapCommandSchemaInfo> schemasExisting = OnapCommandDiscoveryUtils.loadSchemas(); + + Map<String, OnapCommandSchemaInfo> rpcCommands = new HashMap<>(); + for (OnapCommandSchemaInfo info: schemasExisting) { + if (info.isRpc()) { + rpcCommands.put(info.getProduct() + ":" + info.getCmdName(), info); + } + } + + //mrkanag: Enable clustering for keeping command in more than one OCLIP engine + //Remove if already an same command exists with RPC + for (OnapCommandSchemaInfo info: schemas) { + OnapCommandSchemaInfo infoExisting = rpcCommands.get(info.getProduct() + ":" + info.getCmdName()); + if (infoExisting != null) { + rpcCommands.remove(info.getProduct() + ":" + info.getCmdName()); + } + } + + //Add all RPC ones + schemas.addAll(rpcCommands.values()); + OnapCommandDiscoveryUtils.persistSchemaInfo(schemas); } } else { - try { - Resource resource = OnapCommandDiscoveryUtils.findResource(DISCOVERY_FILE, - DATA_PATH_JSON_PATTERN); - if (resource != null) { - File file = new File(resource.getURI().getPath()); - ObjectMapper mapper = new ObjectMapper(); - OnapCommandSchemaInfo[] list = mapper.readValue(file, OnapCommandSchemaInfo[].class); - schemas.addAll(Arrays.asList(list)); - } - } catch (IOException e) { - throw new OnapCommandDiscoveryFailed(DATA_DIRECTORY, - DISCOVERY_FILE, e); - } + schemas = OnapCommandDiscoveryUtils.loadSchemas(); + } + + return schemas; + } + + public static String getDataStorePath() { + return OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_DATA_DIR); + } + + public static List<OnapCommandSchemaInfo> loadSchemas() throws OnapCommandException { + List<OnapCommandSchemaInfo> schemas = new ArrayList<>(); + + if (!OnapCommandDiscoveryUtils.isAlreadyDiscovered()) return schemas; + + String dataDir = OnapCommandDiscoveryUtils.getDataStorePath(); + try { + File file = new File(dataDir + File.separator + DISCOVERY_FILE); + ObjectMapper mapper = new ObjectMapper(); + OnapCommandSchemaInfo[] list = mapper.readValue(file, OnapCommandSchemaInfo[].class); + schemas.addAll(Arrays.asList(list)); + } catch (IOException e) { + throw new OnapCommandDiscoveryFailed(dataDir, + DISCOVERY_FILE, e); } return schemas; @@ -125,19 +168,8 @@ public class OnapCommandDiscoveryUtils { * exception */ public static boolean isAlreadyDiscovered() throws OnapCommandDiscoveryFailed { - Resource resource = null; - try { - resource = OnapCommandDiscoveryUtils.findResource(DISCOVERY_FILE, - DATA_PATH_JSON_PATTERN); - if (resource != null) { - return true; - } - } catch (IOException e) { - throw new OnapCommandDiscoveryFailed(DATA_DIRECTORY, - DISCOVERY_FILE, e); - } - - return false; + String dataDir = OnapCommandDiscoveryUtils.getDataStorePath(); + return new File(dataDir + File.separator + DISCOVERY_FILE).exists(); } /** @@ -150,16 +182,16 @@ public class OnapCommandDiscoveryUtils { */ public static void persistSchemaInfo(List<OnapCommandSchemaInfo> schemas) throws OnapCommandDiscoveryFailed { if (schemas != null) { + String dataDir = OnapCommandDiscoveryUtils.getDataStorePath(); + try { - Resource[] resources = OnapCommandDiscoveryUtils.findResources(DATA_DIRECTORY); - if (resources != null && resources.length == 1) { - String path = resources[0].getURI().getPath(); - File file = new File(path + File.separator + DISCOVERY_FILE); - ObjectMapper mapper = new ObjectMapper(); - mapper.writerWithDefaultPrettyPrinter().writeValue(file, schemas); - } + FileUtils.forceMkdir(new File(dataDir)); + + File file = new File(dataDir + File.separator + DISCOVERY_FILE); + ObjectMapper mapper = new ObjectMapper(); + mapper.writerWithDefaultPrettyPrinter().writeValue(file, schemas); } catch (IOException e1) { - throw new OnapCommandDiscoveryFailed(DATA_DIRECTORY, + throw new OnapCommandDiscoveryFailed(dataDir, DISCOVERY_FILE, e1); } } @@ -244,11 +276,44 @@ public class OnapCommandDiscoveryUtils { public static List<OnapCommandSchemaInfo> discoverSchemas() throws OnapCommandException { List<OnapCommandSchemaInfo> extSchemas = new ArrayList<>(); try { + //collect default input parameters for every profile + Resource[] deafultRres = findResources(DEFAULT_SCHEMA_PATH_PATERN); + Map <String, List<Object>> defaultInputs = new HashMap<>(); + + if (deafultRres != null && deafultRres.length > 0) { + Map<String, ?> deafultResourceMap; + + for (Resource resource : deafultRres) { + try { + deafultResourceMap = loadYaml(resource); + } catch (OnapCommandException e) { + OnapCommandUtils.log.error("Ignores invalid schema " + resource.getURI().toString(), e); + continue; + } + + if (deafultResourceMap != null && deafultResourceMap.size() > 0) { + //default_input_parameters_http.yaml + String profileName = resource.getFilename().substring( + DEAFULT_INPUT_PARAMETERS_NAME.length() + 1, + resource.getFilename().indexOf(".")); + if (deafultResourceMap.containsKey(PARAMETERS)) { + List<Object> params = new ArrayList<>(); + for (Map<String, ?> p: (List<Map<String, ?>>) deafultResourceMap.get(PARAMETERS)) { + if (p.keySet().contains(IS_DEFAULT_PARAM) && (Boolean) p.get(IS_DEFAULT_PARAM)) { + params.add(p); + } + } + + defaultInputs.put(profileName, params); + } + } + } + } + Resource[] res = findResources(SCHEMA_PATH_PATERN); if (res != null && res.length > 0) { - Map<String, ?> resourceMap; - for (Resource resource : res) { + Map<String, ?> resourceMap; try { resourceMap = loadYaml(resource); } catch (OnapCommandException e) { @@ -282,6 +347,8 @@ public class OnapCommandDiscoveryUtils { schema.setSchemaName(resource.getFilename()); schema.setCmdName((String) resourceMap.get(NAME)); + schema.setDescription((String) resourceMap.get(DESCRIPTION)); + Map<String, ?> infoMap = (Map<String, ?>) resourceMap.get(OnapCommandConstants.INFO); if (infoMap != null && infoMap.get(OnapCommandConstants.INFO_TYPE) != null) { schema.setType(infoMap.get(OnapCommandConstants.INFO_TYPE).toString()); @@ -299,8 +366,28 @@ public class OnapCommandDiscoveryUtils { schema.setState(infoMap.get(OnapCommandConstants.INFO_STATE).toString()); } + if (infoMap != null && infoMap.get(OnapCommandConstants.INFO_SERVICE) != null) { + schema.setService(infoMap.get(OnapCommandConstants.INFO_SERVICE).toString()); + } + + if (infoMap != null && infoMap.get(OnapCommandConstants.INFO_AUTHOR) != null) { + schema.setAuthor(infoMap.get(OnapCommandConstants.INFO_AUTHOR).toString()); + } + + schema.setSchemaProfile(identitySchemaProfileType(resourceMap)); + if (resourceMap.containsKey(PARAMETERS)) { + schema.setInputs((List<Object>)resourceMap.get(PARAMETERS)); + if (defaultInputs.get(schema.getSchemaProfile()) != null) { + schema.getInputs().addAll(defaultInputs.get(schema.getSchemaProfile())); + } + } + + if (resourceMap.containsKey(RESULTS)) { + schema.setOutputs((List<Object>)((Map<String, Object>)resourceMap.get(RESULTS)).get(ATTRIBUTES)); + } + extSchemas.add(schema); } } @@ -471,3 +558,4 @@ public class OnapCommandDiscoveryUtils { return values; } } + 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 862e328b..e279fa0b 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 @@ -16,10 +16,12 @@ package org.onap.cli.fw.utils; +import static org.onap.cli.fw.conf.OnapCommandConstants.BOOLEAN_TRUE; import static org.onap.cli.fw.conf.OnapCommandConstants.BOOLEAN_VALUE; import static org.onap.cli.fw.conf.OnapCommandConstants.IS_INCLUDE; -import static org.onap.cli.fw.conf.OnapCommandConstants.BOOLEAN_TRUE; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -29,6 +31,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import org.apache.commons.io.FileUtils; import org.onap.cli.fw.cmd.OnapCommand; import org.onap.cli.fw.conf.OnapCommandConfig; import org.onap.cli.fw.conf.OnapCommandConstants; @@ -218,6 +221,17 @@ public class OnapCommandUtils { //defined. value = splEntry; } + } else if (splEntry.startsWith(OnapCommandConstants.SPL_ENTRY_FILE)) { + //start to read after file:filepath + String fileName = splEntry.substring(5); + try { + value = FileUtils.readFileToString(new File(fileName)); + } catch (IOException e) { + //when file is not found, assign the same file:FILE_PATH + //so that it will given hit to user that FILE_PATH to be + //exist. + value = ""; + } } else { value = splEntry; } diff --git a/framework/src/main/java/org/onap/cli/fw/utils/ProcessRunner.java b/framework/src/main/java/org/onap/cli/fw/utils/ProcessRunner.java new file mode 100644 index 00000000..b373a913 --- /dev/null +++ b/framework/src/main/java/org/onap/cli/fw/utils/ProcessRunner.java @@ -0,0 +1,166 @@ +/* + * Copyright 2018 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.utils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.io.IOUtils; + +public class ProcessRunner { + public static final String WIN_SHELL = "cmd.exe /c "; + public static final String UNIX_SHELL = "sh -c "; + private String []cmd = null; + private String shell = System.getProperty("os.name").toLowerCase().startsWith("windows") ? WIN_SHELL : UNIX_SHELL; + private String cwd = System.getProperty("user.home"); + private String []env = null; + private int exitCode = -1; + private String output; + private String error; + private Map<String, Object> results; + + public ProcessRunner(String []cmd, String []env, String cwd) { + this.cmd = cmd; + + if (cwd != null && !cwd.isEmpty()) { + this.cwd = cwd; + } + + this.env = env; + } + + public void overrideToUnix() { + this.shell = UNIX_SHELL; + } + + public ProcessRunner(String []cmd, String cwd) { + this(cmd, null, cwd); + } + + public ProcessRunner(String []cmd) { + this(cmd, null, null); + } + + public ProcessRunner(String cmd, String []env, String cwd) { + this(new String []{cmd}, env, cwd); + } + + public ProcessRunner(String cmd, String cwd) { + this(new String []{cmd}, null, cwd); + } + + public ProcessRunner(String cmd) { + this(new String []{cmd}, null, null); + } + + @SuppressWarnings("unchecked") + public void run() throws InterruptedException, IOException { + Process p = null; + final StringWriter writerOutput = new StringWriter(); + final StringWriter writerError = new StringWriter(); + if (this.cmd.length == 1) { + p = Runtime.getRuntime().exec(this.shell + this.cmd[0], this.env, null); + } else { + List list = new ArrayList(Arrays.asList(this.shell.split(" "))); + list.addAll(Arrays.asList(this.cmd)); + String []cmds = Arrays.copyOf(list.toArray(), list.size(), String[].class); + p = Runtime.getRuntime().exec(cmds, this.env, null); + } + + final Process p1 = p; + new Thread(new Runnable() { + public void run() { + try { + IOUtils.copy(p1.getInputStream(), writerOutput); + } catch (IOException e) { + } + } + }).start(); + + new Thread(new Runnable() { + public void run() { + try { + IOUtils.copy(p1.getErrorStream(), writerError); + } catch (IOException e) { + } + } + }).start(); + + //mrkanag: handle the case if the given cmd does not exist + p.waitFor(1, TimeUnit.MINUTES); + this.exitCode = p.exitValue(); + this.output = writerOutput.toString(); + this.error = writerError.toString(); + p.destroy(); + } + + public String streamToString(InputStream stream) throws IOException { + StringBuilder sb = new StringBuilder(); + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader(stream)); + String line = null; + while ((line = br.readLine()) != null) { + sb.append(line + System.getProperty("line.separator")); + } + } finally { + if (br != null) { + br.close(); + } + } + return sb.toString(); + } + + public int getExitCode() { + return this.exitCode; + } + + public String getOutput() { + return this.output; + } + + public String getError() { + return this.error; + } + + public static void main(String[] args) { + try { + ProcessRunner pr = new ProcessRunner("dir", null); + pr.run(); + System.out.println(pr.getOutput()); + System.out.println(pr.getError()); + System.out.println(pr.getExitCode()); + + pr = new ProcessRunner(new String [] {"dir", "c:"}, null); + pr.run(); + System.out.println(pr.getOutput()); + System.out.println(pr.getError()); + System.out.println(pr.getExitCode()); + + } catch (InterruptedException | IOException e) { + e.printStackTrace(); + } + } +}
\ No newline at end of file |