summaryrefslogtreecommitdiffstats
path: root/model/policy-model/src
diff options
context:
space:
mode:
Diffstat (limited to 'model/policy-model/src')
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java419
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java74
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java429
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java536
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java737
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java1020
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java137
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java389
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java48
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java400
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java157
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java745
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java136
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java299
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java135
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java425
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java51
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java51
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java35
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java186
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java266
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java46
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java153
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java271
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java155
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java165
-rw-r--r--model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java26
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java84
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestExceptions.java53
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestLogic.java181
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicies.java433
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicyModel.java357
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestState.java475
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateOutput.java137
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateTaskReference.java160
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTaskParameter.java116
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTasks.java331
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModel.java139
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModelCreator.java448
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyAnalyser.java60
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyLogicReader.java114
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelComparer.java129
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelMerger.java109
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelSplitter.java95
-rw-r--r--model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/utils/PolicyModelValidator.java41
-rw-r--r--model/policy-model/src/test/resources/META-INF/persistence.xml69
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt15
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt14
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt71
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt70
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt8
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt69
-rw-r--r--model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt69
-rw-r--r--model/policy-model/src/test/resources/logback-test.xml74
-rw-r--r--model/policy-model/src/test/resources/path/to/apex/logic/funkylogic/LogicParent_LogicParentLocalName_LogicInstanceName.funkylogic21
55 files changed, 11433 insertions, 0 deletions
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java
new file mode 100644
index 000000000..a537d90b9
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogic.java
@@ -0,0 +1,419 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.basicmodel.dao.converters.CDATAConditioner;
+import org.onap.policy.apex.model.basicmodel.xml.AxReferenceKeyAdapter;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class holds Logic for executing a task or task selection on an Apex policy state. The
+ * flavour of the logic describes the type of logic being used and it may be a language identifier
+ * such as "Javascript" or "Jython". The logic itself is held as a string. The {@link AxLogic}
+ * instance is used by the Apex engine to start an executor with the required flavour. Once the
+ * executor is started, the Apex engine passes the logic to the executor and the executor executes
+ * it. In the Apex engine, executors are deployed as plugins. Apex also provides the executor with
+ * run-time context, which makes context such as input fields, output fields, and context albums
+ * available to the task at runtime.
+ * <p>
+ * Validation checks that the logic key is valid, that the logic flavour is defined and is valid
+ * when checked against the {@code LOGIC_FLAVOUR_REGEXP} regular expression, and that the specified
+ * logic string is not null or blank.
+ */
+
+@Entity
+@Table(name = "AxLogic")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxLogic", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "logicFlavour", "logic"})
+
+public class AxLogic extends AxConcept {
+ private static final long serialVersionUID = -4260562004005697328L;
+
+ private static final String WHITESPACE_REGEXP = "\\s+$";
+
+ private static final String LOGIC_FLAVOUR_TOKEN = "logicFlavour";
+ private static final String KEY_NULL_MESSAGE = "key may not be null";
+ private static final String LOGIC_FLAVOUR_NULL_MESSAGE = "logicFlavour may not be null";
+ private static final String LOGIC_NULL_MESSAGE = "logic may not be null";
+
+ /** Regular expression that specifies the allowed characters in logic flavour tokens. */
+ public static final String LOGIC_FLAVOUR_REGEXP = "[A-Za-z0-9\\-_]+";
+
+ /** When logic flavour is undefined, it has this value. */
+ public static final String LOGIC_FLAVOUR_UNDEFINED = "UNDEFINED";
+
+ /** The maximum permissible size of a logic definition. */
+ public static final int MAX_LOGIC_SIZE = 32672; // The maximum size supported by Apache Derby
+
+ @EmbeddedId()
+ @XmlElement(name = "key", required = true)
+ @XmlJavaTypeAdapter(AxReferenceKeyAdapter.class)
+ private AxReferenceKey key;
+
+ @Column(name = LOGIC_FLAVOUR_TOKEN)
+ @XmlElement(required = true)
+ private String logicFlavour;
+
+ @Column(name = "logic", length = MAX_LOGIC_SIZE)
+ @Convert(converter = CDATAConditioner.class)
+ @XmlJavaTypeAdapter(value = CDATAConditioner.class)
+ @XmlElement(required = true)
+ private String logic;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxLogic() {
+ this(new AxReferenceKey());
+ logicFlavour = LOGIC_FLAVOUR_UNDEFINED;
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxLogic(final AxLogic copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxLogic(final AxReferenceKey key) {
+ this(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ this(new AxReferenceKey(parentKey, logicName), logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super();
+ Assertions.argumentNotNull(key, KEY_NULL_MESSAGE);
+ Assertions.argumentNotNull(logicFlavour, LOGIC_FLAVOUR_NULL_MESSAGE);
+ Assertions.argumentNotNull(logic, LOGIC_NULL_MESSAGE);
+
+ this.key = key;
+ this.logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ this.logic = logic.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super();
+ Assertions.argumentNotNull(key, KEY_NULL_MESSAGE);
+ Assertions.argumentNotNull(logicFlavour, LOGIC_FLAVOUR_NULL_MESSAGE);
+ Assertions.argumentNotNull(logicReader, "logicReader may not be null");
+
+ this.key = key;
+ this.logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ logic = logicReader.readLogic(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the key.
+ *
+ * @param key the key
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, KEY_NULL_MESSAGE);
+ this.key = key;
+ }
+
+ /**
+ * Gets the logic flavour.
+ *
+ * @return the logic flavour
+ */
+ public String getLogicFlavour() {
+ return logicFlavour;
+ }
+
+ /**
+ * Sets the logic flavour.
+ *
+ * @param logicFlavour the logic flavour
+ */
+ public void setLogicFlavour(final String logicFlavour) {
+ this.logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ }
+
+ /**
+ * Gets the logic.
+ *
+ * @return the logic
+ */
+ public String getLogic() {
+ return logic;
+ }
+
+ /**
+ * Sets the logic.
+ *
+ * @param logic the logic
+ */
+ public void setLogic(final String logic) {
+ Assertions.argumentNotNull(logic, LOGIC_NULL_MESSAGE);
+ this.logic = logic.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (logicFlavour.replaceAll(WHITESPACE_REGEXP, "").length() == 0
+ || logicFlavour.equals(LOGIC_FLAVOUR_UNDEFINED)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "logic flavour is not defined"));
+ }
+
+ try {
+ Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ } catch (final IllegalArgumentException e) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "logic flavour invalid-" + e.getMessage()));
+ }
+
+ if (logic.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "no logic specified, logic may not be blank"));
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ if (key != null) {
+ key.clean();
+ }
+ logicFlavour = Assertions.validateStringParameter(LOGIC_FLAVOUR_TOKEN, logicFlavour, LOGIC_FLAVOUR_REGEXP);
+ logic = logic.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",logicFlavour=");
+ builder.append(logicFlavour);
+ builder.append(",logic=");
+ builder.append(logic);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxLogic.class);
+
+ final AxLogic copy = ((AxLogic) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setLogicFlavour(logicFlavour);
+ copy.setLogic(logic);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + logicFlavour.hashCode();
+ result = prime * result + logic.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxLogic other = (AxLogic) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!logicFlavour.equals(other.logicFlavour)) {
+ return false;
+ }
+ final String thislogic = CDATAConditioner.clean(logic).replaceAll("\n", "");
+ final String otherlogic = CDATAConditioner.clean(other.logic).replaceAll("\n", "");
+ return thislogic.equals(otherlogic);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxLogic other = (AxLogic) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!logicFlavour.equals(other.logicFlavour)) {
+ return logicFlavour.compareTo(other.logicFlavour);
+ }
+ return logic.compareTo(other.logic);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java
new file mode 100644
index 000000000..7532f9f34
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxLogicReader.java
@@ -0,0 +1,74 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+/**
+ * This interface is used to provide logic to a {@link AxLogic} instance. Implementations usually
+ * store logic on disk in a structure similar to Java package naming conventions. The logic package
+ * gives the package path, a directory where a set of logic is defined. Default logic is logic that
+ * can be used as dummy logic in tasks or states that are filler tasks or states. The actual logic
+ * is returned by the {@code readLogic()} method. The interface is used mainly by unit test classes
+ * that generate test logic.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface AxLogicReader {
+
+ /**
+ * Get the logic package path.
+ *
+ * @return the logic package path
+ */
+ String getLogicPackage();
+
+ /**
+ * Set the logic package path.
+ *
+ * @param logicPackage the name of the package that contains the logic for this logic reader
+ * @return the logic reader on which this method was called, used for daisy chaining
+ * configuration
+ */
+ AxLogicReader setLogicPackage(final String logicPackage);
+
+ /**
+ * Get the default logic name.
+ *
+ * @return the default logic name
+ */
+ String getDefaultLogic();
+
+ /**
+ * Set the default logic name.
+ *
+ * @param defaultLogic the default logic name
+ * @return the logic reader on which this method was called, used for daisy chaining
+ * configuration
+ */
+ AxLogicReader setDefaultLogic(final String defaultLogic);
+
+ /**
+ * Read the logic for an AxLogic object.
+ *
+ * @param axLogic the AxLogic object
+ * @return the logic as a string
+ */
+ String readLogic(final AxLogic axLogic);
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java
new file mode 100644
index 000000000..248e4fdae
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicies.java
@@ -0,0 +1,429 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.persistence.CascadeType;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is a policy container and holds a map of the policies for an entire Apex model. All
+ * Apex models that use policies must have an {@link AxPolicies} field. The {@link AxPolicies} class
+ * implements the helper methods of the {@link AxConceptGetter} interface to allow {@link AxPolicy}
+ * instances to be retrieved by calling methods directly on this class without referencing the
+ * contained map.
+ * <p>
+ * Validation checks that the container key is not null. An error is issued if no policies are
+ * defined in the container. Each policy entry is checked to ensure that its key and value are not
+ * null and that the key matches the key in the map value. Each policy entry is then validated
+ * individually.
+ */
+@Entity
+@Table(name = "AxPolicies")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxPolicies", namespace = "http://www.onap.org/policy/apex-pdp", propOrder = {"key", "policyMap"})
+
+public class AxPolicies extends AxConcept implements AxConceptGetter<AxPolicy> {
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ // @formatter:off
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(
+ joinColumns = {@JoinColumn(name = "policyMapName", referencedColumnName = "name"),
+ @JoinColumn(name = "policyMapVersion", referencedColumnName = "version")},
+ inverseJoinColumns = {@JoinColumn(name = "policyName", referencedColumnName = "name"),
+ @JoinColumn(name = "policyVersion", referencedColumnName = "version")})
+ @XmlElement(required = true)
+ private Map<AxArtifactKey, AxPolicy> policyMap;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a {@link AxPolicies} object with a null artifact key and
+ * creates an empty event map.
+ */
+ public AxPolicies() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxPolicies} object with the given artifact key and
+ * creates an empty event map.
+ *
+ * @param key the key
+ */
+ public AxPolicies(final AxArtifactKey key) {
+ this(key, new TreeMap<AxArtifactKey, AxPolicy>());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxPolicies(final AxPolicies copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * This Constructor creates a policy container with all of its fields defined.
+ *
+ * @param key the policy container key
+ * @param policyMap the policies to be stored in the policy container
+ */
+ public AxPolicies(final AxArtifactKey key, final Map<AxArtifactKey, AxPolicy> policyMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(policyMap, "policyMap may not be null");
+
+ this.key = key;
+ this.policyMap = new TreeMap<>();
+ this.policyMap.putAll(policyMap);
+ }
+
+ /**
+ * When a model is unmarshalled from disk or from the database, the policy map is returned as a
+ * raw hash map. This method is called by JAXB after unmarshaling and is used to convert the
+ * hash map to a {@link NavigableMap} so that it will work with the {@link AxConceptGetter}
+ * interface.
+ *
+ * @param u the unmarshaler that is unmarshaling the model
+ * @param parent the parent object of this object in the unmarshaler
+ */
+ public void afterUnmarshal(final Unmarshaller u, final Object parent) {
+ // The map must be navigable to allow name and version searching, unmarshaling returns a
+ // hash map
+ final NavigableMap<AxArtifactKey, AxPolicy> navigablePolicyMap = new TreeMap<>();
+ navigablePolicyMap.putAll(policyMap);
+ policyMap = navigablePolicyMap;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxPolicy policy : policyMap.values()) {
+ keyList.addAll(policy.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the policy container.
+ *
+ * @param key the policy container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the policy map containing all policies in the policy container.
+ *
+ * @return the policy map with all the policies in the container
+ */
+ public Map<AxArtifactKey, AxPolicy> getPolicyMap() {
+ return policyMap;
+ }
+
+ /**
+ * Sets the policy map containing all policies in the policy container.
+ *
+ * @param policyMap the policy map with all the policies to be put in the container
+ */
+ public void setPolicyMap(final Map<AxArtifactKey, AxPolicy> policyMap) {
+ Assertions.argumentNotNull(policyMap, "policyMap may not be null");
+ this.policyMap = new TreeMap<>();
+ this.policyMap.putAll(policyMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (policyMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "policyMap may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxPolicy> policyEntry : policyMap.entrySet()) {
+ if (policyEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on policy entry " + policyEntry.getKey() + " may not be the null key"));
+ } else if (policyEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on policy entry " + policyEntry.getKey() + " may not be null"));
+ } else {
+ if (!policyEntry.getKey().equals(policyEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(),
+ ValidationResult.INVALID, "key on policy entry key " + policyEntry.getKey()
+ + " does not equal policy value key " + policyEntry.getValue().getKey()));
+ }
+
+ result = policyEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxPolicy> policyEntry : policyMap.entrySet()) {
+ policyEntry.getKey().clean();
+ policyEntry.getValue().clean();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",policyMap=");
+ builder.append(policyMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxPolicies.class);
+
+ final AxPolicies copy = ((AxPolicies) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+
+ final Map<AxArtifactKey, AxPolicy> newPolicyMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxPolicy> policyMapEntry : policyMap.entrySet()) {
+ newPolicyMap.put(new AxArtifactKey(policyMapEntry.getKey()), new AxPolicy(policyMapEntry.getValue()));
+ }
+ copy.setPolicyMap(newPolicyMap);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + policyMap.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxPolicies other = (AxPolicies) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return policyMap.equals(other.policyMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxPolicies other = (AxPolicies) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!policyMap.equals(other.policyMap)) {
+ return (policyMap.hashCode() - other.policyMap.hashCode());
+ }
+
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#get(org.onap.policy.apex.model
+ * .basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public AxPolicy get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#get(java.lang.String)
+ */
+ @Override
+ public AxPolicy get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#get(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public AxPolicy get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String)
+ */
+ @Override
+ public Set<AxPolicy> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).getAll(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public Set<AxPolicy> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java
new file mode 100644
index 000000000..ff7e4a23f
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicy.java
@@ -0,0 +1,536 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class holds the definition of an Apex policy. A policy is made up of a tree of states, each
+ * represented by an {@link AxState} instance. The states of a policy are held in a map in the
+ * policy. The state tree is built up at policy design time by a policy editor and each state is
+ * connected to its next state by an {@link AxStateOutput} instance.
+ * <p>
+ * Execution of a policy is triggered by an event. A policy starts execution from its first state so
+ * the trigger event for the first sate is the trigger event for the entire policy. Execution from
+ * that first state can continue to one or more subsequent states and so on down branches of states.
+ * The state output of the final state in a branch has no next state, indicating the end of
+ * execution of that branch. Therefore, the set of output events from final states in the policy are
+ * the possible set of output events on the policy. A state may only be used once in the state tree
+ * of a policy and recursive execution of states in the same execution branch is not allowed, so the
+ * same state may not execute more than once on a single execution of a policy.
+ * <p>
+ * The template of a policy is a string that can be used by policy editors to store meta information
+ * on the policy that can be used at design time. The policy template string is not used during
+ * policy execution.
+ * <p>
+ * During validation of a policy, the validation checks listed below are executed:
+ * <ol>
+ * <li>The policy key must not be a null key
+ * <li>The policy key must be valid
+ * <li>If the policy template is not set, an observation is issued
+ * <li>At least one state must be defined
+ * <li>Keys and values must all be defined, that is not null
+ * <li>The key on each entry in the state map must match the key in the entry's value
+ * <li>The parent key of each state in the state map of a policy must be the key of that policy
+ * <li>Each state must itself be valid, see validation in {@link AxState}
+ * <li>The next state of the state output of each state must be defined as a state in the policy
+ * <li>The first state of a policy must be set
+ * <li>The first state of a policy must be defined in the policy
+ * <li>If a state is defined but is not used in a policy,a warning is issued
+ * <li>The state tree of the policy must be valid, see validation in {@link AxStateTree}
+ * </ol>
+ */
+
+@Entity
+@Table(name = "AxPolicy")
+@XmlRootElement(name = "apexPolicy", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxPolicy", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "template", "stateMap", "firstState"})
+
+public class AxPolicy extends AxConcept {
+ private static final long serialVersionUID = -1775614096390365941L;
+
+ @EmbeddedId
+ @XmlElement(name = "policyKey", required = true)
+ private AxArtifactKey key;
+
+ @Column(name = "template")
+ @XmlElement(required = true)
+ private String template;
+
+ // @formatter:off
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinTable(joinColumns = {@JoinColumn(name = "parentKeyName", referencedColumnName = "name"),
+ @JoinColumn(name = "parentKeyVersion", referencedColumnName = "version")})
+ @XmlElement(name = "state", required = true)
+ private Map<String, AxState> stateMap;
+ // @formatter:on
+
+ @Column(name = "firstState")
+ @XmlElement(required = true)
+ private String firstState;
+
+ /**
+ * The Default Constructor creates a policy instance with a null key, a blank template and
+ * undefined first state.
+ */
+ public AxPolicy() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxPolicy(final AxPolicy copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a policy instance with the given key, a blank template and
+ * undefined first state.
+ *
+ * @param key the key of the policy
+ */
+ public AxPolicy(final AxArtifactKey key) {
+ this(key, "", new TreeMap<String, AxState>(), "");
+ }
+
+ /**
+ * This Constructor creates a policy with the given key and all its fields defined.
+ *
+ * @param key the key of the policy
+ * @param template the policy template for policy editor metadata
+ * @param stateMap the state map containing the states of the policy
+ * @param firstState the first state that will execute on this policy
+ */
+ public AxPolicy(final AxArtifactKey key, final String template, final Map<String, AxState> stateMap,
+ final String firstState) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(template, "template may not be null");
+ Assertions.argumentNotNull(stateMap, "stateMap may not be null");
+ Assertions.argumentNotNull(firstState, "firstState may not be null");
+
+ this.key = key;
+ this.template = template;
+ this.stateMap = stateMap;
+ this.firstState = firstState;
+ }
+
+ /**
+ * Gets a tree that holds all the possible execution paths for this policy. This method may be
+ * used for verification of policies, to find the branches of policy execution and the final
+ * states of policies.
+ *
+ * @return the state tree of the policy, a tree representing the execution branches of the
+ * policy
+ */
+ public AxStateTree getStateTree() {
+ return new AxStateTree(this, stateMap.get(firstState), null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ for (final AxState state : stateMap.values()) {
+ keyList.addAll(state.getKeys());
+ }
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the policy.
+ *
+ * @param key the key of the policy
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the policy template for policy editor metadata.
+ *
+ * @return the policy template for policy editor metadata
+ */
+ public String getTemplate() {
+ return template;
+ }
+
+ /**
+ * Sets the policy template for policy editor metadata.
+ *
+ * @param template the policy template for policy editor metadata
+ */
+ public void setTemplate(final String template) {
+ Assertions.argumentNotNull(template, "template may not be null");
+ this.template = template;
+ }
+
+ /**
+ * Gets a map containing the states of the policy.
+ *
+ * @return the map of states in the policy
+ */
+ public Map<String, AxState> getStateMap() {
+ return stateMap;
+ }
+
+ /**
+ * Sets a map containing the states of the policy.
+ *
+ * @param stateMap a map of states in the policy
+ */
+ public void setStateMap(final Map<String, AxState> stateMap) {
+ Assertions.argumentNotNull(stateMap, "stateMap may not be null");
+ this.stateMap = stateMap;
+ }
+
+ /**
+ * Gets the first state of the policy.
+ *
+ * @return the first state of the policy
+ */
+ public String getFirstState() {
+ return firstState;
+ }
+
+ /**
+ * Sets the first state of the policy.
+ *
+ * @param firstState the first state of the policy
+ */
+ public void setFirstState(final String firstState) {
+ Assertions.argumentNotNull(firstState, "firstState may not be null");
+ this.firstState = firstState;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (template.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "a policy template has not been specified"));
+ }
+
+ if (stateMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateMap may not be empty"));
+ } else {
+ for (final Entry<String, AxState> stateEntry : stateMap.entrySet()) {
+ result = validateStateEntry(stateEntry, result);
+ }
+ }
+
+ // Validation continues from this point only if all validation checks this far have been
+ // passed
+ if (!result.isOK()) {
+ return result;
+ }
+
+ // We only check the unused states on models validated this far
+ if (firstState.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "no first state specified, first state may not be blank"));
+ } else {
+ if (!stateMap.containsKey(firstState)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "first state not found in stateMap"));
+ } else {
+ validateStateTree(result);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a state entry
+ *
+ * @param stateEntry the state entry to validate
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateStateEntry(final Entry<String, AxState> stateEntry, AxValidationResult result) {
+ if (stateEntry.getKey() == null || stateEntry.getKey().equals(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on state entry key " + stateEntry.getKey() + " may not be the null key"));
+ return result;
+ }
+
+ if (stateEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on state entry value " + stateEntry.getKey() + " may not be null"));
+ return result;
+ }
+
+ if (!stateEntry.getKey().equals(stateEntry.getValue().getKey().getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on state entry key " + stateEntry.getKey() + " does not equal state entry value local name "
+ + stateEntry.getValue().getKey().getLocalName()));
+ }
+
+ if (!stateEntry.getValue().getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on state entry key " + stateEntry.getValue().getKey() + " does not equal policy key"));
+ }
+
+ result = stateEntry.getValue().validate(result);
+
+ for (final AxStateOutput stateOutput : stateEntry.getValue().getStateOutputs().values()) {
+ if (!stateOutput.getNextState().equals(AxReferenceKey.getNullKey())
+ && !stateMap.containsKey(stateOutput.getNextState().getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ " nextState of state " + stateEntry.getKey() + " not found in StateMap: "
+ + stateOutput.getNextState().getID()));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a state tree to ensure there are no circular references in it
+ *
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateStateTree(AxValidationResult result) {
+ try {
+ // Cpnstructor validates policy state tree
+ AxStateTree policyStateTree = getStateTree();
+
+ // Check for unused states
+ final Set<AxState> referencedStateSet = policyStateTree.getReferencedStateSet();
+ final Set<AxState> unreferencedStateSet = new TreeSet<>(stateMap.values());
+ unreferencedStateSet.removeAll(referencedStateSet);
+
+ for (final AxState unreferencedState : unreferencedStateSet) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "state " + unreferencedState.getKey() + " is not referenced in the policy execution tree"));
+ }
+ } catch (PolicyRuntimeException pre) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "state tree in policy is invalid"));
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ firstState = firstState.trim();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",template=");
+ builder.append(template);
+ builder.append(",stateMap=");
+ builder.append(stateMap);
+ builder.append(",firstState=");
+ builder.append(firstState);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxPolicy.class);
+
+ final AxPolicy copy = ((AxPolicy) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setTemplate(template);
+
+ final Map<String, AxState> newStateMap = new TreeMap<>();
+ for (final Entry<String, AxState> stateMapEntry : stateMap.entrySet()) {
+ newStateMap.put(stateMapEntry.getKey(), new AxState(stateMapEntry.getValue()));
+ }
+ copy.setStateMap(newStateMap);
+
+ copy.setFirstState(firstState);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + template.hashCode();
+ result = prime * result + stateMap.hashCode();
+ result = prime * result + firstState.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxPolicy other = (AxPolicy) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!template.equals(other.template)) {
+ return false;
+ }
+ if (!stateMap.equals(other.stateMap)) {
+ return false;
+ }
+ return firstState.equals(other.firstState);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxPolicy other = (AxPolicy) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!template.equals(other.template)) {
+ return template.compareTo(other.template);
+ }
+ if (!stateMap.equals(other.stateMap)) {
+ return (stateMap.hashCode() - other.stateMap.hashCode());
+ }
+ return firstState.compareTo(other.firstState);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java
new file mode 100644
index 000000000..f6000b1f3
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxPolicyModel.java
@@ -0,0 +1,737 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxModel;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * A container class for an Apex policy model. This class is a container class that allows an Apex
+ * model to be constructed that contains definitions of all the context, event, and policy concepts
+ * required to run policies in Apex. The model contains schema definitions, definitions of events
+ * and context albums that use those schemas, definitions of tasks for policies and definitions of
+ * the policies themselves.
+ * <p>
+ * An Apex policy model is an important artifact in Apex. At editing time, an Apex editor creates
+ * and edits a policy model and a policy model is loaded into and is executed by an Apex engine.
+ * Therefore, an Apex model and the set of policies that it holds is the way that the policy domain
+ * that an Apex engine or a group of Apex engines executes across is expressed, both at design time
+ * and run time. The Apex deployment system is responsible for deploying Apex models to and the
+ * context they need the appropriate engines for execution.
+ * <p>
+ * Model registration is carried out by calling the {@code register()} method, which registers the
+ * policy model and all its constituent containers with the model service. The containers for
+ * context schemas, events, context albums, tasks, policies, and key information are all registered.
+ * <p>
+ * Once a policy model is composed, the overall structure of the policy model and all its references
+ * can be validated. During validation of a policy model, the validation checks listed below are
+ * executed:
+ * <ol>
+ * <li>The policy model is validated as an Apex model, which validates the existence, correctness,
+ * and duplication of all keys in the model as well as validating the key information of the keys,
+ * see validation in {@link AxModel}
+ * <li>The schemas in the model must be valid, see validation in {@link AxContextSchemas}
+ * <li>The context albums in the model must be valid, see validation in {@link AxContextAlbums}
+ * <li>The tasks in the model must be valid, see validation in {@link AxTasks}
+ * <li>The policies in the model must be valid, see validation in {@link AxPolicies}
+ * <li>The events in the model must be valid, see validation in {@link AxEvents}
+ * <li>The context schemas referred to in each field in every event must exist
+ * <li>The context schemas referred to in every context album must exist
+ * <li>The context schemas referred to in every task input field and output field must exist
+ * <li>The context albums referred to in every task must exist
+ * <li>The context albums referred to in every state must exist
+ * <li>The trigger event referred to in every state must exist
+ * <li>The default task referred to in every state must exist
+ * <li>In a state, an event that triggers a task must contain all the input fields required by that
+ * task
+ * <li>In a state, an event that is emitted by a task must contain all the output fields produced by
+ * that task
+ * <li>All tasks referred to by a state must exist
+ * <li>All events referred to on direct state outputs must exist
+ * </ol>
+ */
+@Entity
+@Table(name = "AxPolicyModel")
+
+@XmlRootElement(name = "apexPolicyModel", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxPolicyModel", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"policies", "tasks", "events", "albums", "schemas"})
+
+public class AxPolicyModel extends AxModel {
+ private static final String DOES_NOT_EXIST = " does not exist";
+
+ private static final long serialVersionUID = 8800599637708309945L;
+
+ // @formatter:off
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({@JoinColumn(name = "policiesName", referencedColumnName = "name"),
+ @JoinColumn(name = "policiesVersion", referencedColumnName = "version")})
+ @XmlElement(name = "policies", required = true)
+ private AxPolicies policies;
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({@JoinColumn(name = "tasksName", referencedColumnName = "name"),
+ @JoinColumn(name = "tasksVersion", referencedColumnName = "version")})
+ @XmlElement(name = "tasks", required = true)
+ private AxTasks tasks;
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({@JoinColumn(name = "eventsName", referencedColumnName = "name"),
+ @JoinColumn(name = "eventsVersion", referencedColumnName = "version")})
+ @XmlElement(name = "events", required = true)
+ private AxEvents events;
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({@JoinColumn(name = "albumsName", referencedColumnName = "name"),
+ @JoinColumn(name = "albumsVersion", referencedColumnName = "version")})
+ @XmlElement(name = "albums", required = true)
+ private AxContextAlbums albums;
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({@JoinColumn(name = "schemasName", referencedColumnName = "name"),
+ @JoinColumn(name = "schemasVersion", referencedColumnName = "version")})
+ @XmlElement(name = "schemas", required = true)
+ private AxContextSchemas schemas;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a policy model with a null key and empty containers for
+ * schemas, key information, events, context albums, tasks and policies.
+ */
+ public AxPolicyModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxPolicyModel(final AxPolicyModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a policy model with the given key and empty containers for
+ * schemas, key information, events, context albums, tasks and policies.
+ *
+ * @param key the key
+ */
+ public AxPolicyModel(final AxArtifactKey key) {
+ this(key, new AxContextSchemas(new AxArtifactKey(key.getName() + "_Schemas", key.getVersion())),
+ new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())),
+ new AxEvents(new AxArtifactKey(key.getName() + "_Events", key.getVersion())),
+ new AxContextAlbums(new AxArtifactKey(key.getName() + "_Albums", key.getVersion())),
+ new AxTasks(new AxArtifactKey(key.getName() + "_Tasks", key.getVersion())),
+ new AxPolicies(new AxArtifactKey(key.getName() + "_Policies", key.getVersion())));
+ }
+
+ /**
+ * This Constructor creates a policy model with all of its fields specified.
+ *
+ * @param key the key of the policy model
+ * @param schemas the context schema container for the policy model
+ * @param keyInformation the key information container for the policy model
+ * @param events the event container for the policy model
+ * @param albums the context album container for the policy model
+ * @param tasks the task container for the policy model
+ * @param policies the policy container for the policy model
+ */
+ public AxPolicyModel(final AxArtifactKey key, final AxContextSchemas schemas, final AxKeyInformation keyInformation,
+ final AxEvents events, final AxContextAlbums albums, final AxTasks tasks, final AxPolicies policies) {
+ super(key, keyInformation);
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ Assertions.argumentNotNull(events, "events may not be null");
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ Assertions.argumentNotNull(tasks, "tasks may not be null");
+ Assertions.argumentNotNull(policies, "policies may not be null");
+
+ this.schemas = schemas;
+ this.events = events;
+ this.albums = albums;
+ this.tasks = tasks;
+ this.policies = policies;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxModel#register()
+ */
+ @Override
+ public void register() {
+ super.register();
+ ModelService.registerModel(AxContextSchemas.class, getSchemas());
+ ModelService.registerModel(AxEvents.class, getEvents());
+ ModelService.registerModel(AxContextAlbums.class, getAlbums());
+ ModelService.registerModel(AxTasks.class, getTasks());
+ ModelService.registerModel(AxPolicies.class, getPolicies());
+ ModelService.registerModel(AxPolicyModel.class, this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxModel#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = super.getKeys();
+
+ keyList.addAll(schemas.getKeys());
+ keyList.addAll(events.getKeys());
+ keyList.addAll(albums.getKeys());
+ keyList.addAll(tasks.getKeys());
+ keyList.addAll(policies.getKeys());
+
+ return keyList;
+ }
+
+ /**
+ * Gets a context model from the policy model.
+ *
+ * @return the context model
+ */
+ public AxContextModel getContextModel() {
+ return new AxContextModel(new AxArtifactKey(albums.getKey().getName() + "_Model", albums.getKey().getVersion()),
+ getSchemas(), getAlbums(), getKeyInformation());
+ }
+
+ /**
+ * Gets the policy container from the policy model.
+ *
+ * @return the policy container with all the policies in the model
+ */
+ public AxPolicies getPolicies() {
+ return policies;
+ }
+
+ /**
+ * Sets the policy container for the policy model.
+ *
+ * @param policies the policy container with all the policies in the model
+ */
+ public void setPolicies(final AxPolicies policies) {
+ Assertions.argumentNotNull(policies, "policies may not be null");
+ this.policies = policies;
+ }
+
+ /**
+ * Gets the task container from the policy model.
+ *
+ * @return the task container with all the tasks in the model
+ */
+ public AxTasks getTasks() {
+ return tasks;
+ }
+
+ /**
+ * Sets the task container from the policy model.
+ *
+ * @param tasks the task container with all the tasks in the model
+ */
+ public void setTasks(final AxTasks tasks) {
+ Assertions.argumentNotNull(tasks, "tasks may not be null");
+ this.tasks = tasks;
+ }
+
+ /**
+ * Gets the event container from the policy model.
+ *
+ * @return the event container with all the events in the model
+ */
+ public AxEvents getEvents() {
+ return events;
+ }
+
+ /**
+ * Sets the event container from the policy model.
+ *
+ * @param events the event container with all the events in the model
+ */
+ public void setEvents(final AxEvents events) {
+ Assertions.argumentNotNull(events, "events may not be null");
+ this.events = events;
+ }
+
+ /**
+ * Gets the context album container from the policy model.
+ *
+ * @return the context album container with all the context albums in the model
+ */
+ public AxContextAlbums getAlbums() {
+ return albums;
+ }
+
+ /**
+ * Sets the context album container from the policy model.
+ *
+ * @param albums the context album container with all the context albums in the model
+ */
+ public void setAlbums(final AxContextAlbums albums) {
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ this.albums = albums;
+ }
+
+ /**
+ * Gets the context schema container from the policy model.
+ *
+ * @return the context schema container with all the context schemas in the model
+ */
+ public AxContextSchemas getSchemas() {
+ return schemas;
+ }
+
+ /**
+ * Sets the context schema container from the policy model.
+ *
+ * @param schemas the context schema container with all the context schemas in the model
+ */
+ public void setSchemas(final AxContextSchemas schemas) {
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ this.schemas = schemas;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxModel#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ result = super.validate(result);
+ result = schemas.validate(result);
+ result = events.validate(result);
+ result = albums.validate(result);
+ result = tasks.validate(result);
+ result = policies.validate(result);
+
+ validateEventKeys(result);
+ validateContextAlbumKeys(result);
+ result = validateAllTaskKeys(result);
+ validatePolicyKeys(result);
+
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in events exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateEventKeys(final AxValidationResult result) {
+ for (final AxEvent event : events.getAll(null)) {
+ for (final AxField field : event.getFields()) {
+ if (getSchemas().get(field.getSchema()) == null) {
+ result.addValidationMessage(
+ new AxValidationMessage(event.getKey(), this.getClass(), ValidationResult.INVALID,
+ "event field data type " + field.getSchema().getID() + DOES_NOT_EXIST));
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in concept maps exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateContextAlbumKeys(final AxValidationResult result) {
+ for (final AxContextAlbum contextAlbum : albums.getAll(null)) {
+ if (getSchemas().get(contextAlbum.getItemSchema()) == null) {
+ result.addValidationMessage(
+ new AxValidationMessage(contextAlbum.getKey(), this.getClass(), ValidationResult.INVALID,
+ "context album schema " + contextAlbum.getItemSchema().getID() + DOES_NOT_EXIST));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in tasks exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateAllTaskKeys(AxValidationResult result) {
+ for (final AxTask task : tasks.getAll(null)) {
+ result = validateTaskKeys(task, result);
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in tasks exist.
+ *
+ * @param task The task to validate the keys of
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validateTaskKeys(final AxTask task, AxValidationResult result) {
+ for (final AxField field : task.getInputFieldSet()) {
+ if (getSchemas().get(field.getSchema()) == null) {
+ result.addValidationMessage(
+ new AxValidationMessage(task.getKey(), this.getClass(), ValidationResult.INVALID,
+ "task input field schema " + field.getSchema().getID() + DOES_NOT_EXIST));
+ }
+ }
+ for (final AxField field : task.getOutputFieldSet()) {
+ if (getSchemas().get(field.getSchema()) == null) {
+ result.addValidationMessage(
+ new AxValidationMessage(task.getKey(), this.getClass(), ValidationResult.INVALID,
+ "task output field schema " + field.getSchema().getID() + DOES_NOT_EXIST));
+ }
+ }
+ for (final AxArtifactKey contextAlbumKey : task.getContextAlbumReferences()) {
+ if (albums.get(contextAlbumKey) == null) {
+ result.addValidationMessage(new AxValidationMessage(task.getKey(), this.getClass(),
+ ValidationResult.INVALID, "task context album " + contextAlbumKey.getID() + DOES_NOT_EXIST));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Validate all fundamental concepts keyed in policies exist.
+ *
+ * @param result the validation result to return
+ * @return the result
+ */
+ private AxValidationResult validatePolicyKeys(final AxValidationResult result) {
+ for (final AxPolicy policy : policies.getAll(null)) {
+ for (final AxState state : policy.getStateMap().values()) {
+ validateStateReferences(state, result);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate that the references used on a state are valid
+ *
+ * @param state The state to check
+ * @param result the validation result to append to
+ */
+ private void validateStateReferences(AxState state, AxValidationResult result) {
+ for (final AxArtifactKey contextAlbumKey : state.getContextAlbumReferences()) {
+ if (albums.get(contextAlbumKey) == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state context album " + contextAlbumKey.getID() + DOES_NOT_EXIST));
+ }
+ }
+
+ final AxEvent triggerEvent = events.getEventMap().get(state.getTrigger());
+ if (triggerEvent == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state trigger event " + state.getTrigger().getID() + DOES_NOT_EXIST));
+ }
+
+ final AxTask defaultTask = tasks.getTaskMap().get(state.getDefaultTask());
+ if (defaultTask == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state default task " + state.getDefaultTask().getID() + DOES_NOT_EXIST));
+ }
+
+ // Check task input fields and event fields are compatible for default tasks with no task
+ // selection logic
+ if (state.getTaskSelectionLogic().getKey().equals(AxReferenceKey.getNullKey()) && triggerEvent != null
+ && defaultTask != null) {
+ final Set<AxField> unhandledTaskInputFields = new TreeSet<>(defaultTask.getInputFieldSet());
+ unhandledTaskInputFields.removeAll(triggerEvent.getFields());
+ for (final AxField unhandledTaskInputField : unhandledTaskInputFields) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "task input field " + unhandledTaskInputField + " for task "
+ + defaultTask.getID() + " not in trigger event " + triggerEvent.getID()));
+ }
+ }
+
+ for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
+ if (events.getEventMap().get(stateOutput.getOutgingEvent()) == null) {
+ result.addValidationMessage(new AxValidationMessage(stateOutput.getKey(), this.getClass(),
+ ValidationResult.INVALID, "output event " + stateOutput.getOutgingEvent().getID()
+ + " for state output " + stateOutput.getID() + DOES_NOT_EXIST));
+ }
+ }
+
+ validateEventTaskFieldCompatibilityOnState(state, result);
+ }
+
+ /**
+ * Validate that the fields on tasks and events that trigger them and are output by them are
+ * compatible for all tasks used on a state
+ *
+ * @param state The state to check
+ * @param result the validation result to append to
+ */
+ private void validateEventTaskFieldCompatibilityOnState(AxState state, AxValidationResult result) {
+ // Check task output fields and event fields are compatible for tasks that directly
+ // reference state outputs
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskRefEntry : state.getTaskReferences().entrySet()) {
+ if (!taskRefEntry.getValue().getStateTaskOutputType().equals(AxStateTaskOutputType.DIRECT)) {
+ continue;
+ }
+
+ final AxTask usedTask = tasks.getTaskMap().get(taskRefEntry.getKey());
+ if (usedTask == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state task " + taskRefEntry.getKey().getID() + DOES_NOT_EXIST));
+ } else {
+ AxStateOutput stateOutput =
+ state.getStateOutputs().get(taskRefEntry.getValue().getOutput().getKey().getLocalName());
+ validateEventTaskFieldCompatibilityOnStateOutput(state, usedTask, stateOutput, result);
+ }
+ }
+ }
+
+ /**
+ * Validate that the fields on a task of a state output and the events that trigger it are
+ * compatible
+ *
+ * @param state The state to check
+ * @param task The task to check
+ * @param stateOutput The state output to check
+ * @param result the validation result to append to
+ */
+ private void validateEventTaskFieldCompatibilityOnStateOutput(final AxState state, final AxTask task,
+ final AxStateOutput stateOutput, AxValidationResult result) {
+ if (stateOutput == null) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "state output on task reference for task " + task.getID() + " is null"));
+
+ } else {
+ final AxEvent usedEvent = events.getEventMap().get(stateOutput.getOutgingEvent());
+ if (usedEvent == null) {
+ result.addValidationMessage(new AxValidationMessage(stateOutput.getKey(), this.getClass(),
+ ValidationResult.INVALID, "output event " + stateOutput.getOutgingEvent().getID()
+ + " for state output " + stateOutput.getID() + DOES_NOT_EXIST));
+ }
+
+ if (task != null && usedEvent != null) {
+ final Set<AxField> unhandledTaskOutputFields = new TreeSet<>(task.getOutputFieldSet());
+ unhandledTaskOutputFields.removeAll(usedEvent.getFields());
+ for (final AxField unhandledTaskOutputField : unhandledTaskOutputFields) {
+ result.addValidationMessage(new AxValidationMessage(state.getKey(), this.getClass(),
+ ValidationResult.INVALID, "task output field " + unhandledTaskOutputField + " for task "
+ + task.getID() + " not in output event " + usedEvent.getID()));
+ }
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxModel#clean()
+ */
+ @Override
+ public void clean() {
+ super.clean();
+ policies.clean();
+ tasks.clean();
+ events.clean();
+ albums.clean();
+ schemas.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxModel#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append(super.toString());
+ builder.append(",policies=");
+ builder.append(policies);
+ builder.append(",tasks=");
+ builder.append(tasks);
+ builder.append(",events=");
+ builder.append(events);
+ builder.append(",albums=");
+ builder.append(albums);
+ builder.append(",schemas=");
+ builder.append(schemas);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxPolicyModel.class);
+
+ final AxPolicyModel copy = ((AxPolicyModel) copyObject);
+ super.copyTo(targetObject);
+ copy.setPolicies(new AxPolicies(policies));
+ copy.setTasks(new AxTasks(tasks));
+ copy.setEvents(new AxEvents(events));
+ copy.setAlbums(new AxContextAlbums(albums));
+ copy.setSchemas(new AxContextSchemas(schemas));
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxModel#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + super.hashCode();
+ result = prime * result + policies.hashCode();
+ result = prime * result + tasks.hashCode();
+ result = prime * result + events.hashCode();
+ result = prime * result + albums.hashCode();
+ result = prime * result + schemas.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxModel#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxPolicyModel other = (AxPolicyModel) obj;
+ if (!super.equals(other)) {
+ return false;
+ }
+ if (!policies.equals(other.policies)) {
+ return false;
+ }
+ if (!tasks.equals(other.tasks)) {
+ return false;
+ }
+ if (!events.equals(other.events)) {
+ return false;
+ }
+ if (!albums.equals(other.albums)) {
+ return false;
+ }
+ return schemas.equals(other.schemas);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxModel#compareTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxPolicyModel other = (AxPolicyModel) otherObj;
+ if (!super.equals(other)) {
+ return super.compareTo(other);
+ }
+ if (!policies.equals(other.policies)) {
+ return policies.compareTo(other.policies);
+ }
+ if (!tasks.equals(other.tasks)) {
+ return tasks.compareTo(other.tasks);
+ }
+ if (!events.equals(other.events)) {
+ return events.compareTo(other.events);
+ }
+ if (!albums.equals(other.albums)) {
+ return albums.compareTo(other.albums);
+ }
+ return schemas.compareTo(other.schemas);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java
new file mode 100644
index 000000000..895232e1c
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxState.java
@@ -0,0 +1,1020 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.CascadeType;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class holds the definition of a single state in a policy. A state is a single stage in a
+ * policy. A state has a single input event, its trigger. A state can output many events, but can
+ * only output one event on a single execution. After it executes, a state can pass control to
+ * another state or can simply emit its event to an external system. In the case where a state
+ * passes control to another state, the output event of the state becomes the input event of the
+ * next state. The outputs of a state {@link AxStateOutput} are held as a map in the state. Each
+ * state output contains the outgoing event of the state and optionally the next state to pass
+ * control to.
+ * <p>
+ * A state uses tasks {@link AxTask} to execute its logic. A state holds its tasks in a map and must
+ * have at least one task. A state uses Task Selection Logic {@link AxTaskSelectionLogic} to select
+ * which task should be executed in a given execution cycle. Optional Task Selection Logic can use
+ * fields on the incoming event and information from the context albums available on the state to
+ * decide what task to execute in a given context. The default task of a state is the task that is
+ * executed when task Selection Logic is not specified. In cases where only a single task is
+ * specified on a state, the default task must be that task and the state always executes that task.
+ * <p>
+ * What happens when a state completes its execution cycle depends on the task that is selected for
+ * execution by the state. Therefore, the action to be performed a state on execution of each task
+ * must be defined in the state as a {@link AxStateTaskReference} instance for each task defined in
+ * the state. The {@link AxStateTaskReference} instance defines the action to be performed as either
+ * a {@link AxStateTaskOutputType} of {@link AxStateTaskOutputType#DIRECT} or
+ * {@link AxStateTaskOutputType#LOGIC} and contains an {@link AxReferenceKey} reference to the
+ * instance that will complete the state output.
+ * <p>
+ * In the case of direct output, the {@link AxReferenceKey} reference in the
+ * {@link AxStateTaskReference} instance is a reference to an {@link AxStateOutput} instance. The
+ * state output defines the event to be emitted by the state and the next state to pass control to
+ * if any. All fields of the executed task are marshaled onto the outgoing event automatically by
+ * Apex.
+ * <p>
+ * In the case of logic output, the {@link AxReferenceKey} reference in the
+ * {@link AxStateTaskReference} instance is a reference to State Finalizer Logic in an
+ * {@link AxStateFinalizerLogic} instance, which selects the {@link AxStateOutput} that the state
+ * will use. The state finalizer logic uses fields emitted by the executed task and information from
+ * the context albums available on the state to decide what {@link AxStateOutput} to select in a
+ * given context. The state output defines the event to be emitted by the state and the next state
+ * to pass control to if any. The State Finalizer Logic instances for the state are held in a map in
+ * the state. State Finalizer Logic must marshal the fields of the output event in whatever manner
+ * it wishes; Apex does not automatically transfer the output fields from the task directly to the
+ * output event.
+ * <p>
+ * The Task Selection Logic instance or State Finalizer Logic instances in a state may use
+ * information in context albums to arrive at their task or state output selections. The context
+ * albums that the state uses and that should be made available to the state by Apex policy
+ * distribution are held as a set of references to context albums in the state.
+ * <p>
+ * During validation of a state, the validation checks listed below are executed:
+ * <ol>
+ * <li>The policy key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * <li>The trigger event key must not be a null key and must be valid, see validation in
+ * {@link AxArtifactKey}
+ * <li>At least one state output must be defined
+ * <li>Each state output in a state must have that state as its parent
+ * <li>Each state output must be valid, see validation in {@link AxStateOutput}
+ * <li>The next state defined in a state output must be unique in a state
+ * <li>The default task key must not be a null key and must be valid, see validation in
+ * {@link AxArtifactKey}
+ * <li>The default task must appear in the task map of the state
+ * <li>At least one task must be defined on the state
+ * <li>Each task key on the task map for the state must not be a null key and must be valid, see
+ * validation in {@link AxArtifactKey}
+ * <li>All state task references for each task in the state must exist and must be valid, see
+ * validation in {@link AxStateTaskReference}
+ * <li>Each state task reference in a state must have that state as its parent
+ * <li>For direct state outputs from tasks, the state output must be defined on the state
+ * <li>For logic state outputs from tasks, the State Finalizer Logic must be defined on the state
+ * <li>An observation is issued for each state output defined on the state that is not used as a
+ * direct output on a task
+ * <li>An observation is issued for each state finalizer logic instance defined on the state that is
+ * not used as an output on a task
+ * <li>Each context album key on the context album set for the state must not be a null key and must
+ * be valid, see validation in {@link AxArtifactKey}
+ * <li>Task Selection logic in a state must have that state as its parent
+ * <li>Task Selection logic in a state must be valid, see validation in {@link AxTaskSelectionLogic}
+ * <li>Each State Finalizer logic instance in a state must have that state as its parent
+ * <li>Each State Finalizer logic instance in a state must be valid, see validation in
+ * {@link AxStateFinalizerLogic}
+ * </ol>
+ */
+
+@Entity
+@Table(name = "AxState")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexState", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxState", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "trigger", "stateOutputs", "contextAlbumReferenceSet", "taskSelectionLogic",
+ "stateFinalizerLogicMap", "defaultTask", "taskReferenceMap"})
+
+public class AxState extends AxConcept {
+ private static final String DOES_NOT_EQUAL_STATE_KEY = " does not equal state key";
+
+ private static final long serialVersionUID = 8041771382337655535L;
+
+ @EmbeddedId
+ @XmlElement(name = "stateKey", required = true)
+ private AxReferenceKey key;
+
+ // @formatter:off
+ @Embedded
+ @AttributeOverrides({@AttributeOverride(name = "name", column = @Column(name = "inTriggerName")),
+ @AttributeOverride(name = "version", column = @Column(name = "inTriggerVersion"))})
+ @Column(name = "trigger")
+ @XmlElement(required = true)
+ private AxArtifactKey trigger;
+
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(
+ joinColumns = {@JoinColumn(name = "soParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "soParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "soParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "soLocalName", referencedColumnName = "localName")},
+ inverseJoinColumns = {@JoinColumn(name = "stateParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "stateParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "stateParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "stateLocalName", referencedColumnName = "localName")})
+ @XmlElement(name = "stateOutputs", required = true)
+ private Map<String, AxStateOutput> stateOutputs;
+
+ @ElementCollection
+ @CollectionTable(joinColumns = {@JoinColumn(name = "stateParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "stateParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "stateParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "stateLocalName", referencedColumnName = "localName")})
+ @XmlElement(name = "contextAlbumReference")
+ private Set<AxArtifactKey> contextAlbumReferenceSet;
+
+ @OneToOne
+ @JoinTable(name = "STATE_TSL_JT",
+ joinColumns = {
+ @JoinColumn(name = "tslParentKeyName", referencedColumnName = "parentKeyName", updatable = false,
+ insertable = false),
+ @JoinColumn(name = "tslParentKeyVersion", referencedColumnName = "parentKeyVersion",
+ updatable = false, insertable = false),
+ @JoinColumn(name = "tslParentLocalName ", referencedColumnName = "parentLocalName",
+ updatable = false, insertable = false),
+ @JoinColumn(name = "tslLocalName", referencedColumnName = "localName", updatable = false,
+ insertable = false)})
+ @XmlElement(required = true)
+ private AxTaskSelectionLogic taskSelectionLogic;
+
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(
+ joinColumns = {@JoinColumn(name = "sflParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "sflParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "sflParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "sflLocalName", referencedColumnName = "localName")},
+ inverseJoinColumns = {@JoinColumn(name = "stateParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "stateParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "stateParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "stateLocalName", referencedColumnName = "localName")})
+ @XmlElement(name = "stateFinalizerLogicMap", required = true)
+ private Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap;
+
+ @Embedded
+ @AttributeOverrides({@AttributeOverride(name = "name", column = @Column(name = "defaultTaskName")),
+ @AttributeOverride(name = "version", column = @Column(name = "defaultTaskVersion"))})
+ @Column(name = "defaultTask")
+ @XmlElement(required = true)
+ private AxArtifactKey defaultTask;
+
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(
+ joinColumns = {@JoinColumn(name = "trmParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "trmParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "trmParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "trmLocalName", referencedColumnName = "localName")},
+ inverseJoinColumns = {@JoinColumn(name = "stateParentKeyName", referencedColumnName = "parentKeyName"),
+ @JoinColumn(name = "stateParentKeyVersion", referencedColumnName = "parentKeyVersion"),
+ @JoinColumn(name = "stateParentLocalName", referencedColumnName = "parentLocalName"),
+ @JoinColumn(name = "stateLocalName", referencedColumnName = "localName")})
+ @XmlElement(name = "taskReferences", required = true)
+ private Map<AxArtifactKey, AxStateTaskReference> taskReferenceMap;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a state with a null reference key and with default values for
+ * all other fields.
+ */
+ public AxState() {
+ this(new AxReferenceKey());
+ contextAlbumReferenceSet = new TreeSet<>();
+ taskReferenceMap = new TreeMap<>();
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxState(final AxState copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a state with the given reference key and with default values
+ * for all other fields.
+ *
+ * @param key the reference key of the state
+ */
+ public AxState(final AxReferenceKey key) {
+ this(key, // Key
+ AxArtifactKey.getNullKey(), // Trigger Reference
+ new TreeMap<String, AxStateOutput>(), // State Outputs
+ new TreeSet<AxArtifactKey>(), // Context Album References
+ new AxTaskSelectionLogic(), // Task Selection Logic
+ new TreeMap<String, AxStateFinalizerLogic>(), // State Finalizer Logics
+ AxArtifactKey.getNullKey(), // Default Task
+ new TreeMap<AxArtifactKey, AxStateTaskReference>() // Task References
+ );
+ }
+
+ /**
+ * This Constructor creates a state with all its fields defined.
+ *
+ * @param key the reference key of the state
+ * @param trigger the event that triggers the state
+ * @param stateOutputs the possible state outputs for the state
+ * @param contextAlbumReferenceSet the context album reference set defines the context that may
+ * be used by Task Selection Logic and State Finalizer Logic in the state
+ * @param taskSelectionLogic the task selection logic that selects the task a state executes in
+ * an execution cycle
+ * @param stateFinalizerLogicMap the state finalizer logic instances that selects the state
+ * output to use after a task executes in a state execution cycle
+ * @param defaultTask the default task that will execute in a state if Task Selection Logic is
+ * not specified
+ * @param taskReferenceMap the task reference map that defines the tasks for the state and how
+ * the task outputs are handled
+ */
+ // CHECKSTYLE:OFF: checkstyle:parameterNumber
+ public AxState(final AxReferenceKey key, final AxArtifactKey trigger, final Map<String, AxStateOutput> stateOutputs,
+ final Set<AxArtifactKey> contextAlbumReferenceSet, final AxTaskSelectionLogic taskSelectionLogic,
+ final Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap, final AxArtifactKey defaultTask,
+ final Map<AxArtifactKey, AxStateTaskReference> taskReferenceMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(trigger, "trigger may not be null");
+ Assertions.argumentNotNull(stateOutputs, "stateOutputs may not be null");
+ Assertions.argumentNotNull(contextAlbumReferenceSet, "contextAlbumReferenceSet may not be null");
+ Assertions.argumentNotNull(taskSelectionLogic, "taskSelectionLogic may not be null");
+ Assertions.argumentNotNull(stateFinalizerLogicMap, "stateFinalizerLogicMap may not be null");
+ Assertions.argumentNotNull(defaultTask, "defaultTask may not be null");
+ Assertions.argumentNotNull(taskReferenceMap, "taskReferenceMap may not be null");
+
+ this.key = key;
+ this.trigger = trigger;
+ this.stateOutputs = stateOutputs;
+ this.contextAlbumReferenceSet = contextAlbumReferenceSet;
+ this.taskSelectionLogic = taskSelectionLogic;
+ this.stateFinalizerLogicMap = stateFinalizerLogicMap;
+ this.defaultTask = defaultTask;
+ this.taskReferenceMap = taskReferenceMap;
+ }
+ // CHECKSTYLE:ON: checkstyle:parameterNumber
+
+ /**
+ * When a state is unmarshalled from disk or from the database, the parent of contained objects
+ * is not defined. This method is called by JAXB after unmarshaling and is used to set the
+ * parent keys of all {@link AxTaskSelectionLogic}, {@link AxStateOutput}, and
+ * {@link AxStateFinalizerLogic} instance in the state.
+ *
+ * @param u the unmarshaler that is unmarshaling the model
+ * @param parent the parent object of this object in the unmarshaler
+ */
+ public void afterUnmarshal(final Unmarshaller u, final Object parent) {
+ if (!taskSelectionLogic.getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ taskSelectionLogic.getKey().setParentReferenceKey(key);
+ }
+
+ for (final Entry<String, AxStateOutput> soEntry : stateOutputs.entrySet()) {
+ soEntry.getValue().getKey().setParentReferenceKey(key);
+ }
+
+ for (final Entry<String, AxStateFinalizerLogic> sflEntry : stateFinalizerLogicMap.entrySet()) {
+ sflEntry.getValue().getKey().setParentReferenceKey(key);
+ }
+
+ for (final Entry<AxArtifactKey, AxStateTaskReference> trEntry : taskReferenceMap.entrySet()) {
+ trEntry.getValue().getKey().setParentReferenceKey(key);
+ }
+ }
+
+ /**
+ * Gets the names of all the states that this state may pass control to.
+ *
+ * @return the list of possible states that may receive control when this state completes
+ * execution
+ */
+ public Set<String> getNextStateSet() {
+ final Set<String> nextStateSet = new TreeSet<>();
+
+ for (final AxStateOutput stateOutput : stateOutputs.values()) {
+ nextStateSet.add(stateOutput.getNextState().getLocalName());
+ }
+ return nextStateSet;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(trigger.getKey()));
+ for (final AxStateOutput stateOutput : stateOutputs.values()) {
+ keyList.addAll(stateOutput.getKeys());
+ }
+ for (final AxArtifactKey contextAlbumReferenceKey : contextAlbumReferenceSet) {
+ keyList.add(new AxKeyUse(contextAlbumReferenceKey));
+ }
+ if (!taskSelectionLogic.getKey().equals(AxReferenceKey.getNullKey())) {
+ keyList.addAll(taskSelectionLogic.getKeys());
+ }
+ for (final Entry<String, AxStateFinalizerLogic> stateFinalizerLogicEntry : stateFinalizerLogicMap.entrySet()) {
+ keyList.addAll(stateFinalizerLogicEntry.getValue().getKeys());
+ }
+ keyList.add(new AxKeyUse(defaultTask.getKey()));
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : taskReferenceMap.entrySet()) {
+ keyList.add(new AxKeyUse(taskReferenceEntry.getKey()));
+
+ // A state output is allowed to be used more than once but we only return one usage as a
+ // key
+ for (AxKey referencedKey : taskReferenceEntry.getValue().getKeys()) {
+ if (keyList.contains(referencedKey)) {
+ keyList.add(referencedKey);
+ }
+ }
+ }
+ return keyList;
+ }
+
+ /**
+ * Sets the reference key of the state.
+ *
+ * @param key the state reference key
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the event that triggers the state.
+ *
+ * @return the event that triggers the state
+ */
+ public AxArtifactKey getTrigger() {
+ return trigger;
+ }
+
+ /**
+ * Sets the event that triggers the state.
+ *
+ * @param trigger the event that triggers the state
+ */
+ public void setTrigger(final AxArtifactKey trigger) {
+ Assertions.argumentNotNull(trigger, "trigger may not be null");
+ this.trigger = trigger;
+ }
+
+ /**
+ * Gets the possible state outputs for the state.
+ *
+ * @return the the possible state outputs for the state
+ */
+ public Map<String, AxStateOutput> getStateOutputs() {
+ return stateOutputs;
+ }
+
+ /**
+ * Sets the the possible state outputs for the state.
+ *
+ * @param stateOutputs the the possible state outputs for the state
+ */
+ public void setStateOutputs(final Map<String, AxStateOutput> stateOutputs) {
+ Assertions.argumentNotNull(stateOutputs, "stateOutputs may not be null");
+ this.stateOutputs = stateOutputs;
+ }
+
+ /**
+ * Gets the context album reference set defines the context that may be used by Task Selection
+ * Logic and State Finalizer Logic in the state.
+ *
+ * @return the context album reference set defines the context that may be used by Task
+ * Selection Logic and State Finalizer Logic in the state
+ */
+ public Set<AxArtifactKey> getContextAlbumReferences() {
+ return contextAlbumReferenceSet;
+ }
+
+ /**
+ * Sets the context album reference set defines the context that may be used by Task Selection
+ * Logic and State Finalizer Logic in the state.
+ *
+ * @param contextAlbumReferences the context album reference set defines the context that may be
+ * used by Task Selection Logic and State Finalizer Logic in the state
+ */
+ public void setContextAlbumReferences(final Set<AxArtifactKey> contextAlbumReferences) {
+ Assertions.argumentNotNull(contextAlbumReferences, "contextAlbumReferenceSet may not be null");
+ this.contextAlbumReferenceSet = contextAlbumReferences;
+ }
+
+ /**
+ * Gets the task selection logic that selects the task a state executes in an execution cycle.
+ *
+ * @return the task selection logic that selects the task a state executes in an execution cycle
+ */
+ public AxTaskSelectionLogic getTaskSelectionLogic() {
+ return taskSelectionLogic;
+ }
+
+ /**
+ * Sets the task selection logic that selects the task a state executes in an execution cycle.
+ *
+ * @param taskSelectionLogic the task selection logic that selects the task a state executes in
+ * an execution cycle
+ */
+ public void setTaskSelectionLogic(final AxTaskSelectionLogic taskSelectionLogic) {
+ Assertions.argumentNotNull(taskSelectionLogic, "taskSelectionLogic may not be null");
+ this.taskSelectionLogic = taskSelectionLogic;
+ }
+
+ /**
+ * Check if task selection logic has been specified the state.
+ *
+ * @return true, if task selection logic has been specified
+ */
+ public boolean checkSetTaskSelectionLogic() {
+ return !taskSelectionLogic.getKey().equals(AxReferenceKey.getNullKey());
+ }
+
+ /**
+ * Gets the state finalizer logic instances that selects the state output to use after a task
+ * executes in a state execution cycle.
+ *
+ * @return the state finalizer logic instances that selects the state output to use after a task
+ * executes in a state execution cycle
+ */
+ public Map<String, AxStateFinalizerLogic> getStateFinalizerLogicMap() {
+ return stateFinalizerLogicMap;
+ }
+
+ /**
+ * Sets the state finalizer logic instances that selects the state output to use after a task
+ * executes in a state execution cycle.
+ *
+ * @param stateFinalizerLogicMap the state finalizer logic instances that selects the state
+ * output to use after a task executes in a state execution cycle
+ */
+ public void setStateFinalizerLogicMap(final Map<String, AxStateFinalizerLogic> stateFinalizerLogicMap) {
+ Assertions.argumentNotNull(stateFinalizerLogicMap, "stateFinalizerLogic may not be null");
+ this.stateFinalizerLogicMap = stateFinalizerLogicMap;
+ }
+
+ /**
+ * Gets the default task that will execute in a state if Task Selection Logic is not specified.
+ *
+ * @return the default task that will execute in a state if Task Selection Logic is not
+ * specified
+ */
+ public AxArtifactKey getDefaultTask() {
+ return defaultTask;
+ }
+
+ /**
+ * Sets the default task that will execute in a state if Task Selection Logic is not specified.
+ *
+ * @param defaultTask the default task that will execute in a state if Task Selection Logic is
+ * not specified
+ */
+ public void setDefaultTask(final AxArtifactKey defaultTask) {
+ Assertions.argumentNotNull(defaultTask, "defaultTask may not be null");
+ this.defaultTask = defaultTask;
+ }
+
+ /**
+ * Gets the task reference map that defines the tasks for the state and how the task outputs are
+ * handled.
+ *
+ * @return the task reference map that defines the tasks for the state and how the task outputs
+ * are handled
+ */
+ public Map<AxArtifactKey, AxStateTaskReference> getTaskReferences() {
+ return taskReferenceMap;
+ }
+
+ /**
+ * Sets the task reference map that defines the tasks for the state and how the task outputs are
+ * handled.
+ *
+ * @param taskReferences the task reference map that defines the tasks for the state and how the
+ * task outputs are handled
+ */
+ public void setTaskReferences(final Map<AxArtifactKey, AxStateTaskReference> taskReferences) {
+ Assertions.argumentNotNull(taskReferences, "taskReferenceMap may not be null");
+ this.taskReferenceMap = taskReferences;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (trigger.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "trigger is a null key: " + trigger));
+ }
+ result = trigger.validate(result);
+
+ if (stateOutputs.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateOutputs may not be empty"));
+ } else {
+ validateStateOutputs(result);
+ }
+
+ validateContextAlbumReferences(result);
+ result = validateTaskSelectionLogic(result);
+ validateStateFinalizerLogics(result);
+
+ if (defaultTask.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "default task has a null key: " + defaultTask));
+ }
+ result = defaultTask.validate(result);
+
+ if (taskReferenceMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskReferenceMap may not be empty"));
+ } else {
+ validateStateTaskReferences(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate the state outputs of the state
+ *
+ * @param result the validation result to append to
+ */
+ private void validateStateOutputs(AxValidationResult result) {
+ final Set<String> nextStateNameSet = new TreeSet<>();
+ for (final Entry<String, AxStateOutput> stateOutputEntry : stateOutputs.entrySet()) {
+ if (stateOutputEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null state output value found on state output " + stateOutputEntry.getKey()));
+ } else {
+ if (!stateOutputEntry.getValue().getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on state output " + stateOutputEntry.getKey() + DOES_NOT_EQUAL_STATE_KEY));
+ }
+
+ if (stateOutputEntry.getValue().getNextState().getLocalName().equals(key.getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "state output next state " + stateOutputEntry.getValue().getNextState().getLocalName()
+ + " may not be this state"));
+
+ }
+
+ if (nextStateNameSet.contains(stateOutputEntry.getValue().getNextState().getLocalName())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "duplicate state output next state name "
+ + stateOutputEntry.getValue().getNextState().getLocalName() + " found"));
+ } else {
+ nextStateNameSet.add(stateOutputEntry.getValue().getNextState().getLocalName());
+ }
+ result = stateOutputEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ /**
+ * Validate the context album references of the state
+ *
+ * @param result the validation result to append to
+ */
+ private void validateContextAlbumReferences(AxValidationResult result) {
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ if (contextAlbumReference.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context album reference entry " + contextAlbumReference.getKey()
+ + " may not be the null key"));
+ }
+
+ result = contextAlbumReference.validate(result);
+ }
+ }
+
+ /**
+ * Validate the task selection logic of the state
+ *
+ * @param result the validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateTaskSelectionLogic(AxValidationResult result) {
+ if (!taskSelectionLogic.getKey().equals(AxReferenceKey.getNullKey())) {
+ if (!taskSelectionLogic.getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskSelectionLogic key " + taskSelectionLogic.getKey().getID() + DOES_NOT_EQUAL_STATE_KEY));
+ }
+ result = taskSelectionLogic.validate(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate all the state finalizer logic of the state
+ *
+ * @param result the validation result to append to
+ */
+ private void validateStateFinalizerLogics(AxValidationResult result) {
+ for (final Entry<String, AxStateFinalizerLogic> stateFinalizerLogicEntry : stateFinalizerLogicMap.entrySet()) {
+ if (stateFinalizerLogicEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null state finalizer logic value found on state finalizer entry "
+ + stateFinalizerLogicEntry.getKey()));
+ } else {
+ if (!stateFinalizerLogicEntry.getValue().getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateFinalizerLogic parent key " + stateFinalizerLogicEntry.getValue().getKey().getID()
+ + DOES_NOT_EQUAL_STATE_KEY));
+ }
+
+ result = stateFinalizerLogicEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ /**
+ * Validate the tasks used the state
+ *
+ * @param result the validation result to append to
+ */
+ private void validateStateTaskReferences(AxValidationResult result) {
+ final Set<String> usedStateOutputNameSet = new TreeSet<>();
+ final Set<String> usedStateFinalizerLogicNameSet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskRefEntry : taskReferenceMap.entrySet()) {
+ if (taskRefEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "task has a null key: " + taskRefEntry.getKey()));
+ }
+ result = taskRefEntry.getKey().validate(result);
+
+ if (taskRefEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null task reference value found on task reference " + taskRefEntry.getKey()));
+ } else {
+ result = validateStateTaskReference(taskRefEntry.getKey(), taskRefEntry.getValue(),
+ usedStateOutputNameSet, usedStateFinalizerLogicNameSet, result);
+ }
+ }
+
+ final Set<String> unUsedStateOutputNameSet = new TreeSet<>(stateOutputs.keySet());
+ unUsedStateOutputNameSet.removeAll(usedStateOutputNameSet);
+ for (final String unUsedStateOutputName : unUsedStateOutputNameSet) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "state output " + unUsedStateOutputName + " is not used directly by any task"));
+ }
+
+ final Set<String> usnUedStateFinalizerLogicNameSet = new TreeSet<>(stateFinalizerLogicMap.keySet());
+ usnUedStateFinalizerLogicNameSet.removeAll(usedStateFinalizerLogicNameSet);
+ for (final String unusedStateFinalizerLogicName : usnUedStateFinalizerLogicNameSet) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION,
+ "state finalizer logic " + unusedStateFinalizerLogicName + " is not used by any task"));
+ }
+
+ if (!taskReferenceMap.containsKey(defaultTask)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "defaultTask " + defaultTask + " not found in taskReferenceMap"));
+ }
+ }
+
+ /**
+ * Validate the references of a task used in a state
+ *
+ * @param taskKey The key of the task
+ * @param taskReference the task reference of the task
+ * @param stateOutputNameSet State outputs that have been used so far, will be appended for this
+ * task reference
+ * @param stateFinalizerLogicNameSet State finalizers that have been used so far, may be
+ * appended if this task reference uses a finalzier
+ * @param result the validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateStateTaskReference(final AxArtifactKey taskKey,
+ final AxStateTaskReference taskReference, Set<String> stateOutputNameSet,
+ Set<String> stateFinalizerLogicNameSet, AxValidationResult result) {
+ if (!taskReference.getKey().getParentReferenceKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateTaskReference parent key " + taskReference.getKey().getID() + DOES_NOT_EQUAL_STATE_KEY));
+ }
+
+ if (taskReference.getStateTaskOutputType().equals(AxStateTaskOutputType.DIRECT)) {
+ if (stateOutputs.containsKey(taskReference.getOutput().getLocalName())) {
+ stateOutputNameSet.add(taskReference.getOutput().getLocalName());
+ } else {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "state output for task " + taskKey + " not found in stateOutputs"));
+ }
+ } else if (taskReference.getStateTaskOutputType().equals(AxStateTaskOutputType.LOGIC)) {
+ if (stateFinalizerLogicMap.containsKey(taskReference.getOutput().getLocalName())) {
+ stateFinalizerLogicNameSet.add(taskReference.getOutput().getLocalName());
+ } else {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "state finalizer logic for task " + taskKey + " not found in stateFinalizerLogicMap"));
+ }
+ } else {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "stateTaskReference task output type " + taskReference.getStateTaskOutputType() + " is invalid"));
+ }
+
+ return taskReference.validate(result);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ trigger.clean();
+ for (final AxStateOutput stateOutput : stateOutputs.values()) {
+ stateOutput.clean();
+ }
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ contextAlbumReference.clean();
+ }
+ taskSelectionLogic.clean();
+ for (final AxStateFinalizerLogic stateFinalizerLogic : stateFinalizerLogicMap.values()) {
+ stateFinalizerLogic.clean();
+ }
+ defaultTask.clean();
+ for (final AxStateTaskReference taskReference : taskReferenceMap.values()) {
+ taskReference.clean();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("stateKey=");
+ builder.append(key);
+ builder.append(",trigger=");
+ builder.append(trigger);
+ builder.append(",stateOutputs=");
+ builder.append(stateOutputs);
+ builder.append(",contextAlbumReferenceSet=");
+ builder.append(contextAlbumReferenceSet);
+ builder.append(",taskSelectionLogic=");
+ builder.append(taskSelectionLogic);
+ builder.append(",stateFinalizerLogicSet=");
+ builder.append(stateFinalizerLogicMap);
+ builder.append(",defaultTask=");
+ builder.append(defaultTask);
+ builder.append(",taskReferenceMap=");
+ builder.append(taskReferenceMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxState.class);
+
+ final AxState copy = ((AxState) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setTrigger(new AxArtifactKey(trigger));
+
+ final Map<String, AxStateOutput> newStateOutputs = new TreeMap<>();
+ for (final Entry<String, AxStateOutput> stateOutputEntry : stateOutputs.entrySet()) {
+ newStateOutputs.put(stateOutputEntry.getKey(), new AxStateOutput(stateOutputEntry.getValue()));
+ }
+ copy.setStateOutputs(newStateOutputs);
+
+ final Set<AxArtifactKey> newContextUsage = new TreeSet<>();
+ for (final AxArtifactKey contextAlbumReferenceItem : contextAlbumReferenceSet) {
+ newContextUsage.add(new AxArtifactKey(contextAlbumReferenceItem));
+ }
+ copy.setContextAlbumReferences(newContextUsage);
+
+ copy.setTaskSelectionLogic(new AxTaskSelectionLogic(taskSelectionLogic));
+
+ final Map<String, AxStateFinalizerLogic> newStateFinalizerLogicMap = new TreeMap<>();
+ for (final Entry<String, AxStateFinalizerLogic> stateFinalizerLogicEntry : stateFinalizerLogicMap.entrySet()) {
+ newStateFinalizerLogicMap.put(stateFinalizerLogicEntry.getKey(),
+ new AxStateFinalizerLogic(stateFinalizerLogicEntry.getValue()));
+ }
+ copy.setStateFinalizerLogicMap(newStateFinalizerLogicMap);
+
+ copy.setDefaultTask(new AxArtifactKey(defaultTask));
+
+ final Map<AxArtifactKey, AxStateTaskReference> newTaskReferenceMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : taskReferenceMap.entrySet()) {
+ newTaskReferenceMap.put(new AxArtifactKey(taskReferenceEntry.getKey()),
+ new AxStateTaskReference(taskReferenceEntry.getValue()));
+ }
+ copy.setTaskReferences(newTaskReferenceMap);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + trigger.hashCode();
+ result = prime * result + stateOutputs.hashCode();
+ result = prime * result + contextAlbumReferenceSet.hashCode();
+ result = prime * result + taskSelectionLogic.hashCode();
+ result = prime * result + stateFinalizerLogicMap.hashCode();
+ result = prime * result + defaultTask.hashCode();
+ result = prime * result + taskReferenceMap.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxState other = (AxState) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!trigger.equals(other.trigger)) {
+ return false;
+ }
+ if (!stateOutputs.equals(other.stateOutputs)) {
+ return false;
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return false;
+ }
+ if (!taskSelectionLogic.equals(other.taskSelectionLogic)) {
+ return false;
+ }
+ if (!stateFinalizerLogicMap.equals(other.stateFinalizerLogicMap)) {
+ return false;
+ }
+ if (!defaultTask.equals(other.defaultTask)) {
+ return false;
+ }
+ return taskReferenceMap.equals(other.taskReferenceMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxState other = (AxState) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!trigger.equals(other.trigger)) {
+ return trigger.compareTo(other.trigger);
+ }
+ if (!stateOutputs.equals(other.stateOutputs)) {
+ return stateOutputs.hashCode() - other.stateOutputs.hashCode();
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return (contextAlbumReferenceSet.hashCode() - other.contextAlbumReferenceSet.hashCode());
+ }
+ if (!taskSelectionLogic.equals(other.taskSelectionLogic)) {
+ return taskSelectionLogic.compareTo(other.taskSelectionLogic);
+ }
+ if (!stateFinalizerLogicMap.equals(other.stateFinalizerLogicMap)) {
+ return stateFinalizerLogicMap.hashCode() - other.stateFinalizerLogicMap.hashCode();
+ }
+ if (!defaultTask.equals(other.defaultTask)) {
+ return defaultTask.compareTo(other.defaultTask);
+ }
+ if (!taskReferenceMap.equals(other.taskReferenceMap)) {
+ return (taskReferenceMap.hashCode() - other.taskReferenceMap.hashCode());
+ }
+
+ return 0;
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java
new file mode 100644
index 000000000..76704b051
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateFinalizerLogic.java
@@ -0,0 +1,137 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class holds State Finalizer Logic for {@link AxState} states in Apex. It is a specialization
+ * of the {@link AxLogic} class, so that State Finalizer Logic in Apex states can be strongly typed.
+ * <p>
+ * State Finalizer Logic is used to select the output {@link AxStateOutput} that a state will use.
+ * The logic uses fields emitted by the executed {@link AxTask} task and information from the
+ * context albums available on a state to decide what state output {@link AxStateOutput} to select
+ * in a given context. State Finalizer Logic must marshal the output fields from the task onto the
+ * output event in whatever manner is appropriate for the domain being handled.
+ * <p>
+ * Validation uses standard Apex Logic validation, see validation in {@link AxLogic}.
+ */
+@Entity
+@Table(name = "AxStateFinalizerLogic")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexStateFinalizerLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxStateFinalizerLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+
+public class AxStateFinalizerLogic extends AxLogic {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxStateFinalizerLogic() {
+ super();
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey key) {
+ super(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ super(parentKey, logicName, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super(key, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance by cloning the fields from another logic instance
+ * into this logic instance.
+ *
+ * @param logic the logic instance to clone from
+ */
+ public AxStateFinalizerLogic(final AxLogic logic) {
+ super(new AxReferenceKey(logic.getKey()), logic.getLogicFlavour(), logic.getLogic());
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name, the given logic flavour, with the logic being provided by the
+ * given logic reader instance.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final AxLogicReader logicReader) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logicReader);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxStateFinalizerLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super(key, logicFlavour, logicReader);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java
new file mode 100644
index 000000000..a0c73c260
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateOutput.java
@@ -0,0 +1,389 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class defines a single output that a state can have. A state can have many outputs with each
+ * output defined as an instance of this class. Each state output defines the output event that will
+ * be emitted when this output is selected and optionally the next state that is executed when this
+ * state output is selected. If no next state is defined (the next state is a null
+ * {@link AxReferenceKey} key), then this state output outputs its event to an external system and
+ * is an output state for the full policy.
+ * <p>
+ * During validation of a state output, the validation checks listed below are executed:
+ * <ol>
+ * <li>The state output key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * <li>The outgoing event key must not be a null key and must be valid, see validation in
+ * {@link AxArtifactKey}
+ * <li>The next state key must be valid, see validation in {@link AxReferenceKey}
+ * </ol>
+ */
+
+@Entity
+@Table(name = "AxStateOutput")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexStateOutput", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxStateOutput", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "outgoingEvent", "nextState"})
+
+public class AxStateOutput extends AxConcept {
+ private static final long serialVersionUID = 8041771382337655535L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxReferenceKey key;
+
+ // @formatter:off
+ @Embedded
+ @AttributeOverrides({@AttributeOverride(name = "name", column = @Column(name = "outgoingEventName")),
+ @AttributeOverride(name = "version", column = @Column(name = "outgoingEventVersion"))})
+ @Column(name = "outgoingEvent")
+ @XmlElement(required = true)
+ private AxArtifactKey outgoingEvent;
+
+ @Embedded
+ @AttributeOverrides({@AttributeOverride(name = "parentKeyName", column = @Column(name = "nextStateParentKeyName")),
+ @AttributeOverride(name = "parentKeyVersion", column = @Column(name = "nextStateParentKeyVersion")),
+ @AttributeOverride(name = "parentLocalName", column = @Column(name = "nextStateParentLocalName")),
+ @AttributeOverride(name = "localName", column = @Column(name = "nextStateLocalName"))})
+ @Column(name = "nextState")
+ @XmlElement(required = true)
+ private AxReferenceKey nextState;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a state output instance with a null reference key, outgoing
+ * event key and next state reference key.
+ */
+ public AxStateOutput() {
+ this(new AxReferenceKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxStateOutput(final AxStateOutput copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a state output instance with the given reference key, outgoing
+ * event key and next state reference key.
+ *
+ * @param key the reference key for the state output
+ */
+ public AxStateOutput(final AxReferenceKey key) {
+ this(key, // Key
+ AxArtifactKey.getNullKey(), // Outgoing Event
+ AxReferenceKey.getNullKey() // Next State
+ );
+ }
+
+ /**
+ * This Constructor creates a state output with a reference key composed of the given parent key
+ * and with a local name composed from the parent key local name concatenated with the next
+ * state's local name. The next state and outgoing event of the state output are set as
+ * specified.
+ *
+ * @param parentKey the parent key of the state output
+ * @param nextState the next state to which execution will pass on use of this state output
+ * @param outgoingEvent the outgoing event emitted on use of this state output
+ */
+ public AxStateOutput(final AxReferenceKey parentKey, final AxReferenceKey nextState,
+ final AxArtifactKey outgoingEvent) {
+ this(new AxReferenceKey(parentKey, parentKey.getLocalName() + '_' + nextState.getLocalName()), outgoingEvent,
+ nextState);
+ }
+
+ /**
+ * This Constructor creates a state output with the specified reference key. The next state and
+ * outgoing event of the state output are set as specified.
+ *
+ * @param key the key
+ * @param nextState the next state to which execution will pass on use of this state output
+ * @param outgoingEvent the outgoing event emitted on use of this state output
+ */
+ public AxStateOutput(final AxReferenceKey key, final AxArtifactKey outgoingEvent, final AxReferenceKey nextState) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(outgoingEvent, "outgoingEvent may not be null");
+ Assertions.argumentNotNull(nextState, "nextState may not be null");
+
+ this.key = key;
+ this.outgoingEvent = outgoingEvent;
+ this.nextState = nextState;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(outgoingEvent));
+
+ if (!nextState.equals(AxReferenceKey.getNullKey())) {
+ keyList.add(new AxKeyUse(nextState));
+ }
+
+ return keyList;
+ }
+
+ /**
+ * Sets the reference key for the state output.
+ *
+ * @param key the reference key for the state output
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the outgoing event emitted on use of this state output.
+ *
+ * @return the outgoing event emitted on use of this state output
+ */
+ public AxArtifactKey getOutgingEvent() {
+ return outgoingEvent;
+ }
+
+ /**
+ * Sets the outgoing event emitted on use of this state output.
+ *
+ * @param outgoingEvent the outgoing event emitted on use of this state output
+ */
+ public void setOutgoingEvent(final AxArtifactKey outgoingEvent) {
+ Assertions.argumentNotNull(outgoingEvent, "outgoingEvent may not be null");
+ this.outgoingEvent = outgoingEvent;
+ }
+
+ /**
+ * Gets the next state to which execution will pass on use of this state output.
+ *
+ * @return the next state to which execution will pass on use of this state output
+ */
+ public AxReferenceKey getNextState() {
+ return nextState;
+ }
+
+ /**
+ * Sets the next state to which execution will pass on use of this state output.
+ *
+ * @param nextState the next state to which execution will pass on use of this state output
+ */
+ public void setNextState(final AxReferenceKey nextState) {
+ Assertions.argumentNotNull(nextState, "nextState may not be null");
+ this.nextState = nextState;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (outgoingEvent.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "outgoingEvent reference is a null key, an outgoing event must be specified"));
+ }
+ result = outgoingEvent.validate(result);
+
+ // Note: Null keys are allowed on nextState as there may not be a next state
+ result = nextState.validate(result);
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ outgoingEvent.clean();
+ nextState.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("stateKey=");
+ builder.append(key);
+ builder.append(",outgoingEvent=");
+ builder.append(outgoingEvent);
+ builder.append(",nextState=");
+ builder.append(nextState);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxStateOutput.class);
+
+ final AxStateOutput copy = ((AxStateOutput) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setOutgoingEvent(new AxArtifactKey(outgoingEvent));
+ copy.setNextState(nextState);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + outgoingEvent.hashCode();
+ result = prime * result + nextState.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxStateOutput other = (AxStateOutput) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!outgoingEvent.equals(other.outgoingEvent)) {
+ return false;
+ }
+ return nextState.equals(other.nextState);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxStateOutput other = (AxStateOutput) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!outgoingEvent.equals(other.outgoingEvent)) {
+ return outgoingEvent.compareTo(other.outgoingEvent);
+ }
+ return nextState.compareTo(other.nextState);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java
new file mode 100644
index 000000000..741eb8833
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskOutputType.java
@@ -0,0 +1,48 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * This enumeration defines the type of state output selection that is defined for a task in a
+ * state. The {@link AxStateTaskReference} instance for each task uses this enumeration to decide
+ * what type of output selection to use when a task has completed execution.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxStateTaskOutputType", namespace = "http://www.onap.org/policy/apex-pdp")
+
+public enum AxStateTaskOutputType {
+ /** The state output selection for the task has not been defined. */
+ UNDEFINED,
+ /**
+ * Direct state output selection has been selected, the task will select a {@link AxStateOutput}
+ * directly.
+ */
+ DIRECT,
+ /**
+ * Logic state output selection has been selected, the task will select a {@link AxStateOutput}
+ * using logic defined in a {@link AxStateFinalizerLogic} instance.
+ */
+ LOGIC
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java
new file mode 100644
index 000000000..011af6cbb
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTaskReference.java
@@ -0,0 +1,400 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Enumerated;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class defines the type of output handling that will be used when a task in a state completes
+ * execution. Each task {@link AxTask} in a state {@link AxState} must select a state output
+ * {@link AxStateOutput} in order to pass its fields to an output event. Therefore, each task has an
+ * associated instance of this class that defines how the state output of the state is selected and
+ * how the output fields of the task are marshaled onto the fields of the output event. A
+ * {@link AxStateTaskReference} instance defines the task output handling as either
+ * {@link AxStateTaskOutputType#DIRECT} or {@link AxStateTaskOutputType#LOGIC}. In the case of
+ * {@link AxStateTaskOutputType#DIRECT} output selection, the output reference key held in this
+ * {@link AxStateTaskReference} instance to an instance of an {@link AxStateOutput} class. In the
+ * case of {@link AxStateTaskOutputType#LOGIC} output selection, the output reference key held in
+ * this {@link AxStateTaskReference} instance to an instance of an {@link AxStateFinalizerLogic}
+ * class. See the explanation in the {@link AxState} class for a full description of this handling.
+ * <p>
+ *
+ * During validation of a state task reference, the validation checks listed below are executed:
+ * <ol>
+ * <li>The state task reference key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * <li>The output type must be defined, that is not equal to {@link AxStateTaskOutputType#UNDEFINED}
+ * <li>The output key must not be a null key and must be valid, see validation in
+ * {@link AxReferenceKey}
+ * </ol>
+ */
+
+@Entity
+@Table(name = "AxStateTaskReference")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexStateTaskReference", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxStateTaskReference", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "outputType", "output"})
+
+public class AxStateTaskReference extends AxConcept {
+ private static final long serialVersionUID = 8041771382337655535L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxReferenceKey key;
+
+ @Enumerated
+ @Column(name = "outputType")
+ @XmlElement(required = true)
+ private AxStateTaskOutputType outputType;
+
+ // @formatter:off
+ @Embedded
+ @AttributeOverrides({@AttributeOverride(name = "parentKeyName", column = @Column(name = "outputParentKeyName")),
+ @AttributeOverride(name = "parentKeyVersion", column = @Column(name = "outputParentKeyVersion")),
+ @AttributeOverride(name = "parentLocalName", column = @Column(name = "outputParentLocalName")),
+ @AttributeOverride(name = "localName", column = @Column(name = "outputLocalName"))})
+ @Column(name = "output")
+ @XmlElement(required = true)
+ private AxReferenceKey output;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a state task reference with a null reference key, an
+ * undefined output type and a null output reference key.
+ */
+ public AxStateTaskReference() {
+ this(new AxReferenceKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxStateTaskReference(final AxStateTaskReference copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a state task reference with the given reference key, an
+ * undefined output type and a null output reference key.
+ *
+ * @param key the key
+ */
+ public AxStateTaskReference(final AxReferenceKey key) {
+ this(key, // Key
+ AxStateTaskOutputType.UNDEFINED, // Output type
+ AxReferenceKey.getNullKey()); // Output
+ }
+
+ /**
+ * This Constructor creates a state task reference instance with a reference key composed from
+ * the given parent key with a local name composed by concatenating the name of the task key
+ * with the local name of the output. The output type and output are set to the given values.
+ *
+ * @param parentKey the parent key to use for the key of the state task reference
+ * @param taskKey the task key to use for the first part of the state task reference local name
+ * @param outputType the type of output to perform when this state task reference instance is
+ * used
+ * @param output the output to perform when this state task reference instance is used
+ */
+ public AxStateTaskReference(final AxReferenceKey parentKey, final AxArtifactKey taskKey,
+ final AxStateTaskOutputType outputType, final AxReferenceKey output) {
+ this(new AxReferenceKey(parentKey, taskKey.getName() + '_' + outputType.name() + '_' + output.getLocalName()),
+ outputType, output);
+ }
+
+ /**
+ * This Constructor creates a state task reference instance with the given reference key and all
+ * its fields defined.
+ *
+ * @param key the key of the state task reference
+ * @param outputType the type of output to perform when this state task reference instance is
+ * used
+ * @param output the output to perform when this state task reference instance is used
+ */
+ public AxStateTaskReference(final AxReferenceKey key, final AxStateTaskOutputType outputType,
+ final AxReferenceKey output) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(outputType, "outputType may not be null");
+ Assertions.argumentNotNull(output, "output may not be null");
+
+ this.key = key;
+ this.outputType = outputType;
+ this.output = output;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ if (!output.equals(AxReferenceKey.getNullKey())) {
+ keyList.add(new AxKeyUse(output));
+ }
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the state task reference.
+ *
+ * @param key the key of the state task reference
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the type of output to perform when this state task reference instance is used.
+ *
+ * @return the the type of output to perform when this state task reference instance is used
+ */
+ public AxStateTaskOutputType getStateTaskOutputType() {
+ return outputType;
+ }
+
+ /**
+ * Sets the type of output to perform when this state task reference instance is used.
+ *
+ * @param stateTaskOutputType the type of output to perform when this state task reference
+ * instance is used
+ */
+ public void setStateTaskOutputType(final AxStateTaskOutputType stateTaskOutputType) {
+ Assertions.argumentNotNull(stateTaskOutputType, "outputType may not be null");
+ this.outputType = stateTaskOutputType;
+ }
+
+ /**
+ * Gets the output to perform when this state task reference instance is used.
+ *
+ * @return the output to perform when this state task reference instance is used
+ */
+ public AxReferenceKey getOutput() {
+ return output;
+ }
+
+ /**
+ * Sets the output to perform when this state task reference instance is used.
+ *
+ * @param output the output to perform when this state task reference instance is used
+ */
+ public void setOutput(final AxReferenceKey output) {
+ Assertions.argumentNotNull(output, "output may not be null");
+ this.output = output;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (outputType == AxStateTaskOutputType.UNDEFINED) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "outputType may not be UNDEFINED"));
+ }
+
+ if (output.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "output key " + output.getID() + " is a null key"));
+ }
+ result = output.validate(result);
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ output.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("stateKey=");
+ builder.append(key);
+ builder.append(",outputType=");
+ builder.append(outputType);
+ builder.append(",output=");
+ builder.append(output);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxStateTaskReference.class);
+
+ final AxStateTaskReference copy = ((AxStateTaskReference) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setStateTaskOutputType(AxStateTaskOutputType.valueOf(outputType.name()));
+ copy.setOutput(output);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + outputType.hashCode();
+ result = prime * result + output.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxStateTaskReference other = (AxStateTaskReference) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (outputType != other.outputType) {
+ return false;
+ }
+ return output.equals(other.output);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxStateTaskReference other = (AxStateTaskReference) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!outputType.equals(other.outputType)) {
+ return outputType.compareTo(other.outputType);
+ }
+ return output.compareTo(other.output);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java
new file mode 100644
index 000000000..30076ca0b
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxStateTree.java
@@ -0,0 +1,157 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * The Class is used to return the tree that represents the state branches or chains in a policy. It
+ * creates a tree that holds the state fan out branches in a policy that starts from the given top
+ * state of the tree. Each branch from a state is held in a set of next states for the top state and
+ * each branch in the state tree is itself a {@link AxStateTree} instance.
+ * <p>
+ * Validation checks for recursive state use, in other words validation forbids the use of a given
+ * state more than once in a state tree.
+ */
+public class AxStateTree implements Comparable<AxStateTree> {
+ private final AxState thisState;
+ private final Set<AxStateTree> nextStates;
+
+ /**
+ * This constructor recursively creates a state tree for the given policy starting at the given
+ * state.
+ *
+ * @param policy the policy from which to read states
+ * @param thisState the state to start state tree construction at
+ * @param referencedStateNameSet a set of state names already referenced in the tree, null for
+ * the first recursive call
+ */
+ public AxStateTree(final AxPolicy policy, final AxState thisState, Set<AxReferenceKey> referencedStateNameSet) {
+ Assertions.argumentNotNull(policy, "policy may not be null");
+ Assertions.argumentNotNull(thisState, "thisState may not be null");
+
+ this.thisState = thisState;
+ nextStates = new TreeSet<>();
+
+ for (final AxStateOutput stateOutput : thisState.getStateOutputs().values()) {
+ final AxState nextState = policy.getStateMap().get(stateOutput.getNextState().getLocalName());
+
+ // Check for end of state branch
+ if (stateOutput.getNextState().equals(AxReferenceKey.getNullKey())) {
+ continue;
+ }
+
+ if (referencedStateNameSet == null) {
+ referencedStateNameSet = new LinkedHashSet<>();
+ referencedStateNameSet.add(thisState.getKey());
+ }
+
+ // Check for state tree loops
+ if (referencedStateNameSet.contains(nextState.getKey())) {
+ throw new PolicyRuntimeException("loop detected in state tree for policy " + policy.getID() + " state "
+ + thisState.getKey().getLocalName() + ", next state " + nextState.getKey().getLocalName()
+ + " referenced more than once");
+ }
+ referencedStateNameSet.add(stateOutput.getNextState());
+ nextStates.add(new AxStateTree(policy, nextState, referencedStateNameSet));
+ }
+ }
+
+ /**
+ * Gets the state for this state tree node.
+ *
+ * @return the state
+ */
+ public AxState getState() {
+ return thisState;
+ }
+
+ /**
+ * Gets the next states for this state tree node.
+ *
+ * @return the next states
+ */
+ public Set<AxStateTree> getNextStates() {
+ return nextStates;
+ }
+
+ /**
+ * Gets the list of states referenced by this state tree as a list.
+ *
+ * @return the list of states referenced
+ */
+ public List<AxState> getReferencedStateList() {
+ final List<AxState> referencedStateList = new ArrayList<>();
+
+ referencedStateList.add(thisState);
+ for (final AxStateTree nextStateTree : nextStates) {
+ referencedStateList.addAll(nextStateTree.getReferencedStateList());
+ }
+
+ return referencedStateList;
+ }
+
+ /**
+ * Gets the list of states referenced by this state tree as a set.
+ *
+ * @return the set of states referenced
+ */
+ public Set<AxState> getReferencedStateSet() {
+ final Set<AxState> referencedStateSet = new TreeSet<>();
+
+ referencedStateSet.add(thisState);
+ for (final AxStateTree nextStateTree : nextStates) {
+ referencedStateSet.addAll(nextStateTree.getReferencedStateSet());
+ }
+
+ return referencedStateSet;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxStateTree otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+
+ final AxStateTree other = otherObj;
+ if (!thisState.equals(other.thisState)) {
+ return thisState.compareTo(other.thisState);
+ }
+ if (!nextStates.equals(other.nextStates)) {
+ return (nextStates.hashCode() - other.nextStates.hashCode());
+ }
+ return 0;
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java
new file mode 100644
index 000000000..b1f26f6c0
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTask.java
@@ -0,0 +1,745 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.persistence.CascadeType;
+import javax.persistence.CollectionTable;
+import javax.persistence.ElementCollection;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class holds the definition of a task in Apex. A task is executed by a state and performs
+ * some domain specific logic to carry out work required to be done by a policy. The Task Logic that
+ * is executed by a task is held in a {@link AxTaskLogic} instance.
+ * <p>
+ * A task has a set of input fields and output fields, which are passed to and are emitted from the
+ * task during a task execution cycle. A task may have task parameters {@link AxTaskParameter},
+ * which are configuration values passed to a task at initialization time.
+ * <p>
+ * The Task Logic in a task may use information in context albums to perform their domain specific
+ * work. The context albums that the task uses and that should be made available to the task by Apex
+ * policy distribution are held as a set of references to context albums in the task.
+ * <p>
+ * During validation of a task, the validation checks listed below are executed:
+ * <ol>
+ * <li>The task key must not be a null key and must be valid, see validation in
+ * {@link AxArtifactKey}
+ * <li>The task must have at least one input field
+ * <li>The parent of each input field of a task must be that task
+ * <li>Each input field must be valid, see validation in {@link AxInputField}
+ * <li>The task must have at least one output field
+ * <li>The parent of each output field of a task must be that task
+ * <li>Each output field must be valid, see validation in {@link AxOutputField}
+ * <li>The parent of each task parameter of a task must be that task
+ * <li>Each task parameter must be valid, see validation in {@link AxTaskParameter}
+ * <li>The parent of the task logic in a task must be that task
+ * <li>The task logic must be valid, see validation in {@link AxTaskLogic}
+ * </ol>
+ */
+
+@Entity
+@Table(name = "AxTask")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexTask", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxTask", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "inputFields", "outputFields", "taskParameters", "contextAlbumReferenceSet", "taskLogic"})
+
+public class AxTask extends AxConcept {
+ private static final String DOES_NOT_EQUAL_TASK_KEY = " does not equal task key";
+
+ private static final long serialVersionUID = 5374237330697362762L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @XmlElement(name = "inputFields", required = true)
+ private Map<String, AxInputField> inputFields;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @XmlElement(name = "outputFields", required = true)
+ private Map<String, AxOutputField> outputFields;
+
+ @OneToMany(cascade = CascadeType.ALL)
+ @XmlElement(name = "taskParameters", required = true)
+ private Map<String, AxTaskParameter> taskParameters;
+
+ // @formatter:off
+ @ElementCollection
+ @CollectionTable(joinColumns = {@JoinColumn(name = "contextAlbumName", referencedColumnName = "name"),
+ @JoinColumn(name = "contextAlbumVersion", referencedColumnName = "version")})
+ @XmlElement(name = "contextAlbumReference")
+ private Set<AxArtifactKey> contextAlbumReferenceSet;
+ // @formatter:on
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @XmlElement(required = true)
+ private AxTaskLogic taskLogic;
+
+ /**
+ * The Default Constructor creates a task with a null key no input or output fields, no task
+ * parameters, no context album references and no logic.
+ */
+ public AxTask() {
+ this(new AxArtifactKey());
+ contextAlbumReferenceSet = new TreeSet<>();
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxTask(final AxTask copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a task with the given key no input or output fields, no task
+ * parameters, no context album references and no logic.
+ *
+ * @param key the key of the task
+ */
+ public AxTask(final AxArtifactKey key) {
+ this(key, // Task Key
+ new TreeMap<String, AxInputField>(), // Input fields
+ new TreeMap<String, AxOutputField>(), // Output Fields
+ new TreeMap<String, AxTaskParameter>(), // Task Parameters
+ new TreeSet<AxArtifactKey>(), // Context Album References
+ new AxTaskLogic(new AxReferenceKey(key)) // Task Logic
+ );
+ }
+
+ /**
+ * This Constructor defines all the fields of the task.
+ *
+ * @param key the key of the task
+ * @param inputFields the input fields that the task expects
+ * @param outputFields the output fields that the task emits
+ * @param taskParameters the task parameters that are used to initialize tasks of this type
+ * @param contextAlbumReferenceSet the context album reference set defines the context that may
+ * be used by Task Logic in the state
+ * @param taskLogic the task logic that performs the domain specific work of the task
+ */
+ public AxTask(final AxArtifactKey key, final Map<String, AxInputField> inputFields,
+ final Map<String, AxOutputField> outputFields, final Map<String, AxTaskParameter> taskParameters,
+ final Set<AxArtifactKey> contextAlbumReferenceSet, final AxTaskLogic taskLogic) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(inputFields, "inputFields may not be null");
+ Assertions.argumentNotNull(outputFields, "outputFields may not be null");
+ Assertions.argumentNotNull(taskParameters, "taskParameters may not be null");
+ Assertions.argumentNotNull(contextAlbumReferenceSet, "contextAlbumReferenceSet may not be null");
+ Assertions.argumentNotNull(taskLogic, "taskLogic may not be null");
+
+ this.key = key;
+ this.inputFields = inputFields;
+ this.outputFields = outputFields;
+ this.taskParameters = taskParameters;
+ this.contextAlbumReferenceSet = contextAlbumReferenceSet;
+ this.taskLogic = taskLogic;
+ }
+
+ /**
+ * When a task is unmarshalled from disk or from the database, the parent of contained objects
+ * is not defined. This method is called by JAXB after unmarshaling and is used to set the
+ * parent keys of all {@link AxInputField}, {@link AxOutputField}, and {@link AxTaskParameter}
+ * instance in the task.
+ *
+ * @param u the unmarshaler that is unmarshaling the model
+ * @param parent the parent object of this object in the unmarshaler
+ */
+ public void afterUnmarshal(final Unmarshaller u, final Object parent) {
+ taskLogic.getKey().setParentArtifactKey(key);
+
+ for (final AxInputField inputField : inputFields.values()) {
+ inputField.getKey().setParentArtifactKey(key);
+ inputField.getKey().setParentLocalName("InField");
+ }
+ for (final AxOutputField outputField : outputFields.values()) {
+ outputField.getKey().setParentArtifactKey(key);
+ outputField.getKey().setParentLocalName("OutField");
+ }
+ for (final AxTaskParameter parameter : taskParameters.values()) {
+ parameter.getKey().setParentArtifactKey(key);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ for (final AxInputField inputField : inputFields.values()) {
+ keyList.addAll(inputField.getKeys());
+ }
+ for (final AxOutputField outputField : outputFields.values()) {
+ keyList.addAll(outputField.getKeys());
+ }
+ for (final AxTaskParameter taskParameter : taskParameters.values()) {
+ keyList.addAll(taskParameter.getKeys());
+ }
+ for (final AxArtifactKey contextAlbumKey : contextAlbumReferenceSet) {
+ keyList.add(new AxKeyUse(contextAlbumKey));
+ }
+ keyList.addAll(taskLogic.getKeys());
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the task.
+ *
+ * @param key the key of the task
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the input fields that the task expects.
+ *
+ * @return the input fields that the task expects
+ */
+ public Map<String, AxInputField> getInputFields() {
+ return inputFields;
+ }
+
+ /**
+ * Gets the raw input fields that the task expects as a tree map.
+ *
+ * @return the raw input fields that the task expects
+ */
+ public Map<String, AxField> getRawInputFields() {
+ return new TreeMap<>(inputFields);
+ }
+
+ /**
+ * Convenience method to get the input fields as a set.
+ *
+ * @return the input fields as a set
+ */
+ public Set<AxField> getInputFieldSet() {
+ final Set<AxField> inputFieldSet = new TreeSet<>();
+ for (final AxInputField field : inputFields.values()) {
+ inputFieldSet.add(field);
+ }
+ return inputFieldSet;
+ }
+
+ /**
+ * Sets the input fields that the task expects.
+ *
+ * @param inputFields the input fields that the task expects
+ */
+ public void setInputFields(final Map<String, AxInputField> inputFields) {
+ Assertions.argumentNotNull(inputFields, "inputFields may not be null");
+ this.inputFields = inputFields;
+ }
+
+ /**
+ * Copy the input fields from the given map into the task. This method is used to get a copy of
+ * the input fields, which can be useful for unit testing of policies and tasks.
+ *
+ * @param fields the fields to copy into the task
+ */
+ public void duplicateInputFields(final Map<String, AxField> fields) {
+ Assertions.argumentNotNull(fields, "fields may not be null");
+
+ for (final AxField field : fields.values()) {
+ final AxReferenceKey fieldKey = new AxReferenceKey(this.getKey().getName(), this.getKey().getVersion(),
+ "inputFields", field.getKey().getLocalName());
+ final AxInputField inputField = new AxInputField(fieldKey, field.getSchema());
+ inputFields.put(inputField.getKey().getLocalName(), inputField);
+ }
+ }
+
+ /**
+ * Gets the output fields that the task emits.
+ *
+ * @return the output fields that the task emits
+ */
+ public Map<String, AxOutputField> getOutputFields() {
+ return outputFields;
+ }
+
+ /**
+ * Gets the raw output fields that the task emits as a tree map.
+ *
+ * @return the raw output fields as a tree map
+ */
+ public Map<String, AxField> getRawOutputFields() {
+ return new TreeMap<>(outputFields);
+ }
+
+ /**
+ * Gets the output fields that the task emits as a set.
+ *
+ * @return the output fields as a set
+ */
+ public Set<AxField> getOutputFieldSet() {
+ final Set<AxField> outputFieldSet = new TreeSet<>();
+ for (final AxOutputField field : outputFields.values()) {
+ outputFieldSet.add(field);
+ }
+ return outputFieldSet;
+ }
+
+ /**
+ * Sets the output fields that the task emits.
+ *
+ * @param outputFields the output fields that the task emits
+ */
+ public void setOutputFields(final Map<String, AxOutputField> outputFields) {
+ Assertions.argumentNotNull(outputFields, "outputFields may not be null");
+ this.outputFields = outputFields;
+ }
+
+ /**
+ * Copy the output fields from the given map into the task. This method is used to get a copy of
+ * the output fields, which can be useful for unit testing of policies and tasks.
+ *
+ * @param fields the fields to copy into the task
+ */
+ public void duplicateOutputFields(final Map<String, AxField> fields) {
+ Assertions.argumentNotNull(fields, "fields may not be null");
+
+ for (final AxField field : fields.values()) {
+ final AxReferenceKey fieldKey = new AxReferenceKey(this.getKey().getName(), this.getKey().getVersion(),
+ "outputFields", field.getKey().getLocalName());
+ final AxOutputField outputField = new AxOutputField(fieldKey, field.getSchema());
+ outputFields.put(outputField.getKey().getLocalName(), outputField);
+ }
+ }
+
+ /**
+ * Gets the task parameters that are used to initialize tasks of this type.
+ *
+ * @return the task parameters that are used to initialize tasks of this type
+ */
+ public Map<String, AxTaskParameter> getTaskParameters() {
+ return taskParameters;
+ }
+
+ /**
+ * Sets the task parameters that are used to initialize tasks of this type.
+ *
+ * @param taskParameters the task parameters that are used to initialize tasks of this type
+ */
+ public void setTaskParameters(final Map<String, AxTaskParameter> taskParameters) {
+ Assertions.argumentNotNull(taskParameters, "taskParameters may not be null");
+ this.taskParameters = taskParameters;
+ }
+
+ /**
+ * Gets the context album reference set defines the context that may be used by Task Logic in
+ * the state.
+ *
+ * @return the context album reference set defines the context that may be used by Task Logic in
+ * the state
+ */
+ public Set<AxArtifactKey> getContextAlbumReferences() {
+ return contextAlbumReferenceSet;
+ }
+
+ /**
+ * Sets the context album reference set defines the context that may be used by Task Logic in
+ * the state.
+ *
+ * @param contextAlbumReferences the context album reference set defines the context that may be
+ * used by Task Logic in the state
+ */
+ public void setContextAlbumReferences(final Set<AxArtifactKey> contextAlbumReferences) {
+ Assertions.argumentNotNull(contextAlbumReferences, "contextAlbumReferences may not be null");
+ this.contextAlbumReferenceSet = contextAlbumReferences;
+ }
+
+ /**
+ * Gets the task logic that performs the domain specific work of the task.
+ *
+ * @return the task logic that performs the domain specific work of the task
+ */
+ public AxTaskLogic getTaskLogic() {
+ return taskLogic;
+ }
+
+ /**
+ * Sets the task logic that performs the domain specific work of the task.
+ *
+ * @param taskLogic the task logic that performs the domain specific work of the task
+ */
+ public void setTaskLogic(final AxTaskLogic taskLogic) {
+ Assertions.argumentNotNull(taskLogic, "taskLogic may not be null");
+ this.taskLogic = taskLogic;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (inputFields.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "inputFields may not be empty"));
+ } else {
+ for (final Entry<String, AxInputField> inputFieldEntry : inputFields.entrySet()) {
+ result = validateField(inputFieldEntry.getKey(), inputFieldEntry.getValue(), "input", result);
+ }
+ }
+
+ if (outputFields.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "outputFields may not be empty"));
+ } else {
+ for (final Entry<String, AxOutputField> outputFieldEntry : outputFields.entrySet()) {
+ result = validateField(outputFieldEntry.getKey(), outputFieldEntry.getValue(), "input", result);
+ }
+ }
+
+ for (final Entry<String, AxTaskParameter> taskParameterEntry : taskParameters.entrySet()) {
+ result = vaildateTaskParameterEntry(taskParameterEntry, result);
+ }
+
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ result = vaildateContextAlbumReference(contextAlbumReference, result);
+ }
+
+ if (!taskLogic.getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskLogic parent key " + taskLogic.getKey().getID() + DOES_NOT_EQUAL_TASK_KEY));
+ }
+
+ return taskLogic.validate(result);
+ }
+
+ /**
+ * Validate a field
+ *
+ * @param key the key of the field to validate
+ * @param field the field to validate
+ * @param direction The direction of the field
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult validateField(final String fieldKey, final AxField field, final String direction,
+ AxValidationResult result) {
+ if (field == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null " + direction + " field value found on " + direction + " field " + fieldKey));
+ } else {
+ if (!field.getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on " + direction + " field " + fieldKey + DOES_NOT_EQUAL_TASK_KEY));
+ }
+
+ result = field.validate(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a task parameter entry
+ *
+ * @param taskParameterEntry the task parameter entry to validate
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult vaildateTaskParameterEntry(final Entry<String, AxTaskParameter> taskParameterEntry,
+ AxValidationResult result) {
+ if (taskParameterEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "null input task parameer value found on task parameter " + taskParameterEntry.getKey()));
+ } else {
+ if (!taskParameterEntry.getValue().getKey().getParentArtifactKey().equals(key)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent key on task parameter " + taskParameterEntry.getKey() + DOES_NOT_EQUAL_TASK_KEY));
+ }
+
+ result = taskParameterEntry.getValue().validate(result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Validate a context album reference entry
+ *
+ * @param taskParameterEntry the context album reference entry to validate
+ * @param result The validation result to append to
+ * @return The result of the validation
+ */
+ private AxValidationResult vaildateContextAlbumReference(final AxArtifactKey contextAlbumReference,
+ AxValidationResult result) {
+ if (contextAlbumReference.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context item reference entry " + contextAlbumReference.getKey()
+ + " may not be the null key"));
+ }
+
+ return contextAlbumReference.validate(result);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final AxInputField inputField : inputFields.values()) {
+ inputField.clean();
+ }
+ for (final AxOutputField outputField : outputFields.values()) {
+ outputField.clean();
+ }
+ for (final AxTaskParameter parameter : taskParameters.values()) {
+ parameter.clean();
+ }
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ contextAlbumReference.clean();
+ }
+ taskLogic.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",inputFields=");
+ builder.append(inputFields);
+ builder.append(",outputFields=");
+ builder.append(outputFields);
+ builder.append(",taskParameters=");
+ builder.append(taskParameters);
+ builder.append(",contextAlbumReferenceSet=");
+ builder.append(contextAlbumReferenceSet);
+ builder.append(",taskLogic=");
+ builder.append(taskLogic);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxTask.class);
+
+ final AxTask copy = ((AxTask) copyObject);
+ copy.setKey(key);
+
+ final Map<String, AxInputField> newInputFields = new TreeMap<>();
+ for (final Entry<String, AxInputField> inputFieldEntry : inputFields.entrySet()) {
+ newInputFields.put(inputFieldEntry.getKey(), new AxInputField(inputFieldEntry.getValue()));
+ }
+ copy.setInputFields(newInputFields);
+
+ final Map<String, AxOutputField> newOutputFields = new TreeMap<>();
+ for (final Entry<String, AxOutputField> outputFieldEntry : outputFields.entrySet()) {
+ newOutputFields.put(outputFieldEntry.getKey(), new AxOutputField(outputFieldEntry.getValue()));
+ }
+ copy.setOutputFields(newOutputFields);
+
+ final Map<String, AxTaskParameter> newTaskParameter = new TreeMap<>();
+ for (final Entry<String, AxTaskParameter> taskParameterEntry : taskParameters.entrySet()) {
+ newTaskParameter.put(taskParameterEntry.getKey(), new AxTaskParameter(taskParameterEntry.getValue()));
+ }
+ copy.setTaskParameters(newTaskParameter);
+
+ final Set<AxArtifactKey> newContextUsage = new TreeSet<>();
+ for (final AxArtifactKey contextAlbumReference : contextAlbumReferenceSet) {
+ newContextUsage.add(new AxArtifactKey(contextAlbumReference));
+ }
+ copy.setContextAlbumReferences(newContextUsage);
+
+ copy.setTaskLogic(new AxTaskLogic((AxLogic) taskLogic));
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + inputFields.hashCode();
+ result = prime * result + outputFields.hashCode();
+ result = prime * result + taskParameters.hashCode();
+ result = prime * result + contextAlbumReferenceSet.hashCode();
+ result = prime * result + taskLogic.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxTask other = (AxTask) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!inputFields.equals(other.inputFields)) {
+ return false;
+ }
+ if (!outputFields.equals(other.outputFields)) {
+ return false;
+ }
+ if (!taskParameters.equals(other.taskParameters)) {
+ return false;
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return false;
+ }
+ return taskLogic.equals(other.taskLogic);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxTask other = (AxTask) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!inputFields.equals(other.inputFields)) {
+ return (inputFields.hashCode() - other.inputFields.hashCode());
+ }
+ if (!outputFields.equals(other.outputFields)) {
+ return (outputFields.hashCode() - other.outputFields.hashCode());
+ }
+ if (!taskParameters.equals(other.taskParameters)) {
+ return (taskParameters.hashCode() - other.taskParameters.hashCode());
+ }
+ if (!contextAlbumReferenceSet.equals(other.contextAlbumReferenceSet)) {
+ return (contextAlbumReferenceSet.hashCode() - other.contextAlbumReferenceSet.hashCode());
+ }
+ return taskLogic.compareTo(other.taskLogic);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.java
new file mode 100644
index 000000000..00513e8f7
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskLogic.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.model.policymodel.concepts;
+
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class holds Task Logic for {@link AxTask} tasks in Apex. It is a specialization of the
+ * {@link AxLogic} class, so that Task Logic in Apex states can be strongly typed.
+ * <p>
+ * Task Logic is used to execute tasks {@link AxTask} in Apex. The logic uses fields on the incoming
+ * trigger event and information from the context albums available on a task to get context during
+ * execution. The task logic populates the output fields of the task.
+ * <p>
+ * Validation uses standard Apex Logic validation, see validation in {@link AxLogic}.
+ */
+@Entity
+@Table(name = "AxTaskLogic")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxTaskLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+
+public class AxTaskLogic extends AxLogic {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxTaskLogic() {
+ super();
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxTaskLogic(final AxReferenceKey key) {
+ super(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskLogic(final AxArtifactKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super(key, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance by cloning the fields from another logic instance
+ * into this logic instance.
+ *
+ * @param logic the logic instance to clone from
+ */
+ public AxTaskLogic(final AxLogic logic) {
+ super(new AxReferenceKey(logic.getKey()), logic.getLogicFlavour(), logic.getLogic());
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name, the given logic flavour, with the logic being provided by the
+ * given logic reader instance.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskLogic(final AxArtifactKey parentKey, final String logicName, final String logicFlavour,
+ final AxLogicReader logicReader) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logicReader);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super(key, logicFlavour, logicReader);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java
new file mode 100644
index 000000000..5ae3bfa42
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskParameter.java
@@ -0,0 +1,299 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is used to specify the configuration parameters that may be passed to a task
+ * {@link AxTask}. Task parameters are read from a configuration file when Apex starts and are
+ * passed to the task by the Apex engine when a task is executed. Each task parameter has a key and
+ * a default value. If the task parameter is not set in a configuration file, the task uses its
+ * default value.
+ */
+
+@Entity
+@Table(name = "AxTaskParameter")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexTaskParameter", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxTaskParameter", namespace = "http://www.onap.org/policy/apex-pdp",
+ propOrder = {"key", "defaultValue"})
+
+public class AxTaskParameter extends AxConcept {
+ private static final long serialVersionUID = 7351688156934099977L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxReferenceKey key;
+
+ @Column(name = "defaultValue")
+ @XmlElement
+ private String defaultValue;
+
+ /**
+ * The Default Constructor creates a task parameter with a null reference key and a null default
+ * value.
+ */
+ public AxTaskParameter() {
+ this(new AxReferenceKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxTaskParameter(final AxTaskParameter copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a task parameter with the given reference key and a null
+ * default value.
+ *
+ * @param taskParameterKey the task parameter key
+ */
+ public AxTaskParameter(final AxReferenceKey taskParameterKey) {
+ this(taskParameterKey, "");
+ }
+
+ /**
+ * The Default Constructor creates a task parameter with the given reference key and default
+ * value.
+ *
+ * @param key the reference key of the task parameter
+ * @param defaultValue the default value of the task parameter
+ */
+ public AxTaskParameter(final AxReferenceKey key, final String defaultValue) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(defaultValue, "defaultValue may not be null");
+
+ this.key = key;
+ this.defaultValue = defaultValue.trim();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxReferenceKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the reference key of the task parameter.
+ *
+ * @param key the reference key of the task parameter
+ */
+ public void setKey(final AxReferenceKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the default value of the task parameter.
+ *
+ * @return the default value of the task parameter
+ */
+ public String getTaskParameterValue() {
+ return defaultValue;
+ }
+
+ /**
+ * Sets the default value of the task parameter.
+ *
+ * @param defaultValue the default value of the task parameter
+ */
+ public void setDefaultValue(final String defaultValue) {
+ Assertions.argumentNotNull(defaultValue, "defaultValue may not be null");
+ this.defaultValue = defaultValue.trim();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (defaultValue.trim().length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.WARNING,
+ "no defaultValue specified, defaultValue is blank"));
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ defaultValue = defaultValue.trim();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",defaultValue=");
+ builder.append(defaultValue);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxTaskParameter.class);
+
+ final AxTaskParameter copy = ((AxTaskParameter) copyObject);
+ copy.setKey(new AxReferenceKey(key));
+ copy.setDefaultValue(defaultValue);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + defaultValue.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxTaskParameter other = (AxTaskParameter) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return defaultValue.equals(other.defaultValue);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxTaskParameter other = (AxTaskParameter) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ return defaultValue.compareTo(other.defaultValue);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java
new file mode 100644
index 000000000..89c9418a4
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTaskSelectionLogic.java
@@ -0,0 +1,135 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+
+/**
+ * This class holds Task Selection Logic for {@link AxState} states in Apex. It is a specialization
+ * of the {@link AxLogic} class, so that Task Selection Logic in Apex states can be strongly typed.
+ * <p>
+ * Task Selection Logic is used to select the task {@link AxTask} that a state will execute. The
+ * logic uses fields on the incoming trigger event and information from the context albums available
+ * on a state to decide what task {@link AxTask} to select for execution in a given context.
+ * <p>
+ * Validation uses standard Apex Logic validation, see validation in {@link AxLogic}.
+ */
+@Entity
+@Table(name = "AxTaskSelectionLogic")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexTaskSelectionLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+@XmlType(name = "AxTaskSelectionLogic", namespace = "http://www.onap.org/policy/apex-pdp")
+
+public class AxTaskSelectionLogic extends AxLogic {
+ private static final long serialVersionUID = 2090324845463750391L;
+
+ /**
+ * The Default Constructor creates a logic instance with a null key, undefined logic flavour and
+ * a null logic string.
+ */
+ public AxTaskSelectionLogic() {
+ super();
+ }
+
+ /**
+ * The Key Constructor creates a logic instance with the given reference key, undefined logic
+ * flavour and a null logic string.
+ *
+ * @param key the reference key of the logic
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey key) {
+ super(key, LOGIC_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name and all of its fields defined.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final String logic) {
+ super(parentKey, logicName, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and all of its fields
+ * defined.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logic the actual logic as a string
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey key, final String logicFlavour, final String logic) {
+ super(key, logicFlavour, logic);
+ }
+
+ /**
+ * This Constructor creates a logic instance by cloning the fields from another logic instance
+ * into this logic instance.
+ *
+ * @param logic the logic instance to clone from
+ */
+ public AxTaskSelectionLogic(final AxLogic logic) {
+ super(new AxReferenceKey(logic.getKey()), logic.getLogicFlavour(), logic.getLogic());
+ }
+
+ /**
+ * This Constructor creates a logic instance with a reference key constructed from the parents
+ * key and the logic local name, the given logic flavour, with the logic being provided by the
+ * given logic reader instance.
+ *
+ * @param parentKey the reference key of the parent of this logic
+ * @param logicName the logic name, held as the local name of the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey parentKey, final String logicName, final String logicFlavour,
+ final AxLogicReader logicReader) {
+ super(new AxReferenceKey(parentKey, logicName), logicFlavour, logicReader);
+ }
+
+ /**
+ * This Constructor creates a logic instance with the given reference key and logic flavour, the
+ * logic is provided by the given logic reader instance.
+ *
+ * @param key the reference key of this logic
+ * @param logicFlavour the flavour of this logic
+ * @param logicReader the logic reader to use to read the logic for this logic instance
+ */
+ public AxTaskSelectionLogic(final AxReferenceKey key, final String logicFlavour, final AxLogicReader logicReader) {
+ super(key, logicFlavour, logicReader);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java
new file mode 100644
index 000000000..532d7d017
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/AxTasks.java
@@ -0,0 +1,425 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.persistence.CascadeType;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is a task container and holds a map of the tasks for an entire Apex model. All Apex
+ * models that use tasks must have an {@link AxTasks} field. The {@link AxTasks} class implements
+ * the helper methods of the {@link AxConceptGetter} interface to allow {@link AxTask} instances to
+ * be retrieved by calling methods directly on this class without referencing the contained map.
+ * <p>
+ * Validation checks that the container key is not null. An error is issued if no tasks are defined
+ * in the container. Each task entry is checked to ensure that its key and value are not null and
+ * that the key matches the key in the map value. Each task entry is then validated individually.
+ */
+@Entity
+@Table(name = "AxTasks")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxTasks", namespace = "http://www.onap.org/policy/apex-pdp", propOrder = {"key", "taskMap"})
+public class AxTasks extends AxConcept implements AxConceptGetter<AxTask> {
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ // @formatter:off
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(
+ joinColumns = {@JoinColumn(name = "taskMapName", referencedColumnName = "name"),
+ @JoinColumn(name = "taskMapVersion", referencedColumnName = "version")},
+ inverseJoinColumns = {@JoinColumn(name = "taskName", referencedColumnName = "name"),
+ @JoinColumn(name = "taskVersion", referencedColumnName = "version")})
+ @XmlElement(required = true)
+ private Map<AxArtifactKey, AxTask> taskMap;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a {@link AxTasks} object with a null artifact key and creates
+ * an empty event map.
+ */
+ public AxTasks() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxTasks(final AxTasks copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Keyed Constructor creates a {@link AxTasks} object with the given artifact key and
+ * creates an empty event map.
+ *
+ * @param key the key
+ */
+ public AxTasks(final AxArtifactKey key) {
+ this(key, new TreeMap<AxArtifactKey, AxTask>());
+ }
+
+ /**
+ * This Constructor creates a task container with all of its fields defined.
+ *
+ * @param key the task container key
+ * @param taskMap the tasks to be stored in the task container
+ */
+ public AxTasks(final AxArtifactKey key, final Map<AxArtifactKey, AxTask> taskMap) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(taskMap, "taskMap may not be null");
+
+ this.key = key;
+ this.taskMap = new TreeMap<>();
+ this.taskMap.putAll(taskMap);
+ }
+
+ /**
+ * When a model is unmarshalled from disk or from the database, the task map is returned as a
+ * raw hash map. This method is called by JAXB after unmarshaling and is used to convert the
+ * hash map to a {@link NavigableMap} so that it will work with the {@link AxConceptGetter}
+ * interface.
+ *
+ * @param u the unmarshaler that is unmarshaling the model
+ * @param parent the parent object of this object in the unmarshaler
+ */
+ public void afterUnmarshal(final Unmarshaller u, final Object parent) {
+ // The map must be navigable to allow name and version searching, unmarshaling returns a
+ // hash map
+ final NavigableMap<AxArtifactKey, AxTask> navigableTaskMap = new TreeMap<>();
+ navigableTaskMap.putAll(taskMap);
+ taskMap = navigableTaskMap;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxTask task : taskMap.values()) {
+ keyList.addAll(task.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * Sets the task container key.
+ *
+ * @param key the task container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the tasks stored in the task container.
+ *
+ * @return the tasks stored in the task container
+ */
+ public Map<AxArtifactKey, AxTask> getTaskMap() {
+ return taskMap;
+ }
+
+ /**
+ * Sets the tasks to be stored in the task container.
+ *
+ * @param taskMap the tasks to be stored in the task container
+ */
+ public void setTaskMap(final Map<AxArtifactKey, AxTask> taskMap) {
+ Assertions.argumentNotNull(taskMap, "taskMap may not be null");
+ this.taskMap = new TreeMap<>();
+ this.taskMap.putAll(taskMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (taskMap.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "taskMap may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxTask> taskEntry : taskMap.entrySet()) {
+ if (taskEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on task entry " + taskEntry.getKey() + " may not be the null key"));
+ } else if (taskEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on task entry " + taskEntry.getKey() + " may not be null"));
+ } else {
+ if (!taskEntry.getKey().equals(taskEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(),
+ ValidationResult.INVALID, "key on task entry key " + taskEntry.getKey()
+ + " does not equal task value key " + taskEntry.getValue().getKey()));
+ }
+
+ result = taskEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxTask> taskEntry : taskMap.entrySet()) {
+ taskEntry.getKey().clean();
+ taskEntry.getValue().clean();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",taskMap=");
+ builder.append(taskMap);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept targetObject) {
+ Assertions.argumentNotNull(targetObject, "target may not be null");
+
+ final Object copyObject = targetObject;
+ Assertions.instanceOf(copyObject, AxTasks.class);
+
+ final AxTasks copy = ((AxTasks) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+
+ final Map<AxArtifactKey, AxTask> newTaskMap = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxTask> taskMapEntry : taskMap.entrySet()) {
+ newTaskMap.put(new AxArtifactKey(taskMapEntry.getKey()), new AxTask(taskMapEntry.getValue()));
+ }
+ copy.setTaskMap(newTaskMap);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + taskMap.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxTasks other = (AxTasks) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return taskMap.equals(other.taskMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxTasks other = (AxTasks) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!taskMap.equals(other.taskMap)) {
+ return (taskMap.hashCode() - other.taskMap.hashCode());
+ }
+
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#get(org.onap.policy.apex.
+ * model. basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public AxTask get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).get(conceptKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#get(java.lang.String)
+ */
+ @Override
+ public AxTask get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).get(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#get(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public AxTask get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String)
+ */
+ @Override
+ public Set<AxTask> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).getAll(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public Set<AxTask> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxTask>) taskMap).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java
new file mode 100644
index 000000000..3b0d53f9c
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+
+/**
+ * This exception is raised if an error occurs in an Apex policy or in Apex policy handling.
+ *
+ * @author Liam Fallon
+ */
+public class PolicyException extends ApexException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex policy exception with a message.
+ *
+ * @param message the message
+ */
+ public PolicyException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex policy exception with a message and a caused by exception.
+ *
+ * @param message the message
+ * @param e the exception that caused this exception to be thrown
+ */
+ public PolicyException(final String message, final Exception e) {
+ super(message, e);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java
new file mode 100644
index 000000000..dbd2fb64f
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/PolicyRuntimeException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
+
+/**
+ * This exception is raised if a runtime error occurs in an Apex policy or in Apex policy handling.
+ *
+ * @author Liam Fallon
+ */
+public class PolicyRuntimeException extends ApexRuntimeException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex policy runtime exception with a message.
+ *
+ * @param message the message
+ */
+ public PolicyRuntimeException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex policy runtime exception with a message and a caused by exception.
+ *
+ * @param message the message
+ * @param e the exception that caused this exception to be thrown
+ */
+ public PolicyRuntimeException(final String message, final Exception e) {
+ super(message, e);
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java
new file mode 100644
index 000000000..cc15a6af5
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/concepts/package-info.java
@@ -0,0 +1,35 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * Contains the concepts required to specify policies and tasks in APEX. It defines the main Apex
+ * concepts of policies and tasks.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+@XmlSchema(namespace = "http://www.onap.org/policy/apex-pdp", elementFormDefault = XmlNsForm.QUALIFIED,
+ xmlns = {@XmlNs(namespaceURI = "http://www.onap.org/policy/apex-pdp", prefix = "")})
+
+package org.onap.policy.apex.model.policymodel.concepts;
+
+import javax.xml.bind.annotation.XmlNs;
+import javax.xml.bind.annotation.XmlNsForm;
+import javax.xml.bind.annotation.XmlSchema;
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java
new file mode 100644
index 000000000..99058484b
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalyser.java
@@ -0,0 +1,186 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
+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.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class analyses a policy model and shows what the usage of each context album, context item, data type, and event is.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyAnalyser {
+ /**
+ * Perform an analysis on a policy model.
+ *
+ * @param policyModel The policy model
+ * @return the analysis result of the policy model
+ */
+ public PolicyAnalysisResult analyse(final AxPolicyModel policyModel) {
+ Assertions.argumentNotNull(policyModel, "policyModel may not be null");
+
+ final PolicyAnalysisResult result = new PolicyAnalysisResult(policyModel);
+
+ for (final AxPolicy policy : policyModel.getPolicies().getPolicyMap().values()) {
+ for (final AxState state : policy.getStateMap().values()) {
+ analyseState(state, result);
+ }
+ }
+
+ for (final AxTask task : policyModel.getTasks().getTaskMap().values()) {
+ analyseTask(task, result);
+ }
+
+ for (final AxEvent event : policyModel.getEvents().getEventMap().values()) {
+ analyseEvent(event, result);
+ }
+
+ for (final AxContextAlbum contextAlbum : policyModel.getAlbums().getAll(null)) {
+ result.getContextSchemaUsage().get(contextAlbum.getItemSchema()).add(contextAlbum.getKey());
+ }
+
+ return result;
+ }
+
+ /**
+ * Perform an analysis on a single policy in a policy model.
+ *
+ * @param policyModel The policy model
+ * @param policy The policy
+ * @return the analysis result of the policy model
+ */
+ public PolicyAnalysisResult analyse(final AxPolicyModel policyModel, final AxPolicy policy) {
+ Assertions.argumentNotNull(policyModel, "policyModel may not be null");
+ Assertions.argumentNotNull(policy, "policy may not be null");
+
+ final PolicyAnalysisResult result = new PolicyAnalysisResult(policyModel);
+
+ for (final AxState state : policy.getStateMap().values()) {
+ analyseState(state, result);
+ }
+
+ // Only analyse tasks used by this policy
+ for (final Entry<AxArtifactKey, Set<AxKey>> taskUsageEntry : result.getTaskUsage().entrySet()) {
+ // If the usage set is empty, then we skip the task as its not used in the policy
+ if (!taskUsageEntry.getValue().isEmpty()) {
+ analyseTask(policyModel.getTasks().getTaskMap().get(taskUsageEntry.getKey()), result);
+ }
+ }
+
+ // Only analyse events used by this policy, same approach as for tasks
+ for (final Entry<AxArtifactKey, Set<AxKey>> eventUsageEntry : result.getEventUsage().entrySet()) {
+ if (!eventUsageEntry.getValue().isEmpty()) {
+ analyseEvent(policyModel.getEvents().getEventMap().get(eventUsageEntry.getKey()), result);
+ }
+ }
+
+ // Only analyse context albums used by this policy, same approach as for tasks
+ for (final Entry<AxArtifactKey, Set<AxKey>> contextAlbumUsageEntry : result.getContextAlbumUsage().entrySet()) {
+ if (!contextAlbumUsageEntry.getValue().isEmpty()) {
+ final AxContextAlbum contextAlbum = policyModel.getAlbums().get(contextAlbumUsageEntry.getKey());
+ result.getContextSchemaUsage().get(contextAlbum.getItemSchema()).add(contextAlbum.getKey());
+ }
+ }
+
+ for (final AxEvent event : policyModel.getEvents().getEventMap().values()) {
+ analyseEvent(event, result);
+ }
+
+ for (final AxContextAlbum contextAlbum : policyModel.getAlbums().getAll(null)) {
+ result.getContextSchemaUsage().get(contextAlbum.getItemSchema()).add(contextAlbum.getKey());
+ }
+
+ return result;
+ }
+
+ /**
+ * Analyse the usage of concepts by a state.
+ *
+ * @param state the state to analyse
+ * @param result the result
+ */
+ private void analyseState(final AxState state, final PolicyAnalysisResult result) {
+ // Event usage by state
+ result.getEventUsage().get(state.getTrigger()).add(state.getKey());
+ for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
+ result.getEventUsage().get(stateOutput.getOutgingEvent()).add(state.getKey());
+ }
+
+ // State Context Usage
+ for (final AxArtifactKey contextAlbumKey : state.getContextAlbumReferences()) {
+ result.getContextAlbumUsage().get(contextAlbumKey).add(state.getKey());
+ }
+
+ // Task usage by state
+ for (final AxArtifactKey task : state.getTaskReferences().keySet()) {
+ result.getTaskUsage().get(task).add(state.getKey());
+ }
+ }
+
+ /**
+ * Analyse the usage of concepts by a task.
+ *
+ * @param task the task to analyse
+ * @param result the result
+ */
+ private void analyseTask(final AxTask task, final PolicyAnalysisResult result) {
+ // Task Context Usage
+ for (final AxArtifactKey contextAlbumKey : task.getContextAlbumReferences()) {
+ result.getContextAlbumUsage().get(contextAlbumKey).add(task.getKey());
+ }
+
+ // Task data type usage
+ for (final AxInputField inputField : task.getInputFields().values()) {
+ result.getContextSchemaUsage().get(inputField.getSchema()).add(task.getKey());
+ }
+ for (final AxOutputField outputField : task.getOutputFields().values()) {
+ result.getContextSchemaUsage().get(outputField.getSchema()).add(task.getKey());
+ }
+ }
+
+ /**
+ * Analyse the usage of concepts by an event.
+ *
+ * @param event the event to analyse
+ * @param result the result of the analysis
+ */
+ private void analyseEvent(final AxEvent event, final PolicyAnalysisResult result) {
+ // Event data type usage
+ for (final AxField eventField : event.getFields()) {
+ result.getContextSchemaUsage().get(eventField.getSchema()).add(event.getKey());
+ }
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java
new file mode 100644
index 000000000..d59af7cba
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyAnalysisResult.java
@@ -0,0 +1,266 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+/**
+ * This class finds and holds the usage of context schemas, context albums, events, and tasks by the policies in a policy model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyAnalysisResult {
+ // Usage of context schemas
+ private final Map<AxArtifactKey, Set<AxKey>> contextSchemaUsage = new TreeMap<>();
+
+ // Usage of context maps
+ private final Map<AxArtifactKey, Set<AxKey>> contextAlbumUsage = new TreeMap<>();
+
+ // Usage of events
+ private final Map<AxArtifactKey, Set<AxKey>> eventUsage = new TreeMap<>();
+
+ // Usage of tasks
+ private final Map<AxArtifactKey, Set<AxKey>> taskUsage = new TreeMap<>();
+
+ /**
+ * This constructor creates a {@link PolicyAnalysisResult} instance that holds maps that contain the usage of context schemas, contxt albums, events, and
+ * tasks by all policies in a policy model.
+ *
+ * @param policyModel the policy model to analyse
+ */
+ public PolicyAnalysisResult(final AxPolicyModel policyModel) {
+ for (final AxArtifactKey contextSchemaKey : policyModel.getSchemas().getSchemasMap().keySet()) {
+ contextSchemaUsage.put(contextSchemaKey, new TreeSet<AxKey>());
+ }
+
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : policyModel.getAlbums().getAlbumsMap().entrySet()) {
+ contextAlbumUsage.put(contextAlbumEntry.getKey(), new TreeSet<AxKey>());
+ }
+
+ for (final AxArtifactKey eventKey : policyModel.getEvents().getEventMap().keySet()) {
+ eventUsage.put(eventKey, new TreeSet<AxKey>());
+ }
+
+ for (final AxArtifactKey taskKey : policyModel.getTasks().getTaskMap().keySet()) {
+ taskUsage.put(taskKey, new TreeSet<AxKey>());
+ }
+ }
+
+ /**
+ * Gets the context schemas used by policies in the policy model.
+ *
+ * @return the context schemas used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getContextSchemaUsage() {
+ return contextSchemaUsage;
+ }
+
+ /**
+ * Gets the context albums used by policies in the policy model.
+ *
+ * @return the context albums used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getContextAlbumUsage() {
+ return contextAlbumUsage;
+ }
+
+ /**
+ * Gets the events used by policies in the policy model.
+ *
+ * @return the events used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getEventUsage() {
+ return eventUsage;
+ }
+
+ /**
+ * Gets the tasks used by policies in the policy model.
+ *
+ * @return the tasks used by policies in the policy model
+ */
+ public Map<AxArtifactKey, Set<AxKey>> getTaskUsage() {
+ return taskUsage;
+ }
+
+ /**
+ * Gets the context schemas used by policies in the policy model.
+ *
+ * @return the context schemas used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedContextSchemas() {
+ return getUsedKeySet(contextSchemaUsage);
+ }
+
+ /**
+ * Gets the context albums used by policies in the policy model.
+ *
+ * @return the context albums used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedContextAlbums() {
+ return getUsedKeySet(contextAlbumUsage);
+ }
+
+ /**
+ * Gets the events used by policies in the policy model.
+ *
+ * @return the events used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedEvents() {
+ return getUsedKeySet(eventUsage);
+ }
+
+ /**
+ * Gets the tasks used by policies in the policy model.
+ *
+ * @return the tasks used by policies in the policy model
+ */
+ public Set<AxArtifactKey> getUsedTasks() {
+ return getUsedKeySet(taskUsage);
+ }
+
+ /**
+ * Gets the context schemas in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused context schemas
+ */
+ public Set<AxArtifactKey> getUnusedContextSchemas() {
+ return getUnusedKeySet(contextSchemaUsage);
+ }
+
+ /**
+ * Gets the context albums in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused context albums
+ */
+ public Set<AxArtifactKey> getUnusedContextAlbums() {
+ return getUnusedKeySet(contextAlbumUsage);
+ }
+
+ /**
+ * Gets the events in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused events
+ */
+ public Set<AxArtifactKey> getUnusedEvents() {
+ return getUnusedKeySet(eventUsage);
+ }
+
+ /**
+ * Gets the tasks in the policy model that were not used by any policies in the policy model.
+ *
+ * @return the unused tasks
+ */
+ public Set<AxArtifactKey> getUnusedTasks() {
+ return getUnusedKeySet(taskUsage);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append(getUsageMapString("Context Schema usage", contextSchemaUsage));
+ builder.append(getUsageMapString("Context Album usage", contextAlbumUsage));
+ builder.append(getUsageMapString("Event usage", eventUsage));
+ builder.append(getUsageMapString("Task usage", taskUsage));
+
+ return builder.toString();
+ }
+
+ /**
+ * Gets the usage map string.
+ *
+ * @param header the header
+ * @param usageMap the usage map
+ * @return the usage map string
+ */
+ private String getUsageMapString(final String header, final Map<? extends AxKey, Set<AxKey>> usageMap) {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append(header);
+ builder.append('\n');
+ for (final Entry<? extends AxKey, Set<AxKey>> usageEntry : usageMap.entrySet()) {
+ builder.append(" ");
+ builder.append(usageEntry.getKey().getID());
+ if (usageEntry.getValue().isEmpty()) {
+ builder.append(" (unused)\n");
+ continue;
+ }
+
+ builder.append('\n');
+ for (final AxKey usageKey : usageEntry.getValue()) {
+ builder.append(" ");
+ builder.append(usageKey.getID());
+ builder.append("\n");
+ }
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Gets the used key set.
+ *
+ * @param usageMap the usage map
+ * @return the used key set
+ */
+ private Set<AxArtifactKey> getUsedKeySet(final Map<AxArtifactKey, Set<AxKey>> usageMap) {
+ final Set<AxArtifactKey> usedKeySet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, Set<AxKey>> usageEntry : usageMap.entrySet()) {
+ if (!usageEntry.getValue().isEmpty()) {
+ usedKeySet.add(usageEntry.getKey());
+ }
+ }
+
+ return usedKeySet;
+ }
+
+ /**
+ * Gets the unused key set.
+ *
+ * @param usageMap the usage map
+ * @return the unused key set
+ */
+ private Set<AxArtifactKey> getUnusedKeySet(final Map<AxArtifactKey, Set<AxKey>> usageMap) {
+ final Set<AxArtifactKey> usedKeySet = new TreeSet<>();
+
+ for (final Entry<AxArtifactKey, Set<AxKey>> usageEntry : usageMap.entrySet()) {
+ if (usageEntry.getValue().isEmpty()) {
+ usedKeySet.add(usageEntry.getKey());
+ }
+ }
+
+ return usedKeySet;
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java
new file mode 100644
index 000000000..5a947c596
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyComparer.java
@@ -0,0 +1,46 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicies;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * This class compares the policies in two {@link AxPolicies} objects and returns the differences.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyComparer {
+ /**
+ * Compare two {@link AxPolicies} objects, comparing their policy maps one after another.
+ *
+ * @param left the left policies
+ * @param right the right policies
+ * @return the difference
+ */
+ public KeyedMapDifference<AxArtifactKey, AxPolicy> compare(final AxPolicies left, final AxPolicies right) {
+ // Find the difference between the AxPolicy objects
+ return new KeyedMapComparer<AxArtifactKey, AxPolicy>().compareMaps(left.getPolicyMap(), right.getPolicyMap());
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.java
new file mode 100644
index 000000000..3e5571242
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyLogicReader.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.model.policymodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogicReader;
+import org.onap.policy.apex.model.policymodel.concepts.PolicyRuntimeException;
+import org.onap.policy.apex.model.utilities.ResourceUtils;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to read Task Logic and Task Selection Logic from files into a string. A
+ * {@link PolicyLogicReader} can then be used to provide the logic on a {@link AxLogic} class
+ * constructor.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyLogicReader implements AxLogicReader {
+ private static final String DOT_JAVA = ".java.";
+
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelSplitter.class);
+
+ // The path of the logic package
+ private String logicPackage = "";
+
+ // Flag indicating if default logic should be returned
+ private String defaultLogic;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#getLogicPackage()
+ */
+ @Override
+ public String getLogicPackage() {
+ return logicPackage;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#setLogicPackage(java.lang.
+ * String)
+ */
+ @Override
+ public AxLogicReader setLogicPackage(final String incomingLogicPackage) {
+ this.logicPackage = incomingLogicPackage;
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#getDefaultLogic()
+ */
+ @Override
+ public String getDefaultLogic() {
+ return defaultLogic;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#setDefaultLogic(boolean)
+ */
+ @Override
+ public AxLogicReader setDefaultLogic(final String incomingDefaultLogic) {
+ this.defaultLogic = incomingDefaultLogic;
+ return this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#readLogic(.policymodel.concepts
+ * .AxLogic)
+ */
+ @Override
+ public String readLogic(final AxLogic axLogic) {
+ // Java uses compiled logic, other executor types run scripts
+ if (axLogic.getLogicFlavour().equals("JAVA")) {
+ // Check if we're using the default logic
+ if (defaultLogic != null) {
+ // Return the java class name for the default logic
+ return logicPackage + DOT_JAVA + defaultLogic;
+ } else {
+ // Return the java class name for the logic
+ if (axLogic.getKey().getParentLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ return logicPackage + DOT_JAVA + axLogic.getKey().getParentKeyName() + '_'
+ + axLogic.getKey().getLocalName();
+ } else {
+ return logicPackage + DOT_JAVA + axLogic.getKey().getParentKeyName() + '_'
+ + axLogic.getKey().getParentLocalName() + '_' + axLogic.getKey().getLocalName();
+ }
+ }
+ }
+ // Now, we read in the script
+
+ // Get the package name of the current package and convert dots to slashes for the file path
+ String fullLogicFilePath = logicPackage.replaceAll("\\.", "/");
+
+ // Now, the logic should be in a sub directory for the logic executor type
+ fullLogicFilePath += "/" + axLogic.getLogicFlavour().toLowerCase();
+
+ // Check if we're using the default logic
+ if (defaultLogic != null) {
+ // Default logic
+ fullLogicFilePath += "/" + defaultLogic;
+ } else {
+ if (axLogic.getKey().getParentLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ fullLogicFilePath += "/" + axLogic.getKey().getParentKeyName() + "_" + axLogic.getKey().getLocalName();
+ } else {
+ fullLogicFilePath += "/" + axLogic.getKey().getParentKeyName() + "_"
+ + axLogic.getKey().getParentLocalName() + "_" + axLogic.getKey().getLocalName();
+ }
+ }
+
+ // Now get the type of executor to find the extension of the file
+ fullLogicFilePath += "." + axLogic.getLogicFlavour().toLowerCase();
+
+ final String logicString = ResourceUtils.getResourceAsString(fullLogicFilePath);
+
+ // Check if the logic was found
+ if (logicString == null || logicString.length() == 0) {
+ LOGGER.warn("logic not found for logic \"" + fullLogicFilePath + "\"");
+ throw new PolicyRuntimeException("logic not found for logic \"" + fullLogicFilePath + "\"");
+ }
+
+ // Return the right trimmed logic string
+ return logicString.replaceAll("\\s+$", "");
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java
new file mode 100644
index 000000000..545a02e89
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelComparer.java
@@ -0,0 +1,271 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+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.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxTask;
+import org.onap.policy.apex.model.utilities.comparison.KeyComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyDifference;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * This class compares two policy models {@link AxPolicyModel} and holds the result of that
+ * comparison. It compares policy models on their keys, their context schema differences, their
+ * event differences, their context album differences, their task differences, their policy
+ * differences, and their key information differences.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PolicyModelComparer {
+ // Comparison of policy model keys
+ private final KeyDifference<AxArtifactKey> policyModelsKeyDifference;
+
+ // Comparison of context schemas
+ private final KeyDifference<AxArtifactKey> contextSchemasKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxContextSchema> contextSchemaComparisonResult =
+ new KeyedMapDifference<>();
+
+ // Comparison of events
+ private final KeyDifference<AxArtifactKey> eventsKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxEvent> eventComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of context albums
+ private final KeyDifference<AxArtifactKey> contextAlbumKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxContextAlbum> contextAlbumComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of tasks
+ private final KeyDifference<AxArtifactKey> tasksKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxTask> taskComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of policies
+ private final KeyDifference<AxArtifactKey> policiesKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxPolicy> policyComparisonResult = new KeyedMapDifference<>();
+
+ // Comparison of key information
+ private final KeyDifference<AxArtifactKey> keyInformationKeyDifference;
+ private KeyedMapDifference<AxArtifactKey, AxKeyInfo> keyInfoComparisonResult = new KeyedMapDifference<>();
+
+ /**
+ * The Constructor.
+ *
+ * @param left the left
+ * @param right the right
+ */
+ public PolicyModelComparer(final AxPolicyModel left, final AxPolicyModel right) {
+ // @formatter:off
+ policyModelsKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ contextSchemasKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ eventsKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ contextAlbumKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ tasksKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ policiesKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+ keyInformationKeyDifference = new KeyComparer<AxArtifactKey>().compareKeys(left.getKey(), right.getKey());
+
+ contextSchemaComparisonResult = new KeyedMapComparer<AxArtifactKey, AxContextSchema>().compareMaps(
+ left.getSchemas().getSchemasMap(), right.getSchemas().getSchemasMap());
+ eventComparisonResult = new KeyedMapComparer<AxArtifactKey, AxEvent>().compareMaps(
+ left.getEvents().getEventMap(), right.getEvents().getEventMap());
+ contextAlbumComparisonResult = new KeyedMapComparer<AxArtifactKey, AxContextAlbum>().compareMaps(
+ left.getAlbums().getAlbumsMap(), right.getAlbums().getAlbumsMap());
+ taskComparisonResult = new KeyedMapComparer<AxArtifactKey, AxTask>().compareMaps(left.getTasks().getTaskMap(), right.getTasks().getTaskMap());
+ policyComparisonResult = new KeyedMapComparer<AxArtifactKey, AxPolicy>().compareMaps(
+ left.getPolicies().getPolicyMap(), right.getPolicies().getPolicyMap());
+ keyInfoComparisonResult = new KeyedMapComparer<AxArtifactKey, AxKeyInfo>().compareMaps(
+ left.getKeyInformation().getKeyInfoMap(), right.getKeyInformation().getKeyInfoMap());
+ // @formatter:on
+ }
+
+ /**
+ * Gets the difference between policy model keys on the two models.
+ *
+ * @return the difference between policy model keys
+ */
+ public KeyDifference<AxArtifactKey> getPolicyModelsKeyDifference() {
+ return policyModelsKeyDifference;
+ }
+
+ /**
+ * Gets the difference between context schema keys on the two models.
+ *
+ * @return the difference between context schema keys
+ */
+ public KeyDifference<AxArtifactKey> getContextSchemaKeyDifference() {
+ return contextSchemasKeyDifference;
+ }
+
+ /**
+ * Gets the difference between context schemas on the two models.
+ *
+ * @return the difference between context schemas
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextSchema> getContextSchemaComparisonResult() {
+ return contextSchemaComparisonResult;
+ }
+
+ /**
+ * Gets the difference between event keys on the two models.
+ *
+ * @return the difference between event keys
+ */
+ public KeyDifference<AxArtifactKey> getEventKeyDifference() {
+ return eventsKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the events on the two models.
+ *
+ * @return the difference between the events
+ */
+ public KeyedMapDifference<AxArtifactKey, AxEvent> getEventComparisonResult() {
+ return eventComparisonResult;
+ }
+
+ /**
+ * Gets the difference between context album keys on the two models.
+ *
+ * @return the difference between context album keys
+ */
+ public KeyDifference<AxArtifactKey> getContextAlbumKeyDifference() {
+ return contextAlbumKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the context albums on the two models.
+ *
+ * @return the difference between the context albums
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextAlbum> getContextAlbumComparisonResult() {
+ return contextAlbumComparisonResult;
+ }
+
+ /**
+ * Gets the difference between task keys on the two models.
+ *
+ * @return the difference between task keys
+ */
+ public KeyDifference<AxArtifactKey> getTaskKeyDifference() {
+ return tasksKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the tasks on the two models.
+ *
+ * @return the difference between the tasks
+ */
+ public KeyedMapDifference<AxArtifactKey, AxTask> getTaskComparisonResult() {
+ return taskComparisonResult;
+ }
+
+ /**
+ * Gets the difference between policy keys on the two models.
+ *
+ * @return the difference between policy keys
+ */
+ public KeyDifference<AxArtifactKey> getPolicykeyDifference() {
+ return policiesKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the policies on the two models.
+ *
+ * @return the difference between the policies
+ */
+ public KeyedMapDifference<AxArtifactKey, AxPolicy> getPolicyComparisonResult() {
+ return policyComparisonResult;
+ }
+
+ /**
+ * Gets the difference between key information keys on the two models.
+ *
+ * @return the difference between key information keys
+ */
+ public KeyDifference<AxArtifactKey> getKeyInformationKeyDifference() {
+ return keyInformationKeyDifference;
+ }
+
+ /**
+ * Gets the difference between the key information on the two models.
+ *
+ * @return the difference between the key information
+ */
+ public KeyedMapDifference<AxArtifactKey, AxKeyInfo> getKeyInfoComparisonResult() {
+ return keyInfoComparisonResult;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return asString(true, true);
+ }
+
+ /**
+ * As string.
+ *
+ * @param diffsOnly the diffs only
+ * @param keysOnly the keys only
+ * @return the string
+ */
+ public String asString(final boolean diffsOnly, final boolean keysOnly) {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append("****** policy map differences ******\n");
+ builder.append(policyModelsKeyDifference.asString(diffsOnly));
+
+ builder.append("*** context schema differences ***\n");
+ builder.append(contextSchemasKeyDifference.asString(diffsOnly));
+ builder.append(contextSchemaComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** event differences ***\n");
+ builder.append(eventsKeyDifference.asString(diffsOnly));
+ builder.append(eventComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** context album differences ***\n");
+ builder.append(contextAlbumKeyDifference.asString(diffsOnly));
+ builder.append(contextAlbumComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** task differences ***\n");
+ builder.append(tasksKeyDifference.asString(diffsOnly));
+ builder.append(taskComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** policy differences ***\n");
+ builder.append(policiesKeyDifference.asString(diffsOnly));
+ builder.append(policyComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("*** key information differences ***\n");
+ builder.append(keyInformationKeyDifference.asString(diffsOnly));
+ builder.append(keyInfoComparisonResult.asString(diffsOnly, keysOnly));
+
+ builder.append("***********************************\n");
+
+ return builder.toString();
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java
new file mode 100644
index 000000000..091f20462
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelMerger.java
@@ -0,0 +1,155 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Helper class used to merge information from two policy models together into a single policy
+ * model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class PolicyModelMerger {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelMerger.class);
+
+ /**
+ * Private constructor used to prevent sub class instantiation.
+ */
+ private PolicyModelMerger() {}
+
+ /**
+ * Get a merged policy model with information from two policy models merged into a larger policy
+ * model.
+ *
+ * @param leftPolicyModel the source Apex Model
+ * @param rightPolicyModel the policies to include in sub policy model
+ * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common
+ * keys are found, if false it uses the concepts from the right model
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
+ final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches) throws ApexModelException {
+ return getMergedPolicyModel(leftPolicyModel, rightPolicyModel, useLeftOnMatches, false);
+ }
+
+ /**
+ * Get a merged policy model with information from two policy models merged into a larger policy
+ * model.
+ *
+ * @param leftPolicyModel the source Apex Model
+ * @param rightPolicyModel the policies to include in sub policy model
+ * @param useLeftOnMatches if true, uses concepts from the left model if concepts with common
+ * keys are found, if false it uses the concepts from the right model
+ * @param ignoreInvalidSource Ignore errors on the source model, do the best you can
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getMergedPolicyModel(final AxPolicyModel leftPolicyModel,
+ final AxPolicyModel rightPolicyModel, final boolean useLeftOnMatches, final boolean ignoreInvalidSource)
+ throws ApexModelException {
+ // Validate the left model
+ if (!ignoreInvalidSource) {
+ final AxValidationResult leftValidationResult = new AxValidationResult();
+ leftPolicyModel.validate(leftValidationResult);
+ if (!leftValidationResult.isValid()) {
+ LOGGER.warn("left model is invalid: " + leftValidationResult.toString());
+ throw new ApexModelException("left model is invalid: " + leftValidationResult.toString());
+ }
+ }
+
+ // Validate the right model
+ if (!ignoreInvalidSource) {
+ final AxValidationResult rightValidationResult = new AxValidationResult();
+ rightPolicyModel.validate(rightValidationResult);
+ if (!rightValidationResult.isValid()) {
+ LOGGER.warn("right model is invalid: " + rightValidationResult.toString());
+ throw new ApexModelException("right model is invalid: " + rightValidationResult.toString());
+ }
+ }
+
+ // The new policy model uses the favoured copy side as its base
+ final AxPolicyModel mergedPolicyModel = (AxPolicyModel) (useLeftOnMatches ? new AxPolicyModel(leftPolicyModel)
+ : new AxPolicyModel(rightPolicyModel));
+
+ // The Compared to policy model is the unfavoured side
+ final AxPolicyModel copyFromPolicyModel = (useLeftOnMatches ? rightPolicyModel : leftPolicyModel);
+
+ //  Get the keys to copy over
+ final Set<AxArtifactKey> copyOverKeyInfoKeys =
+ new TreeSet<>(copyFromPolicyModel.getKeyInformation().getKeyInfoMap().keySet());
+ final Set<AxArtifactKey> copyOverContextSchemaKeys =
+ new TreeSet<>(copyFromPolicyModel.getSchemas().getSchemasMap().keySet());
+ final Set<AxArtifactKey> copyOverEventKeys =
+ new TreeSet<>(copyFromPolicyModel.getEvents().getEventMap().keySet());
+ final Set<AxArtifactKey> copyOverContextAlbumKeys =
+ new TreeSet<>(copyFromPolicyModel.getAlbums().getAlbumsMap().keySet());
+ final Set<AxArtifactKey> copyOverTaskKeys = new TreeSet<>(copyFromPolicyModel.getTasks().getTaskMap().keySet());
+ final Set<AxArtifactKey> copyOverPolicyKeys =
+ new TreeSet<>(copyFromPolicyModel.getPolicies().getPolicyMap().keySet());
+
+ //  Remove keys that already exist
+ copyOverKeyInfoKeys.removeAll(mergedPolicyModel.getKeyInformation().getKeyInfoMap().keySet());
+ copyOverContextSchemaKeys.removeAll(mergedPolicyModel.getSchemas().getSchemasMap().keySet());
+ copyOverEventKeys.removeAll(mergedPolicyModel.getEvents().getEventMap().keySet());
+ copyOverContextAlbumKeys.removeAll(mergedPolicyModel.getAlbums().getAlbumsMap().keySet());
+ copyOverTaskKeys.removeAll(mergedPolicyModel.getTasks().getTaskMap().keySet());
+ copyOverPolicyKeys.removeAll(mergedPolicyModel.getPolicies().getPolicyMap().keySet());
+
+ // Now add all the concepts that must be copied over
+ for (final AxArtifactKey keyInfoKey : copyOverKeyInfoKeys) {
+ mergedPolicyModel.getKeyInformation().getKeyInfoMap().put(keyInfoKey,
+ copyFromPolicyModel.getKeyInformation().getKeyInfoMap().get(keyInfoKey));
+ }
+ for (final AxArtifactKey contextSchemaKey : copyOverContextSchemaKeys) {
+ mergedPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
+ copyFromPolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
+ }
+ for (final AxArtifactKey eventKey : copyOverEventKeys) {
+ mergedPolicyModel.getEvents().getEventMap().put(eventKey,
+ copyFromPolicyModel.getEvents().getEventMap().get(eventKey));
+ }
+ for (final AxArtifactKey contextAlbumKey : copyOverContextAlbumKeys) {
+ mergedPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
+ copyFromPolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
+ }
+ for (final AxArtifactKey taskKey : copyOverTaskKeys) {
+ mergedPolicyModel.getTasks().getTaskMap().put(taskKey,
+ copyFromPolicyModel.getTasks().getTaskMap().get(taskKey));
+ }
+ for (final AxArtifactKey policyKey : copyOverPolicyKeys) {
+ mergedPolicyModel.getPolicies().getPolicyMap().put(policyKey,
+ copyFromPolicyModel.getPolicies().getPolicyMap().get(policyKey));
+ }
+
+ // That's it, return the model
+ return mergedPolicyModel;
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java
new file mode 100644
index 000000000..586d0706e
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/PolicyModelSplitter.java
@@ -0,0 +1,165 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * Helper class used to extract information from a policy model into a policy model that is a subset
+ * of the original policy model.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class PolicyModelSplitter {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyModelSplitter.class);
+
+ /**
+ * Private constructor used to prevent sub class instantiation.
+ */
+ private PolicyModelSplitter() {}
+
+ /**
+ * Get a sub policy model with only the information required for the specified policies from a
+ * larger policy model.
+ *
+ * @param sourcePolicyModel the source Apex Model
+ * @param subPolicies the policies to include in sub policy model
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getSubPolicyModel(final AxPolicyModel sourcePolicyModel,
+ final Collection<AxArtifactKey> subPolicies) throws ApexModelException {
+ return getSubPolicyModel(sourcePolicyModel, subPolicies, false);
+ }
+
+ /**
+ * Get a sub policy model with only the information required for the specified policies from a
+ * larger policy model.
+ *
+ * @param sourcePolicyModel the source Apex Model
+ * @param subPolicies the policies to include in sub policy model
+ * @param ignoreInvalidSource Ignore errors on the source model, do the best you can
+ * @return the new Destination Model
+ * @throws ApexModelException on model transfer errors
+ */
+ public static AxPolicyModel getSubPolicyModel(final AxPolicyModel sourcePolicyModel,
+ final Collection<AxArtifactKey> subPolicies, final boolean ignoreInvalidSource) throws ApexModelException {
+ // Validate the source model
+ if (!ignoreInvalidSource) {
+ final AxValidationResult sourceValidationResult = new AxValidationResult();
+ sourcePolicyModel.validate(sourceValidationResult);
+ if (!sourceValidationResult.isValid()) {
+ LOGGER.warn("source model is invalid: " + sourceValidationResult.toString());
+ throw new ApexModelException("source model is invalid: " + sourceValidationResult.toString());
+ }
+ }
+
+ // The new policy model
+ final AxPolicyModel newPolicyModel = new AxPolicyModel(sourcePolicyModel.getKey());
+ newPolicyModel.getKeyInformation().setKey(sourcePolicyModel.getKeyInformation().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getKey()));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getKeyInformation().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap()
+ .get(sourcePolicyModel.getKeyInformation().getKey()));
+
+ //  Get the events, tasks, context maps, and data types used by each policy
+ final Set<AxArtifactKey> contextSchemaSet = new TreeSet<>();
+ final Set<AxArtifactKey> eventSet = new TreeSet<>();
+ final Set<AxArtifactKey> contextAlbumSet = new TreeSet<>();
+ final Set<AxArtifactKey> taskSet = new TreeSet<>();
+
+ newPolicyModel.getPolicies().setKey(sourcePolicyModel.getPolicies().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getPolicies().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getPolicies().getKey()));
+ for (final AxArtifactKey subPolicyKey : subPolicies) {
+ final AxPolicy subPolicy = sourcePolicyModel.getPolicies().getPolicyMap().get(subPolicyKey);
+ if (subPolicy == null) {
+ LOGGER.warn("source sub policy not found: " + subPolicyKey);
+ continue;
+ }
+
+ // Transfer the policy across
+ newPolicyModel.getPolicies().getPolicyMap().put(subPolicyKey, subPolicy);
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(subPolicyKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(subPolicyKey));
+
+ // Get the references for this policy
+ final PolicyAnalysisResult analysisResult = new PolicyAnalyser().analyse(sourcePolicyModel, subPolicy);
+ contextSchemaSet.addAll(analysisResult.getUsedContextSchemas());
+ eventSet.addAll(analysisResult.getUsedEvents());
+ contextAlbumSet.addAll(analysisResult.getUsedContextAlbums());
+ taskSet.addAll(analysisResult.getUsedTasks());
+
+ }
+
+ // Now add all the referenced data types, events, context maps, and tasks to the policy
+ // model
+ newPolicyModel.getSchemas().setKey(sourcePolicyModel.getSchemas().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getSchemas().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getSchemas().getKey()));
+ for (final AxArtifactKey contextSchemaKey : contextSchemaSet) {
+ newPolicyModel.getSchemas().getSchemasMap().put(contextSchemaKey,
+ sourcePolicyModel.getSchemas().getSchemasMap().get(contextSchemaKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(contextSchemaKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(contextSchemaKey));
+ }
+ newPolicyModel.getEvents().setKey(sourcePolicyModel.getEvents().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getEvents().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getEvents().getKey()));
+ for (final AxArtifactKey eventKey : eventSet) {
+ newPolicyModel.getEvents().getEventMap().put(eventKey,
+ sourcePolicyModel.getEvents().getEventMap().get(eventKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(eventKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(eventKey));
+ }
+ newPolicyModel.getAlbums().setKey(sourcePolicyModel.getAlbums().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getAlbums().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getAlbums().getKey()));
+ for (final AxArtifactKey contextAlbumKey : contextAlbumSet) {
+ newPolicyModel.getAlbums().getAlbumsMap().put(contextAlbumKey,
+ sourcePolicyModel.getAlbums().getAlbumsMap().get(contextAlbumKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(contextAlbumKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(contextAlbumKey));
+ }
+ newPolicyModel.getTasks().setKey(sourcePolicyModel.getTasks().getKey());
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(sourcePolicyModel.getTasks().getKey(),
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(sourcePolicyModel.getTasks().getKey()));
+ for (final AxArtifactKey taskKey : taskSet) {
+ newPolicyModel.getTasks().getTaskMap().put(taskKey, sourcePolicyModel.getTasks().getTaskMap().get(taskKey));
+ newPolicyModel.getKeyInformation().getKeyInfoMap().put(taskKey,
+ sourcePolicyModel.getKeyInformation().getKeyInfoMap().get(taskKey));
+ }
+
+ // That's it, return the model
+ return newPolicyModel;
+ }
+}
diff --git a/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java
new file mode 100644
index 000000000..f84befd26
--- /dev/null
+++ b/model/policy-model/src/main/java/org/onap/policy/apex/model/policymodel/handling/package-info.java
@@ -0,0 +1,26 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * Contains utility classes used to handle APEX polcies and policy models.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.model.policymodel.handling;
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java
new file mode 100644
index 000000000..28f70f48b
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/DummyLogicReader.java
@@ -0,0 +1,84 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import org.onap.policy.apex.model.policymodel.concepts.AxLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogicReader;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class DummyLogicReader implements AxLogicReader {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#getLogicPackage()
+ */
+ @Override
+ public String getLogicPackage() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#setLogicPackage(java.lang.
+ * String)
+ */
+ @Override
+ public AxLogicReader setLogicPackage(final String logicPackage) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#getDefaultLogic()
+ */
+ @Override
+ public String getDefaultLogic() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#setDefaultLogic(java.lang.
+ * String)
+ */
+ @Override
+ public AxLogicReader setDefaultLogic(final String defaultLogic) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.model.policymodel.concepts.AxLogicReader#readLogic(org.onap.policy.apex.
+ * model.policymodel.concepts.AxLogic)
+ */
+ @Override
+ public String readLogic(final AxLogic axLogic) {
+ return "Dummy Logic";
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestExceptions.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestExceptions.java
new file mode 100644
index 000000000..9c7405b97
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestExceptions.java
@@ -0,0 +1,53 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.policymodel.concepts.PolicyException;
+import org.onap.policy.apex.model.policymodel.concepts.PolicyRuntimeException;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestExceptions {
+
+ @Test
+ public void test() {
+ assertNotNull(new PolicyException("Message"));
+ assertNotNull(new PolicyException("Message", new IOException()));
+
+ final PolicyException ae = new PolicyException("Message", new IOException("IO exception message"));
+ assertEquals("Message\ncaused by: Message\ncaused by: IO exception message", ae.getCascadedMessage());
+
+ assertNotNull(new PolicyRuntimeException("Message"));
+ assertNotNull(new PolicyRuntimeException("Message", new IOException()));
+
+ final PolicyRuntimeException re =
+ new PolicyRuntimeException("Runtime Message", new IOException("IO runtime exception message"));
+ assertEquals("Runtime Message\ncaused by: Runtime Message\ncaused by: IO runtime exception message",
+ re.getCascadedMessage());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestLogic.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestLogic.java
new file mode 100644
index 000000000..a415a1c69
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestLogic.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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+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.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestLogic {
+
+ @Test
+ public void testLogic() {
+ final DummyLogicReader logicReader = new DummyLogicReader();
+
+ assertNotNull(new AxLogic());
+ assertNotNull(new AxLogic(new AxReferenceKey()));
+ assertNotNull(new AxLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+
+ assertNotNull(new AxTaskLogic());
+ assertNotNull(new AxTaskLogic(new AxReferenceKey()));
+ assertNotNull(new AxTaskLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskLogic(new AxLogic()));
+ assertNotNull(new AxTaskLogic(new AxArtifactKey(), "LogicName", "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskLogic(new AxArtifactKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+
+ assertNotNull(new AxTaskSelectionLogic());
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey()));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskSelectionLogic(new AxLogic()));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxTaskSelectionLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", logicReader));
+
+ assertNotNull(new AxStateFinalizerLogic());
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey()));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicFlavour", "Logic"));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", "Logic"));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxStateFinalizerLogic(new AxLogic()));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicFlavour", logicReader));
+ assertNotNull(new AxStateFinalizerLogic(new AxReferenceKey(), "LogicName", "LogicFlavour", logicReader));
+
+ final AxLogic logic = new AxLogic();
+
+ final AxReferenceKey logicKey = new AxReferenceKey("LogicParentName", "0.0.1", "PLN", "LN");
+ logic.setKey(logicKey);
+ assertEquals("LogicParentName:0.0.1:PLN:LN", logic.getKey().getID());
+ assertEquals("LogicParentName:0.0.1:PLN:LN", logic.getKeys().get(0).getID());
+
+ logic.setLogicFlavour("LogicFlavour");
+ assertEquals("LogicFlavour", logic.getLogicFlavour());
+
+ logic.setLogic("Logic");
+ assertEquals("Logic", logic.getLogic());
+
+ AxValidationResult result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ logic.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ logic.setKey(logicKey);
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ try {
+ logic.setLogicFlavour(null);
+ fail("test shold throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("parameter \"logicFlavour\" is null", e.getMessage());
+ }
+
+ try {
+ logic.setLogicFlavour("");
+ fail("test shold throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "parameter \"logicFlavour\": value \"\", does not match regular expression \"[A-Za-z0-9\\-_]+\"",
+ e.getMessage());
+ }
+
+ logic.setLogicFlavour(AxLogic.LOGIC_FLAVOUR_UNDEFINED);
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ logic.setLogicFlavour("LogicFlavour");
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ try {
+ logic.setLogic(null);
+ fail("test shold throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("logic may not be null", e.getMessage());
+ }
+
+ logic.setLogic("");
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ logic.setLogic("Logic");
+ result = new AxValidationResult();
+ result = logic.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ logic.clean();
+
+ final AxLogic clonedLogic = new AxLogic(logic);
+ assertEquals(
+ "AxLogic:(key=AxReferenceKey:(parentKeyName=LogicParentName,parentKeyVersion=0.0.1,parentLocalName=PLN,localName=LN),logicFlavour=LogicFlavour,logic=Logic)",
+ clonedLogic.toString());
+
+ assertFalse(logic.hashCode() == 0);
+
+ assertTrue(logic.equals(logic));
+ assertTrue(logic.equals(clonedLogic));
+ assertFalse(logic.equals(null));
+ assertFalse(logic.equals("Hello"));
+ assertFalse(logic.equals(new AxLogic(AxReferenceKey.getNullKey(), "LogicFlavour", "Logic")));
+ assertFalse(logic.equals(new AxLogic(logicKey, "AnotherLogicFlavour", "Logic")));
+ assertFalse(logic.equals(new AxLogic(logicKey, "LogicFlavour", "AnotherLogic")));
+ assertTrue(logic.equals(new AxLogic(logicKey, "LogicFlavour", "Logic")));
+
+ assertEquals(0, logic.compareTo(logic));
+ assertEquals(0, logic.compareTo(clonedLogic));
+ assertNotEquals(0, logic.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, logic.compareTo(null));
+ assertNotEquals(0, logic.compareTo(new AxLogic(AxReferenceKey.getNullKey(), "LogicFlavour", "Logic")));
+ assertNotEquals(0, logic.compareTo(new AxLogic(logicKey, "AnotherLogicFlavour", "Logic")));
+ assertNotEquals(0, logic.compareTo(new AxLogic(logicKey, "LogicFlavour", "AnotherLogic")));
+ assertEquals(0, logic.compareTo(new AxLogic(logicKey, "LogicFlavour", "Logic")));
+
+ assertNotNull(logic.getKeys());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicies.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicies.java
new file mode 100644
index 000000000..9da944b60
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicies.java
@@ -0,0 +1,433 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+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.AxState;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTree;
+import org.onap.policy.apex.model.policymodel.handling.TestApexPolicyModelCreator;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestPolicies {
+
+ @Test
+ public void testPolicies() {
+ final TreeMap<String, AxState> stateMap = new TreeMap<>();
+ final TreeMap<String, AxState> stateMapEmpty = new TreeMap<>();
+
+ assertNotNull(new AxPolicy());
+ assertNotNull(new AxPolicy(new AxArtifactKey()));
+ assertNotNull(new AxPolicy(new AxArtifactKey(), "PolicyTemplate", stateMapEmpty, "FirstState"));
+
+ AxPolicy policy = new AxPolicy();
+
+ final AxArtifactKey policyKey = new AxArtifactKey("PolicyName", "0.0.1");
+
+ final AxState firstState = new AxState(new AxReferenceKey(policy.getKey(), "FirstState"));
+ final AxState badState = new AxState(new AxReferenceKey(policy.getKey(), "BadState"));
+ final AxStateOutput badSO = new AxStateOutput(badState.getKey(), AxArtifactKey.getNullKey(),
+ new AxReferenceKey(policyKey, "BadNextState"));
+ badState.getStateOutputs().put(badSO.getKey().getLocalName(), badSO);
+ stateMap.put(firstState.getKey().getLocalName(), firstState);
+
+ try {
+ policy.setKey(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("key may not be null", e.getMessage());
+ }
+
+ policy.setKey(policyKey);
+ assertEquals("PolicyName:0.0.1", policy.getKey().getID());
+ assertEquals("PolicyName:0.0.1", policy.getKeys().get(0).getID());
+
+ try {
+ policy.setTemplate(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("template may not be null", e.getMessage());
+ }
+
+ policy.setTemplate("PolicyTemplate");
+ assertEquals("PolicyTemplate", policy.getTemplate());
+
+ try {
+ policy.setStateMap(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("stateMap may not be null", e.getMessage());
+ }
+
+ policy.setStateMap(stateMap);
+ assertEquals(stateMap, policy.getStateMap());
+
+ try {
+ policy.setFirstState(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("firstState may not be null", e.getMessage());
+ }
+
+ policy.setFirstState("FirstState");
+ assertEquals("FirstState", policy.getFirstState());
+
+ assertEquals("PolicyName:0.0.1", policy.getKeys().get(0).getID());
+
+ policy = new TestApexPolicyModelCreator().getModel().getPolicies().get("policy");
+
+ AxValidationResult result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedPolicyKey = policy.getKey();
+ policy.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policy.setKey(savedPolicyKey);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final String savedTemplate = policy.getTemplate();
+ policy.setTemplate("");
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ policy.setTemplate(savedTemplate);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final Map<String, AxState> savedStateMap = policy.getStateMap();
+
+ policy.setStateMap(stateMapEmpty);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policy.setStateMap(savedStateMap);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put(AxKey.NULL_KEY_NAME, firstState);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove(AxKey.NULL_KEY_NAME);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put("NullState", null);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove("NullState");
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put("BadStateKey", firstState);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove("BadStateKey");
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ savedStateMap.put(badState.getKey().getLocalName(), badState);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ savedStateMap.remove(badState.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final String savedFirstState = policy.getFirstState();
+
+ policy.setFirstState("");
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policy.setFirstState(savedFirstState);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policy.setFirstState("NonExistantFirstState");
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policy.setFirstState(savedFirstState);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxState clonedState = new AxState(policy.getStateMap().get("state"));
+ clonedState.getKey().setLocalName("ClonedState");
+ clonedState.afterUnmarshal(null, null);
+
+ savedStateMap.put(clonedState.getKey().getLocalName(), clonedState);
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.WARNING, result.getValidationResult());
+
+ savedStateMap.remove(clonedState.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = policy.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policy.clean();
+
+ final AxPolicy clonedPolicy = new AxPolicy(policy);
+ assertEquals("AxPolicy:(key=AxArtifactKey:(name=policy,version=0.0.1),template=FREEFORM,sta",
+ clonedPolicy.toString().substring(0, 77));
+
+ assertFalse(policy.hashCode() == 0);
+
+ assertTrue(policy.equals(policy));
+ assertTrue(policy.equals(clonedPolicy));
+ assertFalse(policy.equals(null));
+ assertFalse(policy.equals("Hello"));
+ assertFalse(
+ policy.equals(new AxPolicy(AxArtifactKey.getNullKey(), savedTemplate, savedStateMap, savedFirstState)));
+ assertFalse(policy.equals(new AxPolicy(savedPolicyKey, "SomeTemplate", savedStateMap, savedFirstState)));
+ assertFalse(policy.equals(new AxPolicy(savedPolicyKey, savedTemplate, stateMapEmpty, savedFirstState)));
+ assertFalse(policy.equals(new AxPolicy(savedPolicyKey, savedTemplate, savedStateMap, "SomeFirstState")));
+ assertTrue(policy.equals(new AxPolicy(savedPolicyKey, savedTemplate, savedStateMap, savedFirstState)));
+
+ assertEquals(0, policy.compareTo(policy));
+ assertEquals(0, policy.compareTo(clonedPolicy));
+ assertNotEquals(0, policy.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, policy.compareTo(null));
+ assertNotEquals(0, policy
+ .compareTo(new AxPolicy(AxArtifactKey.getNullKey(), savedTemplate, savedStateMap, savedFirstState)));
+ assertNotEquals(0,
+ policy.compareTo(new AxPolicy(savedPolicyKey, "SomeTemplate", savedStateMap, savedFirstState)));
+ assertNotEquals(0,
+ policy.compareTo(new AxPolicy(savedPolicyKey, savedTemplate, stateMapEmpty, savedFirstState)));
+ assertNotEquals(0,
+ policy.compareTo(new AxPolicy(savedPolicyKey, savedTemplate, savedStateMap, "SomeFirstState")));
+ assertEquals(0, policy.compareTo(new AxPolicy(savedPolicyKey, savedTemplate, savedStateMap, savedFirstState)));
+
+ assertNotNull(policy.getKeys());
+
+ final AxPolicies policies = new AxPolicies();
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Invalid, no events in event map
+ policies.setKey(new AxArtifactKey("PoliciesKey", "0.0.1"));
+ assertEquals("PoliciesKey:0.0.1", policies.getKey().getID());
+
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(savedPolicyKey, policy);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.getPolicyMap().put(new AxArtifactKey("BadEventKey", "0.0.1"), policy);
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ policies.getPolicyMap().remove(new AxArtifactKey("BadEventKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = policies.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ policies.clean();
+ policies.afterUnmarshal(null, null);
+
+ final AxPolicies clonedPolicies = new AxPolicies(policies);
+ assertEquals("AxPolicies:(key=AxArtifactKey:(name=PoliciesKey,version=0.0.",
+ clonedPolicies.toString().substring(0, 60));
+
+ assertFalse(policies.hashCode() == 0);
+
+ assertTrue(policies.equals(policies));
+ assertTrue(policies.equals(clonedPolicies));
+ assertFalse(policies.equals(null));
+ assertFalse(policies.equals("Hello"));
+ assertFalse(policies.equals(new AxPolicies(new AxArtifactKey())));
+
+ assertEquals(0, policies.compareTo(policies));
+ assertEquals(0, policies.compareTo(clonedPolicies));
+ assertNotEquals(0, policies.compareTo(null));
+ assertNotEquals(0, policies.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, policies.compareTo(new AxPolicies(new AxArtifactKey())));
+
+ clonedPolicies.get(savedPolicyKey).setTemplate("AnotherTemplate");
+ assertNotEquals(0, policies.compareTo(clonedPolicies));
+
+ assertEquals(policies.getKey(), policies.getKeys().get(0));
+
+ assertEquals("policy", policies.get("policy").getKey().getName());
+ assertEquals("policy", policies.get("policy", "0.0.1").getKey().getName());
+ assertEquals(1, policies.getAll("policy", "0.0.1").size());
+ assertEquals(0, policies.getAll("NonExistantPolicy").size());
+
+ AxStateTree stateTree = policy.getStateTree();
+ assertNotNull(stateTree);
+ assertNotNull(stateTree.getReferencedStateList());
+ assertNotNull(stateTree.getReferencedStateSet());
+
+ final AxState secondState = new AxState(policy.getStateMap().get("state"));
+ secondState.getKey().setLocalName("SecondState");
+ secondState.afterUnmarshal(null, null);
+ policy.getStateMap().put("SecondState", secondState);
+ policy.getStateMap().get("state").getStateOutputs().get("stateOutput0").setNextState(secondState.getKey());
+
+ stateTree = policy.getStateTree();
+ assertNotNull(stateTree);
+ assertNotNull(stateTree.getReferencedStateList());
+ assertNotNull(stateTree.getReferencedStateSet());
+ assertNotNull(stateTree.getNextStates());
+
+ policy.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0")
+ .setNextState(policy.getStateMap().get("state").getKey());
+ try {
+ policy.getStateTree();
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "loop detected in state tree for policy policy:0.0.1 state SecondState, next state state referenced more than once",
+ e.getMessage());
+ }
+
+ policy.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0")
+ .setNextState(AxReferenceKey.getNullKey());
+
+ final AxState thirdState = new AxState(policy.getStateMap().get("state"));
+ thirdState.getKey().setLocalName("ThirdState");
+ thirdState.afterUnmarshal(null, null);
+ policy.getStateMap().put("ThirdState", thirdState);
+ policy.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0").setNextState(thirdState.getKey());
+ policy.getStateMap().get("ThirdState").getStateOutputs().get("stateOutput0")
+ .setNextState(AxReferenceKey.getNullKey());
+
+ stateTree = policy.getStateTree();
+
+ final AxStateOutput ssS0Clone =
+ new AxStateOutput(policy.getStateMap().get("SecondState").getStateOutputs().get("stateOutput0"));
+ ssS0Clone.getKey().setLocalName("ssS0Clone");
+ policy.getStateMap().get("SecondState").getStateOutputs().put("ssS0Clone", ssS0Clone);
+
+ try {
+ policy.getStateTree();
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "loop detected in state tree for policy policy:0.0.1 state SecondState, next state ThirdState referenced more than once",
+ e.getMessage());
+ }
+
+ policy.getStateMap().get("SecondState").getStateOutputs().remove("ssS0Clone");
+
+ policy.getStateMap().get("state").getStateOutputs().get("stateOutput0").setNextState(secondState.getKey());
+ secondState.getStateOutputs().get("stateOutput0").setNextState(thirdState.getKey());
+ thirdState.getStateOutputs().get("stateOutput0").setNextState(AxReferenceKey.getNullKey());
+
+ stateTree = policy.getStateTree();
+ assertNotNull(stateTree.getState());
+
+ thirdState.getStateOutputs().get("stateOutput0").setNextState(secondState.getKey());
+
+ try {
+ policy.getStateTree();
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "loop detected in state tree for policy policy:0.0.1 state ThirdState, next state SecondState referenced more than once",
+ e.getMessage());
+ }
+
+ thirdState.getStateOutputs().get("stateOutput0").setNextState(AxReferenceKey.getNullKey());
+
+ stateTree = policy.getStateTree();
+
+ final AxStateTree otherStateTree = policy.getStateTree();
+ assertEquals(0, stateTree.compareTo(otherStateTree));
+
+ for (final AxStateTree childStateTree : stateTree.getNextStates()) {
+ assertNotEquals(0, stateTree.compareTo(childStateTree));
+ }
+
+ otherStateTree.getNextStates().clear();
+ assertNotEquals(0, stateTree.compareTo(otherStateTree));
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicyModel.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicyModel.java
new file mode 100644
index 000000000..db1d1ee62
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestPolicyModel.java
@@ -0,0 +1,357 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicies;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxTasks;
+import org.onap.policy.apex.model.policymodel.handling.TestApexPolicyModelCreator;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestPolicyModel {
+
+ @Test
+ public void testPolicyModel() {
+ assertNotNull(new AxPolicyModel());
+ assertNotNull(new AxPolicyModel(new AxArtifactKey()));
+ assertNotNull(new AxPolicyModel(new AxArtifactKey(), new AxContextSchemas(), new AxKeyInformation(),
+ new AxEvents(), new AxContextAlbums(), new AxTasks(), new AxPolicies()));
+
+ final AxArtifactKey modelKey = new AxArtifactKey("ModelKey", "0.0.1");
+ final AxArtifactKey schemasKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey eventsKey = new AxArtifactKey("EventsKey", "0.0.1");
+ final AxArtifactKey keyInfoKey = new AxArtifactKey("SchemasKey", "0.0.1");
+ final AxArtifactKey albumsKey = new AxArtifactKey("AlbumsKey", "0.0.1");
+ final AxArtifactKey tasksKey = new AxArtifactKey("TasksKey", "0.0.1");
+ final AxArtifactKey policiesKey = new AxArtifactKey("PoliciesKey", "0.0.1");
+
+ AxPolicyModel model = new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey));
+
+ model.register();
+
+ assertNotNull(model.getContextModel());
+ assertEquals("ModelKey:0.0.1", model.getKeys().get(0).getID());
+
+ model.clean();
+ assertNotNull(model);
+ assertEquals("AxPolicyModel:(AxPolicyModel:(key=AxArtifactKey:(n", model.toString().substring(0, 50));
+
+ final AxPolicyModel clonedModel = new AxPolicyModel(model);
+
+ assertFalse(model.hashCode() == 0);
+
+ assertTrue(model.equals(model));
+ assertTrue(model.equals(clonedModel));
+ assertFalse(model.equals("Hello"));
+ assertFalse(model.equals(new AxPolicyModel(new AxArtifactKey())));
+ assertFalse(model.equals(new AxPolicyModel(AxArtifactKey.getNullKey(), new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertFalse(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(), new AxKeyInformation(keyInfoKey),
+ new AxEvents(eventsKey), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey))));
+ assertFalse(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey), new AxKeyInformation(),
+ new AxEvents(eventsKey), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey))));
+ assertFalse(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey))));
+ assertFalse(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey))));
+ assertFalse(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(), new AxPolicies(policiesKey))));
+ assertFalse(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies())));
+ assertTrue(model.equals(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+
+ assertEquals(0, model.compareTo(model));
+ assertEquals(0, model.compareTo(clonedModel));
+ assertNotEquals(0, model.compareTo(new AxArtifactKey()));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(AxArtifactKey.getNullKey(), new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(), new AxKeyInformation(keyInfoKey),
+ new AxEvents(eventsKey), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey), new AxKeyInformation(),
+ new AxEvents(eventsKey), new AxContextAlbums(albumsKey), new AxTasks(tasksKey),
+ new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(), new AxPolicies(policiesKey))));
+ assertNotEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies())));
+ assertEquals(0,
+ model.compareTo(new AxPolicyModel(modelKey, new AxContextSchemas(schemasKey),
+ new AxKeyInformation(keyInfoKey), new AxEvents(eventsKey), new AxContextAlbums(albumsKey),
+ new AxTasks(tasksKey), new AxPolicies(policiesKey))));
+
+ model = new TestApexPolicyModelCreator().getModel();
+
+ AxValidationResult result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedPolicyKey = model.getKey();
+ model.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.setKey(savedPolicyKey);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxField badField = new AxField(new AxReferenceKey(model.getEvents().get("inEvent").getKey(), "BadField"),
+ new AxArtifactKey("NonExistantSchema", "0.0.1"));
+ model.getEvents().get("inEvent").getParameterMap().put(badField.getKey().getLocalName(), badField);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getEvents().get("inEvent").getParameterMap().remove(badField.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxContextAlbum badAlbum = new AxContextAlbum(new AxArtifactKey("BadAlbum", "0.0.1"), "SomeScope", true,
+ new AxArtifactKey("NonExistantSchema", "0.0.1"));
+ model.getAlbums().getAlbumsMap().put(badAlbum.getKey(), badAlbum);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getAlbums().getAlbumsMap().remove(badAlbum.getKey());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxInputField badInField =
+ new AxInputField(new AxReferenceKey(model.getTasks().get("task").getKey(), "BadInField"),
+ new AxArtifactKey("NonExistantSchema", "0.0.1"));
+ model.getTasks().get("task").getInputFields().put(badInField.getKey().getLocalName(), badInField);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getTasks().get("task").getInputFields().remove(badInField.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxOutputField badOutField =
+ new AxOutputField(new AxReferenceKey(model.getTasks().get("task").getKey(), "BadOutField"),
+ new AxArtifactKey("NonExistantSchema", "0.0.1"));
+ model.getTasks().get("task").getOutputFields().put(badOutField.getKey().getLocalName(), badOutField);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getTasks().get("task").getOutputFields().remove(badOutField.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getTasks().get("task").getContextAlbumReferences()
+ .add(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getTasks().get("task").getContextAlbumReferences()
+ .remove(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getContextAlbumReferences()
+ .add(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getContextAlbumReferences()
+ .remove(new AxArtifactKey("NonExistantContextAlbum", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedTrigger = model.getPolicies().get("policy").getStateMap().get("state").getTrigger();
+ model.getPolicies().get("policy").getStateMap().get("state")
+ .setTrigger(new AxArtifactKey("NonExistantEvent", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").setTrigger(savedTrigger);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxArtifactKey savedDefaultTask =
+ model.getPolicies().get("policy").getStateMap().get("state").getDefaultTask();
+ model.getPolicies().get("policy").getStateMap().get("state")
+ .setDefaultTask(new AxArtifactKey("NonExistantTask", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").setDefaultTask(savedDefaultTask);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // It is OK not to have TSL
+ final AxTaskSelectionLogic savedTSL =
+ model.getPolicies().get("policy").getStateMap().get("state").getTaskSelectionLogic();
+ model.getPolicies().get("policy").getStateMap().get("state")
+ .setTaskSelectionLogic(new AxTaskSelectionLogic(AxReferenceKey.getNullKey()));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getTasks().get("task").getInputFields().put(badInField.getKey().getLocalName(), badInField);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getTasks().get("task").getInputFields().remove(badInField.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").setTaskSelectionLogic(savedTSL);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateOutput badStateOutput = new AxStateOutput(
+ new AxReferenceKey(model.getPolicies().get("policy").getStateMap().get("state").getKey(), "BadSO"),
+ new AxArtifactKey("NonExistantEvent", "0.0.1"), AxReferenceKey.getNullKey());
+ model.getPolicies().get("policy").getStateMap().get("state").getStateOutputs()
+ .put(badStateOutput.getKey().getLocalName(), badStateOutput);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getStateOutputs()
+ .remove(badStateOutput.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateTaskReference badTR = new AxStateTaskReference(
+ new AxReferenceKey(model.getPolicies().get("policy").getStateMap().get("state").getKey(),
+ "NonExistantTask"),
+ AxStateTaskOutputType.LOGIC, badStateOutput.getKey());
+ model.getPolicies().get("policy").getStateMap().get("state").getTaskReferences()
+ .put(new AxArtifactKey("NonExistantTask", "0.0.1"), badTR);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ badTR.setStateTaskOutputType(AxStateTaskOutputType.DIRECT);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ model.getPolicies().get("policy").getStateMap().get("state").getTaskReferences()
+ .remove(new AxArtifactKey("NonExistantTask", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateTaskReference tr = model.getPolicies().get("policy").getStateMap().get("state").getTaskReferences()
+ .get(new AxArtifactKey("task", "0.0.1"));
+
+ final String savedSOName = tr.getOutput().getLocalName();
+ tr.getOutput().setLocalName("NonExistantOutput");
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tr.getOutput().setLocalName(savedSOName);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ final AxStateOutput so =
+ model.getPolicies().get("policy").getStateMap().get("state").getStateOutputs().get(savedSOName);
+
+ final AxArtifactKey savedOE = so.getOutgingEvent();
+ so.setOutgoingEvent(new AxArtifactKey("NonExistantEvent", "0.0.1"));
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so.setOutgoingEvent(savedOE);
+ result = new AxValidationResult();
+ result = model.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestState.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestState.java
new file mode 100644
index 000000000..1d62ae63a
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestState.java
@@ -0,0 +1,475 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+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.AxStateTaskOutputType;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestState {
+
+ @Test
+ public void testState() {
+ final TreeMap<String, AxStateOutput> soEmptyMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtEmptySet = new TreeSet<>();
+ final TreeMap<String, AxStateFinalizerLogic> sflEmptyMap = new TreeMap<>();
+ final TreeMap<AxArtifactKey, AxStateTaskReference> trEmptyMap = new TreeMap<>();
+
+ final TreeMap<String, AxStateOutput> soMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtSet = new TreeSet<>();
+ final TreeMap<String, AxStateFinalizerLogic> sflMap = new TreeMap<>();
+ final TreeMap<AxArtifactKey, AxStateTaskReference> trMap = new TreeMap<>();
+
+ assertNotNull(new AxState());
+ assertNotNull(new AxState(new AxReferenceKey()));
+ assertNotNull(new AxState(new AxReferenceKey(), new AxArtifactKey(), soEmptyMap, ctxtEmptySet,
+ new AxTaskSelectionLogic(), sflEmptyMap, new AxArtifactKey(), trEmptyMap));
+
+ final AxState state = new AxState();
+
+ final AxReferenceKey stateKey = new AxReferenceKey("PolicyName", "0.0.1", "StateName");
+ final AxReferenceKey stateKeyNext = new AxReferenceKey("PolicyName", "0.0.1", "StateNameNext");
+ final AxReferenceKey stateKeyBad = new AxReferenceKey("PolicyName", "0.0.1", "BadStateName");
+ final AxArtifactKey triggerKey = new AxArtifactKey("TriggerName", "0.0.1");
+ final AxTaskSelectionLogic tsl = new AxTaskSelectionLogic(stateKey, "TSL", "LogicFlavour", "Some Logic");
+ final AxArtifactKey defTaskKey = new AxArtifactKey("TaskName", "0.0.1");
+ final AxArtifactKey taskKey1 = new AxArtifactKey("Task1", "0.0.1");
+ final AxArtifactKey taskKey2 = new AxArtifactKey("Task2", "0.0.1");
+ final AxArtifactKey taskKeyBad = new AxArtifactKey("TaskBad", "0.0.1");
+
+ try {
+ state.setKey(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("key may not be null", e.getMessage());
+ }
+
+ state.setKey(stateKey);
+ assertEquals("PolicyName:0.0.1:NULL:StateName", state.getKey().getID());
+ assertEquals("PolicyName:0.0.1:NULL:StateName", state.getKeys().get(0).getID());
+
+ final AxStateOutput so0 = new AxStateOutput(new AxReferenceKey(stateKey, "SO0"), triggerKey, new AxReferenceKey());
+ final AxStateOutput soU = new AxStateOutput(new AxReferenceKey(stateKey, "SOU"), triggerKey, stateKeyNext);
+ final AxStateOutput soSame = new AxStateOutput(new AxReferenceKey(stateKey, "SOU"), triggerKey, stateKey);
+ final AxArtifactKey cr0 = new AxArtifactKey("ContextReference", "0.0.1");
+ final AxStateFinalizerLogic sfl = new AxStateFinalizerLogic(stateKey, "SFLogicName", "LogicFlavour", "Logic");
+ final AxStateFinalizerLogic sflU = new AxStateFinalizerLogic(stateKey, "UnusedSFLogicName", "LogicFlavour", "Logic");
+ final AxStateTaskReference str0 = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR0"),
+ AxStateTaskOutputType.DIRECT, so0.getKey());
+ final AxStateTaskReference str1 = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR1"),
+ AxStateTaskOutputType.DIRECT, so0.getKey());
+ final AxStateTaskReference str2 = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR2"),
+ AxStateTaskOutputType.LOGIC, sfl.getKey());
+
+ final AxStateTaskReference strBadState = new AxStateTaskReference(new AxReferenceKey(stateKeyBad, "STR2"),
+ AxStateTaskOutputType.LOGIC, sfl.getKey());
+ final AxStateTaskReference strBadSO = new AxStateTaskReference(new AxReferenceKey(stateKey, "STR2"),
+ AxStateTaskOutputType.UNDEFINED, sfl.getKey());
+ final AxStateTaskReference strBadSFL = new AxStateTaskReference(new AxReferenceKey(stateKeyBad, "STR2"),
+ AxStateTaskOutputType.LOGIC, new AxReferenceKey(stateKey, "SomeSFL"));
+
+ soMap.put(so0.getKey().getLocalName(), so0);
+ ctxtSet.add(cr0);
+ sflMap.put(sfl.getKey().getLocalName(), sfl);
+ trMap.put(defTaskKey.getKey(), str0);
+ trMap.put(taskKey1.getKey(), str1);
+ trMap.put(taskKey2.getKey(), str2);
+
+ try {
+ state.setTrigger(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("trigger may not be null", e.getMessage());
+ }
+
+ state.setTrigger(triggerKey);
+ assertEquals(triggerKey, state.getTrigger());
+
+ try {
+ state.setStateOutputs(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("stateOutputs may not be null", e.getMessage());
+ }
+
+ state.setStateOutputs(soMap);
+ assertEquals(soMap, state.getStateOutputs());
+
+ try {
+ state.setContextAlbumReferences(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("contextAlbumReferenceSet may not be null", e.getMessage());
+ }
+
+ state.setContextAlbumReferences(ctxtSet);
+ assertEquals(ctxtSet, state.getContextAlbumReferences());
+
+ try {
+ state.setTaskSelectionLogic(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("taskSelectionLogic may not be null", e.getMessage());
+ }
+
+ assertEquals(false, state.checkSetTaskSelectionLogic());
+ state.setTaskSelectionLogic(tsl);
+ assertEquals(tsl, state.getTaskSelectionLogic());
+ assertEquals(true, state.checkSetTaskSelectionLogic());
+
+ try {
+ state.setStateFinalizerLogicMap(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("stateFinalizerLogic may not be null", e.getMessage());
+ }
+
+ state.setStateFinalizerLogicMap(sflMap);
+ assertEquals(sflMap, state.getStateFinalizerLogicMap());
+
+ try {
+ state.setDefaultTask(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("defaultTask may not be null", e.getMessage());
+ }
+
+ state.setDefaultTask(defTaskKey);
+ assertEquals(defTaskKey, state.getDefaultTask());
+
+ try {
+ state.setTaskReferences(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("taskReferenceMap may not be null", e.getMessage());
+ }
+
+ state.setTaskReferences(trMap);
+ assertEquals(trMap, state.getTaskReferences());
+
+ state.afterUnmarshal(null, null);
+ assertEquals(state.getKey(), state.getKeys().get(0));
+ state.getTaskSelectionLogic().getKey().setLocalName(AxKey.NULL_KEY_NAME);
+ state.afterUnmarshal(null, null);
+ assertEquals(state.getKey(), state.getKeys().get(0));
+
+ final Set<String> stateSet = state.getNextStateSet();
+ assertEquals(1, stateSet.size());
+
+ AxValidationResult result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setKey(stateKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setTrigger(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setTrigger(triggerKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setStateOutputs(soEmptyMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ so0.getKey().setParentLocalName("Zooby");
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so0.getKey().setParentLocalName("StateName");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("NullOutput", null);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ soMap.remove("NullOutput");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("DupOutput", so0);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ soMap.remove("DupOutput");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("UnusedOutput", soU);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ soMap.remove("UnusedOutput");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ soMap.put("OutputToSameState", soSame);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ soMap.remove("OutputToSameState");
+ state.setStateOutputs(soMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Empty context reference set is OK
+ state.setContextAlbumReferences(ctxtEmptySet);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setContextAlbumReferences(ctxtSet);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ ctxtSet.add(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ ctxtSet.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Null TSL is OK
+ state.getTaskSelectionLogic().setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.getTaskSelectionLogic().setKey(new AxReferenceKey(stateKey, "TSL"));
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setDefaultTask(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setDefaultTask(defTaskKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setTaskReferences(trEmptyMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setTaskReferences(trMap);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(AxArtifactKey.getNullKey(), str0);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(taskKeyBad, strBadSO);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(taskKeyBad);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(taskKeyBad, strBadState);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(taskKeyBad);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ trMap.put(taskKeyBad, strBadSFL);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ trMap.remove(taskKeyBad);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.setDefaultTask(new AxArtifactKey("NonExistantTask", "0.0.1"));
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ state.setDefaultTask(defTaskKey);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ sflMap.put("NullSFL", null);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ sflMap.remove("NullSFL");
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ sflMap.put(sflU.getKey().getLocalName(), sflU);
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.OBSERVATION, result.getValidationResult());
+
+ sflMap.remove(sflU.getKey().getLocalName());
+ result = new AxValidationResult();
+ result = state.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ state.clean();
+
+ final AxState clonedState = new AxState(state);
+ assertEquals("AxState:(stateKey=AxReferenceKey:(parent", clonedState.toString().substring(0, 40));
+
+ assertFalse(state.hashCode() == 0);
+
+ assertTrue(state.equals(state));
+ assertTrue(state.equals(clonedState));
+ assertFalse(state.equals(null));
+ assertFalse(state.equals("Hello"));
+ assertFalse(state
+ .equals(new AxState(new AxReferenceKey(), triggerKey, soMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+ assertFalse(state
+ .equals(new AxState(stateKey, new AxArtifactKey(), soMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+ assertFalse(
+ state.equals(new AxState(stateKey, triggerKey, soEmptyMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+ assertFalse(
+ state.equals(new AxState(stateKey, triggerKey, soMap, ctxtEmptySet, tsl, sflMap, defTaskKey, trMap)));
+ assertFalse(state.equals(new AxState(stateKey, triggerKey, soMap, ctxtSet, new AxTaskSelectionLogic(), sflMap,
+ defTaskKey, trMap)));
+ assertFalse(
+ state.equals(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflEmptyMap, defTaskKey, trMap)));
+ assertFalse(state
+ .equals(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflMap, new AxArtifactKey(), trMap)));
+ assertFalse(
+ state.equals(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflMap, defTaskKey, trEmptyMap)));
+ assertTrue(state.equals(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+
+ assertEquals(0, state.compareTo(state));
+ assertEquals(0, state.compareTo(clonedState));
+ assertNotEquals(0, state.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, state.compareTo(null));
+ assertNotEquals(0, state.compareTo(
+ new AxState(new AxReferenceKey(), triggerKey, soMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+ assertNotEquals(0, state
+ .compareTo(new AxState(stateKey, new AxArtifactKey(), soMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+ assertNotEquals(0, state
+ .compareTo(new AxState(stateKey, triggerKey, soEmptyMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+ assertNotEquals(0, state
+ .compareTo(new AxState(stateKey, triggerKey, soMap, ctxtEmptySet, tsl, sflMap, defTaskKey, trMap)));
+ assertNotEquals(0, state.compareTo(new AxState(stateKey, triggerKey, soMap, ctxtSet, new AxTaskSelectionLogic(),
+ sflMap, defTaskKey, trMap)));
+ assertNotEquals(0, state
+ .compareTo(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflEmptyMap, defTaskKey, trMap)));
+ assertNotEquals(0, state
+ .compareTo(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflMap, new AxArtifactKey(), trMap)));
+ assertNotEquals(0, state
+ .compareTo(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflMap, defTaskKey, trEmptyMap)));
+ assertEquals(0,
+ state.compareTo(new AxState(stateKey, triggerKey, soMap, ctxtSet, tsl, sflMap, defTaskKey, trMap)));
+
+ assertNotNull(state.getKeys());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateOutput.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateOutput.java
new file mode 100644
index 000000000..5911d41be
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateOutput.java
@@ -0,0 +1,137 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+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.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestStateOutput {
+
+ @Test
+ public void testStateOutput() {
+ assertNotNull(new AxStateOutput());
+ assertNotNull(new AxStateOutput(new AxReferenceKey()));
+ assertNotNull(new AxStateOutput(new AxReferenceKey(), new AxReferenceKey(), new AxArtifactKey()));
+ assertNotNull(new AxStateOutput(new AxReferenceKey(), new AxArtifactKey(), new AxReferenceKey()));
+
+ final AxStateOutput so = new AxStateOutput();
+
+ final AxReferenceKey soKey = new AxReferenceKey("SOStateParent", "0.0.1", "SOState", "SOName");
+ final AxReferenceKey nsKey = new AxReferenceKey("SOStateParent", "0.0.1", "NotUsed", "NextStateName");
+ final AxArtifactKey eKey = new AxArtifactKey("EventName", "0.0.1");
+
+ try {
+ so.setKey(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("key may not be null", e.getMessage());
+ }
+
+ so.setKey(soKey);
+ assertEquals("SOStateParent:0.0.1:SOState:SOName", so.getKey().getID());
+ assertEquals("SOStateParent:0.0.1:SOState:SOName", so.getKeys().get(0).getID());
+
+ try {
+ so.setNextState(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("nextState may not be null", e.getMessage());
+ }
+
+ so.setNextState(nsKey);
+ assertEquals(nsKey, so.getNextState());
+
+ try {
+ so.setOutgoingEvent(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("outgoingEvent may not be null", e.getMessage());
+ }
+
+ so.setOutgoingEvent(eKey);
+ assertEquals(eKey, so.getOutgingEvent());
+
+ AxValidationResult result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ so.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so.setKey(soKey);
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ so.setOutgoingEvent(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ so.setOutgoingEvent(eKey);
+ result = new AxValidationResult();
+ result = so.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ so.clean();
+
+ final AxStateOutput clonedPar = new AxStateOutput(so);
+ assertEquals("AxStateOutput:(stateKey=AxReferenceKey:(parentKeyN", clonedPar.toString().substring(0, 50));
+
+ assertFalse(so.hashCode() == 0);
+
+ assertTrue(so.equals(so));
+ assertTrue(so.equals(clonedPar));
+ assertFalse(so.equals(null));
+ assertFalse(so.equals("Hello"));
+ assertFalse(so.equals(new AxStateOutput(AxReferenceKey.getNullKey(), eKey, nsKey)));
+ assertFalse(so.equals(new AxStateOutput(soKey, new AxArtifactKey(), nsKey)));
+ assertFalse(so.equals(new AxStateOutput(soKey, eKey, new AxReferenceKey())));
+ assertTrue(so.equals(new AxStateOutput(soKey, eKey, nsKey)));
+
+ assertEquals(0, so.compareTo(so));
+ assertEquals(0, so.compareTo(clonedPar));
+ assertNotEquals(0, so.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, so.compareTo(null));
+ assertNotEquals(0, so.compareTo(new AxStateOutput(AxReferenceKey.getNullKey(), eKey, nsKey)));
+ assertNotEquals(0, so.compareTo(new AxStateOutput(soKey, new AxArtifactKey(), nsKey)));
+ assertNotEquals(0, so.compareTo(new AxStateOutput(soKey, eKey, new AxReferenceKey())));
+ assertEquals(0, so.compareTo(new AxStateOutput(soKey, eKey, nsKey)));
+
+ assertNotNull(so.getKeys());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateTaskReference.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateTaskReference.java
new file mode 100644
index 000000000..c85fda4be
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestStateTaskReference.java
@@ -0,0 +1,160 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+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.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestStateTaskReference {
+
+ @Test
+ public void testStateTaskReference() {
+ assertNotNull(new AxStateTaskReference());
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey()));
+ assertNotNull(
+ new AxStateTaskReference(new AxReferenceKey(), AxStateTaskOutputType.UNDEFINED, new AxReferenceKey()));
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey(), new AxArtifactKey(),
+ AxStateTaskOutputType.UNDEFINED, new AxReferenceKey()));
+
+ AxStateTaskReference stRef = new AxStateTaskReference();
+
+ AxReferenceKey stRefKey = new AxReferenceKey("StateParent", "0.0.1", "SOState", "SOName");
+ AxReferenceKey soKey = new AxReferenceKey("StateParent", "0.0.1", "SOState", "STRef0");
+
+ try {
+ stRef.setKey(null);
+ fail("test should throw an exception here");
+ } catch (Exception e) {
+ assertEquals("key may not be null", e.getMessage());
+ }
+
+ stRef.setKey(stRefKey);
+ assertEquals("StateParent:0.0.1:SOState:SOName", stRef.getKey().getID());
+ assertEquals("StateParent:0.0.1:SOState:SOName", stRef.getKeys().get(0).getID());
+
+ try {
+ stRef.setStateTaskOutputType(null);
+ fail("test should throw an exception here");
+ } catch (Exception e) {
+ assertEquals("outputType may not be null", e.getMessage());
+ }
+
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
+ assertEquals(AxStateTaskOutputType.UNDEFINED, stRef.getStateTaskOutputType());
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.DIRECT);
+ assertEquals(AxStateTaskOutputType.DIRECT, stRef.getStateTaskOutputType());
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
+ assertEquals(AxStateTaskOutputType.LOGIC, stRef.getStateTaskOutputType());
+
+ try {
+ stRef.setOutput(null);
+ fail("test should throw an exception here");
+ } catch (Exception e) {
+ assertEquals("output may not be null", e.getMessage());
+ }
+
+ stRef.setOutput(soKey);
+ assertEquals(soKey, stRef.getOutput());
+
+ AxValidationResult result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ stRef.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stRef.setKey(stRefKey);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.UNDEFINED);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stRef.setStateTaskOutputType(AxStateTaskOutputType.LOGIC);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stRef.setOutput(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ stRef.setOutput(soKey);
+ result = new AxValidationResult();
+ result = stRef.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ stRef.clean();
+
+ AxStateTaskReference clonedStRef = new AxStateTaskReference(stRef);
+ assertEquals("AxStateTaskReference:(stateKey=AxReferenceKey:(par", clonedStRef.toString().substring(0, 50));
+
+ assertFalse(stRef.hashCode() == 0);
+
+ assertTrue(stRef.equals(stRef));
+ assertTrue(stRef.equals(clonedStRef));
+ assertFalse(stRef.equals(null));
+ assertFalse(stRef.equals("Hello"));
+ assertFalse(stRef
+ .equals(new AxStateTaskReference(AxReferenceKey.getNullKey(), AxStateTaskOutputType.LOGIC, soKey)));
+ assertFalse(stRef.equals(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.DIRECT, soKey)));
+ assertFalse(
+ stRef.equals(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, new AxReferenceKey())));
+ assertTrue(stRef.equals(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, soKey)));
+
+ assertNotNull(new AxStateTaskReference(new AxReferenceKey(), new AxArtifactKey(),
+ AxStateTaskOutputType.UNDEFINED, new AxReferenceKey()));
+
+ assertEquals(0, stRef.compareTo(stRef));
+ assertEquals(0, stRef.compareTo(clonedStRef));
+ assertNotEquals(0, stRef.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, stRef.compareTo(null));
+ assertNotEquals(0, stRef
+ .compareTo(new AxStateTaskReference(AxReferenceKey.getNullKey(), AxStateTaskOutputType.LOGIC, soKey)));
+ assertNotEquals(0, stRef.compareTo(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.DIRECT, soKey)));
+ assertNotEquals(0,
+ stRef.compareTo(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, new AxReferenceKey())));
+ assertEquals(0, stRef.compareTo(new AxStateTaskReference(stRefKey, AxStateTaskOutputType.LOGIC, soKey)));
+
+ assertNotNull(stRef.getKeys());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTaskParameter.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTaskParameter.java
new file mode 100644
index 000000000..63906add2
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTaskParameter.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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+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.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestTaskParameter {
+
+ @Test
+ public void testTaskParameter() {
+ assertNotNull(new AxTaskParameter());
+ assertNotNull(new AxTaskParameter(new AxReferenceKey()));
+ assertNotNull(new AxTaskParameter(new AxReferenceKey(), "DefaultValue"));
+
+ final AxTaskParameter par = new AxTaskParameter();
+
+ final AxReferenceKey parKey = new AxReferenceKey("ParParentName", "0.0.1", "PLN", "LN");
+ par.setKey(parKey);
+ assertEquals("ParParentName:0.0.1:PLN:LN", par.getKey().getID());
+ assertEquals("ParParentName:0.0.1:PLN:LN", par.getKeys().get(0).getID());
+
+ par.setDefaultValue("DefaultValue");
+ assertEquals("DefaultValue", par.getTaskParameterValue());
+
+ AxValidationResult result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(AxValidationResult.ValidationResult.VALID, result.getValidationResult());
+
+ par.setKey(AxReferenceKey.getNullKey());
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ par.setKey(parKey);
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ try {
+ par.setDefaultValue(null);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("defaultValue may not be null", e.getMessage());
+ }
+
+ par.setDefaultValue("");
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.WARNING, result.getValidationResult());
+
+ par.setDefaultValue("DefaultValue");
+ result = new AxValidationResult();
+ result = par.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ par.clean();
+
+ final AxTaskParameter clonedPar = new AxTaskParameter(par);
+ assertEquals(
+ "AxTaskParameter:(key=AxReferenceKey:(parentKeyName=ParParentName,parentKeyVersion=0.0.1,parentLocalName=PLN,localName=LN),defaultValue=DefaultValue)",
+ clonedPar.toString());
+
+ assertFalse(par.hashCode() == 0);
+
+ assertTrue(par.equals(par));
+ assertTrue(par.equals(clonedPar));
+ assertFalse(par.equals(null));
+ assertFalse(par.equals("Hello"));
+ assertFalse(par.equals(new AxTaskParameter(AxReferenceKey.getNullKey(), "DefaultValue")));
+ assertFalse(par.equals(new AxTaskParameter(parKey, "OtherDefaultValue")));
+ assertTrue(par.equals(new AxTaskParameter(parKey, "DefaultValue")));
+
+ assertEquals(0, par.compareTo(par));
+ assertEquals(0, par.compareTo(clonedPar));
+ assertNotEquals(0, par.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, par.compareTo(null));
+ assertNotEquals(0, par.compareTo(new AxTaskParameter(AxReferenceKey.getNullKey(), "DefaultValue")));
+ assertNotEquals(0, par.compareTo(new AxTaskParameter(parKey, "OtherDefaultValue")));
+ assertEquals(0, par.compareTo(new AxTaskParameter(parKey, "DefaultValue")));
+
+ assertNotNull(par.getKeys());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTasks.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTasks.java
new file mode 100644
index 000000000..967e4e0aa
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/concepts/TestTasks.java
@@ -0,0 +1,331 @@
+/*-
+ * ============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.model.policymodel.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.junit.Test;
+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.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
+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.AxTasks;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestTasks {
+
+ @Test
+ public void testTasks() {
+ final TreeMap<String, AxInputField> ifEmptyMap = new TreeMap<>();
+ final TreeMap<String, AxOutputField> ofEmptyMap = new TreeMap<>();
+ final TreeMap<String, AxTaskParameter> tpEmptyMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtEmptySet = new TreeSet<>();
+
+ final TreeMap<String, AxInputField> ifMap = new TreeMap<>();
+ final TreeMap<String, AxOutputField> ofMap = new TreeMap<>();
+ final TreeMap<String, AxTaskParameter> tpMap = new TreeMap<>();
+ final TreeSet<AxArtifactKey> ctxtSet = new TreeSet<>();
+
+ assertNotNull(new AxTask());
+ assertNotNull(new AxTask(new AxArtifactKey()));
+ assertNotNull(new AxTask(new AxArtifactKey(), ifMap, ofMap, tpMap, ctxtSet, new AxTaskLogic()));
+
+ final AxTask task = new AxTask();
+
+ final AxArtifactKey taskKey = new AxArtifactKey("TaskName", "0.0.1");
+ task.setKey(taskKey);
+ assertEquals("TaskName:0.0.1", task.getKey().getID());
+ assertEquals("TaskName:0.0.1", task.getKeys().get(0).getID());
+
+ final AxArtifactKey f0SchemaKey = new AxArtifactKey("FS0", "0.0.1");
+
+ final AxInputField if0 = new AxInputField(new AxReferenceKey(taskKey, "IF0"), f0SchemaKey, false);
+ final AxInputField if1 = new AxInputField(new AxReferenceKey(taskKey, "IF1"), f0SchemaKey, false);
+ final AxOutputField of0 = new AxOutputField(new AxReferenceKey(taskKey, "OF0"), f0SchemaKey, false);
+ final AxOutputField of1 = new AxOutputField(new AxReferenceKey(taskKey, "OF1"), f0SchemaKey, false);
+ final AxTaskParameter tp0 = new AxTaskParameter(new AxReferenceKey(taskKey, "TP0"), "DefaultValue");
+ final AxArtifactKey cr0 = new AxArtifactKey("ContextReference", "0.0.1");
+ final AxTaskLogic tl = new AxTaskLogic(taskKey, "LogicName", "LogicFlavour", "Logic");
+
+ ifMap.put(if0.getKey().getLocalName(), if0);
+ ofMap.put(of0.getKey().getLocalName(), of0);
+ tpMap.put(tp0.getKey().getLocalName(), tp0);
+ ctxtSet.add(cr0);
+
+ task.setInputFields(ifMap);
+ assertEquals(ifMap, task.getInputFields());
+ assertTrue(task.getInputFieldSet().contains(if0));
+ assertTrue(task.getRawInputFields().keySet().contains(if0.getKey().getLocalName()));
+
+ task.setOutputFields(ofMap);
+ assertEquals(ofMap, task.getOutputFields());
+ assertTrue(task.getOutputFieldSet().contains(of0));
+ assertTrue(task.getRawOutputFields().keySet().contains(of0.getKey().getLocalName()));
+
+ final TreeMap<String, AxField> ifDupMap = new TreeMap<>();
+ final TreeMap<String, AxField> ofDupMap = new TreeMap<>();
+ ifDupMap.put(if1.getKey().getLocalName(), if1);
+ ofDupMap.put(of1.getKey().getLocalName(), of1);
+ task.duplicateInputFields(ifDupMap);
+ task.duplicateOutputFields(ofDupMap);
+ assertTrue(ifMap.containsKey("IF1"));
+ assertTrue(ofMap.containsKey("OF1"));
+
+ task.setTaskParameters(tpMap);
+ assertEquals(tpMap, task.getTaskParameters());
+
+ task.setContextAlbumReferences(ctxtSet);
+ assertEquals(ctxtSet, task.getContextAlbumReferences());
+
+ task.setTaskLogic(tl);
+ assertEquals(tl, task.getTaskLogic());
+
+ task.setKey(taskKey);
+ assertEquals("TaskName:0.0.1", task.getKey().getID());
+ assertEquals("TaskName:0.0.1", task.getKeys().get(0).getID());
+
+ task.afterUnmarshal(null, null);
+ assertEquals(1, task.getTaskParameters().size());
+
+ AxValidationResult result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setKey(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ task.setKey(taskKey);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setInputFields(ifEmptyMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ task.setInputFields(ifMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ ifMap.put("NullField", null);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ ifMap.remove("NullField");
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setOutputFields(ofEmptyMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ task.setOutputFields(ofMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ ofMap.put("NullField", null);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ ofMap.remove("NullField");
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Empty task parameter map is OK
+ task.setTaskParameters(tpEmptyMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setTaskParameters(tpMap);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tpMap.put("NullField", null);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tpMap.remove("NullField");
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ // Empty context reference set is OK
+ task.setContextAlbumReferences(ctxtEmptySet);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.setContextAlbumReferences(ctxtSet);
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ ctxtSet.add(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ ctxtSet.remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = task.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ task.clean();
+
+ final AxTask clonedTask = new AxTask(task);
+ assertEquals("AxTask:(key=AxArtifactKey:(name=TaskName", clonedTask.toString().substring(0, 40));
+
+ assertFalse(task.hashCode() == 0);
+
+ assertTrue(task.equals(task));
+ assertTrue(task.equals(clonedTask));
+ assertFalse(task.equals(null));
+ assertFalse(task.equals("Hello"));
+ assertFalse(task.equals(new AxTask(new AxArtifactKey(), ifMap, ofMap, tpMap, ctxtSet, tl)));
+ assertFalse(task.equals(new AxTask(taskKey, ifEmptyMap, ofMap, tpMap, ctxtSet, tl)));
+ assertFalse(task.equals(new AxTask(taskKey, ifMap, ofEmptyMap, tpMap, ctxtSet, tl)));
+ assertFalse(task.equals(new AxTask(taskKey, ifMap, ofMap, tpEmptyMap, ctxtSet, tl)));
+ assertFalse(task.equals(new AxTask(taskKey, ifMap, ofMap, tpMap, ctxtEmptySet, tl)));
+ assertFalse(task.equals(new AxTask(taskKey, ifMap, ofMap, tpMap, ctxtSet, new AxTaskLogic())));
+ assertTrue(task.equals(new AxTask(taskKey, ifMap, ofMap, tpMap, ctxtSet, tl)));
+
+ assertEquals(0, task.compareTo(task));
+ assertEquals(0, task.compareTo(clonedTask));
+ assertNotEquals(0, task.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, task.compareTo(null));
+ assertNotEquals(0, task.compareTo(new AxTask(new AxArtifactKey(), ifMap, ofMap, tpMap, ctxtSet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, ifEmptyMap, ofMap, tpMap, ctxtSet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, ifMap, ofEmptyMap, tpMap, ctxtSet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, ifMap, ofMap, tpEmptyMap, ctxtSet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, ifMap, ofMap, tpMap, ctxtEmptySet, tl)));
+ assertNotEquals(0, task.compareTo(new AxTask(taskKey, ifMap, ofMap, tpMap, ctxtSet, new AxTaskLogic())));
+ assertEquals(0, task.compareTo(new AxTask(taskKey, ifMap, ofMap, tpMap, ctxtSet, tl)));
+
+ assertNotNull(task.getKeys());
+
+ final AxTasks tasks = new AxTasks();
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ // Invalid, no tasks in task map
+ tasks.setKey(new AxArtifactKey("TasksKey", "0.0.1"));
+ assertEquals("TasksKey:0.0.1", tasks.getKey().getID());
+
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(taskKey, task);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(AxArtifactKey.getNullKey(), null);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().remove(AxArtifactKey.getNullKey());
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(new AxArtifactKey("NullValueKey", "0.0.1"), null);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().remove(new AxArtifactKey("NullValueKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.getTaskMap().put(new AxArtifactKey("BadTaskKey", "0.0.1"), task);
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.INVALID, result.getValidationResult());
+
+ tasks.getTaskMap().remove(new AxArtifactKey("BadTaskKey", "0.0.1"));
+ result = new AxValidationResult();
+ result = tasks.validate(result);
+ assertEquals(ValidationResult.VALID, result.getValidationResult());
+
+ tasks.clean();
+ tasks.afterUnmarshal(null, null);
+
+ final AxTasks clonedTasks = new AxTasks(tasks);
+ assertEquals("AxTasks:(key=AxArtifactKey:(name=TasksKey,version=0.0.1),tas",
+ clonedTasks.toString().substring(0, 60));
+
+ assertFalse(tasks.hashCode() == 0);
+
+ assertTrue(tasks.equals(tasks));
+ assertTrue(tasks.equals(clonedTasks));
+ assertFalse(tasks.equals(null));
+ assertFalse(tasks.equals("Hello"));
+ assertFalse(tasks.equals(new AxTasks(new AxArtifactKey())));
+
+ assertEquals(0, tasks.compareTo(tasks));
+ assertEquals(0, tasks.compareTo(clonedTasks));
+ assertNotEquals(0, tasks.compareTo(null));
+ assertNotEquals(0, tasks.compareTo(new AxArtifactKey()));
+ assertNotEquals(0, tasks.compareTo(new AxTasks(new AxArtifactKey())));
+
+ clonedTasks.get(taskKey).getTaskLogic().setLogic("SomeChangedLogic");
+ assertNotEquals(0, tasks.compareTo(clonedTasks));
+
+ assertEquals(tasks.getKey(), tasks.getKeys().get(0));
+
+ assertEquals("TaskName", tasks.get("TaskName").getKey().getName());
+ assertEquals("TaskName", tasks.get("TaskName", "0.0.1").getKey().getName());
+ assertEquals(1, tasks.getAll("TaskName", "0.0.1").size());
+ assertEquals(0, tasks.getAll("NonExistantTaskName").size());
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModel.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModel.java
new file mode 100644
index 000000000..b3fd4a1b0
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModel.java
@@ -0,0 +1,139 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.dao.DAOParameters;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModel;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+public class TestApexPolicyModel {
+ private Connection connection;
+ TestApexModel<AxPolicyModel> testApexModel;
+
+ @Before
+ public void setup() throws Exception {
+ Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
+ connection = DriverManager.getConnection("jdbc:derby:memory:apex_test;create=true");
+
+ testApexModel = new TestApexModel<AxPolicyModel>(AxPolicyModel.class, new TestApexPolicyModelCreator());
+ }
+
+ @After
+ public void teardown() throws Exception {
+ connection.close();
+ new File("derby.log").delete();
+ }
+
+ @Test
+ public void testModelValid() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelValid();
+ assertTrue(result.toString().equals(VALID_MODEL_STRING));
+ }
+
+ @Test
+ public void testApexModelVaidateObservation() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateObservation();
+ assertTrue(result.toString().equals(OBSERVATION_MODEL_STRING));
+ }
+
+
+ @Test
+ public void testApexModelVaidateWarning() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateWarning();
+ assertTrue(result.toString().equals(WARNING_MODEL_STRING));
+ }
+
+ @Test
+ public void testModelVaidateInvalidModel() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateInvalidModel();
+ assertEquals(INVALID_MODEL_STRING, result.toString());
+ }
+
+ @Test
+ public void testModelVaidateMalstructured() throws Exception {
+ final AxValidationResult result = testApexModel.testApexModelVaidateMalstructured();
+ assertTrue(result.toString().equals(INVALID_MODEL_MALSTRUCTURED_STRING));
+ }
+
+ @Test
+ public void testModelWriteReadXML() throws Exception {
+ testApexModel.testApexModelWriteReadXML();
+ }
+
+ @Test
+ public void testModelWriteReadJSON() throws Exception {
+ testApexModel.testApexModelWriteReadJSON();
+ }
+
+ @Test
+ public void testModelWriteReadJPA() throws Exception {
+ final DAOParameters daoParameters = new DAOParameters();
+ daoParameters.setPluginClass("org.onap.policy.apex.model.basicmodel.dao.impl.DefaultApexDao");
+ daoParameters.setPersistenceUnit("DAOTest");
+
+ testApexModel.testApexModelWriteReadJPA(daoParameters);
+ }
+
+ private static final String VALID_MODEL_STRING = "***validation of model successful***";
+
+ private static final String OBSERVATION_MODEL_STRING =
+ "\n" + "***observations noted during validation of model***\n"
+ + "AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state):org.onap.policy.apex.model.policymodel.concepts.AxState:OBSERVATION:state output stateOutput0 is not used directly by any task\n"
+ + "********************************";
+
+ private static final String WARNING_MODEL_STRING = "\n" + "***warnings issued during validation of model***\n"
+ + "AxArtifactKey:(name=policy,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicy:WARNING:state AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=anotherState) is not referenced in the policy execution tree\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=contextAlbum0,version=0.0.1):org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum:INVALID:scope is not defined\n"
+ + "AxArtifactKey:(name=contextAlbum1,version=0.0.1):org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum:INVALID:scope is not defined\n"
+ + "AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:task output field AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false) for task task:0.0.1 not in output event outEvent0:0.0.1\n"
+ + "AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:task output field AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false) for task task:0.0.1 not in output event outEvent0:0.0.1\n"
+ + "********************************";
+
+ private static final String INVALID_MODEL_MALSTRUCTURED_STRING = "\n" + "***validation of model failed***\n"
+ + "AxArtifactKey:(name=policyModel_KeyInfo,version=0.0.1):org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation:INVALID:keyInfoMap may not be empty\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel_KeyInfo,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel_Schemas,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel_Events,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel_Albums,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel_Tasks,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel:INVALID:key information not found for key AxArtifactKey:(name=policyModel_Policies,version=0.0.1)\n"
+ + "AxArtifactKey:(name=policyModel_Schemas,version=0.0.1):org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas:INVALID:contextSchemas may not be empty\n"
+ + "AxArtifactKey:(name=policyModel_Events,version=0.0.1):org.onap.policy.apex.model.eventmodel.concepts.AxEvents:INVALID:eventMap may not be empty\n"
+ + "AxArtifactKey:(name=policyModel_Albums,version=0.0.1):org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums:OBSERVATION:albums are empty\n"
+ + "AxArtifactKey:(name=policyModel_Tasks,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxTasks:INVALID:taskMap may not be empty\n"
+ + "AxArtifactKey:(name=policyModel_Policies,version=0.0.1):org.onap.policy.apex.model.policymodel.concepts.AxPolicies:INVALID:policyMap may not be empty\n"
+ + "********************************";
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModelCreator.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModelCreator.java
new file mode 100644
index 000000000..cf2bb6524
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestApexPolicyModelCreator.java
@@ -0,0 +1,448 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import java.util.UUID;
+
+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.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.test.TestApexModelCreator;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
+import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
+import org.onap.policy.apex.model.eventmodel.concepts.AxField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxInputField;
+import org.onap.policy.apex.model.eventmodel.concepts.AxOutputField;
+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.AxStateFinalizerLogic;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
+import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
+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.model.policymodel.concepts.AxTasks;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestApexPolicyModelCreator implements TestApexModelCreator<AxPolicyModel> {
+
+ @Override
+ public AxPolicyModel getModel() {
+ final AxContextSchema schema0 =
+ new AxContextSchema(new AxArtifactKey("eventContextItem0", "0.0.1"), "Java", "java.lang.String");
+ final AxContextSchema schema1 =
+ new AxContextSchema(new AxArtifactKey("eventContextItem1", "0.0.1"), "Java", "java.lang.Long");
+ final AxContextSchema schema2 = new AxContextSchema(new AxArtifactKey("StringType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem000");
+ final AxContextSchema schema3 = new AxContextSchema(new AxArtifactKey("MapType", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A");
+
+ final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("ContextSchemas", "0.0.1"));
+ schemas.getSchemasMap().put(schema0.getKey(), schema0);
+ schemas.getSchemasMap().put(schema1.getKey(), schema1);
+ schemas.getSchemasMap().put(schema2.getKey(), schema2);
+ schemas.getSchemasMap().put(schema3.getKey(), schema3);
+
+ final AxContextAlbum album0 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbum0", "0.0.1"), "APPLICATION", true, schema3.getKey());
+ final AxContextAlbum album1 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbum1", "0.0.1"), "GLOBAL", false, schema2.getKey());
+
+ final AxContextAlbums albums = new AxContextAlbums(new AxArtifactKey("context", "0.0.1"));
+ albums.getAlbumsMap().put(album0.getKey(), album0);
+ albums.getAlbumsMap().put(album1.getKey(), album1);
+
+ final AxEvent inEvent = new AxEvent(new AxArtifactKey("inEvent", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ inEvent.getParameterMap().put("IEPAR0",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPAR0"), schema0.getKey()));
+ inEvent.getParameterMap().put("IEPAR1",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPAR1"), schema1.getKey()));
+
+ final AxEvent outEvent0 = new AxEvent(new AxArtifactKey("outEvent0", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent0.getParameterMap().put("OE0PAR0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PAR0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE0PAR1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PAR1"), schema1.getKey()));
+ outEvent0.getParameterMap().put("OE1PAR0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PAR0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE1PAR1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PAR1"), schema1.getKey()));
+
+ final AxEvent outEvent1 = new AxEvent(new AxArtifactKey("outEvent1", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent1.getParameterMap().put("OE1PAR0",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PAR0"), schema0.getKey()));
+ outEvent1.getParameterMap().put("OE1PAR1",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PAR1"), schema1.getKey()));
+
+ final AxEvents events = new AxEvents(new AxArtifactKey("events", "0.0.1"));
+ events.getEventMap().put(inEvent.getKey(), inEvent);
+ events.getEventMap().put(outEvent0.getKey(), outEvent0);
+ events.getEventMap().put(outEvent1.getKey(), outEvent1);
+
+ final AxTask task = new AxTask(new AxArtifactKey("task", "0.0.1"));
+
+ for (final AxField field : inEvent.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(),
+ "inputFields", field.getKey().getLocalName());
+ final AxInputField inputField = new AxInputField(fieldkey, field.getSchema());
+ task.getInputFields().put(inputField.getKey().getLocalName(), inputField);
+ }
+
+ for (final AxField field : outEvent0.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(),
+ "outputFields", field.getKey().getLocalName());
+ final AxOutputField outputField = new AxOutputField(fieldkey, field.getSchema());
+ task.getOutputFields().put(outputField.getKey().getLocalName(), outputField);
+ }
+
+ for (final AxField field : outEvent1.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(),
+ "outputFields", field.getKey().getLocalName());
+ final AxOutputField outputField = new AxOutputField(fieldkey, field.getSchema());
+ task.getOutputFields().put(outputField.getKey().getLocalName(), outputField);
+ }
+
+ final AxTaskParameter taskPar0 =
+ new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameter0"), "Task parameter 0 value");
+ final AxTaskParameter taskPar1 =
+ new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameter1"), "Task parameter 1 value");
+
+ task.getTaskParameters().put(taskPar0.getKey().getLocalName(), taskPar0);
+ task.getTaskParameters().put(taskPar1.getKey().getLocalName(), taskPar1);
+ task.getContextAlbumReferences().add(album0.getKey());
+ task.getContextAlbumReferences().add(album1.getKey());
+
+ final AxTaskLogic taskLogic =
+ new AxTaskLogic(new AxReferenceKey(task.getKey(), "taskLogic"), "MVEL", "Some task logic");
+ task.setTaskLogic(taskLogic);
+
+ final AxTasks tasks = new AxTasks(new AxArtifactKey("tasks", "0.0.1"));
+ tasks.getTaskMap().put(task.getKey(), task);
+
+ final AxPolicy policy = new AxPolicy(new AxArtifactKey("policy", "0.0.1"));
+ policy.setTemplate("FREEFORM");
+
+ final AxState state = new AxState(new AxReferenceKey(policy.getKey(), "state"));
+ final AxTaskSelectionLogic taskSelectionLogic = new AxTaskSelectionLogic(
+ new AxReferenceKey(state.getKey(), "taskSelectionLogic"), "MVEL", "Some TS logic ");
+
+ state.setTrigger(inEvent.getKey());
+ state.getContextAlbumReferences().add(album0.getKey());
+ state.getContextAlbumReferences().add(album1.getKey());
+ state.setTaskSelectionLogic(taskSelectionLogic);
+ state.setDefaultTask(task.getKey());
+
+ final AxStateOutput stateOutput0 = new AxStateOutput(new AxReferenceKey(state.getKey(), "stateOutput0"),
+ outEvent0.getKey(), AxReferenceKey.getNullKey());
+ state.getStateOutputs().put(stateOutput0.getKey().getLocalName(), stateOutput0);
+
+ final AxStateTaskReference stateTaskReference =
+ new AxStateTaskReference(new AxReferenceKey(state.getKey(), task.getKey().getName()),
+ AxStateTaskOutputType.DIRECT, stateOutput0.getKey());
+
+ state.getTaskReferences().put(task.getKey(), stateTaskReference);
+
+ policy.getStateMap().put(state.getKey().getLocalName(), state);
+ policy.setFirstState(state.getKey().getLocalName());
+
+ final AxPolicies policies = new AxPolicies(new AxArtifactKey("policies", "0.0.1"));
+ policies.getPolicyMap().put(policy.getKey(), policy);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKey", "0.0.1"));
+ final AxPolicyModel policyModel = new AxPolicyModel(new AxArtifactKey("PolicyModel", "0.0.1"));
+ policyModel.setKeyInformation(keyInformation);
+ policyModel.setSchemas(schemas);
+ policyModel.setAlbums(albums);
+ policyModel.setEvents(events);
+ policyModel.setTasks(tasks);
+ policyModel.setPolicies(policies);
+ policyModel.getKeyInformation().generateKeyInfo(policyModel);
+
+ int uuidIncrementer = 0;
+ for (final AxKeyInfo keyInfo : policyModel.getKeyInformation().getKeyInfoMap().values()) {
+ final String uuidString = String.format("ce9168c-e6df-414f-9646-6da464b6e%03d", uuidIncrementer++);
+ keyInfo.setUuid(UUID.fromString(uuidString));
+ }
+
+ final AxValidationResult result = new AxValidationResult();
+ policyModel.validate(result);
+
+ return policyModel;
+ }
+
+ public AxPolicyModel getAnotherModel() {
+ final AxContextSchema schema0 =
+ new AxContextSchema(new AxArtifactKey("eventContextItemA0", "0.0.1"), "Java", "java.lang.String");
+ final AxContextSchema schema1 =
+ new AxContextSchema(new AxArtifactKey("eventContextItemA1", "0.0.1"), "Java", "java.lang.Long");
+ final AxContextSchema schema2 = new AxContextSchema(new AxArtifactKey("StringTypeA", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem000");
+ final AxContextSchema schema3 = new AxContextSchema(new AxArtifactKey("MapTypeA", "0.0.1"), "Java",
+ "org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A");
+
+ final AxContextSchemas schemas = new AxContextSchemas(new AxArtifactKey("ContextSchemasA", "0.0.1"));
+ schemas.getSchemasMap().put(schema0.getKey(), schema0);
+ schemas.getSchemasMap().put(schema1.getKey(), schema1);
+ schemas.getSchemasMap().put(schema2.getKey(), schema2);
+ schemas.getSchemasMap().put(schema3.getKey(), schema3);
+
+ final AxContextAlbum album0 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbumA0", "0.0.1"), "APPLICATION", true, schema3.getKey());
+ final AxContextAlbum album1 =
+ new AxContextAlbum(new AxArtifactKey("contextAlbumA1", "0.0.1"), "GLOBAL", false, schema2.getKey());
+
+ final AxContextAlbums albums = new AxContextAlbums(new AxArtifactKey("contextA", "0.0.1"));
+ albums.getAlbumsMap().put(album0.getKey(), album0);
+ albums.getAlbumsMap().put(album1.getKey(), album1);
+
+ final AxEvent inEvent = new AxEvent(new AxArtifactKey("inEventA", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ inEvent.getParameterMap().put("IEPARA0",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPARA0"), schema0.getKey()));
+ inEvent.getParameterMap().put("IEPARA1",
+ new AxField(new AxReferenceKey(inEvent.getKey(), "IEPARA1"), schema1.getKey()));
+
+ final AxEvent outEvent0 = new AxEvent(new AxArtifactKey("outEventA0", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent0.getParameterMap().put("OE0PARA0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PARA0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE0PARA1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE0PARA1"), schema1.getKey()));
+ outEvent0.getParameterMap().put("OE1PARA0",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PARA0"), schema0.getKey()));
+ outEvent0.getParameterMap().put("OE1PARA1",
+ new AxField(new AxReferenceKey(outEvent0.getKey(), "OE1PARA1"), schema1.getKey()));
+
+ final AxEvent outEvent1 = new AxEvent(new AxArtifactKey("outEventA1", "0.0.1"),
+ "org.onap.policy.apex.model.policymodel.events", "Source", "Target");
+ outEvent1.getParameterMap().put("OE1PARA0",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PARA0"), schema0.getKey()));
+ outEvent1.getParameterMap().put("OE1PARA1",
+ new AxField(new AxReferenceKey(outEvent1.getKey(), "OE1PARA1"), schema1.getKey()));
+
+ final AxEvents events = new AxEvents(new AxArtifactKey("eventsA", "0.0.1"));
+ events.getEventMap().put(inEvent.getKey(), inEvent);
+ events.getEventMap().put(outEvent0.getKey(), outEvent0);
+ events.getEventMap().put(outEvent1.getKey(), outEvent1);
+
+ final AxTask task = new AxTask(new AxArtifactKey("taskA", "0.0.1"));
+
+ for (final AxField field : inEvent.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(),
+ "inputFieldsA", field.getKey().getLocalName());
+ final AxInputField inputField = new AxInputField(fieldkey, field.getSchema());
+ task.getInputFields().put(inputField.getKey().getLocalName(), inputField);
+ }
+
+ for (final AxField field : outEvent0.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(),
+ "outputFieldsA", field.getKey().getLocalName());
+ final AxOutputField outputField = new AxOutputField(fieldkey, field.getSchema());
+ task.getOutputFields().put(outputField.getKey().getLocalName(), outputField);
+ }
+
+ for (final AxField field : outEvent1.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(task.getKey().getName(), task.getKey().getVersion(),
+ "outputFieldsA", field.getKey().getLocalName());
+ final AxOutputField outputField = new AxOutputField(fieldkey, field.getSchema());
+ task.getOutputFields().put(outputField.getKey().getLocalName(), outputField);
+ }
+
+ final AxTaskParameter taskPar0 =
+ new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameterA0"), "Task parameter 0 value");
+ final AxTaskParameter taskPar1 =
+ new AxTaskParameter(new AxReferenceKey(task.getKey(), "taskParameterA1"), "Task parameter 1 value");
+
+ task.getTaskParameters().put(taskPar0.getKey().getLocalName(), taskPar0);
+ task.getTaskParameters().put(taskPar1.getKey().getLocalName(), taskPar1);
+ task.getContextAlbumReferences().add(album0.getKey());
+ task.getContextAlbumReferences().add(album1.getKey());
+
+ final AxTaskLogic taskLogic =
+ new AxTaskLogic(new AxReferenceKey(task.getKey(), "taskLogicA"), "MVEL", "Some task logic");
+ task.setTaskLogic(taskLogic);
+
+ final AxTasks tasks = new AxTasks(new AxArtifactKey("tasksA", "0.0.1"));
+ tasks.getTaskMap().put(task.getKey(), task);
+
+ final AxPolicy policy = new AxPolicy(new AxArtifactKey("policyA", "0.0.1"));
+ policy.setTemplate("FREEFORM");
+
+ final AxState state = new AxState(new AxReferenceKey(policy.getKey(), "stateA"));
+ final AxTaskSelectionLogic taskSelectionLogic = new AxTaskSelectionLogic(
+ new AxReferenceKey(state.getKey(), "taskSelectionLogicA"), "MVEL", "Some TS logic ");
+
+ state.setTrigger(inEvent.getKey());
+ state.getContextAlbumReferences().add(album0.getKey());
+ state.getContextAlbumReferences().add(album1.getKey());
+ state.setTaskSelectionLogic(taskSelectionLogic);
+ state.setDefaultTask(task.getKey());
+
+ final AxStateOutput stateOutput0 = new AxStateOutput(new AxReferenceKey(state.getKey(), "stateOutputA0"),
+ outEvent0.getKey(), AxReferenceKey.getNullKey());
+ state.getStateOutputs().put(stateOutput0.getKey().getLocalName(), stateOutput0);
+
+ final AxStateTaskReference stateTaskReference =
+ new AxStateTaskReference(new AxReferenceKey(state.getKey(), task.getKey().getName()),
+ AxStateTaskOutputType.DIRECT, stateOutput0.getKey());
+
+ state.getTaskReferences().put(task.getKey(), stateTaskReference);
+
+ policy.getStateMap().put(state.getKey().getLocalName(), state);
+ policy.setFirstState(state.getKey().getLocalName());
+
+ final AxPolicies policies = new AxPolicies(new AxArtifactKey("policiesA", "0.0.1"));
+ policies.getPolicyMap().put(policy.getKey(), policy);
+
+ final AxKeyInformation keyInformation = new AxKeyInformation(new AxArtifactKey("KeyInfoMapKeyA", "0.0.1"));
+ final AxPolicyModel policyModel = new AxPolicyModel(new AxArtifactKey("PolicyModelA", "0.0.1"));
+ policyModel.setKeyInformation(keyInformation);
+ policyModel.setSchemas(schemas);
+ policyModel.setAlbums(albums);
+ policyModel.setEvents(events);
+ policyModel.setTasks(tasks);
+ policyModel.setPolicies(policies);
+ policyModel.getKeyInformation().generateKeyInfo(policyModel);
+
+ int uuidIncrementer = 0;
+ for (final AxKeyInfo keyInfo : policyModel.getKeyInformation().getKeyInfoMap().values()) {
+ final String uuidString = String.format("ce9168c-e6df-414f-9646-6da464b6e%03d", uuidIncrementer++);
+ keyInfo.setUuid(UUID.fromString(uuidString));
+ }
+
+ final AxValidationResult result = new AxValidationResult();
+ policyModel.validate(result);
+
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getMalstructuredModel() {
+ final AxPolicyModel policyModel = new AxPolicyModel(new AxArtifactKey("policyModel", "0.0.1"));
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getObservationModel() {
+ final AxPolicyModel policyModel = getModel();
+
+ final AxState state = policyModel.getPolicies().get("policy").getStateMap().get("state");
+ final AxTask task = policyModel.getTasks().get("task");
+
+ final AxStateFinalizerLogic stateFinalizerLogic =
+ new AxStateFinalizerLogic(new AxReferenceKey(state.getKey(), "SFL"), "MVEL", "Some SF logic ");
+ state.getStateFinalizerLogicMap().put(stateFinalizerLogic.getKey().getLocalName(), stateFinalizerLogic);
+ final AxStateTaskReference stateTaskReference =
+ new AxStateTaskReference(new AxReferenceKey(state.getKey(), task.getKey().getName()),
+ AxStateTaskOutputType.LOGIC, stateFinalizerLogic.getKey());
+
+ state.getTaskReferences().put(task.getKey(), stateTaskReference);
+
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getWarningModel() {
+ final AxPolicyModel policyModel = getModel();
+
+ final AxState anotherState =
+ new AxState(new AxReferenceKey(new AxArtifactKey("policy", "0.0.1"), "anotherState"));
+
+ final AxEvent inEvent = policyModel.getEvents().getEventMap().get(new AxArtifactKey("inEvent", "0.0.1"));
+ final AxEvent outEvent0 = policyModel.getEvents().getEventMap().get(new AxArtifactKey("outEvent0", "0.0.1"));
+
+ final AxTask anotherTask = new AxTask(new AxArtifactKey("anotherTask", "0.0.1"));
+
+ for (final AxField field : inEvent.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(anotherTask.getKey().getName(),
+ anotherTask.getKey().getVersion(), "inputFields", field.getKey().getLocalName());
+ final AxInputField inputField = new AxInputField(fieldkey, field.getSchema());
+ anotherTask.getInputFields().put(inputField.getKey().getLocalName(), inputField);
+ }
+
+ for (final AxField field : outEvent0.getFields()) {
+ final AxReferenceKey fieldkey = new AxReferenceKey(anotherTask.getKey().getName(),
+ anotherTask.getKey().getVersion(), "outputFields", field.getKey().getLocalName());
+ final AxOutputField outputField = new AxOutputField(fieldkey, field.getSchema());
+ anotherTask.getOutputFields().put(outputField.getKey().getLocalName(), outputField);
+ }
+
+ final AxTaskParameter taskPar0 = new AxTaskParameter(new AxReferenceKey(anotherTask.getKey(), "taskParameter0"),
+ "Task parameter 0 value");
+ final AxTaskParameter taskPar1 = new AxTaskParameter(new AxReferenceKey(anotherTask.getKey(), "taskParameter1"),
+ "Task parameter 1 value");
+
+ anotherTask.getTaskParameters().put(taskPar0.getKey().getLocalName(), taskPar0);
+ anotherTask.getTaskParameters().put(taskPar1.getKey().getLocalName(), taskPar1);
+
+ final AxTaskLogic taskLogic =
+ new AxTaskLogic(new AxReferenceKey(anotherTask.getKey(), "taskLogic"), "MVEL", "Some task logic");
+ anotherTask.setTaskLogic(taskLogic);
+ policyModel.getTasks().getTaskMap().put(anotherTask.getKey(), anotherTask);
+
+ final AxStateOutput anotherStateOutput0 =
+ new AxStateOutput(new AxReferenceKey(anotherState.getKey(), "stateOutput0"), outEvent0.getKey(),
+ AxReferenceKey.getNullKey());
+ anotherState.setTrigger(inEvent.getKey());
+ anotherState.getStateOutputs().put(anotherStateOutput0.getKey().getLocalName(), anotherStateOutput0);
+ anotherState.setDefaultTask(anotherTask.getKey());
+ final AxStateTaskReference anotherStateTaskReference =
+ new AxStateTaskReference(new AxReferenceKey(anotherState.getKey(), anotherTask.getKey().getName()),
+ AxStateTaskOutputType.DIRECT, anotherStateOutput0.getKey());
+ anotherState.getTaskReferences().put(anotherTask.getKey(), anotherStateTaskReference);
+
+ policyModel.getPolicies().getPolicyMap().get(new AxArtifactKey("policy", "0.0.1")).getStateMap()
+ .put(anotherState.getKey().getLocalName(), anotherState);
+
+ policyModel.getKeyInformation().generateKeyInfo(policyModel);
+
+ return policyModel;
+ }
+
+ @Override
+ public AxPolicyModel getInvalidModel() {
+ final AxPolicyModel policyModel = getModel();
+
+ policyModel.getAlbums().get(new AxArtifactKey("contextAlbum0", "0.0.1")).setScope("UNDEFINED");
+ policyModel.getAlbums().get(new AxArtifactKey("contextAlbum1", "0.0.1")).setScope("UNDEFINED");
+
+ final AxEvent outEvent0 = policyModel.getEvents().get("outEvent0");
+ outEvent0.getParameterMap().remove("OE1PAR0");
+ outEvent0.getParameterMap().remove("OE1PAR1");
+
+ return policyModel;
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyAnalyser.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyAnalyser.java
new file mode 100644
index 000000000..40aa51ffe
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyAnalyser.java
@@ -0,0 +1,60 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.handling.PolicyAnalyser;
+import org.onap.policy.apex.model.policymodel.handling.PolicyAnalysisResult;
+
+public class TestPolicyAnalyser {
+ @Test
+ public void test() {
+ final AxPolicyModel apexModel = new TestApexPolicyModelCreator().getModel();
+
+ final PolicyAnalyser policyAnalyser = new PolicyAnalyser();
+ final PolicyAnalysisResult analysisResult = policyAnalyser.analyse(apexModel);
+
+ assertTrue(analysisResult.toString().equals(EXPECTED_ANALYSIS_RESULT));
+
+ assertNotNull(analysisResult.getUsedContextAlbums());
+ assertNotNull(analysisResult.getUsedContextSchemas());
+ assertNotNull(analysisResult.getUsedEvents());
+ assertNotNull(analysisResult.getUsedTasks());
+ assertNotNull(analysisResult.getUnusedContextAlbums());
+ assertNotNull(analysisResult.getUnusedContextSchemas());
+ assertNotNull(analysisResult.getUnusedEvents());
+ assertNotNull(analysisResult.getUnusedTasks());
+ }
+
+ private static final String EXPECTED_ANALYSIS_RESULT = "" + "Context Schema usage\n" + " MapType:0.0.1\n"
+ + " contextAlbum0:0.0.1\n" + " StringType:0.0.1\n" + " contextAlbum1:0.0.1\n"
+ + " eventContextItem0:0.0.1\n" + " inEvent:0.0.1\n" + " outEvent0:0.0.1\n" + " outEvent1:0.0.1\n"
+ + " task:0.0.1\n" + " eventContextItem1:0.0.1\n" + " inEvent:0.0.1\n" + " outEvent0:0.0.1\n"
+ + " outEvent1:0.0.1\n" + " task:0.0.1\n" + "Context Album usage\n" + " contextAlbum0:0.0.1\n"
+ + " task:0.0.1\n" + " policy:0.0.1:NULL:state\n" + " contextAlbum1:0.0.1\n" + " task:0.0.1\n"
+ + " policy:0.0.1:NULL:state\n" + "Event usage\n" + " inEvent:0.0.1\n" + " policy:0.0.1:NULL:state\n"
+ + " outEvent0:0.0.1\n" + " policy:0.0.1:NULL:state\n" + " outEvent1:0.0.1 (unused)\n" + "Task usage\n"
+ + " task:0.0.1\n" + " policy:0.0.1:NULL:state\n";
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyLogicReader.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyLogicReader.java
new file mode 100644
index 000000000..446cbeed8
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyLogicReader.java
@@ -0,0 +1,114 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.policymodel.concepts.AxLogic;
+import org.onap.policy.apex.model.policymodel.handling.PolicyLogicReader;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestPolicyLogicReader {
+
+ @Test
+ public void test() {
+ final AxReferenceKey logicKey = new AxReferenceKey("LogicParent", "0.0.1", "LogicInstanceName");
+
+ final PolicyLogicReader plReader = new PolicyLogicReader();
+
+ plReader.setLogicPackage("somewhere.over.the.rainbow");
+ assertEquals("somewhere.over.the.rainbow", plReader.getLogicPackage());
+
+ plReader.setDefaultLogic("FunkyDefaultLogic");
+ assertEquals("FunkyDefaultLogic", plReader.getDefaultLogic());
+
+ try {
+ new AxLogic(logicKey, "FunkyLogic", plReader);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "logic not found for logic \"somewhere/over/the/rainbow/funkylogic/FunkyDefaultLogic.funkylogic\"",
+ e.getMessage());
+ }
+
+ plReader.setDefaultLogic(null);
+ try {
+ new AxLogic(logicKey, "FunkyLogic", plReader);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "logic not found for logic \"somewhere/over/the/rainbow/funkylogic/LogicParent_LogicInstanceName.funkylogic\"",
+ e.getMessage());
+ }
+
+ logicKey.setParentLocalName("LogicParentLocalName");
+ try {
+ new AxLogic(logicKey, "FunkyLogic", plReader);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals(
+ "logic not found for logic \"somewhere/over/the/rainbow/funkylogic/LogicParent_LogicParentLocalName_LogicInstanceName.funkylogic\"",
+ e.getMessage());
+ }
+
+ plReader.setLogicPackage("path.to.apex.logic");
+ try {
+ final AxLogic logic = new AxLogic(logicKey, "FunkyLogic", plReader);
+ assertTrue(logic.getLogic().endsWith("Way out man, this is funky logic!"));
+ } catch (final Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ plReader.setLogicPackage("somewhere.over.the.rainbow");
+ plReader.setDefaultLogic("JavaLogic");
+
+ try {
+ final AxLogic logic = new AxLogic(logicKey, "JAVA", plReader);
+ assertEquals("somewhere.over.the.rainbow.java.JavaLogic", logic.getLogic());
+ } catch (final Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ plReader.setDefaultLogic(null);
+ try {
+ final AxLogic logic = new AxLogic(logicKey, "JAVA", plReader);
+ assertEquals("somewhere.over.the.rainbow.java.LogicParent_LogicParentLocalName_LogicInstanceName",
+ logic.getLogic());
+ } catch (final Exception e) {
+ fail("test should not throw an exception");
+ }
+
+ logicKey.setParentLocalName(AxKey.NULL_KEY_NAME);
+ try {
+ final AxLogic logic = new AxLogic(logicKey, "JAVA", plReader);
+ assertEquals("somewhere.over.the.rainbow.java.LogicParent_LogicInstanceName", logic.getLogic());
+ } catch (final Exception e) {
+ fail("test should not throw an exception");
+ }
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelComparer.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelComparer.java
new file mode 100644
index 000000000..3511b54ba
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelComparer.java
@@ -0,0 +1,129 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.handling.PolicyComparer;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelComparer;
+import org.onap.policy.apex.model.utilities.TextFileUtils;
+
+public class TestPolicyModelComparer {
+
+ @Test
+ public void testPolicyComparer() throws IOException {
+ final AxPolicyModel leftApexModel = new TestApexPolicyModelCreator().getModel();
+ final AxPolicyModel rightApexModel = new AxPolicyModel(leftApexModel);
+
+ PolicyModelComparer policyModelComparer = new PolicyModelComparer(leftApexModel, rightApexModel);
+
+ String resultString = policyModelComparer.asString(false, false);
+ String checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt");
+ assertEquals(resultString.trim().replaceAll("[\\r?\\n]+", " "),
+ checkString.trim().replaceAll("[\\r?\\n]+", " "));
+
+ resultString = policyModelComparer.asString(false, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt");
+ assertTrue(resultString.trim().replaceAll("[\\r?\\n]+", " ")
+ .equals(checkString.trim().replaceAll("[\\r?\\n]+", " ")));
+
+ resultString = policyModelComparer.asString(true, false);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt");
+ assertTrue(resultString.trim().replaceAll("[\\r?\\n]+", " ")
+ .equals(checkString.trim().replaceAll("[\\r?\\n]+", " ")));
+
+ resultString = policyModelComparer.asString(true, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt");
+ assertTrue(resultString.trim().replaceAll("[\\r?\\n]+", " ")
+ .equals(checkString.trim().replaceAll("[\\r?\\n]+", " ")));
+
+ final AxKeyInfo leftOnlyKeyInfo = new AxKeyInfo(new AxArtifactKey("LeftOnlyKeyInfo", "0.0.1"),
+ UUID.fromString("ce9168c-e6df-414f-9646-6da464b6f000"), "Left only key info");
+ final AxKeyInfo rightOnlyKeyInfo = new AxKeyInfo(new AxArtifactKey("RightOnlyKeyInfo", "0.0.1"),
+ UUID.fromString("ce9168c-e6df-414f-9646-6da464b6f001"), "Right only key info");
+
+ leftApexModel.getKeyInformation().getKeyInfoMap().put(leftOnlyKeyInfo.getKey(), leftOnlyKeyInfo);
+ rightApexModel.getKeyInformation().getKeyInfoMap().put(rightOnlyKeyInfo.getKey(), rightOnlyKeyInfo);
+
+ leftApexModel.getKeyInformation().getKeyInfoMap().get(new AxArtifactKey("inEvent", "0.0.1"))
+ .setDescription("Left InEvent Description");
+ rightApexModel.getKeyInformation().getKeyInfoMap().get(new AxArtifactKey("inEvent", "0.0.1"))
+ .setDescription("Right InEvent Description");
+
+ policyModelComparer = new PolicyModelComparer(leftApexModel, rightApexModel);
+
+ resultString = policyModelComparer.asString(false, false);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt");
+ assertEquals(resultString.trim().replaceAll("[\\r?\\n]+", " "),
+ checkString.trim().replaceAll("[\\r?\\n]+", " "));
+
+ resultString = policyModelComparer.asString(false, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt");
+ assertTrue(resultString.trim().replaceAll("[\\r?\\n]+", " ")
+ .equals(checkString.trim().replaceAll("[\\r?\\n]+", " ")));
+
+ resultString = policyModelComparer.asString(true, false);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt");
+ assertTrue(resultString.trim().replaceAll("[\\r?\\n]+", " ")
+ .equals(checkString.trim().replaceAll("[\\r?\\n]+", " ")));
+
+ resultString = policyModelComparer.asString(true, true);
+ checkString = TextFileUtils
+ .getTextFileAsString("src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt");
+ assertTrue(resultString.trim().replaceAll("[\\r?\\n]+", " ")
+ .equals(checkString.trim().replaceAll("[\\r?\\n]+", " ")));
+
+ assertNotNull(policyModelComparer.getContextAlbumComparisonResult());
+ assertNotNull(policyModelComparer.getContextAlbumKeyDifference());
+ assertNotNull(policyModelComparer.getContextSchemaComparisonResult());
+ assertNotNull(policyModelComparer.getContextSchemaKeyDifference());
+ assertNotNull(policyModelComparer.getEventComparisonResult());
+ assertNotNull(policyModelComparer.getEventKeyDifference());
+ assertNotNull(policyModelComparer.getKeyInfoComparisonResult());
+ assertNotNull(policyModelComparer.getKeyInformationKeyDifference());
+ assertNotNull(policyModelComparer.getPolicyComparisonResult());
+ assertNotNull(policyModelComparer.getPolicykeyDifference());
+ assertNotNull(policyModelComparer.getPolicyModelsKeyDifference());
+ assertNotNull(policyModelComparer.getTaskComparisonResult());
+ assertNotNull(policyModelComparer.getTaskKeyDifference());
+
+ assertNotNull(new PolicyComparer().compare(leftApexModel.getPolicies(), rightApexModel.getPolicies()));
+
+ assertEquals("****** policy map differences ******\n*** context s",
+ policyModelComparer.toString().substring(0, 50));
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelMerger.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelMerger.java
new file mode 100644
index 000000000..92d1dc32a
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelMerger.java
@@ -0,0 +1,109 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelMerger;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestPolicyModelMerger {
+
+ @Test
+ public void testPolicyModelMerger() {
+ final AxPolicyModel leftPolicyModel = new TestApexPolicyModelCreator().getModel();
+ AxPolicyModel rightPolicyModel = new TestApexPolicyModelCreator().getModel();
+
+ try {
+ final AxPolicyModel mergedPolicyModel =
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false);
+ assertEquals(leftPolicyModel, mergedPolicyModel);
+ assertEquals(rightPolicyModel, mergedPolicyModel);
+ } catch (final ApexModelException e) {
+ fail("test should not throw an exception");
+ }
+
+ leftPolicyModel.setKey(new AxArtifactKey("LeftPolicyModel", "0.0.1"));
+ try {
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false);
+ fail("test should throw an exception here");
+ } catch (final ApexModelException e) {
+ assertEquals("left model is invalid: \n***validation of model fai", e.getMessage().substring(0, 50));
+ }
+
+ leftPolicyModel.setKey(new AxArtifactKey("LeftPolicyModel", "0.0.1"));
+ try {
+ assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true));
+ } catch (final ApexModelException e) {
+ fail("test should not throw an exception");
+ }
+
+ leftPolicyModel.getKeyInformation().generateKeyInfo(leftPolicyModel);
+ try {
+ final AxPolicyModel mergedPolicyModel =
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, true);
+ assertNotNull(mergedPolicyModel);
+ } catch (final ApexModelException e) {
+ fail("test should not throw an exception");
+ }
+
+ rightPolicyModel.setKey(new AxArtifactKey("RightPolicyModel", "0.0.1"));
+ try {
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false);
+ fail("test should throw an exception here");
+ } catch (final ApexModelException e) {
+ assertEquals("right model is invalid: \n***validation of model fa", e.getMessage().substring(0, 50));
+ }
+
+ rightPolicyModel.setKey(new AxArtifactKey("RightPolicyModel", "0.0.1"));
+ try {
+ assertNotNull(PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false, true));
+ } catch (final ApexModelException e) {
+ fail("test should not throw an exception");
+ }
+
+ rightPolicyModel.getKeyInformation().generateKeyInfo(rightPolicyModel);
+ try {
+ final AxPolicyModel mergedPolicyModel =
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, false);
+ assertNotNull(mergedPolicyModel);
+ } catch (final ApexModelException e) {
+ fail("test should not throw an exception");
+ }
+
+ rightPolicyModel = new TestApexPolicyModelCreator().getAnotherModel();
+ try {
+ final AxPolicyModel mergedPolicyModel =
+ PolicyModelMerger.getMergedPolicyModel(leftPolicyModel, rightPolicyModel, true);
+ assertNotNull(mergedPolicyModel);
+ } catch (final ApexModelException e) {
+ fail("test should not throw an exception");
+ }
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelSplitter.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelSplitter.java
new file mode 100644
index 000000000..fde6e3712
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/handling/TestPolicyModelSplitter.java
@@ -0,0 +1,95 @@
+/*-
+ * ============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.model.policymodel.handling;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.model.policymodel.handling.PolicyModelSplitter;
+
+public class TestPolicyModelSplitter {
+ @Test
+ public void test() {
+ final AxPolicyModel apexModel = new TestApexPolicyModelCreator().getModel();
+
+ final Set<AxArtifactKey> requiredPolicySet = new TreeSet<AxArtifactKey>();
+ requiredPolicySet.add(new AxArtifactKey("policy", "0.0.1"));
+
+ // There's only one policy so a split of this model on that policy should return the same
+ // model
+ AxPolicyModel splitApexModel = null;
+ try {
+ splitApexModel = PolicyModelSplitter.getSubPolicyModel(apexModel, requiredPolicySet);
+ } catch (final ApexModelException e) {
+ fail(e.getMessage());
+ }
+
+ // The only difference between the models should be that the unused event outEvent1 should
+ // not be in the split model
+ apexModel.getEvents().getEventMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ apexModel.getKeyInformation().getKeyInfoMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ assertTrue(apexModel.equals(splitApexModel));
+
+ final Set<AxArtifactKey> requiredMissingPolicySet = new TreeSet<AxArtifactKey>();
+ requiredPolicySet.add(new AxArtifactKey("MissingPolicy", "0.0.1"));
+
+ AxPolicyModel missingSplitApexModel = null;
+ try {
+ missingSplitApexModel = PolicyModelSplitter.getSubPolicyModel(apexModel, requiredMissingPolicySet);
+ } catch (final ApexModelException e) {
+ fail(e.getMessage());
+ }
+ assertNotNull(missingSplitApexModel);
+
+ splitApexModel = null;
+ try {
+ splitApexModel = PolicyModelSplitter.getSubPolicyModel(apexModel, requiredPolicySet, true);
+ } catch (final ApexModelException e) {
+ fail(e.getMessage());
+ }
+
+ // The only difference between the models should be that the unused event outEvent1 should
+ // not be in the split model
+ apexModel.getEvents().getEventMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ apexModel.getKeyInformation().getKeyInfoMap().remove(new AxArtifactKey("outEvent1", "0.0.1"));
+ assertTrue(apexModel.equals(splitApexModel));
+
+ // There's only one policy so a split of this model on that policy should return the same
+ // model
+ try {
+ apexModel.getKey().setName("InvalidPolicyModelName");
+ PolicyModelSplitter.getSubPolicyModel(apexModel, requiredPolicySet);
+ fail("test should throw an exception here");
+ } catch (final Exception e) {
+ assertEquals("source model is invalid: \n***validation of model f", e.getMessage().substring(0, 50));
+ }
+
+ }
+}
diff --git a/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/utils/PolicyModelValidator.java b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/utils/PolicyModelValidator.java
new file mode 100644
index 000000000..4610a827e
--- /dev/null
+++ b/model/policy-model/src/test/java/org/onap/policy/apex/model/policymodel/utils/PolicyModelValidator.java
@@ -0,0 +1,41 @@
+/*-
+ * ============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.model.policymodel.utils;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+
+public class PolicyModelValidator {
+ public static void main(final String[] args) throws ApexModelException, FileNotFoundException {
+ final ApexModelReader<AxPolicyModel> policyModelReader =
+ new ApexModelReader<AxPolicyModel>(AxPolicyModel.class);
+
+
+ final AxPolicyModel policyModel = policyModelReader.read(new FileInputStream(args[0]));
+ final AxValidationResult result = policyModel.validate(new AxValidationResult());
+ System.out.println(result);
+ }
+}
diff --git a/model/policy-model/src/test/resources/META-INF/persistence.xml b/model/policy-model/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 000000000..6131c82d1
--- /dev/null
+++ b/model/policy-model/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+-->
+
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
+ <persistence-unit name="DAOTest" transaction-type="RESOURCE_LOCAL">
+ <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+ <class>org.onap.policy.apex.model.basicmodel.dao.converters.CDATAConditioner</class>
+ <class>org.onap.policy.apex.model.basicmodel.dao.converters.UUID2String</class>
+ <class>org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey</class>
+ <class>org.onap.policy.apex.model.basicmodel.concepts.AxConcept</class>
+ <class>org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo</class>
+ <class>org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation</class>
+ <class>org.onap.policy.apex.model.basicmodel.concepts.AxModel</class>
+ <class>org.onap.policy.apex.model.basicmodel.concepts.TestEntity</class>
+ <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema</class>
+ <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas</class>
+ <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum</class>
+ <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums</class>
+ <class>org.onap.policy.apex.model.contextmodel.concepts.AxContextModel</class>
+ <class>org.onap.policy.apex.model.eventmodel.concepts.AxField</class>
+ <class>org.onap.policy.apex.model.eventmodel.concepts.AxInputField</class>
+ <class>org.onap.policy.apex.model.eventmodel.concepts.AxOutputField</class>
+ <class>org.onap.policy.apex.model.eventmodel.concepts.AxEvent</class>
+ <class>org.onap.policy.apex.model.eventmodel.concepts.AxEvents</class>
+ <class>org.onap.policy.apex.model.eventmodel.concepts.AxEventModel</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxLogic</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxTaskParameter</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxTaskLogic</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxTask</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxTasks</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxStateOutput</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxState</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxPolicy</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxPolicies</class>
+ <class>org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel</class>
+
+ <properties>
+ <property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:apex_test" />
+ <property name="javax.persistence.target-database" value="Derby" />
+ <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
+
+ <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
+ <property name="eclipselink.ddl-generation.output-mode" value="database" />
+ <property name="eclipselink.logging.level" value="INFO" />
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt
new file mode 100644
index 000000000..57b790222
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseKeys.txt
@@ -0,0 +1,15 @@
+****** policy map differences ******
+*** context schema differences ***
+*** event differences ***
+*** context album differences ***
+*** task differences ***
+*** policy differences ***
+*** key information differences ***
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1)
+*** list of differing entries between left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+***********************************
+
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt
new file mode 100644
index 000000000..e3ba6dc7c
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentTerseValues.txt
@@ -0,0 +1,14 @@
+****** policy map differences ******
+*** context schema differences ***
+*** event differences ***
+*** context album differences ***
+*** task differences ***
+*** policy differences ***
+*** key information differences ***
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f000,description=Left only key info)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f001,description=Right only key info)
+*** list of differing entries between left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1),values={AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Left InEvent Description)AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Right InEvent Description),}
+***********************************
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt
new file mode 100644
index 000000000..926a8d764
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseKeys.txt
@@ -0,0 +1,71 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1)
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1)
+*** list of differing entries between left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1)
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=context,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+key=AxArtifactKey:(name=events,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+key=AxArtifactKey:(name=policies,version=0.0.1)
+key=AxArtifactKey:(name=policy,version=0.0.1)
+key=AxArtifactKey:(name=task,version=0.0.1)
+key=AxArtifactKey:(name=tasks,version=0.0.1)
+***********************************
+
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt
new file mode 100644
index 000000000..d3aad785e
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonDifferentVerboseValues.txt
@@ -0,0 +1,70 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=MapType,version=0.0.1),schemaFlavour=Java,schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A)
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=StringType,version=0.0.1),schemaFlavour=Java,schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem000)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),schemaFlavour=Java,schemaDefinition=java.lang.String)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),schemaFlavour=Java,schemaDefinition=java.lang.Long)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=inEvent,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={IEPAR0=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), IEPAR1=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)})
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent0,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE0PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE0PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false), OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)})
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent1,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)})
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxContextAlbum:(key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),scope=APPLICATION,isWritable=true,itemSchema=AxArtifactKey:(name=MapType,version=0.0.1))
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxContextAlbum:(key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),scope=GLOBAL,isWritable=false,itemSchema=AxArtifactKey:(name=StringType,version=0.0.1))
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxTask:(key=AxArtifactKey:(name=task,version=0.0.1),inputFields={IEPAR0=AxInputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=inputFields,localName=IEPAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), IEPAR1=AxInputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=inputFields,localName=IEPAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},outputFields={OE0PAR0=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE0PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE0PAR1=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE0PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false), OE1PAR0=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},taskParameters={taskParameter0=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter0),defaultValue=Task parameter 0 value), taskParameter1=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter1),defaultValue=Task parameter 1 value)},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskLogic=AxTaskLogic:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskLogic),logicFlavour=MVEL,logic=Some task logic))
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxPolicy:(key=AxArtifactKey:(name=policy,version=0.0.1),template=FREEFORM,stateMap={state=AxState:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state),trigger=AxArtifactKey:(name=inEvent,version=0.0.1),stateOutputs={stateOutput0=AxStateOutput:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0),outgoingEvent=AxArtifactKey:(name=outEvent0,version=0.0.1),nextState=AxReferenceKey:(parentKeyName=NULL,parentKeyVersion=0.0.0,parentLocalName=NULL,localName=NULL))},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskSelectionLogic=AxTaskSelectionLogic:(key=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=taskSelectionLogic),logicFlavour=MVEL,logic=Some TS logic),stateFinalizerLogicSet={},defaultTask=AxArtifactKey:(name=task,version=0.0.1),taskReferenceMap={AxArtifactKey:(name=task,version=0.0.1)=AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=task),outputType=DIRECT,output=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0))})},firstState=state)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** list of keys on left only
+key=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=LeftOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f000,description=Left only key info)
+*** list of keys on right only
+key=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=RightOnlyKeyInfo,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6f001,description=Right only key info)
+*** list of differing entries between left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1),values={AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Left InEvent Description)AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Right InEvent Description),}
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=ContextSchemas,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e000,description=Generated description for concept referred to by key "ContextSchemas:0.0.1")
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e001,description=Generated description for concept referred to by key "KeyInfoMapKey:0.0.1")
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=MapType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e002,description=Generated description for concept referred to by key "MapType:0.0.1")
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=PolicyModel,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e003,description=Generated description for concept referred to by key "PolicyModel:0.0.1")
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=StringType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e004,description=Generated description for concept referred to by key "StringType:0.0.1")
+key=AxArtifactKey:(name=context,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=context,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e005,description=Generated description for concept referred to by key "context:0.0.1")
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e006,description=Generated description for concept referred to by key "contextAlbum0:0.0.1")
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e007,description=Generated description for concept referred to by key "contextAlbum1:0.0.1")
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e008,description=Generated description for concept referred to by key "eventContextItem0:0.0.1")
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e009,description=Generated description for concept referred to by key "eventContextItem1:0.0.1")
+key=AxArtifactKey:(name=events,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=events,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e010,description=Generated description for concept referred to by key "events:0.0.1")
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e012,description=Generated description for concept referred to by key "outEvent0:0.0.1")
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e013,description=Generated description for concept referred to by key "outEvent1:0.0.1")
+key=AxArtifactKey:(name=policies,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policies,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e014,description=Generated description for concept referred to by key "policies:0.0.1")
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policy,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e015,description=Generated description for concept referred to by key "policy:0.0.1")
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=task,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e016,description=Generated description for concept referred to by key "task:0.0.1")
+key=AxArtifactKey:(name=tasks,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=tasks,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e017,description=Generated description for concept referred to by key "tasks:0.0.1")
+***********************************
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt
new file mode 100644
index 000000000..b9c0decdd
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalTerse.txt
@@ -0,0 +1,8 @@
+****** policy map differences ******
+*** context schema differences ***
+*** event differences ***
+*** context album differences ***
+*** task differences ***
+*** policy differences ***
+*** key information differences ***
+*********************************** \ No newline at end of file
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt
new file mode 100644
index 000000000..17862e1b1
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseKeys.txt
@@ -0,0 +1,69 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1)
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1)
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1)
+key=AxArtifactKey:(name=MapType,version=0.0.1)
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1)
+key=AxArtifactKey:(name=StringType,version=0.0.1)
+key=AxArtifactKey:(name=context,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1)
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1)
+key=AxArtifactKey:(name=events,version=0.0.1)
+key=AxArtifactKey:(name=inEvent,version=0.0.1)
+key=AxArtifactKey:(name=outEvent0,version=0.0.1)
+key=AxArtifactKey:(name=outEvent1,version=0.0.1)
+key=AxArtifactKey:(name=policies,version=0.0.1)
+key=AxArtifactKey:(name=policy,version=0.0.1)
+key=AxArtifactKey:(name=task,version=0.0.1)
+key=AxArtifactKey:(name=tasks,version=0.0.1)
+***********************************
+
diff --git a/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt
new file mode 100644
index 000000000..f566a7e5f
--- /dev/null
+++ b/model/policy-model/src/test/resources/checkFiles/PolicyModelComparisonIdenticalVerboseValues.txt
@@ -0,0 +1,69 @@
+****** policy map differences ******
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** context schema differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=MapType,version=0.0.1),schemaFlavour=Java,schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem00A)
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=StringType,version=0.0.1),schemaFlavour=Java,schemaDefinition=org.onap.policy.apex.model.policymodel.concepts.TestContextItem000)
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),schemaFlavour=Java,schemaDefinition=java.lang.String)
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxContextSchema:(key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),schemaFlavour=Java,schemaDefinition=java.lang.Long)
+*** event differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=inEvent,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={IEPAR0=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), IEPAR1=AxField:(key=AxReferenceKey:(parentKeyName=inEvent,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=IEPAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)})
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent0,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE0PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE0PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE0PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false), OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent0,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)})
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxEvent:(key=AxArtifactKey:(name=outEvent1,version=0.0.1),nameSpace=org.onap.policy.apex.model.policymodel.events,source=Source,target=Target,parameter={OE1PAR0=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxField:(key=AxReferenceKey:(parentKeyName=outEvent1,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)})
+*** context album differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxContextAlbum:(key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),scope=APPLICATION,isWritable=true,itemSchema=AxArtifactKey:(name=MapType,version=0.0.1))
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxContextAlbum:(key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),scope=GLOBAL,isWritable=false,itemSchema=AxArtifactKey:(name=StringType,version=0.0.1))
+*** task differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxTask:(key=AxArtifactKey:(name=task,version=0.0.1),inputFields={IEPAR0=AxInputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=inputFields,localName=IEPAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), IEPAR1=AxInputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=inputFields,localName=IEPAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},outputFields={OE0PAR0=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE0PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE0PAR1=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE0PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false), OE1PAR0=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE1PAR0),fieldSchemaKey=AxArtifactKey:(name=eventContextItem0,version=0.0.1),optional=false), OE1PAR1=AxOutputField:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=outputFields,localName=OE1PAR1),fieldSchemaKey=AxArtifactKey:(name=eventContextItem1,version=0.0.1),optional=false)},taskParameters={taskParameter0=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter0),defaultValue=Task parameter 0 value), taskParameter1=AxTaskParameter:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskParameter1),defaultValue=Task parameter 1 value)},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskLogic=AxTaskLogic:(key=AxReferenceKey:(parentKeyName=task,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=taskLogic),logicFlavour=MVEL,logic=Some task logic))
+*** policy differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxPolicy:(key=AxArtifactKey:(name=policy,version=0.0.1),template=FREEFORM,stateMap={state=AxState:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=NULL,localName=state),trigger=AxArtifactKey:(name=inEvent,version=0.0.1),stateOutputs={stateOutput0=AxStateOutput:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0),outgoingEvent=AxArtifactKey:(name=outEvent0,version=0.0.1),nextState=AxReferenceKey:(parentKeyName=NULL,parentKeyVersion=0.0.0,parentLocalName=NULL,localName=NULL))},contextAlbumReferenceSet=[AxArtifactKey:(name=contextAlbum0,version=0.0.1), AxArtifactKey:(name=contextAlbum1,version=0.0.1)],taskSelectionLogic=AxTaskSelectionLogic:(key=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=taskSelectionLogic),logicFlavour=MVEL,logic=Some TS logic),stateFinalizerLogicSet={},defaultTask=AxArtifactKey:(name=task,version=0.0.1),taskReferenceMap={AxArtifactKey:(name=task,version=0.0.1)=AxStateTaskReference:(stateKey=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=task),outputType=DIRECT,output=AxReferenceKey:(parentKeyName=policy,parentKeyVersion=0.0.1,parentLocalName=state,localName=stateOutput0))})},firstState=state)
+*** key information differences ***
+left key AxArtifactKey:(name=PolicyModel,version=0.0.1) equals right key AxArtifactKey:(name=PolicyModel,version=0.0.1)
+*** all left keys in right
+*** all right keys in left
+*** all values in left and right are identical
+*** list of identical entries in left and right
+key=AxArtifactKey:(name=ContextSchemas,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=ContextSchemas,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e000,description=Generated description for concept referred to by key "ContextSchemas:0.0.1")
+key=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=KeyInfoMapKey,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e001,description=Generated description for concept referred to by key "KeyInfoMapKey:0.0.1")
+key=AxArtifactKey:(name=MapType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=MapType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e002,description=Generated description for concept referred to by key "MapType:0.0.1")
+key=AxArtifactKey:(name=PolicyModel,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=PolicyModel,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e003,description=Generated description for concept referred to by key "PolicyModel:0.0.1")
+key=AxArtifactKey:(name=StringType,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=StringType,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e004,description=Generated description for concept referred to by key "StringType:0.0.1")
+key=AxArtifactKey:(name=context,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=context,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e005,description=Generated description for concept referred to by key "context:0.0.1")
+key=AxArtifactKey:(name=contextAlbum0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e006,description=Generated description for concept referred to by key "contextAlbum0:0.0.1")
+key=AxArtifactKey:(name=contextAlbum1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=contextAlbum1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e007,description=Generated description for concept referred to by key "contextAlbum1:0.0.1")
+key=AxArtifactKey:(name=eventContextItem0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e008,description=Generated description for concept referred to by key "eventContextItem0:0.0.1")
+key=AxArtifactKey:(name=eventContextItem1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=eventContextItem1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e009,description=Generated description for concept referred to by key "eventContextItem1:0.0.1")
+key=AxArtifactKey:(name=events,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=events,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e010,description=Generated description for concept referred to by key "events:0.0.1")
+key=AxArtifactKey:(name=inEvent,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=inEvent,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e011,description=Generated description for concept referred to by key "inEvent:0.0.1")
+key=AxArtifactKey:(name=outEvent0,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent0,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e012,description=Generated description for concept referred to by key "outEvent0:0.0.1")
+key=AxArtifactKey:(name=outEvent1,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=outEvent1,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e013,description=Generated description for concept referred to by key "outEvent1:0.0.1")
+key=AxArtifactKey:(name=policies,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policies,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e014,description=Generated description for concept referred to by key "policies:0.0.1")
+key=AxArtifactKey:(name=policy,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=policy,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e015,description=Generated description for concept referred to by key "policy:0.0.1")
+key=AxArtifactKey:(name=task,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=task,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e016,description=Generated description for concept referred to by key "task:0.0.1")
+key=AxArtifactKey:(name=tasks,version=0.0.1),value=AxKeyInfo:(artifactId=AxArtifactKey:(name=tasks,version=0.0.1),uuid=0ce9168c-e6df-414f-9646-6da464b6e017,description=Generated description for concept referred to by key "tasks:0.0.1")
+***********************************
+
diff --git a/model/policy-model/src/test/resources/logback-test.xml b/model/policy-model/src/test/resources/logback-test.xml
new file mode 100644
index 000000000..114b39c70
--- /dev/null
+++ b/model/policy-model/src/test/resources/logback-test.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============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=========================================================
+-->
+
+<configuration>
+
+ <contextName>Apex</contextName>
+ <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+ <property name="LOG_DIR" value="${java.io.tmpdir}/apex_logging/" />
+
+ <!-- USE FOR STD OUT ONLY -->
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+ </encoder>
+ </appender>
+
+ <root level="INFO">
+ <appender-ref ref="STDOUT" />
+ </root>
+
+ <logger name="org.infinispan" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org.onap.policy.apex.core" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${LOG_DIR}/apex.log</file>
+ <encoder>
+ <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+ %logger{26} - %msg %n %ex{full}</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="CTXT_FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${LOG_DIR}/apex_ctxt.log</file>
+ <encoder>
+ <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+ %logger{26} - %msg %n %ex{full}</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="org.onap.policy.apex.core.context.impl.monitoring" level="TRACE" additivity="false">
+ <appender-ref ref="CTXT_FILE" />
+ </logger>
+
+ <logger name="org.onap.policy.apex.core.context" level="INFO" additivity="false">
+ <appender-ref ref="STDOUT" />
+ </logger>
+</configuration>
diff --git a/model/policy-model/src/test/resources/path/to/apex/logic/funkylogic/LogicParent_LogicParentLocalName_LogicInstanceName.funkylogic b/model/policy-model/src/test/resources/path/to/apex/logic/funkylogic/LogicParent_LogicParentLocalName_LogicInstanceName.funkylogic
new file mode 100644
index 000000000..7ccf3da88
--- /dev/null
+++ b/model/policy-model/src/test/resources/path/to/apex/logic/funkylogic/LogicParent_LogicParentLocalName_LogicInstanceName.funkylogic
@@ -0,0 +1,21 @@
+#-------------------------------------------------------------------------------
+# ============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=========================================================
+#-------------------------------------------------------------------------------
+
+Way out man, this is funky logic! \ No newline at end of file