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.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
26 import org.apache.commons.io.IOUtils;
27 import org.onap.cli.fw.cmd.OnapCommand;
28 import org.onap.cli.fw.conf.OnapCommandConfig;
29 import org.onap.cli.fw.conf.OnapCommandConstants;
30 import org.onap.cli.fw.error.OnapCommandException;
31 import org.onap.cli.fw.error.OnapCommandHelpFailed;
32 import org.onap.cli.fw.error.OnapCommandInvalidRegistration;
33 import org.onap.cli.fw.error.OnapCommandNotFound;
34 import org.onap.cli.fw.error.OnapCommandProductVersionInvalid;
35 import org.onap.cli.fw.error.OnapCommandRegistrationProductInfoMissing;
36 import org.onap.cli.fw.error.OnapUnsupportedSchemaProfile;
37 import org.onap.cli.fw.input.cache.OnapCommandParameterCache;
38 import org.onap.cli.fw.output.OnapCommandPrintDirection;
39 import org.onap.cli.fw.output.OnapCommandResult;
40 import org.onap.cli.fw.output.OnapCommandResultAttribute;
41 import org.onap.cli.fw.output.OnapCommandResultAttributeScope;
42 import org.onap.cli.fw.output.OnapCommandResultType;
43 import org.onap.cli.fw.schema.OnapCommandSchema;
44 import org.onap.cli.fw.schema.OnapCommandSchemaInfo;
45 import org.onap.cli.fw.utils.OnapCommandDiscoveryUtils;
46 import org.onap.cli.fw.utils.OnapCommandHelperUtils;
47 import org.onap.cli.fw.utils.OnapCommandUtils;
51 * Oclip Command registrar provides a common place, where every command would get registered automatically when its
55 public class OnapCommandRegistrar {
56 private Map<String, Class<? extends OnapCommand>> registry = new HashMap<>();
58 private Map<String, Class<? extends OnapCommand>> registryProfilePlugins = new HashMap<>();
60 private Set<String> availableProductVersions = new HashSet<>();
62 private String enabledProductVersion = null;
64 private boolean isInteractiveMode = false;
66 private OnapCommandParameterCache paramCache = OnapCommandParameterCache.getInstance();
68 public boolean isInteractiveMode() {
69 return isInteractiveMode;
72 public void setInteractiveMode(boolean isInteractiveMode) {
73 this.isInteractiveMode = isInteractiveMode;
76 public Map<String, String> getParamCache() {
77 return paramCache.getParams(this.getEnabledProductVersion());
80 public void addParamCache(String paramName, String paramValue) {
81 paramCache.add(this.getEnabledProductVersion(), paramName, paramValue);
84 public void removeParamCache(String paramName) {
85 paramCache.remove(this.getEnabledProductVersion(), paramName);
88 public void setProfile(String profileName) {
89 this.paramCache.setProfile(profileName);
92 private static OnapCommandRegistrar registrar = null;
95 * Register the command into registrar and throws OnapInvalidCommandRegistration for invalid command.
101 * @throws OnapCommandInvalidRegistration
102 * Invalid registration exception
103 * @throws OnapCommandRegistrationProductInfoMissing
105 private void register(String name, String version, Class<? extends OnapCommand> cmd) throws OnapCommandInvalidRegistration, OnapCommandRegistrationProductInfoMissing {
106 if (version == null || version.isEmpty()) {
107 throw new OnapCommandRegistrationProductInfoMissing(name);
110 this.registry.put(name + ":" + version, cmd);
111 this.availableProductVersions.add(version);
115 private void registerProfilePlugin(String profile, Class<? extends OnapCommand> cmd) {
116 this.registryProfilePlugins.put(profile, cmd);
119 private OnapCommandRegistrar() {
120 this.enabledProductVersion = System.getenv(OnapCommandConstants.OPEN_CLI_PRODUCT_IN_USE_ENV_NAME);
121 if (this.enabledProductVersion == null) {
122 this.enabledProductVersion = OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_PRODUCT_NAME);
127 * Get global registrar.
129 * @throws OnapCommandException
132 public static OnapCommandRegistrar getRegistrar() throws OnapCommandException {
133 if (registrar == null) {
134 registrar = new OnapCommandRegistrar();
135 registrar.autoDiscoverSchemas();
142 * Get the list of discovered commands by registrar.
146 public Set<String> listCommands() {
147 return this.registry.keySet();
151 * Get the list of discovered commands for a given product version in registrar.
155 public Set<String> listCommandsForEnabledProductVersion() {
156 String version = this.getEnabledProductVersion();
158 Set<String> cmds = new HashSet<>();
159 if (!this.availableProductVersions.contains(version)) {
163 for (String cmd: this.registry.keySet()) {
164 if (cmd.split(":")[1].equalsIgnoreCase(version)) {
165 cmds.add(cmd.split(":")[0]);
171 public Class<? extends OnapCommand> getProfilePlugin(String profile) throws OnapUnsupportedSchemaProfile {
172 if (!this.registryProfilePlugins.containsKey(profile)) {
173 throw new OnapUnsupportedSchemaProfile(profile);
176 return this.registryProfilePlugins.get(profile);
179 public Set<String> getAvailableProductVersions() {
180 return this.availableProductVersions;
183 public void setEnabledProductVersion(String version) throws OnapCommandProductVersionInvalid {
184 if (!this.availableProductVersions.contains(version)) {
185 throw new OnapCommandProductVersionInvalid(version, availableProductVersions);
188 this.enabledProductVersion = version;
191 public String getEnabledProductVersion() {
192 return this.enabledProductVersion;
196 * Returns command details.
199 * @throws OnapCommandException
202 public List<OnapCommandSchemaInfo> listCommandInfo() throws OnapCommandException {
203 return OnapCommandDiscoveryUtils.discoverSchemas();
207 * Get the OnapCommand, which CLI main would use to find the command based on the command name.
211 * @return OnapCommand
212 * @throws OnapCommandException
215 public OnapCommand get(String cmdName) throws OnapCommandException {
216 return this.get(cmdName, this.getEnabledProductVersion());
220 * Get the OnapCommand, which CLI main would use to find the command based on the command name.
226 * @return OnapCommand
227 * @throws OnapCommandException
230 public OnapCommand get(String cmdName, String version) throws OnapCommandException {
231 Class<? extends OnapCommand> cls = registry.get(cmdName + ":" + version);
232 //mrkanag: Restrict auth/catalog type commands only available during devMode. in production
233 //don't expose the auth type and catalog type commands
236 throw new OnapCommandNotFound(cmdName, version);
239 OnapCommand cmd = OnapCommandDiscoveryUtils.loadCommandClass(cls);
240 String schemaName = OnapCommandDiscoveryUtils.getSchemaInfo(cmdName, version).getSchemaName();
241 cmd.initializeSchema(schemaName);
246 private Map<String, Class<OnapCommand>> autoDiscoverCommandPlugins() throws OnapCommandException {
247 List<Class<OnapCommand>> cmds = OnapCommandDiscoveryUtils.discoverCommandPlugins();
248 Map<String, Class<OnapCommand>> map = new HashMap<>();
250 for (Class<OnapCommand> cmd : cmds) {
251 if (cmd.isAnnotationPresent(OnapCommandSchema.class)) {
252 OnapCommandSchema ano = cmd.getAnnotation(OnapCommandSchema.class);
253 if (ano.schema() != null && !ano.schema().isEmpty()) {
254 map.put(ano.schema(), cmd);
255 } else if (ano.type() != null && !ano.type().isEmpty()) {
256 this.registerProfilePlugin(ano.type(), cmd);
257 map.put(ano.type(), cmd);
259 throw new OnapUnsupportedSchemaProfile(ano.schema());
267 private void autoDiscoverSchemas() throws OnapCommandException {
268 List<OnapCommandSchemaInfo> schemas = OnapCommandDiscoveryUtils.discoverOrLoadSchemas(true);
270 Map<String, Class<OnapCommand>> plugins = this.autoDiscoverCommandPlugins();
272 for (OnapCommandSchemaInfo schema : schemas) {
273 if (schema.isIgnore()) {
277 if (plugins.containsKey(schema.getSchemaName())) {
278 this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaName()));
279 } else if (plugins.containsKey(schema.getSchemaProfile())) {
280 this.register(schema.getCmdName(), schema.getProduct(), plugins.get(schema.getSchemaProfile()));
282 throw new OnapUnsupportedSchemaProfile(schema.getSchemaURI());
288 * Helps to find the Oclip CLI version, could be used with --version or -v option.
292 public String getVersion() {
293 String version = this.getClass().getPackage().getImplementationVersion();
294 if (version == null) {
295 version = OnapCommandConfig.getPropertyValue(OnapCommandConstants.OPEN_CLI_VERSION);
298 String buildTime = OnapCommandHelperUtils.findLastBuildTime();
299 if (buildTime!= null && !buildTime.isEmpty()) {
300 buildTime = " [" + buildTime + "]";
305 String configuredProductVersion = this.getEnabledProductVersion();
307 String versionInfo = "";
309 versionInfo = IOUtils.toString(this.getClass().getClassLoader().getResourceAsStream(OnapCommandConstants.VERSION_INFO));
310 } catch (IOException e) {
311 //Never occurs // NOSONAR
314 versionInfo = versionInfo.replaceAll(OnapCommandConstants.VERSION_INFO_PLACE_HOLDER_ENB_PRD_VER, configuredProductVersion);
315 versionInfo = versionInfo.replaceAll(OnapCommandConstants.VERSION_INFO_PLACE_HOLDER_AVL_PRD_VER, this.availableProductVersions.toString());
316 versionInfo = versionInfo.replaceAll(OnapCommandConstants.VERSION_INFO_PLACE_HOLDER_VERSION + "", version + buildTime);
322 * Provides the help message in tabular format for all commands registered in this registrar.
325 * @throws OnapCommandHelpFailed
328 public String getHelp() throws OnapCommandHelpFailed {
329 return this.getHelp(false);
332 public String getHelpForEnabledProductVersion() throws OnapCommandHelpFailed {
333 return this.getHelp(true);
336 private String getHelp(boolean isEnabledProductVersionOnly) throws OnapCommandHelpFailed {
337 OnapCommandResult help = new OnapCommandResult();
338 help.setType(OnapCommandResultType.TABLE);
339 help.setPrintDirection(OnapCommandPrintDirection.LANDSCAPE);
341 OnapCommandResultAttribute attr = new OnapCommandResultAttribute();
342 attr.setName(OnapCommandConstants.NAME.toUpperCase());
343 attr.setDescription(OnapCommandConstants.DESCRIPTION);
344 attr.setScope(OnapCommandResultAttributeScope.SHORT);
345 help.getRecords().add(attr);
347 OnapCommandResultAttribute attrVer = new OnapCommandResultAttribute();
348 if (!isEnabledProductVersionOnly) {
349 attrVer.setName(OnapCommandConstants.INFO_PRODUCT.toUpperCase());
350 attrVer.setDescription(OnapCommandConstants.DESCRIPTION);
351 attrVer.setScope(OnapCommandResultAttributeScope.SHORT);
352 help.getRecords().add(attrVer);
355 OnapCommandResultAttribute attrSrv = new OnapCommandResultAttribute();
356 attrSrv.setName(OnapCommandConstants.INFO_SERVICE.toUpperCase());
357 attrSrv.setDescription(OnapCommandConstants.INFO_SERVICE);
358 attrSrv.setScope(OnapCommandResultAttributeScope.SHORT);
359 help.getRecords().add(attrSrv);
361 OnapCommandResultAttribute attrDesc = new OnapCommandResultAttribute();
362 attrDesc.setName(OnapCommandConstants.DESCRIPTION.toUpperCase());
363 attrDesc.setDescription(OnapCommandConstants.DESCRIPTION);
364 attrDesc.setScope(OnapCommandResultAttributeScope.SHORT);
365 help.getRecords().add(attrDesc);
367 for (String cmdName : isEnabledProductVersionOnly ? OnapCommandUtils.sort(this.listCommandsForEnabledProductVersion()) : OnapCommandUtils.sort(this.listCommands())) {
370 if (!isEnabledProductVersionOnly) {
371 String []cmdVer = cmdName.split(":");
372 cmd = this.get(cmdVer[0], cmdVer[1]);
373 attr.getValues().add(cmdVer[0]);
374 attrVer.getValues().add(cmdVer[1]);
376 cmd = this.get(cmdName);
377 attr.getValues().add(cmdName);
380 attrSrv.getValues().add(cmd.printVersion());
381 attrDesc.getValues().add(cmd.getDescription());
382 } catch (OnapCommandException e) {
383 throw new OnapCommandHelpFailed(e);
388 return "\n\nCommands:\n" + help.print() + (isEnabledProductVersionOnly ? "" : "\n" + this.getVersion());
389 } catch (OnapCommandException e) {
390 throw new OnapCommandHelpFailed(e);