diff options
28 files changed, 3134 insertions, 0 deletions
@@ -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 <sven.van.der.meer@ericsson.com> + */ +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 <sven.van.der.meer@ericsson.com> + */ + +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[] + } +} |