CVC: Add support for execution, schema, product 38/79338/1
authorKanagaraj Manickam k00365106 <kanagaraj.manickam@huawei.com>
Thu, 28 Feb 2019 09:02:18 +0000 (14:32 +0530)
committerKanagaraj Manickam k00365106 <kanagaraj.manickam@huawei.com>
Thu, 28 Feb 2019 09:02:18 +0000 (14:32 +0530)
Issue-ID: CLI-129

Change-Id: I602859733b8f965ab031625eba6494a9b754cb64
Signed-off-by: Kanagaraj Manickam k00365106 <kanagaraj.manickam@huawei.com>
68 files changed:
.gitignore
deployment/zip/src/main/release/conf/log4j.properties
deployment/zip/src/main/release/conf/open-cli.properties
framework/pom.xml
framework/src/main/java/org/onap/cli/fw/cmd/OnapCommand.java
framework/src/main/java/org/onap/cli/fw/cmd/OnapCommandType.java
framework/src/main/java/org/onap/cli/fw/cmd/dummy/OnapCommandDummy.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionListCommand.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/execution/OnapCommandExceutionShowCommand.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/product/OnapProductsListCommand.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/product/OnapServiceListCommand.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaListCommand.java [moved from framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaListCommand.java with 69% similarity]
framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaRefreshCommand.java [moved from framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommand.java with 84% similarity]
framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaShowCommand.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaSwitchCommand.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/cmd/schema/OnapSchemaValidateCommand.java [moved from framework/src/main/java/org/onap/cli/fw/cmd/OnapSchemaValidateCommand.java with 91% similarity]
framework/src/main/java/org/onap/cli/fw/conf/OnapCommandConstants.java
framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactAlreadyExist.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentChecksumNotMatch.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactContentNotExist.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/error/OnapCommandArtifactNotFound.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/error/OnapCommandExecutionNotFound.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/error/OnapCommandNotFound.java
framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileLoadFailed.java [moved from framework/src/main/java/org/onap/cli/fw/error/OnapCommandLoadProfileFailed.java with 85% similarity]
framework/src/main/java/org/onap/cli/fw/error/OnapCommandProfileNotFound.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/error/OnapSchemaSyncFailure.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/output/print/OnapCommandPrint.java
framework/src/main/java/org/onap/cli/fw/registrar/OnapCommandRegistrar.java
framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaInfo.java
framework/src/main/java/org/onap/cli/fw/schema/OnapCommandSchemaLoader.java
framework/src/main/java/org/onap/cli/fw/store/OnapCommandArtifactStore.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/store/OnapCommandExecutionStore.java [new file with mode: 0644]
framework/src/main/java/org/onap/cli/fw/store/OnapCommandProfileStore.java [moved from framework/src/main/java/org/onap/cli/fw/input/cache/OnapCommandParameterCache.java with 54% similarity]
framework/src/main/java/org/onap/cli/fw/utils/OnapCommandDiscoveryUtils.java
framework/src/main/java/org/onap/cli/fw/utils/OnapCommandUtils.java
framework/src/main/resources/META-INF/services/org.onap.cli.fw.cmd.OnapCommand
framework/src/main/resources/log4j.properties
framework/src/main/resources/open-cli-schema/default_input_parameters.yaml
framework/src/main/resources/open-cli-schema/execution/execution-list.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/execution/execution-show.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/open-cli-registry.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/product/product-list.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/product/service-list.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/schema/schema-list.yaml [moved from framework/src/main/resources/open-cli-schema/schema-list.yaml with 76% similarity]
framework/src/main/resources/open-cli-schema/schema/schema-refresh.yaml [moved from framework/src/main/resources/open-cli-schema/schema-refresh.yaml with 94% similarity]
framework/src/main/resources/open-cli-schema/schema/schema-show.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/schema/schema-switch.yaml [new file with mode: 0644]
framework/src/main/resources/open-cli-schema/schema/schema-validate.yaml [moved from framework/src/main/resources/open-cli-schema/schema-validate.yaml with 92% similarity]
framework/src/main/resources/open-cli.properties
framework/src/test/java/org/onap/cli/fw/cmd/OnapSchemaRefreshCommandTest.java
framework/src/test/java/org/onap/cli/fw/error/OnapCommandErrorTest.java
framework/src/test/java/org/onap/cli/fw/input/OnapCommandParameterCacheTest.java
framework/src/test/java/org/onap/cli/fw/input/cache/OnapCommandParameterCacheTest.java
framework/src/test/java/org/onap/cli/fw/registrar/OnapCommandRegistrarTest.java
framework/src/test/java/org/onap/cli/fw/utils/OnapCommandUtilsTest.java
framework/src/test/resources/data/test-profile.json [deleted file]
framework/src/test/resources/data/test2-profile.json [deleted file]
grpc/grpc-client/pom.xml
grpc/grpc-client/src/main/java/org/open/infc/grpc/client/OpenInterfaceGrpcClient.java
grpc/grpc-client/src/main/java/org/open/infc/grpc/client/OpenRemoteCli.java
grpc/grpc-server/src/main/java/org/open/infc/grpc/server/OpenInterfaceGrpcServer.java
grpc/grpc-stub/src/main/proto/oclip.proto
main/src/main/java/org/onap/cli/main/OnapCli.java
main/src/main/java/org/onap/cli/main/utils/OnapCliArgsParser.java
main/src/test/java/org/onap/cli/main/utils/OnapCliUtilsTest.java
profiles/http/src/test/resources/open-cli.properties
profiles/snmp/src/test/resources/open-cli.properties
validate/validation/src/test/resources/open-cli.properties

index 9b8e81a..cca40b2 100644 (file)
@@ -1,6 +1,7 @@
 bin/
 target/
 coverage-report/
+data/
 .project
 .settings
 .classpath
index 659f4a2..d535098 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-log4j.rootLogger=INFO, file
+log4j.rootLogger=ERROR, file
+log4j.logger.org.onap.cli=ERROR, file
+log4j.logger.org.open.infc.grpc.server=INFO, file, stdout
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
 
 # Redirect log messages to a log file, support file rolling.
 log4j.appender.file=org.apache.log4j.RollingFileAppender
-log4j.appender.file.File=${OPEN_CLI_HOME}/logs/oclip.log
+log4j.appender.file.File=${OPEN_CLI_HOME}/logs/open-cli.log
 log4j.appender.file.MaxFileSize=5MB
 log4j.appender.file.MaxBackupIndex=10
 log4j.appender.file.layout=org.apache.log4j.PatternLayout
index 113963b..eca284a 100644 (file)
 # limitations under the License.
 
 cli.product_name=open-cli
-cli.version=2.0.0
-
+cli.version=2.0.5
 cli.discover_always=false
+cli.data.dir=/opt/oclip/data
+cli.artifact.dir=/opt/oclip/artifacts
 
 #schema validation
-cli.schema.base.sections=open_cli_schema_version,name,description,parameters,results,http,info
+cli.schema.base.sections=open_cli_schema_version,name,description,parameters,results,info
 cli.schema.base.sections.mandatory=open_cli_schema_version
 
-cli.schema.base.info.sections=product,service,type,author,ignore
+cli.schema.base.info.sections=product,service,type,author,ignore,state
 cli.schema.base.info.sections.mandatory=product,service
 
-cli.schema.base.parameters.sections=name,description,type,short_option,long_option, is_optional,default_value,is_secured,is_include
+cli.schema.base.parameters.sections=name,description,type,short_option,long_option, is_optional,default_value,is_secured,is_include,is_default_param
 cli.schema.base.parameters.sections.mandatory=name,description,type
 
 cli.schema.base.results.sections=name,description,scope,type,is_secured, default_value
index 9346990..72b2a00 100644 (file)
     <name>cli/framework</name>
     <packaging>jar</packaging>
     <dependencies>
+        <dependency>
+            <groupId>org.onap.cli</groupId>
+            <artifactId>oclip-grpc-client</artifactId>
+            <version>1.0.2</version>
+        </dependency>
         <dependency>
             <groupId>org.yaml</groupId>
             <artifactId>snakeyaml</artifactId>
index f9066ef..dbd2463 100644 (file)
@@ -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();
 
index e874a14..34ccc76 100644 (file)
@@ -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 (file)
index 0000000..aed9224
--- /dev/null
@@ -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 (file)
index 0000000..5470472
--- /dev/null
@@ -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 (file)
index 0000000..8d29c03
--- /dev/null
@@ -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 (file)
index 0000000..d0788c1
--- /dev/null
@@ -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 (file)
index 0000000..8cbfa36
--- /dev/null
@@ -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) : "");
+        }
+    }
+}
  * 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());
             }
  * 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 (file)
index 0000000..b7c027f
--- /dev/null
@@ -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 (file)
index 0000000..ea5c828
--- /dev/null
@@ -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();
+    }
+
+}
  * 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);
     }
 
index 71c44ac..7d169d5 100644 (file)
@@ -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 (file)
index 0000000..6db8042
--- /dev/null
@@ -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 (file)
index 0000000..823b5b0
--- /dev/null
@@ -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 (file)
index 0000000..a2e4dbd
--- /dev/null
@@ -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 (file)
index 0000000..05b0eb5
--- /dev/null
@@ -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 (file)
index 0000000..1174946
--- /dev/null
@@ -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");
+    }
+}
index e34136d..f5aa7b5 100644 (file)
@@ -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);
+    }
 }
@@ -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 (file)
index 0000000..efc7b36
--- /dev/null
@@ -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 (file)
index 0000000..de90979
--- /dev/null
@@ -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);
+    }
+
+}
index 614ef5d..834dea0 100644 (file)
@@ -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 {
index 07c2dbe..d793752 100644 (file)
 
 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;
+    }
 }
index a470325..c1a6412 100644 (file)
@@ -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;
+    }
 }
index a5c0826..fe191f5 100644 (file)
@@ -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 (file)
index 0000000..f01f9a2
--- /dev/null
@@ -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 (file)
index 0000000..71cd245
--- /dev/null
@@ -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");
+        }
+    }
+}
  * 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;
index 26d4965..8c97bd3 100644 (file)
 
 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;
     }
 }
+
index 862e328..e279fa0 100644 (file)
 
 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;
                     }
index 85294cb..547d787 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-org.onap.cli.fw.cmd.OnapSchemaValidateCommand
-org.onap.cli.fw.cmd.OnapSchemaRefreshCommand
-org.onap.cli.fw.cmd.OnapSchemaListCommand
\ No newline at end of file
+org.onap.cli.fw.cmd.schema.OnapSchemaValidateCommand
+org.onap.cli.fw.cmd.schema.OnapSchemaRefreshCommand
+org.onap.cli.fw.cmd.schema.OnapSchemaListCommand
+org.onap.cli.fw.cmd.schema.OnapSchemaShowCommand
+#org.onap.cli.fw.cmd.schema.OnapSchemaSwitchCommand
+org.onap.cli.fw.cmd.product.OnapProductsListCommand
+org.onap.cli.fw.cmd.product.OnapServiceListCommand
+org.onap.cli.fw.cmd.execution.OnapCommandExceutionListCommand
+org.onap.cli.fw.cmd.execution.OnapCommandExceutionShowCommand
index 97422c3..d535098 100644 (file)
@@ -13,9 +13,8 @@
 # limitations under the License.
 
 log4j.rootLogger=ERROR, file
-
 log4j.logger.org.onap.cli=ERROR, file
-
+log4j.logger.org.open.infc.grpc.server=INFO, file, stdout
 # Direct log messages to stdout
 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.Target=System.out
index aab7498..d1a074d 100644 (file)
@@ -72,5 +72,4 @@ parameters:
     short_option: D
     long_option: context
     is_default_param: true
-    is_optional: true
     is_optional: true
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/execution/execution-list.yaml b/framework/src/main/resources/open-cli-schema/execution/execution-list.yaml
new file mode 100644 (file)
index 0000000..55ac6ca
--- /dev/null
@@ -0,0 +1,114 @@
+# 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.
+
+open_cli_schema_version: 1.0
+name: execution-list
+description: List the executions of the given command so far
+
+info:
+  product: open-cli
+  service: execution
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+parameters:
+  - name: request-id
+    type: string
+    description: Request id
+    short_option: e
+    long_option: request-id
+    is_optional: true
+  - name: product
+    type: string
+    description: For a given product version
+    short_option: l
+    long_option: product
+    is_optional: true
+  - name: service
+    type: string
+    description: For a given service
+    short_option: b
+    long_option: service
+    is_optional: true
+  - name: profile
+    type: string
+    description: For a given profile
+    short_option: c
+    long_option: profile
+    is_optional: true
+  - name: command
+    type: string
+    description: For a given command
+    short_option: n
+    long_option: command
+    is_optional: true
+  - name: start-time
+    type: string
+    description: From start time
+    short_option: x
+    long_option: start-time
+    is_optional: true
+  - name: end-time
+    type: string
+    description: Till end time
+    short_option: y
+    long_option: end-time
+    is_optional: true
+results:
+  direction: landscape
+  attributes:
+    - name: request-id
+      description: Request id
+      scope: short
+      type: string
+    - name: execution-id
+      description: Execution id
+      scope: short
+      type: string
+    - name: product
+      description: Product
+      scope: short
+      type: string
+    - name: service
+      description: service
+      scope: short
+      type: string
+    - name: command
+      description: command
+      scope: short
+      type: string
+    - name: profile
+      description: Profile
+      scope: short
+      type: string
+    - name: status
+      description: Execution status
+      scope: short
+      type: string
+    - name: start-time
+      description: Command execution starting Time
+      scope: short
+      type: string
+    - name: end-time
+      description: Command execution finishing Time
+      scope: short
+      type: string
+    - name: input
+      description: Input
+      scope: long
+      type: string
+    - name: output
+      description: Output
+      scope: long
+      type: string
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/execution/execution-show.yaml b/framework/src/main/resources/open-cli-schema/execution/execution-show.yaml
new file mode 100644 (file)
index 0000000..7b4bd59
--- /dev/null
@@ -0,0 +1,74 @@
+# 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.
+
+open_cli_schema_version: 1.0
+name: execution-show
+description: Show the complete executions for the given request id
+
+info:
+  product: open-cli
+  service: execution
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+parameters:
+  - name: execution-id
+    type: string
+    description: Execution id
+    short_option: l
+    long_option: execution-id
+    is_optional: false
+results:
+  direction: portrait
+  attributes:
+    - name: request-id
+      type: string
+      description: Request id
+      scope: short
+    - name: product
+      description: Product
+      scope: short
+      type: string
+    - name: service
+      description: service
+      scope: short
+      type: string
+    - name: command
+      description: command
+      scope: short
+      type: string
+    - name: profile
+      description: Profile
+      scope: short
+      type: string
+    - name: input
+      description: Input
+      scope: short
+      type: string
+    - name: status
+      description: Execution status
+      scope: short
+      type: string
+    - name: start-time
+      description: Command execution starting Time
+      scope: short
+      type: string
+    - name: end-time
+      description: Command execution finishing Time
+      scope: short
+      type: string
+    - name: output
+      description: Output
+      scope: short
+      type: string
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/open-cli-registry.yaml b/framework/src/main/resources/open-cli-schema/open-cli-registry.yaml
new file mode 100644 (file)
index 0000000..9b988b4
--- /dev/null
@@ -0,0 +1,40 @@
+# 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.
+
+open_cli_schema_version: 1.0
+
+product:
+  name: OPEN CLI
+
+  version: 1.0
+
+  description: |
+    OPEN CLI PLATFORM provides a dynamic platform to load and execute commands
+    based on the Open Command Specification (OCS) 1.0.
+
+contact: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+services:
+  - name: product
+    description: Product and service searching abilities
+  - name: schema
+    description: OCS schema management
+  - name: profile
+    description: Profile management
+  - name: artifact
+    description: Artifact management
+  - name: execution
+    description: Execution management
+  - name: rpc
+    description: RPC management across OCLIP
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/product/product-list.yaml b/framework/src/main/resources/open-cli-schema/product/product-list.yaml
new file mode 100644 (file)
index 0000000..6b0d49b
--- /dev/null
@@ -0,0 +1,35 @@
+# 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.
+
+open_cli_schema_version: 1.0
+name: product-list
+description: List available products registered in OCLIP
+
+info:
+  product: open-cli
+  service: product
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+results:
+  direction: landscape
+  attributes:
+    - name: product
+      description: Product name
+      scope: short
+      type: string
+    - name: description
+      description: Product description
+      scope: short
+      type: string
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/product/service-list.yaml b/framework/src/main/resources/open-cli-schema/product/service-list.yaml
new file mode 100644 (file)
index 0000000..8a84b25
--- /dev/null
@@ -0,0 +1,43 @@
+# 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.
+
+open_cli_schema_version: 1.0
+name: service-list
+description: List the services in given product registered in OCLIP
+
+info:
+  product: open-cli
+  service: product
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+parameters:
+  - name: product
+    type: string
+    description: For a given product version
+    short_option: l
+    long_option: product
+    is_optional: false
+
+results:
+  direction: landscape
+  attributes:
+    - name: service
+      description: Service name
+      scope: short
+      type: string
+    - name: description
+      description: Product description
+      scope: short
+      type: string
\ No newline at end of file
@@ -29,20 +29,25 @@ parameters:
     short_option: l
     long_option: product
     is_optional: false
-
+  - name: service
+    type: string
+    description: For a given service in a product
+    short_option: n
+    long_option: service
+    is_optional: true
 results:
   direction: landscape
   attributes:
-    - name: sr.no
-      description: Serial Number
-      scope: short
-      type: string
     - name: command
       description: Command name
       scope: short
       type: string
     - name: schema
       description: Schema name
+      scope: long
+      type: string
+    - name: service
+      description: Service name
       scope: short
       type: string
     - name: ocs-version
@@ -51,5 +56,13 @@ results:
       type: string
     - name: type
       description: Command type
+      scope: long
+      type: string
+    - name: enabled
+      description: Command is enabled or not
+      scope: short
+      type: string
+    - name: rpc
+      description: Command is executed remotely
       scope: short
       type: string
\ No newline at end of file
@@ -25,10 +25,6 @@ info:
 results:
   direction: landscape
   attributes:
-    - name: sr.no
-      description: Serial Number
-      scope: short
-      type: string
     - name: command
       description: Command name
       scope: short
@@ -48,4 +44,8 @@ results:
     - name: type
       description: Command type
       scope: short
+      type: string
+    - name: enabled
+      description: Command is enabled or not
+      scope: short
       type: string
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/schema/schema-show.yaml b/framework/src/main/resources/open-cli-schema/schema/schema-show.yaml
new file mode 100644 (file)
index 0000000..451d36d
--- /dev/null
@@ -0,0 +1,51 @@
+# 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.
+
+open_cli_schema_version: 1.0
+name: schema-show
+description: OCLIP command to show available schema in JSON format
+
+info:
+  product: open-cli
+  service: schema
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+parameters:
+  - name: product
+    type: string
+    description: For a given product version
+    short_option: l
+    long_option: product
+    is_optional: false
+  - name: service
+    type: string
+    description: For a given service
+    short_option: x
+    long_option: service
+    is_optional: true
+  - name: command
+    type: string
+    description: Schema details to fetch
+    short_option: n
+    long_option: command
+    is_optional: false
+
+results:
+  direction: portrait
+  attributes:
+    - name: schema
+      description: Scheam json
+      scope: short
+      type: json
\ No newline at end of file
diff --git a/framework/src/main/resources/open-cli-schema/schema/schema-switch.yaml b/framework/src/main/resources/open-cli-schema/schema/schema-switch.yaml
new file mode 100644 (file)
index 0000000..b676e85
--- /dev/null
@@ -0,0 +1,37 @@
+# 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.
+
+open_cli_schema_version: 1.0
+name: schema-switch
+description: OCLIP command to switch the given command enable/disable
+
+info:
+  product: open-cli
+  service: schema
+  type: cmd
+  author: Kanagaraj Manickam kanagaraj.manickam@huawei.com
+
+parameters:
+  - name: name
+    type: string
+    description: Command name
+    short_option: l
+    long_option: name
+    is_optional: false
+  - name: product
+    type: string
+    description: Product name
+    short_option: i
+    long_option: product
+    is_optional: false
@@ -46,10 +46,6 @@ parameters:
 results:
   direction: landscape
   attributes:
-    - name: sl-no
-      description: Serial Number of error
-      scope: short
-      type: string
     - name: error
       description: Schema validation error
       scope: short
index 012c449..e0ca44a 100644 (file)
@@ -15,6 +15,8 @@
 cli.product_name=open-cli
 cli.version=2.0.5
 cli.discover_always=false
+cli.data.dir=data
+cli.artifact.dir=d:/temp/OCLIP
 
 #schema validation
 cli.schema.base.sections=open_cli_schema_version,name,description,parameters,results,info
index 99f4519..43bb188 100644 (file)
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue;
 import java.util.List;
 
 import org.junit.Test;
+import org.onap.cli.fw.cmd.schema.OnapSchemaRefreshCommand;
 import org.onap.cli.fw.error.OnapCommandException;
 import org.onap.cli.fw.output.OnapCommandResultAttribute;
 
index 2dcb9ce..02e951b 100644 (file)
@@ -231,11 +231,11 @@ public class OnapCommandErrorTest {
 
     @Test
     public void oclipProfileLoadTest() {
-        OnapCommandLoadProfileFailed failed = new OnapCommandLoadProfileFailed("error");
+        OnapCommandProfileLoadFailed failed = new OnapCommandProfileLoadFailed("error");
 
         assertEquals("0xc001::Failed to load profile details, error", failed.getMessage());
 
-        failed = new OnapCommandLoadProfileFailed(new Exception("error"));
+        failed = new OnapCommandProfileLoadFailed(new Exception("error"));
 
         assertEquals("0xc001::Failed to load profile details, error", failed.getMessage());
     }
index 302d280..c2f3bd6 100644 (file)
 package org.onap.cli.fw.input;
 
 import org.junit.Test;
-import org.onap.cli.fw.input.cache.OnapCommandParameterCache;
+import org.onap.cli.fw.store.OnapCommandProfileStore;
 
 public class OnapCommandParameterCacheTest {
 
     @Test
     public void test() {
-        OnapCommandParameterCache cache = OnapCommandParameterCache.getInstance();
-
-        cache.add("1.0", "a", "b");
-        cache.remove("1.0", "a");
-        cache.setProfile("test123");
-        cache.getParams("1.0");
+        OnapCommandProfileStore cache = OnapCommandProfileStore.getInstance();
     }
 
 
index be53994..76844d7 100644 (file)
@@ -18,16 +18,19 @@ package org.onap.cli.fw.input.cache;
 
 import static org.junit.Assert.assertTrue;
 
-import org.junit.Test;
+import java.io.File;
+import java.io.IOException;
 
+import org.apache.commons.io.FileUtils;
+import org.junit.Test;
 
 public class OnapCommandParameterCacheTest {
     @Test
-    public void paramTypeGetTest() {
-
-        assertTrue(OnapCommandParameterCache.getInstance().getProfiles().contains("test"));
-
-
+    public void paramTypeGetTest() throws IOException {
+        FileUtils.forceMkdir(new File("data"));
+        FileUtils.touch(new File("data" + File.separator + "test-profile.json"));
+        //assertTrue(OnapCommandProfileStore.getInstance().getProfiles().contains("test"));
+        // FileUtils.cleanDirectory(new File("data"));
     }
 
 }
index b798915..800a6c9 100644 (file)
@@ -88,27 +88,6 @@ public class OnapCommandRegistrarTest {
         registerar.listCommands();
     }
 
-    @Test
-    public void testProfile() throws OnapCommandException {
-        try {
-            OnapCommandRegistrar.getRegistrar().setProfile("test234", new ArrayList<String>(), new ArrayList<String>());
-            OnapCommandRegistrar.getRegistrar().addParamCache("a", "b");
-            OnapCommandRegistrar.getRegistrar().getParamCache();
-            OnapCommandRegistrar.getRegistrar().removeParamCache("a");
-            OnapCommandRegistrar.getRegistrar().setInteractiveMode(false);
-            assertTrue(!OnapCommandRegistrar.getRegistrar().isInteractiveMode());
-            OnapCommandRegistrar.getRegistrar().setEnabledProductVersion("open-cli");
-            assertEquals("open-cli", OnapCommandRegistrar.getRegistrar().getEnabledProductVersion());
-            OnapCommandRegistrar.getRegistrar().getAvailableProductVersions();
-            assertTrue(
-                OnapCommandRegistrar.getRegistrar().listCommandsForEnabledProductVersion().contains("sample-test"));
-            assertTrue(OnapCommandRegistrar.getRegistrar().listCommandInfo().size() > 2);
-        } catch (Exception e) {
-            fail("failed to test the profile");
-        }
-    }
-
-
     @Test
     public void test() throws OnapCommandException {
         OnapCommandRegistrar registrar = OnapCommandRegistrar.getRegistrar();
index dd956b9..1489006 100644 (file)
@@ -242,7 +242,7 @@ public class OnapCommandUtilsTest {
     @Test
     public void findOnapCommandsTest() {
         List<Class<OnapCommand>> cmds = OnapCommandDiscoveryUtils.discoverCommandPlugins();
-        assertTrue(cmds.size() == 4);
+        assertTrue(cmds.size() >= 1);
     }
 
     @Test
diff --git a/framework/src/test/resources/data/test-profile.json b/framework/src/test/resources/data/test-profile.json
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/framework/src/test/resources/data/test2-profile.json b/framework/src/test/resources/data/test2-profile.json
deleted file mode 100644 (file)
index e69de29..0000000
index 37c0276..15e4f5b 100644 (file)
           <artifactId>oclip-grpc-stub</artifactId>
           <version>${project.version}</version>
       </dependency>
+      <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.16</version>
+        </dependency>
   </dependencies>
    <build>
         <plugins>
index e61f54f..2d9d32f 100644 (file)
@@ -18,8 +18,8 @@
 package org.open.infc.grpc.client;
 
 import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import org.open.infc.grpc.Args;
 import org.open.infc.grpc.Input;
@@ -32,7 +32,7 @@ import io.grpc.ManagedChannelBuilder;
 import io.grpc.StatusRuntimeException;
 
 public class OpenInterfaceGrpcClient {
-      private static final Logger logger = Logger.getLogger(OpenInterfaceGrpcClient.class.getName());
+      private static final Logger logger = LoggerFactory.getLogger(OpenInterfaceGrpcClient.class.getName());
 
       private final ManagedChannel channel;
       private final OpenInterfaceGrpc.OpenInterfaceBlockingStub blockingStub;
@@ -61,7 +61,7 @@ public class OpenInterfaceGrpcClient {
         try {
             result = blockingStub.invoke(input);
         } catch (StatusRuntimeException e) {
-          logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
+          logger.warn("RPC failed: {0}", e.getStatus());
         }
         logger.info("Output: " + result.toString());
         return result;
@@ -74,7 +74,7 @@ public class OpenInterfaceGrpcClient {
         try {
             result = blockingStub.remoteCli(args);
         } catch (StatusRuntimeException e) {
-          logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
+          logger.warn("RPC failed: {0}", e.getStatus());
         }
 
         logger.info("Result: " + result.toString());
index 0e9eba7..fc0c2aa 100644 (file)
 
 package org.open.infc.grpc.client;
 
-import java.net.URL;
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
-import java.util.logging.Logger;
+import java.util.Map;
 
 import org.open.infc.grpc.Args;
+import org.open.infc.grpc.Input;
+import org.open.infc.grpc.Output;
 import org.open.infc.grpc.Result;
 
 public class OpenRemoteCli {
-    public static final String OCLIP_GRPC_SERVER = "http://localhost:50051";
-    public static final String OCLIP_GRPC_SERVER_ENV = "OCLIP_GRPC_SERVER";
-
-    public static Result run (String[] args) throws Exception {
-        String oclipHome = System.getenv(OCLIP_GRPC_SERVER_ENV);
-
-        if (oclipHome == null) {
-            oclipHome = OCLIP_GRPC_SERVER;
-        }
-
-          if (System.getenv("OPEN_CLI_DEBUG") == null) {
-              Logger globalLogger = Logger.getLogger(OpenInterfaceGrpcClient.class.getName());
-              globalLogger.setLevel(java.util.logging.Level.OFF);
-          } else {
-              System.out.println(OCLIP_GRPC_SERVER_ENV + "=" + oclipHome);
-          }
-
-          if (args.length <= 2 || !args[0].equals("-P")) {
-              System.out.println("Usage: oclip -P <product-name> <command-name> <command-arguments");
-              System.out.println("NOTE: Set environment variable " + OCLIP_GRPC_SERVER_ENV + " to OCLIP gRPC server. By default its " + OCLIP_GRPC_SERVER);
-              System.exit(0);
-          }
-
-          List<String> argList = new ArrayList<>();
-
-          for (String arg: args) {
-              argList.add(arg);
-          }
-
-          //-P
-          argList.remove(0);
-
-          //<product-name>
-          String product = argList.remove(0);
-
-          URL oclipUrl = new URL(oclipHome);
+    /**
+     * Runs CLI remotely
+     * @param host
+     * @param port
+     * @param product
+     * @param cmd
+     * @param args
+     * @return
+     * @throws Exception
+     */
+    public static Result run (String host, int port, String reqId, List <String> args) throws Exception {
           OpenInterfaceGrpcClient client = new OpenInterfaceGrpcClient(
-                  oclipUrl.getHost(), oclipUrl.getPort());
+                  host, port);
 
           try {
-              Result result = client.remoteCli(Args.newBuilder().addAllArgs(argList).setProduct(product).build());
+              Result result = client.remoteCli(Args.newBuilder().setRequestId(reqId).addAllArgs(args).build());
               return result;
           } finally {
             client.shutdown();
           }
     }
 
+    /**
+     * Runs commands as remote procedure call :)
+     * @param host
+     * @param port
+     * @param product
+     * @param action
+     * @param reqId
+     * @param params
+     * @return
+     * @throws Exception
+     */
+    public static Output invoke (String host, int port, String product, String profile, String action, String reqId, Map <String, String> params) throws Exception {
+        OpenInterfaceGrpcClient client = new OpenInterfaceGrpcClient(
+                host, port);
 
-    public static void main(String[] args) throws Exception {
-        int exitCode = 1;
         try {
-            Result result = OpenRemoteCli.run(args);
-            System.out.println(result.getOutput());
-            exitCode = result.getExitCode();
+
+            Map <String, String> options = new HashMap<>();
+            options.put("product", product);
+            if (profile != null && !profile.isEmpty())
+                options.put("profile", profile);
+            params.put("format", "json");
+            Input input = Input.newBuilder().setAction(action).setRequestId(reqId).putAllOptions(options).putAllParams(params).build();
+
+            Output output = client.invoke(input);
+            return output;
         } finally {
-            System.exit(exitCode);
-          }
+          client.shutdown();
+        }
     }
 }
index 05e3f67..45a6408 100644 (file)
 package org.open.infc.grpc.server;
 
 import java.io.IOException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
-import java.util.logging.Logger;
+import java.util.Set;
 
 import org.onap.cli.fw.cmd.OnapCommand;
 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.input.OnapCommandParameter;
 import org.onap.cli.fw.output.OnapCommandResultType;
 import org.onap.cli.fw.registrar.OnapCommandRegistrar;
+import org.onap.cli.fw.store.OnapCommandExecutionStore;
+import org.onap.cli.fw.store.OnapCommandExecutionStore.ExecutionStoreContext;
 import org.onap.cli.main.OnapCli;
 import org.open.infc.grpc.Args;
 import org.open.infc.grpc.Input;
@@ -33,6 +40,10 @@ import org.open.infc.grpc.OpenInterfaceGrpc;
 import org.open.infc.grpc.Output;
 import org.open.infc.grpc.Output.Builder;
 import org.open.infc.grpc.Result;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 import io.grpc.Server;
 import io.grpc.ServerBuilder;
@@ -40,7 +51,7 @@ import io.grpc.stub.StreamObserver;
 
 public class OpenInterfaceGrpcServer {
 
-      private static final Logger logger = Logger.getLogger(OpenInterfaceGrpcServer.class.getName());
+      private static final Logger logger = LoggerFactory.getLogger(OpenInterfaceGrpcServer.class.getName());
 
       private static final String CONF_FILE = "oclip-grpc-server.properties";
       private static final String CONF_SERVER_PORT = "oclip.grpc_server_port";
@@ -50,14 +61,22 @@ public class OpenInterfaceGrpcServer {
       }
       private Server server;
 
-      private void start() throws IOException {
+      private void start(String portArg) throws IOException {
         /* The port on which the server should run */
-        int port = Integer.parseInt(OnapCommandConfig.getPropertyValue(CONF_SERVER_PORT));
+        int port = Integer.parseInt(portArg == null ? OnapCommandConfig.getPropertyValue(CONF_SERVER_PORT) : portArg);
         server = ServerBuilder.forPort(port)
             .addService(new OpenInterfaceGrpcImpl())
             .build()
             .start();
         logger.info("Server started, listening on " + port);
+
+        try {
+            OnapCommandRegistrar.getRegistrar().setHost(InetAddress.getLocalHost().getHostAddress().trim());
+            OnapCommandRegistrar.getRegistrar().setPort(port);
+        } catch (OnapCommandException e) {
+            //Never Occurs
+        }
+
         Runtime.getRuntime().addShutdownHook(new Thread() {
           @Override
           public void run() {
@@ -89,15 +108,16 @@ public class OpenInterfaceGrpcServer {
        */
       public static void main(String[] args) throws IOException, InterruptedException {
         final OpenInterfaceGrpcServer server = new OpenInterfaceGrpcServer();
-        server.start();
+        server.start(args.length ==1 ? args[0] : null);
         server.blockUntilShutdown();
       }
 
       static class OpenRemoteCli extends OnapCli {
-          private String outputs = "";
-          public OpenRemoteCli(String product, String[] args) {
-            super(product, args);
-          }
+          public OpenRemoteCli(String[] args) {
+            super(args);
+        }
+
+        private String outputs = "";
 
           public void print(String msg) {
               outputs += msg + "\n";
@@ -112,32 +132,126 @@ public class OpenInterfaceGrpcServer {
 
         @Override
         public void invoke(Input req, StreamObserver<Output> responseObserver) {
-            Builder reply = Output.newBuilder();
+            Output output = null;
             logger.info(req.toString());
 
-            String product = req.getOptionsMap().get(OnapCommandConstants.OPEN_CLI_PRODUCT_NAME);
+            String product = req.getOptionsMap().get(OnapCommandConstants.RPC_PRODUCT);
             String format =  req.getOptionsMap().getOrDefault(OnapCommandConstants.DEFAULT_PARAMETER_OUTPUT_FORMAT, OnapCommandResultType.JSON.name().toLowerCase());
-            String command = req.getAction();
+            String commandName = req.getAction();
+            String profile = req.getOptionsMap().get(OnapCommandConstants.RPC_PROFILE);
+            OnapCommand cmd = null;
 
+            ExecutionStoreContext executionStoreContext = null;
             try {
-                OnapCommand cmd = OnapCommandRegistrar.getRegistrar().get(command, product);
+                cmd = OnapCommandRegistrar.getRegistrar().get(commandName, product);
                 cmd.getParametersMap().get(OnapCommandConstants.DEFAULT_PARAMETER_OUTPUT_FORMAT).setValue(format);
-                for (Entry<String, String> arg: req.getParams().entrySet()) {
-                    cmd.getParametersMap().get(arg.getKey()).setValue(arg.getValue());
+
+                if (!cmd.isRpc()) {
+                    if (profile != null) {
+                        //Set the profile to current one
+                        OnapCommandRegistrar.getRegistrar().setProfile(
+                                profile,
+                                new ArrayList<String>(),
+                                new ArrayList<String>());
+
+                        //fill from profile
+                        for (OnapCommandParameter param: cmd.getParameters()) {
+                            Map<String, String> cache= OnapCommandRegistrar.getRegistrar().getParamCache(product);
+                            if (cache.containsKey(
+                                    cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption())) {
+                                param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
+                                        cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption()));
+                            } else if (cache.containsKey(
+                                    cmd.getInfo().getService() + ":" + param.getLongOption())) {
+                                param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
+                                        cmd.getInfo().getService() + ":" + param.getLongOption()));
+                            } else if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(param.getLongOption())) {
+                                param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(param.getLongOption()));
+                            }
+                        }
+                    }
+
+                    Set <String> params = cmd.getParametersMap().keySet();
+                    for (Entry<String, String> arg: req.getParamsMap().entrySet()) {
+                        if (params.contains(arg.getKey()))
+                            cmd.getParametersMap().get(arg.getKey()).setValue(arg.getValue());
+                    }
+                } else {
+                    cmd.getParametersMap().get(OnapCommandConstants.INFO_PRODUCT).setValue(product);
+
+                    if (profile != null)
+                        cmd.getParametersMap().get(OnapCommandConstants.RPC_PROFILE).setValue(profile);
+
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_CMD).setValue(commandName);
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_ARGS).setValue(req.getParamsMap());
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_MODE).setValue(OnapCommandConstants.RPC_MODE_RUN_RPC);
                 }
+
+                if (!cmd.isRpc()) {
+                    //Start the execution
+                    if (req.getRequestId() != null) {
+                        String input = cmd.getArgsJson(true);
+                        executionStoreContext = OnapCommandExecutionStore.getStore().storeExectutionStart(
+                                req.getRequestId(),
+                                cmd.getInfo().getProduct(),
+                                cmd.getInfo().getService(),
+                                cmd.getName(),
+                                profile,
+                                input);
+                    }
+                }
+
                 cmd.execute();
 
-                reply.putAttrs(OnapCommandConstants.RESULTS, cmd.getResult().print());
-                reply.setSuccess(true);
-                reply.putAttrs(OnapCommandConstants.ERROR, "{}");
+                if (!cmd.isRpc()) {
+                    String printOut = cmd.getResult().print();
+                    Builder reply = Output.newBuilder();
+                    reply.setSuccess(true);
+                    reply.putAttrs(OnapCommandConstants.ERROR, "{}");
+                    reply.putAddons("execution-id", executionStoreContext.getExecutionId());
+                    try {
+                        reply.putAttrs(OnapCommandConstants.RESULTS, new ObjectMapper().readTree(printOut).toString());
+                    } catch (IOException e) {
+                        reply.putAttrs(OnapCommandConstants.RESULTS, printOut);
+                    }
+
+                    output = reply.build();
+
+                    if (req.getRequestId() != null) {
+                        //complete the execution recording
+                         OnapCommandExecutionStore.getStore().storeExectutionEnd(
+                                 executionStoreContext,
+                                 printOut,
+                                 null,
+                                 cmd.getResult().isPassed());
+                    }
+                    logger.info(output.toString());
+                } else {
+                    //Rpc command will set the output.
+                    output = (Output) cmd.getResult().getOutput();
+                }
+
             } catch (OnapCommandException e) {
                 logger.info(e.getMessage());
+
+
+                Builder reply = Output.newBuilder();
                 reply.putAttrs(OnapCommandConstants.RESULTS, "{}");
                 reply.setSuccess(false);
                 reply.putAttrs(OnapCommandConstants.ERROR, e.toJsonString());
+                if (executionStoreContext != null) {
+                       OnapCommandExecutionStore.getStore().storeExectutionEnd(
+                                executionStoreContext,
+                                null,
+                                e.getMessage(),
+                                false);
+                      reply.putAddons("execution-id", executionStoreContext.getExecutionId());
+                }
+
+                output = reply.build();
             }
 
-            responseObserver.onNext(reply.build());
+            responseObserver.onNext(output);
             responseObserver.onCompleted();
         }
 
@@ -145,7 +259,14 @@ public class OpenInterfaceGrpcServer {
         public void remoteCli(Args req, StreamObserver<Result> responseObserver) {
             logger.info(req.toString());
 
-            OpenRemoteCli cli = new OpenRemoteCli(req.getProduct(), req.getArgsList().toArray(new String [] {}));
+            List<String> args = new ArrayList<>();
+            if (req.getRequestId() != null) {
+                args.add(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_REQID));
+                args.add(req.getRequestId());
+            }
+
+            args.addAll(req.getArgsList());
+            OpenRemoteCli cli = new OpenRemoteCli(args.toArray(new String [] {}));
             cli.handle();
             logger.info(cli.getResult());
             Result reply = Result.newBuilder().setExitCode(cli.getExitCode()).setOutput(cli.getResult()).build();
index 0322482..b4e77a3 100644 (file)
@@ -43,8 +43,9 @@ message Output {
 
 //Used for remote CLI
 message Args{
-    repeated string args = 1;
-    string product = 2;
+    string requestId = 1;
+    string action = 2;
+    repeated string args = 3;
 }
 
 message Result {
index de6d232..0392dae 100644 (file)
 
 package org.onap.cli.main;
 
-import jline.TerminalFactory;
-import jline.console.ConsoleReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+
 import org.apache.commons.io.IOUtils;
 import org.onap.cli.fw.cmd.OnapCommand;
 import org.onap.cli.fw.conf.OnapCommandConfig;
@@ -33,25 +40,22 @@ 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.registrar.OnapCommandRegistrar;
+import org.onap.cli.fw.store.OnapCommandExecutionStore;
+import org.onap.cli.fw.store.OnapCommandExecutionStore.ExecutionStoreContext;
 import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils;
 import org.onap.cli.main.conf.OnapCliConstants;
 import org.onap.cli.main.interactive.StringCompleter;
 import org.onap.cli.main.utils.OnapCliArgsParser;
 import org.onap.cli.sample.yaml.SampleYamlGenerator;
+import org.open.infc.grpc.Result;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
+import jline.TerminalFactory;
+import jline.console.ConsoleReader;
 
 /**
- * Oclip Command Line Interface (CLI).
+ * OCLIP Command Line Interface (CLI).
  *
  */
 public class OnapCli {
@@ -60,19 +64,32 @@ public class OnapCli {
 
     private List<String> args = new ArrayList<>();
 
+    private List<String> argsParamFile = new ArrayList<>();
+
     private String product = null;
 
+    private String profile = null;
+
+    private String paramFile = null;
+
+    private String rpcHost = null;
+
+    private String rpcPort = null;
+
+    private boolean printHelp = false;
+
+    private boolean printVersion = false;
+
+    private String requestId = null;
+
+    private String cmdName = null;
+
     private int exitCode = -1;
 
     public OnapCli(String[] args) {
         this.setArgs(args);
     }
 
-    public OnapCli(String product, String[] args) {
-        this(args);
-        this.setProduct(product);
-    }
-
     public OnapCli() {
     }
 
@@ -81,12 +98,55 @@ public class OnapCli {
     }
 
     public void setArgs(String [] args) {
+        //--help --version --requestId --rpc-host xxx --rpc-port xxx --product xxx --profile xxx --param-file xxx CMD blah blah
+
+        int cmdIdx = 0; //index of CMD
+        while(args.length > cmdIdx) {
+            //no options given, directly command name invoked
+            if (!args[cmdIdx].startsWith("-")) {
+                break;
+            }
+
+            if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_PRODUCT))) {
+                this.product = args[++cmdIdx];
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_PROFILE))) {
+                this.profile = args[++cmdIdx];
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_HOST))) {
+                this.rpcHost = args[++cmdIdx];
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_PORT))) {
+                this.rpcPort = args[++cmdIdx];
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCliConstants.PARAM_PARAM_FILE_LONG))) {
+                this.paramFile = args[++cmdIdx];
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCommandConstants.RPC_REQID))) {
+                this.requestId = args[++cmdIdx];
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCliConstants.PARAM_HELP_LOGN)) ||
+                    args[cmdIdx].equals(OnapCommandParameter.printShortOption(OnapCliConstants.PARAM_HELP_SHORT))) {
+                this.printHelp = true;
+                cmdIdx++; //move to next option
+            } else if (args[cmdIdx].equals(OnapCommandParameter.printLongOption(OnapCliConstants.PARAM_VERSION_LONG)) ||
+                    args[cmdIdx].equals(OnapCommandParameter.printShortOption(OnapCliConstants.PARAM_VERSION_SHORT))) {
+                this.printVersion = true;
+                cmdIdx++; //move to next option
+            }
+        }
+
+        if (args.length > cmdIdx) {
+            this.cmdName = args[cmdIdx];
+            cmdIdx ++;
+        }
+
         this.args.clear();
-        this.args.addAll(Arrays.asList(args));
-    }
 
-    public void setProduct(String product) {
-         this.product = product;
+        //add all args starting from the command name
+        for (int i=cmdIdx; i<args.length; i++) {
+            this.args.add(args[i]);
+        }
     }
 
     private void exitSuccessfully() {
@@ -123,8 +183,7 @@ public class OnapCli {
      */
     public void handleHelp() {
         try {
-            if ((args.size() == 1) && (this.getLongOption(OnapCliConstants.PARAM_HELP_LOGN).equals(args.get(0))
-                    || this.getShortOption(OnapCliConstants.PARAM_HELP_SHORT).equals(args.get(0)))) {
+            if (this.printHelp) {
                 this.print(IOUtils.toString(this.getClass().getClassLoader().getResourceAsStream("oclip-readme.txt")));
                 String help = OnapCommandRegistrar.getRegistrar().getHelp();
                 this.print(help);
@@ -141,8 +200,7 @@ public class OnapCli {
      */
     public void handleVersion() {
         try {
-            if ((args.size() == 1) && (this.getLongOption(OnapCliConstants.PARAM_VERSION_LONG).equals(args.get(0))
-                    || this.getShortOption(OnapCliConstants.PARAM_VERSION_SHORT).equals(args.get(0)))) {
+            if (this.printVersion) {
                 String version = OnapCommandRegistrar.getRegistrar().getVersion();
                 this.print(version);
                 this.exitSuccessfully();
@@ -155,20 +213,15 @@ public class OnapCli {
 
 
     /**
-     * Handles profile. --profile or -c
+     * Handles profile. --profile
      */
     public void handleProfile() {
         try {
-            if ((this.args.size() >= 2) && (this.getLongOption(OnapCliConstants.PARAM_PROFILE_LONG).equals(this.args.get(0))
-                    || this.getShortOption(OnapCliConstants.PARAM_PROFILE_SHORT).equals(this.args.get(0)))) {
-
+            if (this.profile != null) {
                 OnapCommandRegistrar.getRegistrar().setProfile(
-                        this.args.get(1),
+                        this.profile,
                         new ArrayList<String>(),
                         new ArrayList<String>());
-                //Make space of interactive mode/command mode
-                this.args.remove(0); //--profile or -c
-                this.args.remove(0); //profile name
             }
         } catch (Exception e) {
             this.print(e);
@@ -177,20 +230,11 @@ public class OnapCli {
     }
 
     /**
-     * Handles batch command. --param-file or -p
-     * CAUTION: This option should be passed after --profile always.
+     * Handles batch command. --param-file
      */
     public void handleBatchCommand() {
         try {
-            if ((this.args.size() >= 3) && (this.getLongOption(OnapCliConstants.PARAM_PARAM_FILE_LONG).equals(this.args.get(0))
-                    || this.getShortOption(OnapCliConstants.PARAM_PARAM_FILE_SHORT).equals(this.args.get(0)))) {
-
-                String paramFilePath = this.args.get(1);
-
-                //Make space of interactive mode/command mode
-                this.args.remove(0); //--param-file or -p
-                this.args.remove(0); //file name
-
+            if (this.paramFile != null) {
                 //Read YAML and loop thru it
                 // one
                 // - param-long-option-1: value
@@ -203,28 +247,24 @@ public class OnapCli {
                 // - positional-arg1
                 // - positional-arg2
                 try {
-                    Map<String, Object> values = (Map<String, Object>) OnapCommandDiscoveryUtils.loadYaml(paramFilePath);
+                    Map<String, Object> values = (Map<String, Object>) OnapCommandDiscoveryUtils.loadYaml(this.paramFile);
 
                     for (Entry<String, Object> cmdsParam: values.entrySet()) {
-                        List<String> args = new ArrayList<>();
-                        args.add(this.args.get(0));
                         for (Object param: (List)cmdsParam.getValue()) {
                             if (param instanceof Map) { //optional args
                                 Map <String, String> paramMap = (Map<String, String>) param;
                                 String paramName = paramMap.keySet().iterator().next();
                                 Object paramValue = paramMap.get(paramName);
-                                args.add("--" + paramName);
-                                args.add(paramValue.toString());
+                                argsParamFile.add(this.getLongOption(paramName));
+                                argsParamFile.add(paramValue.toString());
                             } else { //positional args
-                                args.add(param.toString());
+                                argsParamFile.add(param.toString());
                             }
                         }
-
-                        this.handleCommand(args);
                     }
 
                 } catch (Exception e) { // NOSONAR
-                    this.print("Failed to read param file " + paramFilePath);
+                    this.print("Failed to read param file " + this.paramFile);
                     this.print(e);
                 }
             }
@@ -266,8 +306,12 @@ public class OnapCli {
             sampleFileAtt.getValues().add((String) sampleTest.get(OnapCommandConstants.VERIFY_SAMPLE_FILE_ID));
             sampleIdAtt.getValues().add((String) sampleTest.get(OnapCommandConstants.VERIFY_SAMPLE_ID));
 
-            cmd = OnapCommandRegistrar.getRegistrar().get(args.get(0));
-            OnapCliArgsParser.populateParams(cmd.getParameters(), (List<String>) sampleTest.get(OnapCommandConstants.VERIFY_INPUT));
+            cmd = OnapCommandRegistrar.getRegistrar().get(this.cmdName);
+            List<String> arguments = (List<String>) sampleTest.get(OnapCommandConstants.VERIFY_INPUT);
+            if (arguments.size() > 0 && arguments.get(0).equals(this.cmdName)) {
+                arguments.remove(0);
+            }
+            OnapCliArgsParser.populateParams(cmd.getParameters(), arguments);
             this.print("\n***************Test Command: \n" + sampleTest.get(OnapCommandConstants.VERIFY_INPUT).toString());
 
             cmd.getParametersMap().get(OnapCommandConstants.DEFAULT_PARAMETER_DEBUG).setValue(Boolean.TRUE);
@@ -310,11 +354,12 @@ public class OnapCli {
 
         this.print(testSuiteResult.print());
     }
+
     /**
      * Handles Interactive Mode.
      */
     public void handleInteractive() { // NOSONAR
-        if (args.isEmpty()) {
+        if (this.cmdName == null) {
             ConsoleReader console = null;
             try {
                 OnapCommandRegistrar.getRegistrar().setInteractiveMode(true);
@@ -354,7 +399,7 @@ public class OnapCli {
                         }
 
                     } else if (!args.isEmpty() && this.args.get(0).equals(OnapCliConstants.PARAM_INTERACTIVE_VERSION)) {
-                        this.args = Arrays.asList(new String [] {this.getLongOption(OnapCliConstants.PARAM_VERSION_LONG)});
+                        this.printVersion = true;
                         handleVersion();
 
                     } else if (!args.isEmpty() && this.args.get(0).equals(OnapCliConstants.PARAM_INTERACTIVE_PROFILE)) {
@@ -363,7 +408,7 @@ public class OnapCli {
                             this.print("Available profiles: ");
                             this.print(OnapCommandRegistrar.getRegistrar().getUserProfiles().toString());
                         } else {
-                            this.args.set(0, this.getLongOption(OnapCliConstants.PARAM_PROFILE_LONG));
+                            this.profile = args.get(1);
                             handleProfile();
                         }
 
@@ -391,7 +436,7 @@ public class OnapCli {
                             continue;
                         }
 
-                        handleCommand(new ArrayList<>());
+                        handleCommand();
                     }
                 }
             } catch (IOException e) { // NOSONAR
@@ -412,14 +457,14 @@ public class OnapCli {
     /**
      * Handles command.
      */
-    public void handleCommand(List<String> params) {
-        OnapCommand cmd;
-        if (!args.isEmpty()) {
+    public void handleCommand() {
+        OnapCommand cmd = null;
+        if (this.cmdName != null) {
             try {
                 if (this.product != null) {
-                    cmd = OnapCommandRegistrar.getRegistrar().get(args.get(0), this.product);
+                    cmd = OnapCommandRegistrar.getRegistrar().get(this.cmdName, this.product);
                 } else {
-                    cmd = OnapCommandRegistrar.getRegistrar().get(args.get(0));
+                    cmd = OnapCommandRegistrar.getRegistrar().get(this.cmdName);
                 }
             } catch (Exception e) {
                 this.print(e);
@@ -427,7 +472,14 @@ public class OnapCli {
                 return;
             }
 
+            ExecutionStoreContext executionStoreContext = null;
+
             try {
+                //Registrar identified this command marked with rpc as true and it will make direct RPC command call...
+                if (cmd.isRpc() && !this.cmdName.equals("schema-rpc")) {
+                    this.handleRpcCommand(cmd);
+                    return;
+                }
 
                 // verify
                 if(args.contains(OnapCommandConstants.VERIFY_LONG_OPTION)
@@ -454,35 +506,74 @@ public class OnapCli {
                 }
 
                 //refer params from profile
-                for (OnapCommandParameter param: cmd.getParameters()) {
-                    if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(
-                            cmd.getInfo().getService() + ":" + param.getLongOption())) {
-                        param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
-                                cmd.getInfo().getService() + ":" + param.getLongOption()));
-                    } else if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(param.getLongOption())) {
-                        param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(param.getLongOption()));
+                if (this.profile != null)
+                    for (OnapCommandParameter param: cmd.getParameters()) {
+                        if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(
+                                cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption())) {
+                            param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
+                                    cmd.getInfo().getService() + ":" + cmd.getName() + ":" + param.getLongOption()));
+                        } else if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(
+                                cmd.getInfo().getService() + ":" + param.getLongOption())) {
+                            param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(
+                                    cmd.getInfo().getService() + ":" + param.getLongOption()));
+                        } else if (OnapCommandRegistrar.getRegistrar().getParamCache().containsKey(param.getLongOption())) {
+                            param.setValue(OnapCommandRegistrar.getRegistrar().getParamCache().get(param.getLongOption()));
+                        }
                     }
-                }
 
                 //load the parameters value from the map read from param-file
-                if (params != null && !params.isEmpty()) {
-                    OnapCliArgsParser.populateParams(cmd.getParameters(), params);
+                if (!this.argsParamFile.isEmpty()) {
+                    OnapCliArgsParser.populateParams(cmd.getParameters(), this.argsParamFile);
                 }
 
-                OnapCliArgsParser.populateParams(cmd.getParameters(), args);
+                OnapCliArgsParser.populateParams(cmd.getParameters(), this.args);
+
+                //start the execution
+                if (this.requestId != null) {
+                    String input = cmd.getArgsJson(true);
+                    executionStoreContext = OnapCommandExecutionStore.getStore().storeExectutionStart(
+                            this.requestId,
+                            cmd.getInfo().getProduct(),
+                            cmd.getInfo().getService(),
+                            this.cmdName,
+                            this.profile,
+                            input);
+                }
 
                 OnapCommandResult result = cmd.execute();
 
+                String printOut = result.print();
+                if (this.requestId != null) {
+                    OnapCommandExecutionStore.getStore().storeExectutionEnd(
+                            executionStoreContext,
+                            printOut,
+                            null, result.isPassed());
+                }
+
                 this.print(result.getDebugInfo());
-                this.print(result.print());
-                this.exitSuccessfully();
+                this.print(printOut);
+
+                if (result.isPassed()) {
+                    this.exitSuccessfully();
+                    generateSmapleYaml(cmd);
+                }
+
+                else this.exitFailure();
+
 
-                generateSmapleYaml(cmd);
             } catch (OnapCommandWarning w) {
                 this.print(w);
                 this.print(cmd.getResult().getDebugInfo());
                 this.exitSuccessfully();
             } catch (Exception e) {
+                if (executionStoreContext != null) {
+                    OnapCommandExecutionStore.getStore().storeExectutionEnd(
+                            executionStoreContext,
+                            null,
+                            e.getMessage(),
+                            false);
+                }
+
                 this.print(e);
                 this.print(cmd.getResult().getDebugInfo());
                 this.exitFailure();
@@ -490,11 +581,52 @@ public class OnapCli {
         }
     }
 
+    /**
+     * When user invokes cli with RPC arguments...
+     */
+    public void handleRpc() {
+        if (!this.args.isEmpty()) {
+            try {
+                if (this.rpcHost != null && this.rpcPort != null && this.product != null) {
+                    OnapCommand cmd = OnapCommandRegistrar.getRegistrar().get("schema-rpc", "open-cli");
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_HOST).setValue(this.rpcHost);
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_PORT).setValue(this.rpcPort);
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_PRODUCT).setValue(this.product);
+                    cmd.getParametersMap().get(OnapCommandConstants.RPC_CMD).setValue(this.cmdName);
+
+                    this.handleRpcCommand(cmd);
+                }
+            } catch (Exception e) {
+                this.print(e);
+                this.exitFailure();
+            }
+        }
+    }
+
+    private void handleRpcCommand(OnapCommand cmd) throws OnapCommandException {
+        Map<String, List<String>> argsMap = new HashMap<>();
+        argsMap.put(OnapCommandConstants.RPC_ARGS, this.args);
+        if (this.profile != null )
+            cmd.getParametersMap().get(OnapCommandConstants.RPC_PROFILE).setValue(this.profile);
+        cmd.getParametersMap().get(OnapCommandConstants.RPC_REQID).setValue(this.requestId);
+        cmd.getParametersMap().get(OnapCommandConstants.RPC_MODE).setValue(OnapCommandConstants.RPC_MODE_RUN_CLI);
+        cmd.getParametersMap().get(OnapCommandConstants.RPC_ARGS).setValue(argsMap);
+
+        OnapCommandResult result = cmd.execute();
+        Result output = (Result) result.getOutput();
+
+        this.exitCode = output.getExitCode();
+        this.print(output.getOutput());
+    }
     /**
      * Handles all client input.
      */
     public void handle() {
-        this.handleHelp();
+        this.handleRpc();
+
+        if (this.exitCode == -1) {
+            this.handleHelp();
+        }
 
         if (this.exitCode == -1) {
             this.handleVersion();
@@ -513,7 +645,7 @@ public class OnapCli {
         }
 
         if (this.exitCode == -1) {
-            this.handleCommand(new ArrayList<>());
+            this.handleCommand();
         }
     }
 
@@ -574,6 +706,7 @@ public class OnapCli {
     private ConsoleReader createConsoleReader() throws IOException {
         ConsoleReader console = new ConsoleReader(); // NOSONAR
         try {
+            //ignore system commands
             StringCompleter strCompleter = new StringCompleter(OnapCommandRegistrar.getRegistrar().listCommandsForEnabledProductVersion());
             strCompleter.add(OnapCliConstants.PARAM_INTERACTIVE_EXIT,
                     OnapCliConstants.PARAM_INTERACTIVE_CLEAR,
@@ -601,7 +734,7 @@ public class OnapCli {
                         OnapCommandConfig.getPropertyValue(OnapCommandConstants.SAMPLE_GEN_TARGET_FOLDER) + "/" + cmd.getSchemaName().replaceAll(".yaml", "") + "-sample.yaml",
                         cmd.getResult().isDebug());
             } catch (IOException error) {
-                throw new OnapCommandInvalidSample(args.get(0), error);
+                throw new OnapCommandInvalidSample(this.cmdName, error);
             }
         }
     }
index cf884ea..a1bde71 100644 (file)
@@ -92,8 +92,7 @@ public class OnapCliArgsParser {
         }
 
         int positionalIdx = 0;
-        // Skip the first args oclip cmd name, so start from 1
-        for (int i = 1; i < args.size(); i++) {
+        for (int i = 0; i < args.size(); i++) {
             String paramName = null;
             if (shortOptionMap.containsKey(args.get(i))) {
                 paramName = shortOptionMap.get(args.get(i));
index 2c74cf0..0c92a1a 100644 (file)
@@ -63,7 +63,6 @@ public class OnapCliUtilsTest {
         paramslist.add(param5);
 
         String[] args = new String[] {
-            "sample-create",
             "--host-username", "admin",
             "--host-password", "123",
             "--host-url", "a@b.com",
@@ -72,25 +71,28 @@ public class OnapCliUtilsTest {
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         List<String> expectedList = Arrays.asList(args);
 
-        Assert.assertEquals("host-username", expectedList.get(2), param1.getValue());
-        Assert.assertEquals("host-password", expectedList.get(4), param2.getValue());
-        Assert.assertEquals("host-url", expectedList.get(6), param3.getValue());
-        Assert.assertEquals("string-param", expectedList.get(8), param4.getValue());
-        Assert.assertEquals("long-opt", expectedList.get(10), param5.getValue());
+        Assert.assertEquals("host-username", expectedList.get(1), param1.getValue());
+        Assert.assertEquals("host-password", expectedList.get(3), param2.getValue());
+        Assert.assertEquals("host-url", expectedList.get(5), param3.getValue());
+        Assert.assertEquals("string-param", expectedList.get(7), param4.getValue());
+        Assert.assertEquals("long-opt", expectedList.get(9), param5.getValue());
 
     }
 
     @Test
     public void testpositionalargs() throws OnapCommandException {
         OnapCommandParameter paramargs = new OnapCommandParameter();
-        paramargs.setName("http://localhost:8082/file.txt");
+        paramargs.setParameterType(OnapCommandParameterType.STRING);
+        paramargs.setName("test");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(paramargs);
-        String[] args = new String[] { "positional-args", "http://localhost:8082/file.txt" };
-        paramargs.setParameterType(OnapCommandParameterType.STRING);
+
+        String[] args = new String[] { "positional-args"};
+
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
+
         List<String> expectedList = Arrays.asList(args);
-        Assert.assertEquals("positional-args", expectedList.get(1), paramslist.iterator().next().getValue());
+        Assert.assertEquals(expectedList.get(0), paramslist.iterator().next().getValue());
     }
 
     @Test
@@ -100,12 +102,12 @@ public class OnapCliUtilsTest {
         boolparam.setName("bool-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(boolparam);
-        String[] args = new String[] { "sample-create", "--bool" };
+        String[] args = new String[] {  "--bool" };
 
         boolparam.setParameterType(OnapCommandParameterType.BOOL);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         List<String> expectedList = Arrays.asList(args);
-        Assert.assertNotNull(expectedList.get(1), paramslist.iterator().next().getValue());
+        Assert.assertNotNull(expectedList.get(0), paramslist.iterator().next().getValue());
 
     }
 
@@ -116,12 +118,12 @@ public class OnapCliUtilsTest {
         boolparam.setName("bool-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(boolparam);
-        String[] args = new String[] { "sample-create", "-b", };
+        String[] args = new String[] {  "-b", };
 
         boolparam.setParameterType(OnapCommandParameterType.BOOL);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         List<String> expectedList = Arrays.asList(args);
-        Assert.assertNotNull(expectedList.get(1), paramslist.iterator().next().getValue());
+        Assert.assertNotNull(expectedList.get(0), paramslist.iterator().next().getValue());
     }
 
     @Test
@@ -131,7 +133,7 @@ public class OnapCliUtilsTest {
         boolparam.setName("text-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(boolparam);
-        String[] args = new String[] { "sample-create", "--text-param" , "text"};
+        String[] args = new String[] {  "--text-param" , "text"};
 
         boolparam.setParameterType(OnapCommandParameterType.TEXT);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
@@ -147,7 +149,7 @@ public class OnapCliUtilsTest {
         boolparam.setName("text-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(boolparam);
-        String[] args = new String[] { "sample-create", "-e" , "text"};
+        String[] args = new String[] {  "-e" , "text"};
 
         boolparam.setParameterType(OnapCommandParameterType.TEXT);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
@@ -163,7 +165,7 @@ public class OnapCliUtilsTest {
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(jsonparam);
         File resourcesDirectory = new File("src/test/resources/sampletest.json");
-        String[] args = new String[] { "sample-create", "-j", "file:" + resourcesDirectory };
+        String[] args = new String[] {  "-j", "file:" + resourcesDirectory };
         jsonparam.setParameterType(OnapCommandParameterType.JSON);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         List<String> expectedList = Arrays.asList(args);
@@ -178,7 +180,7 @@ public class OnapCliUtilsTest {
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(jsonparam);
         File resourcesDirectory = new File("src/test/resources/sampletest.json");
-        String[] args = new String[] { "sample-create", "--json-param", "file:" + resourcesDirectory };
+        String[] args = new String[] {  "--json-param", "file:" + resourcesDirectory };
         jsonparam.setParameterType(OnapCommandParameterType.JSON);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         List<String> expectedList = Arrays.asList(args);
@@ -217,7 +219,6 @@ public class OnapCliUtilsTest {
         paramslist.add(param5);
 
         String[] args11 = new String[] {
-            "sample-create",
             "-u", "admin",
             "-p", "123",
             "-r", "a@b.com",
@@ -227,11 +228,11 @@ public class OnapCliUtilsTest {
 
         List<String> expectedList = Arrays.asList(args11);
 
-        Assert.assertEquals("u", expectedList.get(2), param1.getValue());
-        Assert.assertEquals("-p", expectedList.get(4), param2.getValue());
-        Assert.assertEquals("r", expectedList.get(6), param3.getValue());
-        Assert.assertEquals("c", expectedList.get(8), param4.getValue());
-        Assert.assertEquals("l", expectedList.get(10), param5.getValue());
+        Assert.assertEquals("u", expectedList.get(1), param1.getValue());
+        Assert.assertEquals("-p", expectedList.get(3), param2.getValue());
+        Assert.assertEquals("r", expectedList.get(5), param3.getValue());
+        Assert.assertEquals("c", expectedList.get(7), param4.getValue());
+        Assert.assertEquals("l", expectedList.get(9), param5.getValue());
     }
 
     @Test
@@ -240,7 +241,7 @@ public class OnapCliUtilsTest {
         arrayval.setLongOption("node-ip");
         arrayval.setName("node-ip");
 
-        String[] args = new String[] { "sample-create", "--node-ip", "{}" };
+        String[] args = new String[] {  "--node-ip", "{}" };
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(arrayval);
 
@@ -262,7 +263,7 @@ public class OnapCliUtilsTest {
 
         param1.setParameterType(OnapCommandParameterType.MAP);
         OnapCliArgsParser.populateParams(paramslist,
-                Arrays.asList("show", "--map", "param1=value1", "--map", "param2=value2"));
+                Arrays.asList("--map", "param1=value1", "--map", "param2=value2"));
 
         Assert.assertEquals("{param1=value1, param2=value2}",
             paramslist.iterator().next().getValue().toString());
@@ -323,7 +324,7 @@ public class OnapCliUtilsTest {
         boolparam.setName("bool-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(boolparam);
-        String[] args = new String[] { "sample-create", "-b", "-b", "-h" };
+        String[] args = new String[] {  "-b", "-b", "-h" };
 
         boolparam.setParameterType(OnapCommandParameterType.BOOL);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
@@ -338,7 +339,7 @@ public class OnapCliUtilsTest {
         boolparam.setName("bool-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(boolparam);
-        String[] args = new String[] { "sample-create", "--bool", "--bool", "--help" };
+        String[] args = new String[] {  "--bool", "--bool", "--help" };
 
         boolparam.setParameterType(OnapCommandParameterType.BOOL);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
@@ -355,7 +356,7 @@ public class OnapCliUtilsTest {
         paramslist.add(jsonparam);
         File resourcesDirectory = new File("src/test/resources/sampletest.json");
         String[] args = new String[] {
-            "sample-create", "--json-param",
+             "--json-param",
             "file:" + resourcesDirectory, "--json-param" };
         jsonparam.setParameterType(OnapCommandParameterType.JSON);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
@@ -372,7 +373,7 @@ public class OnapCliUtilsTest {
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(jsonparam);
         File resourcesDirectory = new File("src/test/resources/sampletest.json");
-        String[] args = new String[] { "sample-create", "-j", "file:" + resourcesDirectory, "-j" };
+        String[] args = new String[] {  "-j", "file:" + resourcesDirectory, "-j" };
         jsonparam.setParameterType(OnapCommandParameterType.JSON);
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         List<String> expectedList = Arrays.asList(args);
@@ -388,7 +389,7 @@ public class OnapCliUtilsTest {
         arrParam.setName("array-param");
         Set<OnapCommandParameter> paramslist = new HashSet<>();
         paramslist.add(arrParam);
-        String[] args = new String[] { "sample-create", "-q", "test1", "-q", "test2" };
+        String[] args = new String[] {  "-q", "test1", "-q", "test2" };
 
         OnapCliArgsParser.populateParams(paramslist, Arrays.asList(args));
         Assert.assertTrue(((List<String>) arrParam.getValue())
index 66ea5a5..cbe18a2 100644 (file)
@@ -14,8 +14,8 @@
 
 cli.product_name=open-cli
 cli.version=1.0
-
 cli.discover_always=false
+cli.data.dir=data
 
 #schema validation
 cli.schema.base.sections=open_cli_schema_version,name,description,parameters,results,http,info
index 1210f47..adf409a 100644 (file)
@@ -14,7 +14,7 @@
 
 cli.product_name=open-cli
 cli.version=1.0
-
+cli.data.dir=data
 cli.discover_always=false
 
 #schema validation
index d9b89e7..b2f0f81 100644 (file)
@@ -14,7 +14,7 @@
 
 cli.product_name=open-cli
 cli.version=1.0
-
+cli.data.dir=data
 cli.discover_always=false
 
 #schema validation