From 1eb5198939bd1d60665ff49e49763d0067c1bcb5 Mon Sep 17 00:00:00 2001 From: ramverma Date: Mon, 16 Jul 2018 15:23:45 +0100 Subject: Adding tools module to apex-pdp The tools module contains the utility applications for apex like converting policy model to cli, generating json events from policy model, simple websocket client example etc. The tools are defined to work in console and hence contain sysouts which are actually needed. Change-Id: Ia6d40fa7d3f6609ef86abd91a438d6ccbcd1f277 Issue-ID: POLICY-863 Signed-off-by: ramverma --- .../onap/policy/apex/tools/common/CliOptions.java | 105 ++++++ .../onap/policy/apex/tools/common/CliParser.java | 119 +++++++ .../org/onap/policy/apex/tools/common/Console.java | 352 +++++++++++++++++++++ .../onap/policy/apex/tools/common/OutputFile.java | 136 ++++++++ .../policy/apex/tools/common/package-info.java | 27 ++ .../src/main/resources/app-version.txt | 1 + 6 files changed, 740 insertions(+) create mode 100644 tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliOptions.java create mode 100644 tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliParser.java create mode 100644 tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/Console.java create mode 100644 tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/OutputFile.java create mode 100644 tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/package-info.java create mode 100644 tools/tools-common/src/main/resources/app-version.txt (limited to 'tools/tools-common/src/main') diff --git a/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliOptions.java b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliOptions.java new file mode 100644 index 000000000..277769be2 --- /dev/null +++ b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliOptions.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.tools.common; + +import org.apache.commons.cli.Option; + +/** + * Standard application CLI options. + * + * @author Sven van der Meer (sven.van.der.meer@ericsson.com) + */ +public final class CliOptions { + + /** Private constructor to prevent instantiation. */ + private CliOptions() {} + + /** A console option with "-c" and "--console". */ + public static final Option CONSOLE = + Option.builder("c").longOpt("console").desc("application as console with input from standard in").build(); + + /** A help option with "-h" and "--help". */ + public static final Option HELP = + Option.builder("h").longOpt("help").desc("prints this help and usage screen").build(); + + /** A version option with "-v" and "--version". */ + public static final Option VERSION = + Option.builder("v").longOpt("version").desc("prints the application version").build(); + + /** A print-stacktrace option with "--print-stacktrace". */ + public static final Option PRINTSTACKTRACE = + Option.builder().longOpt("print-stacktrace").desc("prints stack traces for any exception").build(); + + /** A check-java-class option with "--check-java-class". */ + public static final Option CHECKJAVACLASS = Option.builder("j").longOpt("check-java-class") + .desc("switch on checking of Java class references, requires JAR in class path").build(); + + /** A quiet option with "-q" and "--quiet". */ + public static final Option QUIET = + Option.builder("q").longOpt("quiet").desc("application in quiet mode, no output at all").build(); + + /** A no-warning option with "--no-warnings". */ + public static final Option NOWARNINGS = + Option.builder().longOpt("no-warnings").desc("switch off all warnings").build(); + + /** A no-error option with "--no-errors". */ + public static final Option NOERRORS = + Option.builder().longOpt("no-errors").desc("switch off error messages").build(); + + /** A no-progress option with "--no-progress". */ + public static final Option SHOWPROGRESS = + Option.builder().longOpt("no-progress").desc("switch off progress information").build(); + + /** A file-in option with "-f" and "--input-file". */ + public static final Option FILEIN = + Option.builder("f").hasArg().argName("FILE").longOpt("input-file").desc("set the input file").build(); + + /** A file-out option with "-o" and "--output-file". */ + public static final Option FILEOUT = Option.builder("o").hasArg().argName("FILE").longOpt("output-file") + .desc("set the output file").required(false).build(); + + /** An overwrite option with "-ow" and "--overwrite". */ + public static final Option OVERWRITE = Option.builder("ow").required(false).longOpt("overwrite") + .desc("overwrite the output file if it exists. This option can only be used with the -" + FILEOUT.getOpt() + + " option") + .build(); + + /** An option for the policy model file with "-m" and "--model". */ + public static final Option MODELFILE = Option.builder("m").hasArg().argName("MODEL-FILE").longOpt("model") + .desc("set the input policy model file").build(); + + /** A type option defining what type is used for events with "-t" and "--type". */ + public static final Option TYPE = Option.builder("t").hasArg().argName("TYPE").longOpt("type").desc( + "set the event type for generation, one of: stimuli (trigger events), response (action events), internal (events between states)") + .build(); + + /** A server option with "-s" and "--server". */ + public static final Option SERVER = Option.builder("s").hasArg().argName("HOSTNAME").longOpt("server") + .desc("set the Websocket server hostname, default: localhost").build(); + + /** A port option with "-p" and "--port". */ + public static final Option PORT = Option.builder("p").hasArg().argName("PORT").longOpt("port") + .desc("set the Websocket server port, default: 8887").build(); + + /** A skip validation option with "-sv" and "--skip-validation". */ + public static final Option SKIPVALIDATION = Option.builder("sv").longOpt("skip-validation") + .desc("switch of validation of the input file").required(false).type(boolean.class).build(); +} diff --git a/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliParser.java b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliParser.java new file mode 100644 index 000000000..588abfc6b --- /dev/null +++ b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliParser.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.tools.common; + +//// +//// NOTE: This file contains tags for ASCIIDOC +//// DO NOT REMOVE any of those tag lines, e.g. +////// tag::** +////// end::** +//// + +import java.util.Scanner; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +/** + * Application CLI parser. + * + * @author Sven van der Meer (sven.van.der.meer@ericsson.com) + */ +public class CliParser { + + /** The local set of CLI options. */ + private final Options options; + + /** The command line, null on start, not null after successful parse. */ + private CommandLine cmd; + + /** + * Creates a new CLI parser. + */ + public CliParser() { + options = new Options(); + } + + /** + * Adds an option to the parser. + * + * @param option the new option, must not be null + * @return self to allow chaining + */ + public CliParser addOption(final Option option) { + if (option == null) { + throw new IllegalStateException("CLI parser: given option was null"); + } + options.addOption(option); + return this; + } + + /** + * Parses the arguments with the set options. + * + * @param args the arguments to parse + * @return a command line with parsed arguments, null on parse errors. + */ + public CommandLine parseCli(final String[] args) { + final CommandLineParser parser = new DefaultParser(); + try { + cmd = parser.parse(options, args); + } catch (final ParseException ex) { + System.err.println("Parsing failed. Reason: " + ex.getMessage()); + ex.printStackTrace(); + } + return cmd; + } + + /** + * Returns the parsed command line. + * + * @return the parsed command line, null if nothing parsed + */ + public CommandLine getCommandLine() { + return cmd; + } + + /** + * Returns the CLI options. + * + * @return CLI options + */ + public Options getOptions() { + return options; + } + + /** + * Returns the version for an application as set by Maven. + * + * @return version, null if version file /app-version.txt was not found + */ + @SuppressWarnings("resource") + // tag::cliParserVersion[] + public String getAppVersion() { + return new Scanner(CliParser.class.getResourceAsStream("/app-version.txt"), "UTF-8").useDelimiter("\\A").next(); + } + // end::cliParserVersion[] +} diff --git a/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/Console.java b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/Console.java new file mode 100644 index 000000000..571333147 --- /dev/null +++ b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/Console.java @@ -0,0 +1,352 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.tools.common; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.text.StrBuilder; +import org.slf4j.helpers.MessageFormatter; + +/** + * A console for printing messages with functionality similar to loggers. The class provides a static instance for all + * parts of an application. The default configuration is to not collect errors or warnings. The default types being + * activated are errors, warnings, and info messages. + * + * @author Sven van der Meer (sven.van.der.meer@ericsson.com) + */ +public final class Console { + + /** The console as static object. */ + public static final Console CONSOLE = new Console(); + + /** Type for a quiet console, no messages being printed. */ + public static final int TYPE_QUIET = 0; + + /** Type for printing error messages. */ + public static final int TYPE_ERROR = 0b0001; + + /** Type for printing warning messages. */ + public static final int TYPE_WARNING = 0b0010; + + /** Type for printing information messages. */ + public static final int TYPE_INFO = 0b0100; + + /** Type for printing progress messages. */ + public static final int TYPE_PROGRESS = 0b1000; + + /** Type for printing debug messages. */ + public static final int TYPE_DEBUG = 0b001_0000; + + /** Type for printing trace messages. */ + public static final int TYPE_TRACE = 0b010_0000; + + /** Type for printing stack traces of caught exceptions. */ + public static final int TYPE_STACKTRACE = 0b110_0000; + + /** Type for a verbose console, activating all message types. */ + public static final int TYPE_VERBOSE = 0b111_1111; + + /** Configuration for a collecting error messages. */ + public static final int CONFIG_COLLECT_ERRORS = 0b0001; + + /** Configuration for a collecting warning messages. */ + public static final int CONFIG_COLLECT_WARNINGS = 0b0010; + + /** The setting for message types, set using type flags. */ + private int types; + + /** The console configuration, set using configuration flags. */ + private int configuration; + + /** A name for the application, if set used as prefix for messages. */ + private String appName; + + /** The list of errors, filled if error collection is activates. */ + private final List errors; + + /** The list of warnings, filled if warning collection is activates. */ + private final List warnings; + + /** + * Creates a new console. The constructor is private since the class provides static access to an instance. The + * default for types is verbose. + */ + private Console() { + types = TYPE_VERBOSE; + + configuration = 0; + errors = new ArrayList<>(); + warnings = new ArrayList<>(); + } + + /** + * Sets the application name. + * + * @param appName new application name, use null to reset the application name, a non-blank string for + * a new name, blank strings are ignored + */ + public void setAppName(final String appName) { + if (appName == null) { + this.appName = null; + } else if (!StringUtils.isBlank(appName)) { + this.appName = appName; + } + } + + /** + * Returns the application name. + * + * @return application name, null if not set, non-blank string otherwise + */ + public String getAppName() { + return appName; + } + + /** + * Activates a type. + * + * @param type the type to activate + */ + public void activate(final int type) { + types = types | type; + } + + /** + * Deactivates a type. + * + * @param type type to deactivate + */ + public void deActivate(final int type) { + types = types & ~type; + } + + /** + * Sets the type to the given type, effectively deactivating all other types. + * + * @param type new type + */ + public void set(final int type) { + types = type; + } + + /** + * Configures the console. Use the configuration flags in combination for the required configuration. For instance, + * to collect errors and warnings use CONFIG_COLLECT_ERRORS | CONFIG_COLLECT_WARNINGS. + * + * @param config the new configuration, overwrites the current configuration, 0 deactivates all settings + */ + public void configure(final int config) { + this.configuration = config; + } + + /** + * Sets the type to the given types, effectively deactivating all other types. + * + * @param ts array of types to set + */ + public void set(final int... ts) { + this.types = 0; + for (final int type : ts) { + this.activate(type); + } + } + + /** + * Prints an error message with message and objects if {@link #TYPE_ERROR} is set; and increases the error count. + * Errors are collected (if configuration is set) and the error counter is increased regardless of the console error + * type settings. + * + * @param message the error message, using the same format as the SLF4J MessageFormatter, nothing done if + * blank + * @param objects the objects for substitution in the message + */ + public void error(final String message, final Object... objects) { + if (StringUtils.isBlank(message)) { + return; + } + + final StrBuilder err = new StrBuilder(); + if (appName != null) { + err.append(this.getAppName()).append(": "); + } + err.append("error: "); + err.append(MessageFormatter.arrayFormat(message, objects).getMessage()); + + if ((types & TYPE_ERROR) == TYPE_ERROR) { + System.err.println(err.build()); + } + if ((configuration & CONFIG_COLLECT_ERRORS) == CONFIG_COLLECT_ERRORS) { + errors.add(err.build()); + } + } + + /** + * Prints a warning message with message and objects if {@link #TYPE_WARNING} is set; and increases the warning + * count. Warnings are collected (if configuration is set) and the warning counter is increased regardless of the + * console warning type settings. + * + * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if + * blank + * @param objects the objects for substitution in the message + */ + public void warn(final String message, final Object... objects) { + if (StringUtils.isBlank(message)) { + return; + } + + final StrBuilder warn = new StrBuilder(); + if (appName != null) { + warn.append(this.getAppName()).append(": "); + } + warn.append("warning: "); + warn.append(MessageFormatter.arrayFormat(message, objects).getMessage()); + + if ((types & TYPE_WARNING) == TYPE_WARNING) { + System.err.println(warn.build()); + } + if ((configuration & CONFIG_COLLECT_WARNINGS) == CONFIG_COLLECT_WARNINGS) { + warnings.add(warn.build()); + } + } + + /** + * Prints an info message with message and objects if {@link #TYPE_INFO} is set. + * + * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if + * blank + * @param objects the objects for substitution in the message + */ + public void info(final String message, final Object... objects) { + if (StringUtils.isBlank(message)) { + return; + } + + if ((types & TYPE_INFO) == TYPE_INFO) { + if (appName != null) { + System.err.print(appName + ": "); + } + System.err.println(MessageFormatter.arrayFormat(message, objects).getMessage()); + } + } + + /** + * Prints a progress message with message and objects if {@link #TYPE_PROGRESS} is set. + * + * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if + * blank + * @param objects the objects for substitution in the message + */ + public void progress(final String message, final Object... objects) { + if (StringUtils.isBlank(message)) { + return; + } + + if ((types & TYPE_PROGRESS) == TYPE_PROGRESS) { + if (appName != null) { + System.err.print(appName + ": "); + } + System.err.print("progress: "); + System.err.println(MessageFormatter.arrayFormat(message, objects).getMessage()); + } + } + + /** + * Prints a debug message with message and objects if {@link #TYPE_DEBUG} is set. + * + * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if + * blank + * @param objects the objects for substitution in the message + */ + public void debug(final String message, final Object... objects) { + if (StringUtils.isBlank(message)) { + return; + } + + if ((types & TYPE_DEBUG) == TYPE_DEBUG) { + if (appName != null) { + System.err.print(appName + ": "); + } + System.err.print("debug: "); + System.err.println(MessageFormatter.arrayFormat(message, objects).getMessage()); + } + } + + /** + * Prints a trace message with message and objects if {@link #TYPE_TRACE} is set. + * + * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if + * blank + * @param objects the objects for substitution in the message + */ + public void trace(final String message, final Object... objects) { + if (StringUtils.isBlank(message)) { + return; + } + + if ((types & TYPE_TRACE) == TYPE_TRACE) { + if (appName != null) { + System.err.print(appName + ": "); + } + System.err.print("trace: "); + System.err.println(MessageFormatter.arrayFormat(message, objects).getMessage()); + } + } + + /** + * Prints message, cause, and stack trace for a given exception if {@link #TYPE_STACKTRACE} is set. + * + * @param exception the exception to print, ignored if null + */ + public void stacktrace(final Exception exception) { + if (exception == null) { + return; + } + + if ((types & TYPE_STACKTRACE) == TYPE_STACKTRACE) { + if (appName != null) { + System.err.print(appName + ": "); + } + System.err.println("exception stack trace: "); + System.err.println(" - message: " + exception.getMessage()); + if (exception.getCause() != null) { + System.err.println(" - cause: " + exception.getCause()); + } + exception.printStackTrace(); + } + } + + /** + * Resets the error counter and the list of errors. + */ + public void resetErrors() { + errors.clear(); + } + + /** + * Resets the warning counter and the list of warnings. + */ + public void resetWarnings() { + warnings.clear(); + } + +} diff --git a/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/OutputFile.java b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/OutputFile.java new file mode 100644 index 000000000..b529a7e08 --- /dev/null +++ b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/OutputFile.java @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.tools.common; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; +import java.nio.file.FileSystems; +import java.nio.file.Path; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; + +/** + * Standard output file handling and tests. + * + * @author Sven van der Meer (sven.van.der.meer@ericsson.com) + */ +public class OutputFile { + + /** The output file name. */ + private final String fileName; + + /** The output file name. */ + private final boolean overwrite; + + /** + * Creates a new object for a given file name. + * + * @param fileName the file name + */ + public OutputFile(final String fileName) { + this(fileName, false); + } + + /** + * Creates a new object for a given file name. + * + * @param fileName the file name + * @param overwrite if the file already exists, can it be overwritten, or should an error be raised + */ + public OutputFile(final String fileName, final boolean overwrite) { + Validate.notBlank(fileName); + this.fileName = fileName; + this.overwrite = overwrite; + } + + /** + * Get a File object for this output file. + * + * @return a File object for this output file + */ + public File toFile() { + final Path fp = FileSystems.getDefault().getPath(fileName); + return fp.toFile(); + } + + /** + * Get a Writer object for this output file. + * + * @return a Writer object for this output file + */ + public Writer toWriter() { + try { + return new BufferedWriter(new FileWriter(toFile())); + } catch (final IOException e) { + return null; + } + } + + /** + * Get a OutputStream object for this output file. + * + * @return an OutputStream object for this output file + */ + public OutputStream toOutputStream() { + try { + return new FileOutputStream(toFile()); + } catch (final IOException e) { + return null; + } + } + + /** + * Validates the output file. Validation tests for file name being blank, file existing, creation, and finally + * can-write. + * + * @return null on success, an error message on error + */ + public String validate() { + if (StringUtils.isBlank(fileName)) { + return "file name was blank"; + } + + final File file = toFile(); + if (file.exists()) { + if (!overwrite) { + return "file already exists"; + } + } else { + try { + file.createNewFile(); + } catch (final IOException e) { + return "could not create output file: " + e.getMessage(); + } + } + + if (!file.canWrite()) { + return "cannot write to file"; + } + + return null; + } +} diff --git a/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/package-info.java b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/package-info.java new file mode 100644 index 000000000..e193aac5d --- /dev/null +++ b/tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. All rights reserved. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Utilities for APEX related applications, such as CLI parser and application console. + * + * @author Sven van der Meer (sven.van.der.meer@ericsson.com) + */ + +package org.onap.policy.apex.tools.common; diff --git a/tools/tools-common/src/main/resources/app-version.txt b/tools/tools-common/src/main/resources/app-version.txt new file mode 100644 index 000000000..f2ab45c3b --- /dev/null +++ b/tools/tools-common/src/main/resources/app-version.txt @@ -0,0 +1 @@ +${project.version} \ No newline at end of file -- cgit 1.2.3-korg