aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pom.xml1
-rw-r--r--tools/model-generator/pom.xml60
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/KeyInfoGetter.java153
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/SchemaUtils.java175
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Application.java124
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Model2Cli.java463
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/package-info.java27
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Application.java111
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Model2JsonEventSchema.java265
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/package-info.java27
-rw-r--r--tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/package-info.java27
-rw-r--r--tools/model-generator/src/main/resources/org/onap/policy/apex/tools/model/generator/event-json.stg86
-rw-r--r--tools/pom.xml41
-rw-r--r--tools/simple-wsclient/pom.xml76
-rw-r--r--tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/Application.java181
-rw-r--r--tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleConsole.java145
-rw-r--r--tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleEcho.java108
-rw-r--r--tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/package-info.java27
-rw-r--r--tools/tools-common/pom.xml73
-rw-r--r--tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliOptions.java105
-rw-r--r--tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/CliParser.java119
-rw-r--r--tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/Console.java352
-rw-r--r--tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/OutputFile.java136
-rw-r--r--tools/tools-common/src/main/java/org/onap/policy/apex/tools/common/package-info.java27
-rw-r--r--tools/tools-common/src/main/resources/app-version.txt1
-rw-r--r--tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/TestCliParser.java43
-rw-r--r--tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleAppVersion.java65
-rw-r--r--tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleCliParser.java116
28 files changed, 3134 insertions, 0 deletions
diff --git a/pom.xml b/pom.xml
index 2b545b6c3..ad9f12f0c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -159,5 +159,6 @@
<module>packages</module>
<module>testsuites</module>
<module>client</module>
+ <module>tools</module>
</modules>
</project>
diff --git a/tools/model-generator/pom.xml b/tools/model-generator/pom.xml
new file mode 100644
index 000000000..2cdc7c20f
--- /dev/null
+++ b/tools/model-generator/pom.xml
@@ -0,0 +1,60 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 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=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.policy.apex-pdp.tools</groupId>
+ <artifactId>tools</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>model-generator</artifactId>
+ <name>${project.artifactId}</name>
+ <description>[${project.parent.artifactId}] Apex generators from policy model</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.tools</groupId>
+ <artifactId>tools-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.model</groupId>
+ <artifactId>model-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.services</groupId>
+ <artifactId>services-engine</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-schema</groupId>
+ <artifactId>context-schema-avro</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.auth</groupId>
+ <artifactId>cli-codegen</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/KeyInfoGetter.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/KeyInfoGetter.java
new file mode 100644
index 000000000..a04ed49f3
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/KeyInfoGetter.java
@@ -0,0 +1,153 @@
+/*-
+ * ============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.model.generator;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * Getter methods for policy keys.
+ *
+ * @author John Keeney (john.keeney@ericsson.com)
+ */
+
+public class KeyInfoGetter {
+
+ /** The policy model for the getters. */
+ private final AxPolicyModel model;
+
+ /**
+ * Creates a new key getter.
+ *
+ * @param model the policy model to use
+ */
+ public KeyInfoGetter(final AxPolicyModel model) {
+ this.model = model;
+ }
+
+ /**
+ * Returns the key name as string.
+ *
+ * @param key the key to transform
+ * @return key name as string, null if key was null
+ */
+ public String getName(final AxArtifactKey key) {
+ if (key == null) {
+ return null;
+ }
+ return key.getName();
+ }
+
+ /**
+ * Returns the version of an artifact key.
+ *
+ * @param key the key to extract version from
+ * @return version of the key, null if key was null
+ */
+ public String getVersion(final AxArtifactKey key) {
+ if (key == null) {
+ return null;
+ }
+ return key.getVersion();
+ }
+
+ /**
+ * Returns the parent name for the key.
+ *
+ * @param key the key to process
+ * @return parent name, null if key was null
+ */
+ public String getPName(final AxReferenceKey key) {
+ if (key == null) {
+ return null;
+ }
+ return key.getParentKeyName();
+ }
+
+ /**
+ * Returns the parent version for the key.
+ *
+ * @param key the key to process
+ * @return parent version, null if key was null
+ */
+ public String getPVersion(final AxReferenceKey key) {
+ if (key == null) {
+ return null;
+ }
+ return key.getParentKeyVersion();
+ }
+
+ /**
+ * Returns the local name for the key.
+ *
+ * @param key the key to process
+ * @return local name, null if key was null
+ */
+ public String getLName(final AxReferenceKey key) {
+ if (key == null) {
+ return null;
+ }
+ return key.getLocalName();
+ }
+
+ /**
+ * Returns the local name of the parent for the key.
+ *
+ * @param key the key to process
+ * @return local name of the parent, null if key was null
+ */
+ public String getPLName(final AxReferenceKey key) {
+ if (key == null) {
+ return null;
+ }
+ return key.getParentLocalName();
+ }
+
+ /**
+ * Returns the UUID of an artifact key.
+ *
+ * @param key the key to extract version from
+ * @return UUID of the key, null if key was null
+ */
+ public String getUUID(final AxArtifactKey key) {
+ final AxKeyInfo ki = model.getKeyInformation().get(key);
+ if (ki == null || ki.getUUID() == null) {
+ return null;
+ }
+ return ki.getUUID().toString();
+ }
+
+ /**
+ * Returns the description of an artifact key.
+ *
+ * @param key the key to extract version from
+ * @return description of the key, null if key was null
+ */
+ public String getDesc(final AxArtifactKey key) {
+ final AxKeyInfo ki = model.getKeyInformation().get(key);
+ if (ki == null || ki.getDescription() == null) {
+ return null;
+ }
+ return ki.getDescription().toString();
+ }
+}
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/SchemaUtils.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/SchemaUtils.java
new file mode 100644
index 000000000..3a4feb049
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/SchemaUtils.java
@@ -0,0 +1,175 @@
+/*-
+ * ============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.model.generator;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avro.AvroRuntimeException;
+import org.apache.avro.Schema;
+import org.apache.avro.Schema.Field;
+import org.apache.avro.reflect.ReflectData;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelper;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+
+/**
+ * Utility methods for schema handling.
+ *
+ * @author John Keeney (john.keeney@ericsson.com)
+ */
+public final class SchemaUtils {
+
+ /**
+ * Private constructor to avoid instantiation.
+ */
+ private SchemaUtils() {}
+
+ /**
+ * Returns the schema for an event.
+ *
+ * @param event the event to process
+ * @return the schema of the event
+ * @throws ApexEventException in any error case
+ */
+ public static Schema getEventSchema(final AxEvent event) throws ApexEventException {
+ final Schema skeletonSchema = Schema.createRecord(event.getKey().getName(), event.getNameSpace(),
+ "org.onap.policy.apex.model.eventmodel.events", false);
+
+ // Get the schema field for each parameter
+ final List<Field> fields = new ArrayList<>(getSkeletonEventSchemaFields());
+
+ final Map<String, Schema> preExistingParamSchemas = new LinkedHashMap<>();
+ for (final AxField parameter : event.getParameterMap().values()) {
+ final Schema fieldSchema = getEventParameterSchema(parameter, preExistingParamSchemas);
+ final Field f = new Field(parameter.getKey().getLocalName(), fieldSchema, (String) null, (Object) null);
+ fields.add(f);
+ }
+ skeletonSchema.setFields(fields);
+
+ return skeletonSchema;
+ }
+
+ /**
+ * Returns the schema fields as an array.
+ *
+ * @return an array with schema fields in the following order: nameSpace, name, version, source, target
+ */
+ public static List<Field> getSkeletonEventSchemaFields() {
+ // Fixed fields
+ final Field f1 = new Field("nameSpace", Schema.create(Schema.Type.STRING), (String) null, (Object) null);
+ final Field f2 = new Field("name", Schema.create(Schema.Type.STRING), (String) null, (Object) null);
+ final Field f3 = new Field("version", Schema.create(Schema.Type.STRING), (String) null, (Object) null);
+ final Field f4 = new Field("source", Schema.create(Schema.Type.STRING), (String) null, (Object) null);
+ final Field f5 = new Field("target", Schema.create(Schema.Type.STRING), (String) null, (Object) null);
+
+ return Arrays.asList(f1, f2, f3, f4, f5);
+ }
+
+ /**
+ * Returns the schema for an event parameter.
+ *
+ * @param parameter the parameter to process
+ * @param preexistingParamSchemas map of pre-existing schemas
+ * @return the schema for the event parameter
+ * @throws ApexEventException in case of any error
+ */
+ public static Schema getEventParameterSchema(final AxField parameter,
+ final Map<String, Schema> preexistingParamSchemas) throws ApexEventException {
+ final SchemaHelper schemaHelper =
+ new SchemaHelperFactory().createSchemaHelper(parameter.getKey(), parameter.getSchema().getKey());
+
+ Schema parameterSchema = null;
+ try {
+ if (schemaHelper instanceof AvroSchemaHelper) {
+ parameterSchema = ((AvroSchemaHelper) schemaHelper).getAvroSchema();
+ } else {
+ parameterSchema = ReflectData.get().getSchema(schemaHelper.getSchemaClass());
+ }
+ } catch (final AvroRuntimeException e) {
+ throw new ApexEventException("failed to decode a schema for parameter " + parameter.getKey().getLocalName()
+ + " of type " + parameter.getSchema().getID() + " with Java type " + schemaHelper.getSchemaClass(),
+ e);
+ }
+ final String schemaname = parameterSchema.getFullName();
+
+ // Get the Avro schema for this parameter, we need to keep track of sub-schemas for records because Avro does
+ // not
+ // allow re-declaration of sub-schema records of the same type. You simply reference the first sub-schema.
+ final Schema alreadyseen = preexistingParamSchemas.get(schemaname);
+
+ try {
+ processSubSchemas(parameterSchema, preexistingParamSchemas);
+ } catch (AvroRuntimeException | ApexEventException e) {
+ throw new ApexEventException("failed to decode a schema for parameter " + parameter.getKey().getLocalName()
+ + " of type " + parameter.getSchema().getID() + " using Schema type " + schemaname, e);
+ }
+ if (alreadyseen != null) {
+ // logger.warn("parameter "+ parameter.getKey().getLocalName() + " of type " + parameter.getSchema().getID()
+ // + " tries to redfine AVRO type
+ // "+schemaname+", but it was previously defined. This parameter will use the previously defined version
+ // because AVRO does not support redefinition
+ // of types that have already been defined");
+ parameterSchema = alreadyseen;
+ }
+
+ return parameterSchema;
+ }
+
+ /**
+ * Processes a sub-schema.
+ *
+ * @param avroParameterSchema an AVRO schema to process
+ * @param map mapping of strings to schemas
+ * @throws ApexEventException in case of any error
+ */
+ public static void processSubSchemas(final Schema avroParameterSchema, final Map<String, Schema> map)
+ throws ApexEventException {
+ if (avroParameterSchema.getType() == Schema.Type.RECORD) {
+ final String schematypename = avroParameterSchema.getFullName();
+ final Schema alreadyregistered = map.get(schematypename);
+ if (alreadyregistered != null && !avroParameterSchema.equals(alreadyregistered)) {
+ throw new ApexEventException(
+ "Parameter attempts to redefine type " + schematypename + " when it has already been defined");
+ }
+ map.put(schematypename, avroParameterSchema);
+ for (final Schema.Field f : avroParameterSchema.getFields()) {
+ final Schema fieldschema = f.schema();
+ processSubSchemas(fieldschema, map);
+ }
+ } else if (avroParameterSchema.getType() == Schema.Type.ARRAY) {
+ processSubSchemas(avroParameterSchema.getElementType(), map);
+ } else if (avroParameterSchema.getType() == Schema.Type.MAP) {
+ processSubSchemas(avroParameterSchema.getValueType(), map);
+ } else if (avroParameterSchema.getType() == Schema.Type.UNION) {
+ for (final Schema s : avroParameterSchema.getTypes()) {
+ processSubSchemas(s, map);
+ }
+ }
+ }
+
+}
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Application.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Application.java
new file mode 100644
index 000000000..236750310
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Application.java
@@ -0,0 +1,124 @@
+/*-
+ * ============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.model.generator.model2cli;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.tools.common.CliOptions;
+import org.onap.policy.apex.tools.common.CliParser;
+import org.onap.policy.apex.tools.common.OutputFile;
+
+/**
+ * Process an Apex Policy Model file to generate the CLI commands to generate an equivalent Apex Policy Model.
+ *
+ * @author Sven van der Meer &lt;sven.van.der.meer@ericsson.com&gt;
+ */
+public final class Application {
+
+ /** The name of the application. */
+ public static final String APP_NAME = "gen-model2cli";
+
+ /** The description 1-liner of the application. */
+ public static final String APP_DESCRIPTION = "generates CLI Editor Commands from a policy model";
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private Application() {}
+
+ /**
+ * Main method to start the application.
+ *
+ * @param args the command line arguments
+ */
+ public static void main(final String[] args) {
+ final CliParser cli = new CliParser();
+ cli.addOption(CliOptions.HELP);
+ cli.addOption(CliOptions.VERSION);
+ cli.addOption(CliOptions.SKIPVALIDATION);
+ cli.addOption(CliOptions.MODELFILE);
+ cli.addOption(CliOptions.FILEOUT);
+ cli.addOption(CliOptions.OVERWRITE);
+
+ final CommandLine cmd = cli.parseCli(args);
+
+ // help is an exit option, print usage and exit
+ if (cmd.hasOption(CliOptions.HELP.getOpt())) {
+ final HelpFormatter formatter = new HelpFormatter();
+ System.out.println(APP_NAME + " v" + cli.getAppVersion() + " - " + APP_DESCRIPTION);
+ formatter.printHelp(APP_NAME, cli.getOptions());
+ System.out.println();
+ return;
+ }
+
+ // version is an exit option, print version and exit
+ if (cmd.hasOption(CliOptions.VERSION.getOpt())) {
+ System.out.println(APP_NAME + " " + cli.getAppVersion());
+ System.out.println();
+ return;
+ }
+
+ String modelFile = cmd.getOptionValue(CliOptions.MODELFILE.getOpt());
+ if (modelFile != null) {
+ modelFile = cmd.getOptionValue("model");
+ }
+ if (modelFile == null) {
+ System.err.println(APP_NAME + ": no '-" + CliOptions.MODELFILE.getOpt()
+ + "' model file given, cannot proceed (try -h for help)");
+ return;
+ }
+
+ OutputFile outfile = null;
+ final String of = cmd.getOptionValue(CliOptions.FILEOUT.getOpt());
+ final boolean overwrite = cmd.hasOption(CliOptions.OVERWRITE.getOpt());
+ if (overwrite && of == null) {
+ System.err.println(APP_NAME + ": error with '-" + CliOptions.OVERWRITE.getOpt()
+ + "' option. This option is only valid if a '-" + CliOptions.FILEOUT.getOpt()
+ + "' option is also used. Cannot proceed (try -h for help)");
+ return;
+ }
+ if (of != null) {
+ outfile = new OutputFile(of, overwrite);
+ final String isoutfileok = outfile.validate();
+ if (isoutfileok != null) {
+ System.err.println(APP_NAME + ": error with '-" + CliOptions.FILEOUT.getOpt() + "' option: \""
+ + isoutfileok + "\". Cannot proceed (try -h for help)");
+ return;
+ }
+ }
+
+ if (outfile == null) {
+ System.out.println();
+ System.out.println(APP_NAME + ": starting CLI generator");
+ System.out.println(" --> model file: " + modelFile);
+ System.out.println();
+ System.out.println();
+ }
+
+ try {
+ final Model2Cli app = new Model2Cli(modelFile, outfile, !cmd.hasOption("sv"), APP_NAME);
+ app.runApp();
+ } catch (final ApexException aex) {
+ System.err.println(APP_NAME + ": caught APEX exception with message: " + aex.getMessage());
+ }
+ }
+}
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Model2Cli.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Model2Cli.java
new file mode 100644
index 000000000..5117a2ecf
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/Model2Cli.java
@@ -0,0 +1,463 @@
+/*-
+ * ============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.model.generator.model2cli;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import org.apache.commons.lang3.Validate;
+import org.onap.policy.apex.auth.clicodegen.CGCliEditor;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.modelapi.ApexModelFactory;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+import org.onap.policy.apex.tools.common.OutputFile;
+import org.onap.policy.apex.tools.model.generator.KeyInfoGetter;
+import org.stringtemplate.v4.ST;
+
+/**
+ * Takes a model and generates the JSON event schemas.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class Model2Cli {
+
+ /** Application name, used as prompt. */
+ private final String appName;
+
+ /** The file name of the policy model. */
+ private final String modelFile;
+
+ /** The output file, if any. */
+ private final OutputFile outFile;
+
+ /** Pre-validate the model. */
+ private final boolean validate;
+
+ /** utility for getting key information and parsing keys etc.. */
+ private KeyInfoGetter kig = null;
+
+ /**
+ * Creates a new model to CLI commands generator.
+ *
+ * @param modelFile the model file to be used
+ * @param outFile the out file
+ * @param validate true for model validation, false otherwise
+ * @param appName application name for printouts
+ */
+ public Model2Cli(final String modelFile, final OutputFile outFile, final boolean validate, final String appName) {
+ Validate.notNull(modelFile, "Model2Cli: given model file name was blank");
+ Validate.notNull(appName, "Model2Cli: given application name was blank");
+ this.modelFile = modelFile;
+ this.outFile = outFile;
+ this.appName = appName;
+ this.validate = validate;
+ }
+
+ /**
+ * Runs the application.
+ *
+ * @return status of the application execution, 0 for success, positive integer for exit condition (such as help or
+ * version), negative integer for errors
+ * @throws ApexException if any problem occurred in the model
+ */
+ public int runApp() throws ApexException {
+ final CGCliEditor codeGen = new CGCliEditor();
+
+ final ApexModelFactory factory = new ApexModelFactory();
+ final ApexModel model = factory.createApexModel(new Properties(), true);
+
+ final ApexAPIResult result = model.loadFromFile(modelFile);
+ if (result.isNOK()) {
+ System.err.println(appName + ": " + result.getMessage());
+ return -1;
+ }
+
+ final AxPolicyModel policyModel = model.getPolicyModel();
+ policyModel.register();
+
+ if (validate) {
+ final AxValidationResult val = new AxValidationResult();
+ policyModel.validate(val);
+ if (!val.isOK()) {
+ System.err.println("Cannot translate the model. The model is not valid: \n" + val.toString());
+ return -1;
+ }
+ }
+
+ kig = new KeyInfoGetter(policyModel);
+
+ // Order is important. 0: model, 1: context schemas, 2: tasks, 3: events, 4: ContextAlbums, 5: Policies
+ // 0: model
+ final AxArtifactKey pmkey = policyModel.getKey();
+ codeGen.addModelParams(kig.getName(pmkey), kig.getVersion(pmkey), kig.getUUID(pmkey), kig.getDesc(pmkey));
+
+ // 1: Context Schemas
+ for (final AxContextSchema s : policyModel.getSchemas().getSchemasMap().values()) {
+ final AxArtifactKey key = s.getKey();
+
+ codeGen.addSchemaDeclaration(kig.getName(key), kig.getVersion(key), kig.getUUID(key), kig.getDesc(key),
+ s.getSchemaFlavour(), s.getSchema());
+ }
+
+ // 2: tasks
+ for (final AxTask t : policyModel.getTasks().getTaskMap().values()) {
+ final AxArtifactKey key = t.getKey();
+ final List<ST> infields = getInfieldsForTask(codeGen, t);
+ final List<ST> outfields = getOutfieldsForTask(codeGen, t);
+ final ST logic = getLogicForTask(codeGen, t);
+ final List<ST> parameters = getParametersForTask(codeGen, t);
+ final List<ST> contextRefs = getCtxtRefsForTask(codeGen, t);
+
+ codeGen.addTaskDeclaration(kig.getName(key), kig.getVersion(key), kig.getUUID(key), kig.getDesc(key),
+ infields, outfields, logic, parameters, contextRefs);
+ }
+
+ // 3: events
+ for (final AxEvent e : policyModel.getEvents().getEventMap().values()) {
+ final AxArtifactKey key = e.getKey();
+ final List<ST> fields = getParametersForEvent(codeGen, e);
+
+ codeGen.addEventDeclaration(kig.getName(key), kig.getVersion(key), kig.getUUID(key), kig.getDesc(key),
+ e.getNameSpace(), e.getSource(), e.getTarget(), fields);
+ }
+
+ // 4: context albums
+ for (final AxContextAlbum a : policyModel.getAlbums().getAlbumsMap().values()) {
+ final AxArtifactKey key = a.getKey();
+
+ codeGen.addContextAlbumDeclaration(kig.getName(key), kig.getVersion(key), kig.getUUID(key),
+ kig.getDesc(key), a.getScope(), a.isWritable(), kig.getName(a.getItemSchema()),
+ kig.getVersion(a.getItemSchema()));
+ }
+
+ // 5: policies
+ for (final AxPolicy p : policyModel.getPolicies().getPolicyMap().values()) {
+ final AxArtifactKey key = p.getKey();
+ final List<ST> states = getStatesForPolicy(codeGen, p);
+ codeGen.addPolicyDefinition(kig.getName(key), kig.getVersion(key), kig.getUUID(key), kig.getDesc(key),
+ p.getTemplate(), p.getFirstState(), states);
+ }
+
+ final String out = codeGen.getModel().render();
+ if (outFile != null) {
+ try {
+ final Writer w = outFile.toWriter();
+ if (w == null) {
+ System.err.println("Error writing output to file " + outFile);
+ return -1;
+ }
+ w.write(out);
+ w.close();
+ } catch (final IOException e) {
+ System.err.println("Error writing output to file " + outFile + ": " + e.getMessage());
+ return -1;
+ }
+ } else {
+ System.err.println(out);
+ }
+ return 0;
+ }
+
+ /**
+ * Gets the parameters for event.
+ *
+ * @param cg the code generator
+ * @param e the event
+ * @return the parameters for event
+ */
+ private List<ST> getParametersForEvent(final CGCliEditor cg, final AxEvent e) {
+ final Collection<AxField> fields = e.getFields();
+ final List<ST> ret = new ArrayList<>(fields.size());
+ for (final AxField f : fields) {
+ final AxReferenceKey fkey = f.getKey();
+
+ final ST val = cg.createEventFieldDefinition(kig.getPName(fkey), kig.getPVersion(fkey), kig.getLName(fkey),
+ kig.getName(f.getSchema()), kig.getVersion(f.getSchema()), f.getOptional());
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the context references for task.
+ *
+ * @param cg the code generator
+ * @param t the task
+ * @return the context references for task
+ */
+ private List<ST> getCtxtRefsForTask(final CGCliEditor cg, final AxTask t) {
+ final Collection<AxArtifactKey> ctxs = t.getContextAlbumReferences();
+ final List<ST> ret = new ArrayList<>(ctxs.size());
+ final AxArtifactKey tkey = t.getKey();
+ for (final AxArtifactKey ckey : ctxs) {
+
+ final ST val = cg.createTaskDefinitionContextRef(kig.getName(tkey), kig.getVersion(tkey), kig.getName(ckey),
+ kig.getVersion(ckey));
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the parameters for task.
+ *
+ * @param cg the code generator
+ * @param t the task
+ * @return the parameters for task
+ */
+ private List<ST> getParametersForTask(final CGCliEditor cg, final AxTask t) {
+ final Collection<AxTaskParameter> pars = t.getTaskParameters().values();
+ final List<ST> ret = new ArrayList<>(pars.size());
+ for (final AxTaskParameter p : pars) {
+ final AxReferenceKey pkey = p.getKey();
+
+ final ST val = cg.createTaskDefinitionParameters(kig.getPName(pkey), kig.getPVersion(pkey),
+ kig.getLName(pkey), p.getTaskParameterValue());
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the logic for task.
+ *
+ * @param cg the code generator
+ * @param t the task
+ * @return the logic for task
+ */
+ private ST getLogicForTask(final CGCliEditor cg, final AxTask t) {
+ final AxArtifactKey tkey = t.getKey();
+ final AxTaskLogic tl = t.getTaskLogic();
+
+ final ST val =
+ cg.createTaskDefLogic(kig.getName(tkey), kig.getVersion(tkey), tl.getLogicFlavour(), tl.getLogic());
+
+ return val;
+ }
+
+ /**
+ * Gets the output fields for task.
+ *
+ * @param cg the code generator
+ * @param t the task
+ * @return the output fields for task
+ */
+ private List<ST> getOutfieldsForTask(final CGCliEditor cg, final AxTask t) {
+ final Collection<? extends AxField> fields = t.getOutputFields().values();
+ final List<ST> ret = new ArrayList<>(fields.size());
+ for (final AxField f : fields) {
+ final AxReferenceKey fkey = f.getKey();
+
+ final ST val = cg.createTaskDefinitionOutfields(kig.getPName(fkey), kig.getPVersion(fkey),
+ kig.getLName(fkey), kig.getName(f.getSchema()), kig.getVersion(f.getSchema()));
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the input fields for task.
+ *
+ * @param cg the code generator
+ * @param t the task
+ * @return the input fields for task
+ */
+ private List<ST> getInfieldsForTask(final CGCliEditor cg, final AxTask t) {
+ final Collection<? extends AxField> fields = t.getInputFields().values();
+ final List<ST> ret = new ArrayList<>(fields.size());
+ for (final AxField f : fields) {
+ final AxReferenceKey fkey = f.getKey();
+
+ final ST val = cg.createTaskDefinitionInfields(kig.getPName(fkey), kig.getPVersion(fkey),
+ kig.getLName(fkey), kig.getName(f.getSchema()), kig.getVersion(f.getSchema()));
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the states for policy.
+ *
+ * @param cg the code generator
+ * @param p the policy
+ * @return the states for policy
+ */
+ private List<ST> getStatesForPolicy(final CGCliEditor cg, final AxPolicy p) {
+ final Collection<AxState> states = p.getStateMap().values();
+ final List<ST> ret = new ArrayList<>(states.size());
+ for (final AxState st : states) {
+ final AxReferenceKey skey = st.getKey();
+ final List<ST> outputs = getStateOutputsForState(cg, st);
+ final List<ST> finalizerLogics = getFinalizersForState(cg, st);
+ final List<ST> tasks = getTaskRefsForState(cg, st);
+ final List<ST> tsLogic = getTSLForState(cg, st);
+ final List<ST> ctxRefs = getCtxtRefsForState(cg, st);
+
+ final ST val = cg.createPolicyStateDef(kig.getPName(skey), kig.getPVersion(skey), kig.getLName(skey),
+ kig.getName(st.getTrigger()), kig.getVersion(st.getTrigger()), kig.getName(st.getDefaultTask()),
+ kig.getVersion(st.getDefaultTask()), outputs, tasks, tsLogic, finalizerLogics, ctxRefs);
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the finalizers for state.
+ *
+ * @param cg the code generator
+ * @param st the state
+ * @return the finalizers for state
+ */
+ private List<ST> getFinalizersForState(final CGCliEditor cg, final AxState st) {
+ final Collection<AxStateFinalizerLogic> fins = st.getStateFinalizerLogicMap().values();
+ final List<ST> ret = new ArrayList<>(fins.size());
+ final AxReferenceKey skey = st.getKey();
+ for (final AxStateFinalizerLogic fin : fins) {
+ final AxReferenceKey finkey = fin.getKey();
+
+ final ST val = cg.createPolicyStateDefFinalizerLogic(kig.getPName(skey), kig.getPVersion(skey),
+ kig.getLName(skey), kig.getLName(finkey), fin.getLogicFlavour(), fin.getLogic());
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the context references for state.
+ *
+ * @param cg the code generator
+ * @param st the state
+ * @return the context references for state
+ */
+ private List<ST> getCtxtRefsForState(final CGCliEditor cg, final AxState st) {
+ final Collection<AxArtifactKey> ctxs = st.getContextAlbumReferences();
+ final List<ST> ret = new ArrayList<>(ctxs.size());
+ final AxReferenceKey skey = st.getKey();
+ for (final AxArtifactKey ctx : ctxs) {
+
+ final ST val = cg.createPolicyStateDefContextRef(kig.getPName(skey), kig.getPVersion(skey),
+ kig.getLName(skey), kig.getName(ctx), kig.getVersion(ctx));
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the Task Selection Logic for state.
+ *
+ * @param cg the code generator
+ * @param st the state
+ * @return the TSL for state (if any) in a list
+ */
+ private List<ST> getTSLForState(final CGCliEditor cg, final AxState st) {
+ final AxReferenceKey skey = st.getKey();
+ if (st.checkSetTaskSelectionLogic()) {
+ final AxTaskSelectionLogic tsl = st.getTaskSelectionLogic();
+ final ST val = cg.createPolicyStateDefTaskSelLogic(kig.getPName(skey), kig.getPVersion(skey),
+ kig.getLName(skey), tsl.getLogicFlavour(), tsl.getLogic());
+ return Collections.singletonList(val);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * Gets the task references for state.
+ *
+ * @param cg the code generator
+ * @param st the state
+ * @return the task references for state
+ */
+ private List<ST> getTaskRefsForState(final CGCliEditor cg, final AxState st) {
+ final Map<AxArtifactKey, AxStateTaskReference> taskrefs = st.getTaskReferences();
+ final List<ST> ret = new ArrayList<>(taskrefs.size());
+ final AxReferenceKey skey = st.getKey();
+ for (final Entry<AxArtifactKey, AxStateTaskReference> e : taskrefs.entrySet()) {
+ final AxArtifactKey tkey = e.getKey();
+ final AxStateTaskReference tr = e.getValue();
+ final AxReferenceKey trkey = tr.getKey();
+
+ final ST val = cg.createPolicyStateTask(kig.getPName(skey), kig.getPVersion(skey), kig.getLName(skey),
+ kig.getLName(trkey), kig.getName(tkey), kig.getVersion(tkey), tr.getStateTaskOutputType().name(),
+ kig.getLName(tr.getOutput()));
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+ /**
+ * Gets the state outputs for state.
+ *
+ * @param cg the code generator
+ * @param st the state
+ * @return the state outputs for state
+ */
+ private List<ST> getStateOutputsForState(final CGCliEditor cg, final AxState st) {
+ final Collection<AxStateOutput> outs = st.getStateOutputs().values();
+ final List<ST> ret = new ArrayList<>(outs.size());
+ final AxReferenceKey skey = st.getKey();
+ for (final AxStateOutput out : outs) {
+ final AxReferenceKey outkey = out.getKey();
+
+ final ST val = cg.createPolicyStateOutput(kig.getPName(skey), kig.getPVersion(skey), kig.getLName(skey),
+ kig.getLName(outkey), kig.getName(out.getOutgingEvent()), kig.getVersion(out.getOutgingEvent()),
+ kig.getLName(out.getNextState()));
+
+ ret.add(val);
+ }
+ return ret;
+ }
+
+}
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/package-info.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/package-info.java
new file mode 100644
index 000000000..b8b3ffaef
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2cli/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=========================================================
+ */
+
+/**
+ * An application generating CLI editor commands from a policy model.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+
+package org.onap.policy.apex.tools.model.generator.model2cli;
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Application.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Application.java
new file mode 100644
index 000000000..2bc70f69e
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Application.java
@@ -0,0 +1,111 @@
+/*-
+ * ============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.model.generator.model2event;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.tools.common.CliOptions;
+import org.onap.policy.apex.tools.common.CliParser;
+
+/**
+ * Model 2 event generator with main method.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public final class Application {
+
+ /** The name of the application. */
+ public static final String APP_NAME = "gen-model2event";
+
+ /** The description 1-liner of the application. */
+ public static final String APP_DESCRIPTION = "generates JSON templates for events generated from a policy model";
+
+ /** Private constructor to prevent instantiation. */
+ private Application() {}
+
+ /**
+ * Main method to start the application.
+ *
+ * @param args the command line arguments
+ */
+ public static void main(final String[] args) {
+ final CliParser cli = new CliParser();
+ cli.addOption(CliOptions.HELP);
+ cli.addOption(CliOptions.VERSION);
+ cli.addOption(CliOptions.MODELFILE);
+ cli.addOption(CliOptions.TYPE);
+
+ final CommandLine cmd = cli.parseCli(args);
+
+ // help is an exit option, print usage and exit
+ if (cmd.hasOption('h') || cmd.hasOption("help")) {
+ final HelpFormatter formatter = new HelpFormatter();
+ System.out.println(APP_NAME + " v" + cli.getAppVersion() + " - " + APP_DESCRIPTION);
+ formatter.printHelp(APP_NAME, cli.getOptions());
+ System.out.println();
+ return;
+ }
+
+ // version is an exit option, print version and exit
+ if (cmd.hasOption('v') || cmd.hasOption("version")) {
+ System.out.println(APP_NAME + " " + cli.getAppVersion());
+ System.out.println();
+ return;
+ }
+
+ String modelFile = cmd.getOptionValue('m');
+ if (modelFile == null) {
+ modelFile = cmd.getOptionValue("model");
+ }
+ if (modelFile == null) {
+ System.err.println(APP_NAME + ": no model file given, cannot proceed (try -h for help)");
+ return;
+ }
+
+ String type = cmd.getOptionValue('t');
+ if (type == null) {
+ type = cmd.getOptionValue("type");
+ }
+ if (type == null) {
+ System.err.println(APP_NAME + ": no event type given, cannot proceed (try -h for help)");
+ return;
+ }
+ if (!type.equals("stimuli") && !type.equals("response") && !type.equals("internal")) {
+ System.err.println(APP_NAME + ": unknown type <" + type + ">, cannot proceed (try -h for help)");
+ return;
+ }
+
+ System.out.println();
+ System.out.println(APP_NAME + ": starting Event generator");
+ System.out.println(" --> model file: " + modelFile);
+ System.out.println(" --> type: " + type);
+ System.out.println();
+ System.out.println();
+
+ try {
+ final Model2JsonEventSchema app = new Model2JsonEventSchema(modelFile, type, APP_NAME);
+ app.runApp();
+ } catch (final ApexException aex) {
+ System.err.println(APP_NAME + ": caught APEX exception with message: " + aex.getMessage());
+ }
+ }
+}
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Model2JsonEventSchema.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Model2JsonEventSchema.java
new file mode 100644
index 000000000..ec6d72c4b
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/Model2JsonEventSchema.java
@@ -0,0 +1,265 @@
+/*-
+ * ============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.model.generator.model2event;
+
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.avro.Schema;
+import org.apache.avro.Schema.Field;
+import org.apache.commons.lang3.Validate;
+import org.onap.policy.apex.context.parameters.SchemaParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.modelapi.ApexAPIResult;
+import org.onap.policy.apex.model.modelapi.ApexModel;
+import org.onap.policy.apex.model.modelapi.ApexModelFactory;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicies;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.plugins.context.schema.avro.AvroSchemaHelperParameters;
+import org.onap.policy.apex.tools.model.generator.SchemaUtils;
+import org.stringtemplate.v4.ST;
+import org.stringtemplate.v4.STGroup;
+import org.stringtemplate.v4.STGroupFile;
+
+/**
+ * Takes a model and generates the JSON event schemas.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class Model2JsonEventSchema {
+
+ /** Application name, used as prompt. */
+ private final String appName;
+
+ /** The file name of the policy model. */
+ private final String modelFile;
+
+ /** The type of events to generate: stimuli, response, internal. */
+ private final String type;
+
+ /**
+ * Creates a new model to event schema generator.
+ *
+ * @param modelFile the model file to be used
+ * @param type the type of events to generate, one of: stimuli, response, internal
+ * @param appName application name for printouts
+ */
+ public Model2JsonEventSchema(final String modelFile, final String type, final String appName) {
+ Validate.notNull(modelFile, "Model2JsonEvent: given model file name was blank");
+ Validate.notNull(type, "Model2JsonEvent: given type was blank");
+ Validate.notNull(appName, "Model2JsonEvent: given application name was blank");
+ this.modelFile = modelFile;
+ this.type = type;
+ this.appName = appName;
+ }
+
+ /**
+ * Adds a type to a field for a given schema.
+ *
+ * @param schema the schema to add a type for
+ * @param stg the STG
+ * @return a template with the type
+ */
+ protected ST addFieldType(final Schema schema, final STGroup stg) {
+ ST ret = null;
+ switch (schema.getType()) {
+ case BOOLEAN:
+ case BYTES:
+ case DOUBLE:
+ case FIXED:
+ case FLOAT:
+ case INT:
+ case LONG:
+ case STRING:
+ ret = stg.getInstanceOf("fieldTypeAtomic");
+ ret.add("type", schema.getType());
+ break;
+
+ case ARRAY:
+ ret = stg.getInstanceOf("fieldTypeArray");
+ ret.add("array", this.addFieldType(schema.getElementType(), stg));
+ break;
+ case ENUM:
+ ret = stg.getInstanceOf("fieldTypeEnum");
+ ret.add("symbols", schema.getEnumSymbols());
+ break;
+
+ case MAP:
+ ret = stg.getInstanceOf("fieldTypeMap");
+ ret.add("map", this.addFieldType(schema.getValueType(), stg));
+ break;
+
+ case RECORD:
+ ret = stg.getInstanceOf("fieldTypeRecord");
+ for (final Field field : schema.getFields()) {
+ final ST st = stg.getInstanceOf("field");
+ st.add("name", field.name());
+ st.add("type", this.addFieldType(field.schema(), stg));
+ ret.add("fields", st);
+ }
+ break;
+
+ case NULL:
+ break;
+ case UNION:
+ break;
+ default:
+ break;
+ }
+ return ret;
+ }
+
+ /**
+ * Runs the application.
+ *
+ * @throws ApexException if any problem occurred in the model
+ * @return status of the application execution, 0 for success, positive integer for exit condition (such as help or
+ * version), negative integer for errors
+ */
+ public int runApp() throws ApexException {
+ final STGroupFile stg = new STGroupFile("org/onap/policy/apex/tools/model/generator/event-json.stg");
+ final ST stEvents = stg.getInstanceOf("events");
+
+ final ApexModelFactory factory = new ApexModelFactory();
+ final ApexModel model = factory.createApexModel(new Properties(), true);
+
+ final ApexAPIResult result = model.loadFromFile(modelFile);
+ if (result.isNOK()) {
+ System.err.println(appName + ": " + result.getMessage());
+ return -1;
+ }
+
+ final AxPolicyModel policyModel = model.getPolicyModel();
+ policyModel.register();
+ new SchemaParameters().getSchemaHelperParameterMap().put("Avro", new AvroSchemaHelperParameters());
+
+ final Set<AxEvent> events = new HashSet<>();
+ final Set<AxArtifactKey> eventKeys = new HashSet<>();
+ final AxPolicies policies = policyModel.getPolicies();
+ switch (type) {
+ case "stimuli":
+ for (final AxPolicy policy : policies.getPolicyMap().values()) {
+ final String firsState = policy.getFirstState();
+ for (final AxState state : policy.getStateMap().values()) {
+ if (state.getKey().getLocalName().equals(firsState)) {
+ eventKeys.add(state.getTrigger());
+ }
+ }
+ }
+ break;
+ case "response":
+ for (final AxPolicy policy : policies.getPolicyMap().values()) {
+ for (final AxState state : policy.getStateMap().values()) {
+ if (state.getNextStateSet().iterator().next().equals("NULL")) {
+ for (final AxStateOutput output : state.getStateOutputs().values()) {
+ eventKeys.add(output.getOutgingEvent());
+ }
+ }
+ }
+ }
+ break;
+ case "internal":
+ for (final AxPolicy policy : policies.getPolicyMap().values()) {
+ final String firsState = policy.getFirstState();
+ for (final AxState state : policy.getStateMap().values()) {
+ if (state.getKey().getLocalName().equals(firsState)) {
+ continue;
+ }
+ if (state.getNextStateSet().iterator().next().equals("NULL")) {
+ continue;
+ }
+ for (final AxStateOutput output : state.getStateOutputs().values()) {
+ eventKeys.add(output.getOutgingEvent());
+ }
+ }
+ }
+ break;
+ default:
+ System.err.println(appName + ": unknown type <" + type + ">, cannot proceed");
+ return -1;
+ }
+
+ for (final AxEvent event : policyModel.getEvents().getEventMap().values()) {
+ for (final AxArtifactKey key : eventKeys) {
+ if (event.getKey().equals(key)) {
+ events.add(event);
+ }
+ }
+ }
+
+ for (final AxEvent event : events) {
+ final ST stEvent = stg.getInstanceOf("event");
+ stEvent.add("name", event.getKey().getName());
+ stEvent.add("nameSpace", event.getNameSpace());
+ stEvent.add("version", event.getKey().getVersion());
+ stEvent.add("source", event.getSource());
+ stEvent.add("target", event.getTarget());
+
+ final Schema avro = SchemaUtils.getEventSchema(event);
+ for (final Field field : avro.getFields()) {
+ // filter magic names
+ switch (field.name()) {
+ case "name":
+ case "nameSpace":
+ case "version":
+ case "source":
+ case "target":
+ break;
+ default:
+ stEvent.add("fields", this.setField(field, stg));
+ }
+ }
+ stEvents.add("event", stEvent);
+ }
+ System.err.println(stEvents.render());
+ return 0;
+ }
+
+ /**
+ * Adds a field to the output.
+ *
+ * @param field the field from the event
+ * @param stg the STG
+ * @return a template for the field
+ */
+ protected ST setField(final Field field, final STGroup stg) {
+ final ST st = stg.getInstanceOf("field");
+ switch (field.name()) {
+ case "name":
+ case "nameSpace":
+ case "version":
+ case "source":
+ case "target":
+ break;
+ default:
+ st.add("name", field.name());
+ st.add("type", this.addFieldType(field.schema(), stg));
+ }
+ return st;
+ }
+
+}
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/package-info.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/package-info.java
new file mode 100644
index 000000000..602b4e9c9
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/model2event/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=========================================================
+ */
+
+/**
+ * An application generating input/output event templates from a policy model.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+
+package org.onap.policy.apex.tools.model.generator.model2event;
diff --git a/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/package-info.java b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/package-info.java
new file mode 100644
index 000000000..1f60a18f3
--- /dev/null
+++ b/tools/model-generator/src/main/java/org/onap/policy/apex/tools/model/generator/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=========================================================
+ */
+
+/**
+ * Applications that generate events and commands from policy models.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+
+package org.onap.policy.apex.tools.model.generator;
diff --git a/tools/model-generator/src/main/resources/org/onap/policy/apex/tools/model/generator/event-json.stg b/tools/model-generator/src/main/resources/org/onap/policy/apex/tools/model/generator/event-json.stg
new file mode 100644
index 000000000..9a6b8580b
--- /dev/null
+++ b/tools/model-generator/src/main/resources/org/onap/policy/apex/tools/model/generator/event-json.stg
@@ -0,0 +1,86 @@
+/*
+ * ============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=========================================================
+ */
+
+/*
+ * Template for creating a template JSON event.
+ *
+ * @package org.onap.policy.apex.tool.model.generator
+ * @author Sven van der Meer &lt;sven.van.der.meer@ericsson.com&gt;
+ */
+
+typeMap ::= [
+ "BOOLEAN":"###boolean: true, false###",
+ "BYTES":"###bytes###",
+ "DOUBLE":"###double: 0.0###",
+ "FLOAT":"###float: 0.0###",
+ "INT":"###integer: 0###",
+ "LONG":"###long: 0###",
+ "STRING":"\"###string###\"",
+ default:key
+]
+
+events(event) ::= <<
+<event:{e|<e>}; separator="\n\n">
+>>
+
+event(name, nameSpace, version, source, target, fields) ::= <<
+{
+ "name" : "<name>",
+ "nameSpace" : "<nameSpace>",
+ "version" : "<version>",
+ "source" : "<source>",
+ "target" : "<target>",
+ <fields:{field|<field>}; separator=",\n">
+}
+>>
+
+field(name, type) ::= <<
+"<name>" : <type>
+>>
+
+fieldTypeAtomic(type) ::= <<
+<typeMap.(type)>
+>>
+
+fieldTypeArray(array) ::= <<
+[
+ <typeMap.(array)>,
+ <typeMap.(array)>
+]
+>>
+
+fieldTypeEnum(symbols) ::= <<
+###Enum, one of <symbols>###
+>>
+
+fieldTypeMap(map) ::= <<
+{
+ "ID#1":
+ <map>,
+ "ID#n":
+ <map>
+}
+>>
+
+fieldTypeRecord(fields) ::= <<
+{
+ <fields:{field|<field>}; separator=",\n">
+}
+>> \ No newline at end of file
diff --git a/tools/pom.xml b/tools/pom.xml
new file mode 100644
index 000000000..d824f3dd3
--- /dev/null
+++ b/tools/pom.xml
@@ -0,0 +1,41 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 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=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.policy.apex-pdp</groupId>
+ <artifactId>apex-pdp</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.onap.policy.apex-pdp.tools</groupId>
+ <artifactId>tools</artifactId>
+
+ <packaging>pom</packaging>
+ <name>${project.artifactId}</name>
+ <description>The Apex applications, implementation dependent wrappers and mediation for Apex in various technologies.</description>
+
+ <modules>
+ <module>tools-common</module>
+ <module>simple-wsclient</module>
+ <module>model-generator</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/tools/simple-wsclient/pom.xml b/tools/simple-wsclient/pom.xml
new file mode 100644
index 000000000..2a49b9571
--- /dev/null
+++ b/tools/simple-wsclient/pom.xml
@@ -0,0 +1,76 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 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=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.policy.apex-pdp.tools</groupId>
+ <artifactId>tools</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>simple-wsclient</artifactId>
+ <name>${project.artifactId}</name>
+ <description>[${project.parent.artifactId}] Simple Websocket client (console and echo)</description>
+
+ <properties>
+ <apex-apps-wsclients-simple-dir>${project.basedir}/src</apex-apps-wsclients-simple-dir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.java-websocket</groupId>
+ <artifactId>Java-WebSocket</artifactId>
+ <version>1.3.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.apex-pdp.tools</groupId>
+ <artifactId>tools-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>console-client</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <mainClass>org.onap.policy.apex.tools.simple.wsclients.Application</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/Application.java b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/Application.java
new file mode 100644
index 000000000..bfd6573bc
--- /dev/null
+++ b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/Application.java
@@ -0,0 +1,181 @@
+/*-
+ * ============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.simple.wsclient;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.channels.NotYetConnectedException;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.lang3.Validate;
+import org.onap.policy.apex.tools.common.CliOptions;
+import org.onap.policy.apex.tools.common.CliParser;
+
+/**
+ * Simple console application with main method.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public final class Application {
+
+ /**
+ * Private constructor prevents subclassing.
+ */
+ private Application() {}
+
+ /**
+ * The main method for the WS applications.
+ *
+ * @param args command line argument s
+ */
+ public static void main(final String[] args) {
+ String appName = "ws-simple-echo";
+ String appDescr = "receives events from APEX via WS and prints them to standard out";
+ boolean console = false;
+
+ final CliParser cli = new CliParser();
+ cli.addOption(CliOptions.HELP);
+ cli.addOption(CliOptions.VERSION);
+ cli.addOption(CliOptions.CONSOLE);
+ cli.addOption(CliOptions.SERVER);
+ cli.addOption(CliOptions.PORT);
+
+ final CommandLine cmd = cli.parseCli(args);
+
+ if (cmd.hasOption('c') || cmd.hasOption("console")) {
+ appName = "ws-simple-console";
+ appDescr = "takes events from stdin and sends via WS to APEX";
+ console = true;
+ }
+
+ // help is an exit option, print usage and exit
+ if (cmd.hasOption('h') || cmd.hasOption("help")) {
+ final HelpFormatter formatter = new HelpFormatter();
+ System.out.println(appName + " v" + cli.getAppVersion() + " - " + appDescr);
+ formatter.printHelp(appName, cli.getOptions());
+ System.out.println();
+ return;
+ }
+
+ // version is an exit option, print version and exit
+ if (cmd.hasOption('v') || cmd.hasOption("version")) {
+ System.out.println(appName + " " + cli.getAppVersion());
+ System.out.println();
+ return;
+ }
+
+ String server = cmd.getOptionValue('s');
+ if (server == null) {
+ server = cmd.getOptionValue("server");
+ }
+ if (server == null) {
+ server = "localhost";
+ }
+
+ String port = cmd.getOptionValue('p');
+ if (port == null) {
+ port = cmd.getOptionValue("port");
+ }
+ if (port == null) {
+ port = "8887";
+ }
+
+ if (console) {
+ runConsole(server, port, appName);
+ } else {
+ runEcho(server, port, appName);
+ }
+
+ }
+
+ /**
+ * Runs the simple echo client.
+ *
+ * @param server the server, must not be blank
+ * @param port the port, must not be blank
+ * @param appName the application name, must not be blank
+ */
+ public static void runEcho(final String server, final String port, final String appName) {
+ Validate.notBlank(server);
+ Validate.notBlank(port);
+ Validate.notBlank(appName);
+
+ System.out.println();
+ System.out.println(appName + ": starting simple event echo");
+ System.out.println(" --> server: " + server);
+ System.out.println(" --> port: " + port);
+ System.out.println();
+ System.out.println("Once started, the application will simply print out all received events to standard out.");
+ System.out.println("Each received event will be prefixed by '---' and suffixed by '===='");
+ System.out.println();
+ System.out.println();
+
+ try {
+ final SimpleEcho simpleEcho = new SimpleEcho(server, port, appName);
+ simpleEcho.connect();
+ } catch (final URISyntaxException uex) {
+ System.err.println(appName + ": URI exception, could not create URI from server and port settings");
+ } catch (final NullPointerException nex) {
+ System.err.println(appName + ": null pointer, server or port were null");
+ } catch (final IllegalArgumentException iex) {
+ System.err.println(appName + ": illegal argument, server or port were blank");
+ }
+ }
+
+ /**
+ * Runs the simple console.
+ *
+ * @param server the server, must not be blank
+ * @param port the port, must not be blank
+ * @param appName the application name, must not be blank
+ */
+ public static void runConsole(final String server, final String port, final String appName) {
+ Validate.notBlank(server);
+ Validate.notBlank(port);
+ Validate.notBlank(appName);
+
+ System.out.println();
+ System.out.println(appName + ": starting simple event console");
+ System.out.println(" --> server: " + server);
+ System.out.println(" --> port: " + port);
+ System.out.println();
+ System.out.println(" - terminate the application typing 'exit<enter>' or using 'CTRL+C'");
+ System.out.println(" - events are created by a non-blank starting line and terminated by a blank line");
+ System.out.println();
+ System.out.println();
+
+ try {
+ final SimpleConsole simpleConsole = new SimpleConsole(server, port, appName);
+ simpleConsole.runClient();
+ } catch (final URISyntaxException uex) {
+ System.err.println(appName + ": URI exception, could not create URI from server and port settings");
+ } catch (final NullPointerException nex) {
+ System.err.println(appName + ": null pointer, server or port were null");
+ } catch (final IllegalArgumentException iex) {
+ System.err.println(appName + ": illegal argument, server or port were blank");
+ } catch (final NotYetConnectedException nex) {
+ System.err.println(appName + ": not yet connected, connection to server took too long");
+ } catch (final IOException ioe) {
+ System.err.println(appName + ": IO exception, something went wrong on the standard input");
+ }
+ }
+}
diff --git a/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleConsole.java b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleConsole.java
new file mode 100644
index 000000000..810c74da5
--- /dev/null
+++ b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleConsole.java
@@ -0,0 +1,145 @@
+/*-
+ * ============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.simple.wsclient;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.channels.NotYetConnectedException;
+
+import org.apache.commons.lang3.Validate;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.framing.CloseFrame;
+import org.java_websocket.handshake.ServerHandshake;
+
+/**
+ * Simple WS client with a console for events.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class SimpleConsole extends WebSocketClient {
+
+ /** Application name, used as prompt. */
+ private final String appName;
+
+ /**
+ * Creates a new simple echo object.
+ *
+ * @param server the name of the server as either IP address or fully qualified host name, must not be blank
+ * @param port the port to be used, must not be blank
+ * @param appName the application name, used as prompt, must not be blank
+ * @throws URISyntaxException is URI could not be created from server/port settings
+ * @throws RuntimeException if server or port where blank
+ */
+ public SimpleConsole(final String server, final String port, final String appName) throws URISyntaxException {
+ super(new URI("ws://" + server + ":" + port));
+ Validate.notBlank(appName, "SimpleConsole: given application name was blank");
+ this.appName = appName;
+ }
+
+ @Override
+ public void onClose(final int code, final String reason, final boolean remote) {
+ System.out.println(this.appName + ": Connection closed by " + (remote ? "APEX" : "me"));
+ System.out.print(" ==-->> ");
+ switch (code) {
+ case CloseFrame.NORMAL:
+ System.out.println("normal");
+ break;
+ case CloseFrame.GOING_AWAY:
+ System.out.println("APEX going away");
+ break;
+ case CloseFrame.PROTOCOL_ERROR:
+ System.out.println("some protocol error");
+ break;
+ case CloseFrame.REFUSE:
+ System.out.println("received unacceptable type of data");
+ break;
+ case CloseFrame.NO_UTF8:
+ System.out.println("expected UTF-8, found something else");
+ break;
+ case CloseFrame.TOOBIG:
+ System.out.println("message too big");
+ break;
+ case CloseFrame.UNEXPECTED_CONDITION:
+ System.out.println("unexpected server condition");
+ break;
+ default:
+ System.out.println("unkown close frame code");
+ break;
+ }
+ System.out.print(" ==-->> " + reason);
+ }
+
+ @Override
+ public void onError(final Exception ex) {
+ System.err.println(this.appName + ": " + ex.getMessage());
+ }
+
+ @Override
+ public void onMessage(final String message) {
+ // this client does not expect messages
+ }
+
+ @Override
+ public void onOpen(final ServerHandshake handshakedata) {
+ System.out.println(this.appName + ": opened connection to APEX (" + handshakedata.getHttpStatusMessage() + ")");
+ }
+
+ /**
+ * Runs the console client. In particular, it starts a new thread for the Websocket connection and then reads from
+ * standard input.
+ *
+ * @throws NotYetConnectedException if not connected to server when sending events
+ * @throws IOException on an IO problem on standard in
+ */
+ public void runClient() throws NotYetConnectedException, IOException {
+ final Thread thread = new Thread() {
+ @Override
+ public void run() {
+ connect();
+ }
+ };
+ thread.start();
+
+ final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+ String event = "";
+ String line;
+ while ((line = in.readLine()) != null) {
+ if (line.equals("exit")) {
+ break;
+ }
+
+ final String current = line.trim();
+ if ("".equals(current)) {
+ this.send(event);
+ event = "";
+ } else {
+ event += current;
+ }
+ }
+
+ thread.interrupt();
+ this.close(CloseFrame.NORMAL);
+ }
+
+}
diff --git a/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleEcho.java b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleEcho.java
new file mode 100644
index 000000000..4b67cb862
--- /dev/null
+++ b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/SimpleEcho.java
@@ -0,0 +1,108 @@
+/*-
+ * ============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.simple.wsclient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.commons.lang3.Validate;
+import org.java_websocket.client.WebSocketClient;
+import org.java_websocket.framing.CloseFrame;
+import org.java_websocket.handshake.ServerHandshake;
+
+/**
+ * Simple WS client as an echo.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class SimpleEcho extends WebSocketClient {
+
+ /** Application name, used as prompt. */
+ private final String appName;
+
+ /**
+ * Creates a new simple echo object.
+ *
+ * @param server the name of the server as either IP address or fully qualified host name, must not be blank
+ * @param port the port to be used, must not be blank
+ * @param appName the application name, used as prompt, must not be blank
+ * @throws URISyntaxException is URI could not be created from server/port settings
+ * @throws RuntimeException if server or port where blank
+ */
+ public SimpleEcho(final String server, final String port, final String appName) throws URISyntaxException {
+ super(new URI("ws://" + server + ":" + port));
+ Validate.notBlank(appName, "SimpleEcho: given application name was blank");
+ this.appName = appName;
+ }
+
+ @Override
+ public void onClose(final int code, final String reason, final boolean remote) {
+ System.out.println(this.appName + ": Connection closed by " + (remote ? "APEX" : "me"));
+ System.out.print(" ==-->> ");
+ switch (code) {
+ case CloseFrame.NORMAL:
+ System.out.println("normal");
+ break;
+ case CloseFrame.GOING_AWAY:
+ System.out.println("APEX going away");
+ break;
+ case CloseFrame.PROTOCOL_ERROR:
+ System.out.println("some protocol error");
+ break;
+ case CloseFrame.REFUSE:
+ System.out.println("received unacceptable type of data");
+ break;
+ case CloseFrame.NO_UTF8:
+ System.out.println("expected UTF-8, found something else");
+ break;
+ case CloseFrame.TOOBIG:
+ System.out.println("message too big");
+ break;
+ case CloseFrame.UNEXPECTED_CONDITION:
+ System.out.println("unexpected server condition");
+ break;
+ default:
+ System.out.println("unkown close frame code");
+ break;
+ }
+ System.out.print(" ==-->> " + reason);
+ }
+
+ @Override
+ public void onError(final Exception ex) {
+ System.err.println(this.appName + ": " + ex.getMessage());
+ }
+
+ @Override
+ public void onMessage(final String message) {
+ System.out.println(this.appName + ": received");
+ System.out.println("---------------------------------");
+ System.out.println(message);
+ System.out.println("=================================");
+ System.out.println();
+ }
+
+ @Override
+ public void onOpen(final ServerHandshake handshakedata) {
+ System.out.println(this.appName + ": opened connection to APEX (" + handshakedata.getHttpStatusMessage() + ")");
+ }
+
+}
diff --git a/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/package-info.java b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/package-info.java
new file mode 100644
index 000000000..ea30f93b5
--- /dev/null
+++ b/tools/simple-wsclient/src/main/java/org/onap/policy/apex/tools/simple/wsclient/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=========================================================
+ */
+
+/**
+ * A simple Websocket client, runs as console or echo client.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+
+package org.onap.policy.apex.tools.simple.wsclient;
diff --git a/tools/tools-common/pom.xml b/tools/tools-common/pom.xml
new file mode 100644
index 000000000..e4d0c40d2
--- /dev/null
+++ b/tools/tools-common/pom.xml
@@ -0,0 +1,73 @@
+<!--
+ ============LICENSE_START=======================================================
+ Copyright (C) 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=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.onap.policy.apex-pdp.tools</groupId>
+ <artifactId>tools</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>tools-common</artifactId>
+ <name>${project.artifactId}</name>
+ <description>[${project.parent.artifactId}] Utilities for APEX tools</description>
+
+ <properties>
+ <apex-apps-utilities-dir>${project.basedir}/src</apex-apps-utilities-dir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.6</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-text</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>${version.commons-cli}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/app-version.txt</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>false</filtering>
+ <excludes>
+ <exclude>**/app-version.txt</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+</project> \ No newline at end of file
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 <code>/app-version.txt</code> 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<String> errors;
+
+ /** The list of warnings, filled if warning collection is activates. */
+ private final List<String> 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 <code>null</code> 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 <code>CONFIG_COLLECT_ERRORS | CONFIG_COLLECT_WARNINGS</code>.
+ *
+ * @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
+ * <code>blank</code>
+ * @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
+ * <code>blank</code>
+ * @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
+ * <code>blank</code>
+ * @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
+ * <code>blank</code>
+ * @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
+ * <code>blank</code>
+ * @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
+ * <code>blank</code>
+ * @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 <code>null</code>
+ */
+ 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
diff --git a/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/TestCliParser.java b/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/TestCliParser.java
new file mode 100644
index 000000000..bf14cfec0
--- /dev/null
+++ b/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/TestCliParser.java
@@ -0,0 +1,43 @@
+/*-
+ * ============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.junit.Test;
+import org.onap.policy.apex.tools.common.CliParser;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Tests for {@link CliParser}.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class TestCliParser {
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(TestCliParser.class);
+
+ /** Testapp version. */
+ @Test
+ public void testappVersion() {
+ final CliParser cli = new CliParser();
+ LOGGER.info(cli.getAppVersion());
+ }
+}
diff --git a/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleAppVersion.java b/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleAppVersion.java
new file mode 100644
index 000000000..6d6fa9c1d
--- /dev/null
+++ b/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleAppVersion.java
@@ -0,0 +1,65 @@
+/*-
+ * ============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.docs;
+
+////
+//// NOTE: This file contains tags for ASCIIDOC
+//// DO NOT REMOVE any of those tag lines, e.g.
+////// tag::**
+////// end::**
+////
+
+import org.apache.commons.cli.CommandLine;
+import org.junit.Test;
+import org.onap.policy.apex.tools.common.CliOptions;
+import org.onap.policy.apex.tools.common.CliParser;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Examples for documentation using {@link CliParser#getAppVersion()}.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class ExampleAppVersion {
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ExampleAppVersion.class);
+
+ /** Test example app version. */
+ @Test
+ public void testExampleAppVersion() {
+ final String[] args = new String[] { "-v" };
+
+ // tag::setupParser[]
+ final CliParser cli = new CliParser();
+ cli.addOption(CliOptions.VERSION);
+ final CommandLine cmd = cli.parseCli(args);
+ // end::setupParser[]
+
+ // tag::processCliVersion[]
+ // version is an exit option, print version and exit
+ if (cmd.hasOption('v') || cmd.hasOption("version")) {
+ LOGGER.info("myApp" + " " + cli.getAppVersion());
+ return;
+ }
+ // end::processCliVersion[]
+ }
+}
diff --git a/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleCliParser.java b/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleCliParser.java
new file mode 100644
index 000000000..487bed297
--- /dev/null
+++ b/tools/tools-common/src/test/java/org/onap/policy/apex/tools/common/docs/ExampleCliParser.java
@@ -0,0 +1,116 @@
+/*-
+ * ============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.docs;
+
+////
+//// NOTE: This file contains tags for ASCIIDOC
+//// DO NOT REMOVE any of those tag lines, e.g.
+//// //tag::**
+//// //end::**
+////
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.HelpFormatter;
+import org.junit.Test;
+import org.onap.policy.apex.tools.common.CliOptions;
+import org.onap.policy.apex.tools.common.CliParser;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Examples for documentation using {@link CliParser}.
+ *
+ * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
+ */
+public class ExampleCliParser {
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ExampleCliParser.class);
+
+ /**
+ * Test example parser.
+ */
+ @Test
+ public void testExampleParser() {
+ final String[] args = new String[] { "-h" };
+
+ // tag::setApp[]
+ final String appName = "test-app";
+ final String appDescription = "a test app for documenting how to use the CLI utilities";
+ // end::setApp[]
+
+ // tag::setCli[]
+ final CliParser cli = new CliParser();
+ cli.addOption(CliOptions.HELP);
+ cli.addOption(CliOptions.VERSION);
+ cli.addOption(CliOptions.MODELFILE);
+ // end::setCli[]
+
+ // tag::parseCli[]
+ final CommandLine cmd = cli.parseCli(args);
+ // end::parseCli[]
+
+ // tag::processCliHelp[]
+ // help is an exit option, print usage and exit
+ if (cmd.hasOption('h') || cmd.hasOption("help")) {
+ final HelpFormatter formatter = new HelpFormatter();
+ LOGGER.info(appName + " v" + cli.getAppVersion() + " - " + appDescription);
+ formatter.printHelp(appName, cli.getOptions());
+ return;
+ }
+ // end::processCliHelp[]
+
+ // tag::processCliVersion[]
+ // version is an exit option, print version and exit
+ if (cmd.hasOption('v') || cmd.hasOption("version")) {
+ LOGGER.info(appName + " " + cli.getAppVersion());
+ return;
+ }
+ // end::processCliVersion[]
+
+ // tag::processCliModel[]
+ String modelFile = cmd.getOptionValue('m');
+ if (modelFile == null) {
+ modelFile = cmd.getOptionValue("model");
+ }
+ if (modelFile == null) {
+ LOGGER.error(appName + ": no model file given, cannot proceed (try -h for help)");
+ return;
+ }
+ // end::processCliModel[]
+
+ // tag::someStartPrint[]
+ LOGGER.info(appName + ": starting");
+ LOGGER.info(" --> model file: " + modelFile);
+ // end::someStartPrint[]
+
+ // tag::yourApp[]
+ // your code for the application here
+ // e.g.
+ // try {
+ // Model2Cli app = new Model2Cli(modelFile, !cmd.hasOption("sv"), appName);
+ // app.runApp();
+ // }
+ // catch(ApexException aex) {
+ // LOGGER.error(appName + ": caught APEX exception with message: " + aex.getMessage());
+ // }
+ // end::yourApp[]
+ }
+}