diff options
Diffstat (limited to 'tools/model-generator/src/main/java')
9 files changed, 1372 insertions, 0 deletions
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; |