2 * Copyright 2017 Huawei Technologies Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.cli.fw.registrar;
19 import java.io.IOException;
20 import java.nio.charset.Charset;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
27 import org.apache.commons.io.IOUtils;
28 import org.onap.cli.fw.cmd.OnapCommand;
29 import org.onap.cli.fw.cmd.OnapCommandType;
30 import org.onap.cli.fw.cmd.dummy.OnapCommandDummy;
31 import org.onap.cli.fw.conf.OnapCommandConfig;
32 import org.onap.cli.fw.conf.OnapCommandConstants;
33 import org.onap.cli.fw.error.OnapCommandException;
34 import org.onap.cli.fw.error.OnapCommandHelpFailed;
35 import org.onap.cli.fw.error.OnapCommandNotFound;
36 import org.onap.cli.fw.error.OnapCommandProductVersionInvalid;
37 import org.onap.cli.fw.error.OnapCommandRegistrationProductInfoMissing;
38 import org.onap.cli.fw.error.OnapUnsupportedSchemaProfile;
39 import org.onap.cli.fw.output.OnapCommandPrintDirection;
40 import org.onap.cli.fw.output.OnapCommandResult;
41 import org.onap.cli.fw.output.OnapCommandResultAttribute;
42 import org.onap.cli.fw.output.OnapCommandResultAttributeScope;
43 import org.onap.cli.fw.output.OnapCommandResultType;
44 import org.onap.cli.fw.schema.OnapCommandSchema;
45 import org.onap.cli.fw.schema.OnapCommandSchemaInfo;
46 import org.onap.cli.fw.store.OnapCommandProfileStore;
47 import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils;
48 import org.onap.cli.fw.utils.OnapCommandHelperUtils;
49 import org.onap.cli.fw.utils.OnapCommandUtils;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
55 * Oclip Command registrar provides a common place, where every command would get registered automatically when its
59 public class OnapCommandRegistrar {
61 private static Logger log = LoggerFactory.getLogger(OnapCommandRegistrar.class);
63 private Map<String, Class<? extends OnapCommand>> registry = new HashMap<>();
65 private Map<String, Class<? extends OnapCommand>> registryProfilePlugins = new HashMap<>();
67 private Set<String> availableProductVersions = new HashSet<>();
69 private String enabledProductVersion = null;
71 private boolean isInteractiveMode = false;
77 private OnapCommandProfileStore paramCache = OnapCommandProfileStore.getInstance();
79 public boolean isInteractiveMode() {
80 return isInteractiveMode;
83 public void setInteractiveMode(boolean isInteractiveMode) {
84 this.isInteractiveMode = isInteractiveMode;
87 public Map<String, String> getParamCache() {
88 return this.getParamCache(this.getEnabledProductVersion());
91 public Map<String, String> getParamCache(String product) {
92 return paramCache.getParams(product);
95 public void addParamCache(String paramName, String paramValue) {
96 paramCache.add(this.getEnabledProductVersion(), paramName, paramValue);
99 public void removeParamCache(String paramName) {
100 paramCache.remove(this.getEnabledProductVersion(), paramName);
103 public void setProfile(String profileName, List<String> includes, List<String> excludes) throws OnapCommandException {
104 this.paramCache.setProfile(profileName);
106 for (String profile : includes) {
107 this.paramCache.includeProfile(profile);
110 for (String profile : excludes) {
111 this.paramCache.excludeProfile(profile);
115 public List<String> getUserProfiles() {
116 return paramCache.getProfiles();
119 private static OnapCommandRegistrar registrar = null;
122 * Register the command into registrar and throws OnapInvalidCommandRegistration for invalid command.
124 * @param name Command Name
125 * @param cmd Command Class
126 * @throws OnapCommandRegistrationProductInfoMissing
128 private void register(String name, String version, Class<? extends OnapCommand> cmd) throws OnapCommandRegistrationProductInfoMissing {
129 if (version == null || version.isEmpty()) {
130 throw new OnapCommandRegistrationProductInfoMissing(name);
133 this.registry.put(name + ":" + version, cmd);
134 log.info("REGISITER : {} : {} = {}", name, version, cmd.getCanonicalName());
135 this.availableProductVersions.add(version);
139 private void registerProfilePlugin(String profile, Class<? extends OnapCommand> cmd) {
140 this.registryProfilePlugins.put(profile, cmd);
143 private OnapCommandRegistrar() {
144 this.enabledProductVersion = System.getenv(OnapCommandConstants.OPEN_CLI_PRODUCT_IN_USE_ENV_NAME); //NOSONAR
145 if (this.enabledProductVersion == null) {
146 this.enabledProductVersion = OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_PRODUCT_NAME);
151 * Get global registrar.
153 * @throws OnapCommandException exception
155 public static OnapCommandRegistrar getRegistrar() throws OnapCommandException {
156 if (registrar == null) {
157 registrar = new OnapCommandRegistrar();
158 registrar.autoDiscoverSchemas(true);
164 public void resync() throws OnapCommandException {
165 registrar.autoDiscoverSchemas(false);
169 * Get the list of discovered commands by registrar.
173 public Set<String> listCommands() {
174 return this.registry.keySet();
178 * Get the list of discovered commands for a given product version in registrar.
182 public Set<String> listCommandsForEnabledProductVersion() {
183 String version = this.getEnabledProductVersion();
185 Set<String> cmds = new HashSet<>();
186 if (!this.availableProductVersions.contains(version)) {
190 for (String cmd : this.registry.keySet()) {
191 if (cmd.split(":")[1].equalsIgnoreCase(version)) {
192 cmds.add(cmd.split(":")[0]);
198 public Class<? extends OnapCommand> getProfilePlugin(String profile) throws OnapUnsupportedSchemaProfile {
199 if (!this.registryProfilePlugins.containsKey(profile)) {
200 throw new OnapUnsupportedSchemaProfile(profile);
203 return this.registryProfilePlugins.get(profile);
206 public Set<String> getAvailableProductVersions() {
207 return this.availableProductVersions;
210 public void setEnabledProductVersion(String version) throws OnapCommandProductVersionInvalid {
211 if (!this.availableProductVersions.contains(version)) {
212 throw new OnapCommandProductVersionInvalid(version, availableProductVersions);
215 this.enabledProductVersion = version;
218 public String getEnabledProductVersion() {
219 return this.enabledProductVersion;
223 * Returns command details.
226 * @throws OnapCommandException exception
228 public List<OnapCommandSchemaInfo> listCommandInfo() throws OnapCommandException {
229 return OnapCommandDiscoveryUtils.discoverSchemas();
233 * Get the OnapCommand, which CLI main would use to find the command based on the command name.
235 * @param cmdName Name of command
236 * @return OnapCommand
237 * @throws OnapCommandException Exception
239 public OnapCommand get(String cmdName) throws OnapCommandException {
240 return this.get(cmdName, this.getEnabledProductVersion());
244 * Get the OnapCommand, which CLI main would use to find the command based on the command name.
246 * @param cmdName Name of command
247 * @param version product version
248 * @return OnapCommand
249 * @throws OnapCommandException Exception
251 public OnapCommand get(String cmdName, String version) throws OnapCommandException {
252 Class<? extends OnapCommand> cls = registry.get(cmdName + ":" + version);
253 //mrkanag: Restrict auth/catalog type commands only available during devMode. in production
254 //don't expose the auth type and catalog type commands
257 throw new OnapCommandNotFound(cmdName, version);
260 OnapCommand cmd = OnapCommandDiscoveryUtils.loadCommandClass(cls);
262 OnapCommandSchemaInfo info = OnapCommandDiscoveryUtils.getSchemaInfo(cmdName, version);
264 cmd.initializeSchema(info);
269 private Map<String, Class<OnapCommand>> autoDiscoverCommandPlugins() throws OnapCommandException {
270 List<Class<OnapCommand>> cmds = OnapCommandDiscoveryUtils.discoverCommandPlugins();
271 Map<String, Class<OnapCommand>> map = new HashMap<>();
273 for (Class<OnapCommand> cmd : cmds) {
274 if (cmd.isAnnotationPresent(OnapCommandSchema.class)) {
275 OnapCommandSchema ano = cmd.getAnnotation(OnapCommandSchema.class);
276 if (ano.schema() != null && !ano.schema().isEmpty()) {
277 map.put(ano.schema(), cmd);
278 } else if (ano.type() != null && !ano.type().isEmpty()) {
279 this.registerProfilePlugin(ano.type(), cmd);
280 map.put(ano.type(), cmd);
282 throw new OnapUnsupportedSchemaProfile(ano.schema());
290 private void autoDiscoverSchemas(boolean refresh) throws OnapCommandException {
291 List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(refresh);
293 Map<String, Class<OnapCommand>> plugins = this.autoDiscoverCommandPlugins();
295 for (OnapCommandSchemaInfo schema : schemas) {
296 if (schema.isIgnore()) {
297 log.info("Ignoring schema {}", schema.getSchemaURI());
301 //First check if there is an specific plug-in exist, otherwise check for profile plug-in
302 if (schema.isRpc()) {
303 //proxy the schema by using rpc schema, when the schema is marked with rpc
304 this.register(schema.getCmdName(), schema.getProduct(), plugins.get("schema-rpc.yaml"));
305 } else if (plugins.containsKey(schema.getSchemaName())) {
306 this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaName()));
307 } else if (plugins.containsKey(schema.getSchemaProfile())) {
308 this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaProfile()));
310 this.register(schema.getCmdName(), schema.getProduct(), OnapCommandDummy.class);
316 * Helps to find the Oclip CLI version, could be used with --version or -v option.
320 public String getVersion() {
321 String version = this.getClass().getPackage().getImplementationVersion();
322 if (version == null) {
323 version = OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_VERSION);
326 String buildTime = OnapCommandHelperUtils.findLastBuildTime();
327 if (buildTime != null && !buildTime.isEmpty()) {
328 buildTime = " [" + buildTime + "]";
333 String configuredProductVersion = this.getEnabledProductVersion();
335 String versionInfo = "";
337 versionInfo = IOUtils.toString((this.getClass().getClassLoader().getResourceAsStream(OnapCommandConstants.VERSION_INFO)), (Charset) null);
338 } catch (IOException e) { // NOSONAR
342 versionInfo = versionInfo.replaceAll(OnapCommandConstants.VERSION_INFO_PLACE_HOLDER_ENB_PRD_VER, configuredProductVersion);
343 versionInfo = versionInfo.replaceAll(OnapCommandConstants.VERSION_INFO_PLACE_HOLDER_AVL_PRD_VER, this.availableProductVersions.toString());
344 versionInfo = versionInfo.replaceAll(OnapCommandConstants.VERSION_INFO_PLACE_HOLDER_VERSION + "", version + buildTime);
350 * Provides the help message in tabular format for all commands registered in this registrar.
353 * @throws OnapCommandHelpFailed Help cmd failed
355 public String getHelp() throws OnapCommandHelpFailed {
356 return this.getHelp(false);
359 public String getHelpForEnabledProductVersion() throws OnapCommandHelpFailed {
360 return this.getHelp(true);
363 private String getHelp(boolean isEnabledProductVersionOnly) throws OnapCommandHelpFailed {
364 OnapCommandResult help = new OnapCommandResult();
365 help.setType(OnapCommandResultType.TABLE);
366 help.setPrintDirection(OnapCommandPrintDirection.LANDSCAPE);
368 OnapCommandResultAttribute attr = new OnapCommandResultAttribute();
369 attr.setName(OnapCommandConstants.NAME.toUpperCase());
370 attr.setDescription(OnapCommandConstants.DESCRIPTION);
371 attr.setScope(OnapCommandResultAttributeScope.SHORT);
372 help.getRecords().add(attr);
374 OnapCommandResultAttribute attrVer = new OnapCommandResultAttribute();
375 if (!isEnabledProductVersionOnly) {
376 attrVer.setName(OnapCommandConstants.INFO_PRODUCT.toUpperCase());
377 attrVer.setDescription(OnapCommandConstants.DESCRIPTION);
378 attrVer.setScope(OnapCommandResultAttributeScope.SHORT);
379 help.getRecords().add(attrVer);
382 OnapCommandResultAttribute attrSrv = new OnapCommandResultAttribute();
383 attrSrv.setName(OnapCommandConstants.INFO_SERVICE.toUpperCase());
384 attrSrv.setDescription(OnapCommandConstants.INFO_SERVICE);
385 attrSrv.setScope(OnapCommandResultAttributeScope.SHORT);
386 help.getRecords().add(attrSrv);
388 OnapCommandResultAttribute attrState = new OnapCommandResultAttribute();
389 attrState.setName(OnapCommandConstants.INFO_STATE.toUpperCase());
390 attrState.setDescription(OnapCommandConstants.INFO_STATE);
391 attrState.setScope(OnapCommandResultAttributeScope.SHORT);
392 help.getRecords().add(attrState);
395 OnapCommandResultAttribute attrDesc = new OnapCommandResultAttribute();
396 attrDesc.setName(OnapCommandConstants.DESCRIPTION.toUpperCase());
397 attrDesc.setDescription(OnapCommandConstants.DESCRIPTION);
398 attrDesc.setScope(OnapCommandResultAttributeScope.SHORT);
399 help.getRecords().add(attrDesc);
401 for (String cmdName : isEnabledProductVersionOnly ?
402 OnapCommandUtils.sort(this.listCommandsForEnabledProductVersion()) :
403 OnapCommandUtils.sort(this.listCommands())) {
406 if (!isEnabledProductVersionOnly) {
407 String[] cmdVer = cmdName.split(":");
408 cmd = this.get(cmdVer[0], cmdVer[1]);
409 attr.getValues().add(cmdVer[0]);
410 attrVer.getValues().add(cmdVer[1]);
412 cmd = this.get(cmdName);
413 attr.getValues().add(cmdName);
416 //don't expose system commands for user usage
417 if (cmd.getInfo().getCommandType().name().equalsIgnoreCase(OnapCommandType.SYSTEM.name())) {
421 attrSrv.getValues().add(cmd.getInfo().getService());
422 attrDesc.getValues().add(cmd.getDescription());
423 attrState.getValues().add(cmd.getInfo().getState().name());
424 } catch (OnapCommandException e) {
425 throw new OnapCommandHelpFailed(e);
430 return "\n\nCommands:\n" + help.print() + (isEnabledProductVersionOnly ? "" : "\n" + this.getVersion());
431 } catch (OnapCommandException e) {
432 throw new OnapCommandHelpFailed(e);
436 public List<Map<String, Object>> getTestSuite(String cmd, String product) throws OnapCommandException {
437 return OnapCommandDiscoveryUtils.createTestSuite(cmd, product);
440 public String getHost() {
444 public void setHost(String host) {
448 public int getPort() {
452 public void setPort(int port) {