Adding plugins-event module to apex-pdp 37/51037/3
authorramverma <ram.krishna.verma@ericsson.com>
Fri, 8 Jun 2018 10:56:21 +0000 (11:56 +0100)
committerramverma <ram.krishna.verma@ericsson.com>
Fri, 8 Jun 2018 13:07:21 +0000 (14:07 +0100)
Adding plugins-event module to apex-pdp
Fix a minor bug in TextFileUtils

Change-Id: I393c5f5809d078850d6669d22759ba9fa1b4f0e6
Issue-ID: POLICY-862
Signed-off-by: ramverma <ram.krishna.verma@ericsson.com>
72 files changed:
model/utilities/src/main/java/org/onap/policy/apex/model/utilities/TextFileUtils.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/ApexJMSConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/ApexJMSProducer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/JMSCarrierTechnologyParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/ApexKafkaConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/ApexKafkaProducer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/KAFKACarrierTechnologyParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RESTClientCarrierTechnologyParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RESTRequestorCarrierTechnologyParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/apps/uservice/test/adapt/restrequestor/TestRESTREequestorEndpoint.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/apps/uservice/test/adapt/restrequestor/TestRESTRequestor.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/events/EventsIn.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/events/EventsInMulti.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/policymodels/SamplePolicyModelMVEL.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileDelete.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGet.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetConsumerAlone.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetMulti.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetProducerAlone.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FilePost.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FilePut.json [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/ApexWebSocketConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/ApexWebSocketProducer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/WEBSOCKETCarrierTechnologyParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-carrier/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/Apex2JMSObjectEventConverter.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/Apex2JMSTextEventConverter.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/JMSObjectEventProtocolParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/JMSTextEventProtocolParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/pom.xml [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/Apex2XMLEventConverter.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/XMLEventProtocolParameters.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/package-info.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/resources/xml/apex-event.xjb [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/resources/xml/apex-event.xsd [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/TestXMLEventHandler.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/TestXMLTaggedEventConsumer.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/XMLEventGenerator.java [new file with mode: 0644]
plugins/plugins-event/plugins-event-protocol/pom.xml [new file with mode: 0644]
plugins/plugins-event/pom.xml [new file with mode: 0644]
plugins/plugins-executor/plugins-executor-mvel/pom.xml [new file with mode: 0644]
plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MVELExecutorParameters.java [new file with mode: 0644]
plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelStateFinalizerExecutor.java [new file with mode: 0644]
plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelTaskExecutor.java [new file with mode: 0644]
plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelTaskSelectExecutor.java [new file with mode: 0644]
plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/package-info.java [new file with mode: 0644]
plugins/plugins-executor/pom.xml [new file with mode: 0644]
plugins/pom.xml

index d119a3a..97face9 100644 (file)
@@ -5,15 +5,15 @@
  * 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=========================================================
  */
@@ -26,11 +26,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.nio.file.Files;
-import java.nio.file.Paths;
 
 /**
- * The Class TextFileUtils is class that provides useful functions for handling text files.
- * Functions to read and wrtie text files to strings and strings are provided.
+ * The Class TextFileUtils is class that provides useful functions for handling text files. Functions to read and wrtie
+ * text files to strings and strings are provided.
  *
  * @author Liam Fallon (liam.fallon@ericsson.com)
  */
@@ -49,7 +48,8 @@ public abstract class TextFileUtils {
      * @throws IOException on errors reading text from the file
      */
     public static String getTextFileAsString(final String textFilePath) throws IOException {
-        return new String(Files.readAllBytes(Paths.get(textFilePath)));
+        final File textFile = new File(textFilePath);
+        return new String(Files.readAllBytes(textFile.toPath()));
     }
 
     /**
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/pom.xml
new file mode 100644 (file)
index 0000000..61abf52
--- /dev/null
@@ -0,0 +1,54 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+        <artifactId>plugins-event-carrier</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-carrier-jms</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling events being transported over JMS</description>
+
+    <properties>
+        <apex-plugins-event-carrier-jms-dir>${project.basedir}/src</apex-plugins-event-carrier-jms-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jboss</groupId>
+            <artifactId>jboss-remote-naming</artifactId>
+            <version>2.0.4.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.xnio</groupId>
+            <artifactId>xnio-nio</artifactId>
+            <version>3.2.0.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hornetq</groupId>
+            <artifactId>hornetq-jms-client</artifactId>
+            <version>2.3.25.Final</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/ApexJMSConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/ApexJMSConsumer.java
new file mode 100644 (file)
index 0000000..745a1e9
--- /dev/null
@@ -0,0 +1,295 @@
+/*-
+ * ============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.plugins.event.carrier.jms;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.naming.InitialContext;
+
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an Apex event consumer that receives events using JMS.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexJMSConsumer implements MessageListener, ApexEventConsumer, Runnable {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexJMSConsumer.class);
+
+    // The Apex and JMS parameters read from the parameter service
+    private JMSCarrierTechnologyParameters jmsConsumerProperties;
+
+    // The event receiver that will receive events from this consumer
+    private ApexEventReceiver eventReceiver;
+
+    // The consumer thread and stopping flag
+    private Thread consumerThread;
+    private boolean stopOrderedFlag = false;
+
+    // The connection to the JMS server
+    private Connection connection;
+
+    // The topic on which we receive events from JMS
+    private Topic jmsIncomingTopic;
+
+    // The name for this consumer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    @Override
+    public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+            final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+        this.eventReceiver = incomingEventReceiver;
+
+        this.name = consumerName;
+
+        // Check and get the JMS Properties
+        if (!(consumerParameters.getCarrierTechnologyParameters() instanceof JMSCarrierTechnologyParameters)) {
+            final String errorMessage = "specified consumer properties of type \""
+                    + consumerParameters.getCarrierTechnologyParameters().getClass().getCanonicalName()
+                    + "\" are not applicable to a JMS consumer";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        jmsConsumerProperties = (JMSCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+        // Look up the JMS connection factory
+        InitialContext jmsContext = null;
+        ConnectionFactory connectionFactory = null;
+        try {
+            jmsContext = new InitialContext(jmsConsumerProperties.getJMSConsumerProperties());
+            connectionFactory = (ConnectionFactory) jmsContext.lookup(jmsConsumerProperties.getConnectionFactory());
+
+            // Check if we actually got a connection factory
+            if (connectionFactory == null) {
+                throw new NullPointerException(
+                        "JMS context lookup of \"" + jmsConsumerProperties.getConnectionFactory() + "\" returned null");
+            }
+        } catch (final Exception e) {
+            final String errorMessage = "lookup of JMS connection factory  \""
+                    + jmsConsumerProperties.getConnectionFactory() + "\" failed for JMS consumer properties \""
+                    + jmsConsumerProperties.getJMSConsumerProperties() + "\"";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Lookup the topic on which we will receive events
+        try {
+            jmsIncomingTopic = (Topic) jmsContext.lookup(jmsConsumerProperties.getConsumerTopic());
+
+            // Check if we actually got a topic
+            if (jmsIncomingTopic == null) {
+                throw new NullPointerException(
+                        "JMS context lookup of \"" + jmsConsumerProperties.getConsumerTopic() + "\" returned null");
+            }
+        } catch (final Exception e) {
+            final String errorMessage = "lookup of JMS topic  \"" + jmsConsumerProperties.getConsumerTopic()
+                    + "\" failed for JMS consumer properties \"" + jmsConsumerProperties.getJMSConsumerProperties()
+                    + "\"";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Create and start a connection to the JMS server
+        try {
+            connection = connectionFactory.createConnection(jmsConsumerProperties.getSecurityPrincipal(),
+                    jmsConsumerProperties.getSecurityCredentials());
+            connection.start();
+        } catch (final Exception e) {
+            final String errorMessage = "connection to the JMS server failed for JMS properties \""
+                    + jmsConsumerProperties.getJMSConsumerProperties() + "\"";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+     */
+    @Override
+    public void start() {
+        // Configure and start the event reception thread
+        final String threadName = this.getClass().getName() + ":" + this.name;
+        consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+        consumerThread.setDaemon(true);
+        consumerThread.start();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        // JMS session and message consumer for receiving messages
+        Session jmsSession = null;
+        MessageConsumer messageConsumer = null;
+
+        // Create a session to the JMS server
+        try {
+            jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        } catch (final Exception e) {
+            final String errorMessage = "failed to create a JMS session towards the JMS server for receiving messages";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventRuntimeException(errorMessage, e);
+        }
+
+        // Create a message consumer for reception of messages and set this class as a message listener
+        try {
+            messageConsumer = jmsSession.createConsumer(jmsIncomingTopic);
+            messageConsumer.setMessageListener(this);
+        } catch (final Exception e) {
+            final String errorMessage = "failed to create a JMS message consumer for receiving messages";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventRuntimeException(errorMessage, e);
+        }
+
+        // Everything is now set up
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("event receiver " + this.getClass().getName() + ":" + this.name + " subscribed to JMS topic: "
+                    + jmsConsumerProperties.getConsumerTopic());
+        }
+
+        // The endless loop that receives events over JMS
+        while (consumerThread.isAlive() && !stopOrderedFlag) {
+            ThreadUtilities.sleep(jmsConsumerProperties.getConsumerWaitTime());
+        }
+
+        // Close the message consumer
+        try {
+            messageConsumer.close();
+        } catch (final Exception e) {
+            final String errorMessage = "failed to close the JMS message consumer for receiving messages";
+            LOGGER.warn(errorMessage, e);
+        }
+
+        // Close the session
+        try {
+            jmsSession.close();
+        } catch (final Exception e) {
+            final String errorMessage = "failed to close the JMS session for receiving messages";
+            LOGGER.warn(errorMessage, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
+     */
+    @Override
+    public void onMessage(final Message jmsMessage) {
+        try {
+            if (LOGGER.isTraceEnabled()) {
+                LOGGER.trace("event received for {} for forwarding to Apex engine : {} {}",
+                        this.getClass().getName() + ":" + this.name, jmsMessage.getJMSMessageID(),
+                        jmsMessage.getJMSType());
+            }
+
+            eventReceiver.receiveEvent(jmsMessage);
+        } catch (final Exception e) {
+            final String errorMessage = "failed to receive message from JMS";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventRuntimeException(errorMessage, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        stopOrderedFlag = true;
+
+        while (consumerThread.isAlive()) {
+            ThreadUtilities.sleep(jmsConsumerProperties.getConsumerWaitTime());
+        }
+
+        // Close the connection to the JMS server
+        try {
+            if (connection != null) {
+                connection.close();
+            }
+        } catch (final Exception e) {
+            final String errorMessage = "close of connection to the JMS server failed";
+            LOGGER.warn(errorMessage, e);
+        }
+    }
+
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/ApexJMSProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/ApexJMSProducer.java
new file mode 100644 (file)
index 0000000..017f07f
--- /dev/null
@@ -0,0 +1,289 @@
+/*-
+ * ============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.plugins.event.carrier.jms;
+
+import java.io.Serializable;
+import java.util.EnumMap;
+import java.util.Map;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Message;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.naming.InitialContext;
+
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event producer that sends events using JMS.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexJMSProducer implements ApexEventProducer {
+
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexJMSProducer.class);
+
+    // The JMS parameters read from the parameter service
+    private JMSCarrierTechnologyParameters jmsProducerProperties;
+
+    // The connection to the JMS server
+    private Connection connection;
+
+    // The topic on which we send events to JMS
+    private Topic jmsOutgoingTopic;
+
+    // The JMS session on which we will send events
+    private Session jmsSession;
+
+    // The producer on which we will send events
+    private MessageProducer messageProducer;
+
+    // The name for this producer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String,
+     * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters)
+     */
+    @Override
+    public void init(final String producerName, final EventHandlerParameters producerParameters)
+            throws ApexEventException {
+        this.name = producerName;
+
+        // Check and get the JMS Properties
+        if (!(producerParameters.getCarrierTechnologyParameters() instanceof JMSCarrierTechnologyParameters)) {
+            LOGGER.warn("specified producer properties are not applicable to a JMS producer (" + this.name + ")");
+            throw new ApexEventException(
+                    "specified producer properties are not applicable to a JMS producer (" + this.name + ")");
+        }
+        jmsProducerProperties = (JMSCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+
+        // Look up the JMS connection factory
+        InitialContext jmsContext = null;
+        ConnectionFactory connectionFactory = null;
+        try {
+            jmsContext = new InitialContext(jmsProducerProperties.getJMSProducerProperties());
+            connectionFactory = (ConnectionFactory) jmsContext.lookup(jmsProducerProperties.getConnectionFactory());
+
+            // Check if we actually got a connection factory
+            if (connectionFactory == null) {
+                throw new NullPointerException("JMS context lookup of \"" + jmsProducerProperties.getConnectionFactory()
+                        + "\" returned null for producer (" + this.name + ")");
+            }
+        } catch (final Exception e) {
+            final String errorMessage = "lookup of JMS connection factory  \""
+                    + jmsProducerProperties.getConnectionFactory() + "\" failed for JMS producer properties \""
+                    + jmsProducerProperties.getJMSConsumerProperties() + "\" for producer (" + this.name + ")";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Lookup the topic on which we will send events
+        try {
+            jmsOutgoingTopic = (Topic) jmsContext.lookup(jmsProducerProperties.getProducerTopic());
+
+            // Check if we actually got a topic
+            if (jmsOutgoingTopic == null) {
+                throw new NullPointerException("JMS context lookup of \"" + jmsProducerProperties.getProducerTopic()
+                        + "\" returned null for producer (" + this.name + ")");
+            }
+        } catch (final Exception e) {
+            final String errorMessage = "lookup of JMS topic  \"" + jmsProducerProperties.getProducerTopic()
+                    + "\" failed for JMS producer properties \"" + jmsProducerProperties.getJMSProducerProperties()
+                    + "\" for producer (" + this.name + ")";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Create and start a connection to the JMS server
+        try {
+            connection = connectionFactory.createConnection(jmsProducerProperties.getSecurityPrincipal(),
+                    jmsProducerProperties.getSecurityCredentials());
+            connection.start();
+        } catch (final Exception e) {
+            final String errorMessage = "connection to JMS server failed for JMS properties \""
+                    + jmsProducerProperties.getJMSConsumerProperties() + "\" for producer (" + this.name + ")";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Create a JMS session for sending events
+        try {
+            jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        } catch (final Exception e) {
+            final String errorMessage = "creation of session to JMS server failed for JMS properties \""
+                    + jmsProducerProperties.getJMSConsumerProperties() + "\" for producer (" + this.name + ")";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Create a JMS message producer for sending events
+        try {
+            messageProducer = jmsSession.createProducer(jmsOutgoingTopic);
+        } catch (final Exception e) {
+            final String errorMessage =
+                    "creation of producer for sending events to JMS server failed for JMS properties \""
+                            + jmsProducerProperties.getJMSConsumerProperties() + "\"";
+            LOGGER.warn(errorMessage, e);
+            throw new ApexEventException(errorMessage, e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang.String,
+     * java.lang.Object)
+     */
+    @Override
+    public void sendEvent(final long executionId, final String eventname, final Object eventObject) {
+        // Check if this is a synchronized event, if so we have received a reply
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        if (synchronousEventCache != null) {
+            synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+        }
+
+        // Check if the object to be sent is serializable
+        if (!Serializable.class.isAssignableFrom(eventObject.getClass())) {
+            final String errorMessage = "could not send event \"" + eventname + "\" on JMS message producer "
+                    + this.name + ", object of type \"" + eventObject.getClass().getCanonicalName()
+                    + "\" is not serializable";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+
+        // The JMS message to send is constructed using the JMS session
+        Message jmsMessage = null;
+
+        // Check the type of JMS message to send
+        if (jmsProducerProperties.isObjectMessageSending()) {
+            // We should send a JMS Object Message
+            try {
+                jmsMessage = jmsSession.createObjectMessage((Serializable) eventObject);
+            } catch (final Exception e) {
+                final String errorMessage = "could not send event \"" + eventname + "\" on JMS message producer "
+                        + this.name + ", could not create JMS Object Message for object \"" + eventObject;
+                LOGGER.warn(errorMessage);
+                throw new ApexEventRuntimeException(errorMessage);
+            }
+        } else {
+            // We should send a JMS Text Message
+            try {
+                jmsMessage = jmsSession.createTextMessage(eventObject.toString());
+            } catch (final Exception e) {
+                final String errorMessage = "could not send event \"" + eventname + "\" on JMS message producer "
+                        + this.name + ", could not create JMS Text Message for object \"" + eventObject;
+                LOGGER.warn(errorMessage);
+                throw new ApexEventRuntimeException(errorMessage);
+            }
+        }
+
+        try {
+            messageProducer.send(jmsMessage);
+        } catch (final Exception e) {
+            final String errorMessage = "could not send event \"" + eventname + "\" on JMS message producer "
+                    + this.name + ", send failed for object \"" + eventObject;
+            LOGGER.warn(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        // Close the message producer
+        try {
+            messageProducer.close();
+        } catch (final Exception e) {
+            final String errorMessage = "failed to close JMS message producer " + this.name + " for sending messages";
+            LOGGER.warn(errorMessage, e);
+        }
+
+        // Close the session
+        try {
+            jmsSession.close();
+        } catch (final Exception e) {
+            final String errorMessage = "failed to close the JMS session for  " + this.name + " for sending messages";
+            LOGGER.warn(errorMessage, e);
+        }
+
+        // Close the connection to the JMS server
+        try {
+            connection.close();
+        } catch (final Exception e) {
+            final String errorMessage = "close of connection to the JMS server for  " + this.name + " failed";
+            LOGGER.warn(errorMessage, e);
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/JMSCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/JMSCarrierTechnologyParameters.java
new file mode 100644 (file)
index 0000000..48f5fe2
--- /dev/null
@@ -0,0 +1,368 @@
+/*-
+ * ============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.plugins.event.carrier.jms;
+
+import java.util.Properties;
+
+import javax.naming.Context;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for JMS as an event carrier technology.
+ * <p>
+ * The parameters for this plugin are:
+ * <ol>
+ * <li>initialContextFactory: JMS uses a naming {@link Context} object to look up the locations of JMS servers and JMS
+ * topics. An Initial Context Factory is used to when creating a {@link Context} object that can be used for JMS
+ * lookups. The value of this parameter is passed to the {@link Context} with the label
+ * {@link Context#INITIAL_CONTEXT_FACTORY}. Its value must be the full canonical path to a class that implements the
+ * {@code javax.naming.spi.InitialContextFactory} interface. The parameter defaults to the string value
+ * {@code org.jboss.naming.remote.client.InitialContextFactory}.
+ * <li>providerURL: The location of the server to use for naming context lookups. The value of this parameter is passed
+ * to the {@link Context} with the label {@link Context#PROVIDER_URL}. Its value must be a URL that identifies the JMS
+ * naming server. The parameter defaults to the string value {@code remote://localhost:4447}.
+ * <li>securityPrincipal: The user name to use for JMS access. The value of this parameter is passed to the
+ * {@link Context} with the label {@link Context#SECURITY_PRINCIPAL}. Its value must be the user name of a user defined
+ * on the JMS server. The parameter defaults to the string value {@code userid}.
+ * <li>securityCredentials:The password to use for JMS access. The value of this parameter is passed to the
+ * {@link Context} with the label {@link Context#SECURITY_CREDENTIALS}. Its value must be the password of a suer defined
+ * on the JMS server. The parameter defaults to the string value {@code password}.
+ * <li>connectionFactory: JMS uses a {@link javax.jms.ConnectionFactory} instance to create connections towards a JMS
+ * server. The connection factory to use is held in the JMS {@link Context} object. This parameter specifies the label
+ * to use to look up the {@link javax.jms.ConnectionFactory} instance from the JMS {@link Context}.
+ * <li>producerTopic: JMS uses a {@link javax.jms.Topic} instance to for sending and receiving messages. The topic to
+ * use for sending events to JMS from an Apex producer is held in the JMS {@link Context} object. This parameter
+ * specifies the label to use to look up the {@link javax.jms.Topic} instance in the JMS {@link Context} for the JMS
+ * server. The topic must, of course, also be defined on the JMS server. The parameter defaults to the string value
+ * {@code apex-out}.
+ * <li>consumerTopic: The topic to use for receiving events from JMS in an Apex consumer is held in the JMS
+ * {@link Context} object. This parameter specifies the label to use to look up the {@link javax.jms.Topic} instance in
+ * the JMS {@link Context} for the JMS server. The topic must, of course, also be defined on the JMS server. The
+ * parameter defaults to the string value {@code apex-in}.
+ * <li>consumerWaitTime: The amount of milliseconds a JMS consumer should wait between checks of its thread execution
+ * status. The parameter defaults to the long value {@code 100}.
+ * <li>objectMessageSending: A flag that indicates whether Apex producers should send JMS messages as
+ * {@link javax.jms.ObjectMessage} instances for java objects (value {@code true}) or as {@link javax.jms.TextMessage}
+ * instances for strings (value {@code false}) . The parameter defaults to the boolean value {@code true}.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JMSCarrierTechnologyParameters extends CarrierTechnologyParameters {
+    /** The label of this carrier technology. */
+    public static final String JMS_CARRIER_TECHNOLOGY_LABEL = "JMS";
+
+    /** The producer plugin class for the JMS carrier technology. */
+    public static final String JMS_EVENT_PRODUCER_PLUGIN_CLASS = ApexJMSProducer.class.getCanonicalName();
+
+    /** The consumer plugin class for the JMS carrier technology. */
+    public static final String JMS_EVENT_CONSUMER_PLUGIN_CLASS = ApexJMSConsumer.class.getCanonicalName();
+
+    // @formatter:off
+
+    // Default parameter values
+    private static final String  DEFAULT_CONNECTION_FACTORY        = "jms/RemoteConnectionFactory";
+    private static final String  DEFAULT_INITIAL_CONTEXT_FACTORY   = "org.jboss.naming.remote.client.InitialContextFactory";
+    private static final String  DEFAULT_PROVIDER_URL              = "remote://localhost:4447";
+    private static final String  DEFAULT_SECURITY_PRINCIPAL        = "userid";
+    private static final String  DEFAULT_SECURITY_CREDENTIALS      = "password";
+    private static final String  DEFAULT_CONSUMER_TOPIC            = "apex-in";
+    private static final String  DEFAULT_PRODUCER_TOPIC            = "apex-out";
+    private static final int     DEFAULT_CONSUMER_WAIT_TIME        = 100;
+    private static final boolean DEFAULT_TO_OBJECT_MESSAGE_SENDING = true;
+
+    // Parameter property map tokens
+    private static final String PROPERTY_INITIAL_CONTEXT_FACTORY  = Context.INITIAL_CONTEXT_FACTORY;
+    private static final String PROPERTY_PROVIDER_URL             = Context.PROVIDER_URL;
+    private static final String PROPERTY_SECURITY_PRINCIPAL       = Context.SECURITY_PRINCIPAL;
+    private static final String PROPERTY_SECURITY_CREDENTIALS     = Context.SECURITY_CREDENTIALS;
+
+    // JMS carrier parameters
+    private String  connectionFactory     = DEFAULT_CONNECTION_FACTORY;
+    private String  initialContextFactory = DEFAULT_INITIAL_CONTEXT_FACTORY;
+    private String  providerURL           = DEFAULT_PROVIDER_URL;
+    private String  securityPrincipal     = DEFAULT_SECURITY_PRINCIPAL;
+    private String  securityCredentials   = DEFAULT_SECURITY_CREDENTIALS;
+    private String  producerTopic         = DEFAULT_PRODUCER_TOPIC;
+    private String  consumerTopic         = DEFAULT_CONSUMER_TOPIC;
+    private int     consumerWaitTime      = DEFAULT_CONSUMER_WAIT_TIME;
+    private boolean objectMessageSending  = DEFAULT_TO_OBJECT_MESSAGE_SENDING;
+    // @formatter:on
+
+    /**
+     * Constructor to create a jms carrier technology parameters instance and register the instance with the parameter
+     * service.
+     */
+    public JMSCarrierTechnologyParameters() {
+        super(JMSCarrierTechnologyParameters.class.getCanonicalName());
+
+        // Set the carrier technology properties for the JMS carrier technology
+        this.setLabel(JMS_CARRIER_TECHNOLOGY_LABEL);
+        this.setEventProducerPluginClass(JMS_EVENT_PRODUCER_PLUGIN_CLASS);
+        this.setEventConsumerPluginClass(JMS_EVENT_CONSUMER_PLUGIN_CLASS);
+    }
+
+    /**
+     * Gets the JMS producer properties.
+     *
+     * @return the JMS producer properties
+     */
+    public Properties getJMSProducerProperties() {
+        final Properties jmsProperties = new Properties();
+
+        jmsProperties.put(PROPERTY_INITIAL_CONTEXT_FACTORY, initialContextFactory);
+        jmsProperties.put(PROPERTY_PROVIDER_URL, providerURL);
+        jmsProperties.put(PROPERTY_SECURITY_PRINCIPAL, securityPrincipal);
+        jmsProperties.put(PROPERTY_SECURITY_CREDENTIALS, securityCredentials);
+
+        return jmsProperties;
+    }
+
+    /**
+     * Gets the jms consumer properties.
+     *
+     * @return the jms consumer properties
+     */
+    public Properties getJMSConsumerProperties() {
+        final Properties jmsProperties = new Properties();
+
+        jmsProperties.put(PROPERTY_INITIAL_CONTEXT_FACTORY, initialContextFactory);
+        jmsProperties.put(PROPERTY_PROVIDER_URL, providerURL);
+        jmsProperties.put(PROPERTY_SECURITY_PRINCIPAL, securityPrincipal);
+        jmsProperties.put(PROPERTY_SECURITY_CREDENTIALS, securityCredentials);
+
+        return jmsProperties;
+    }
+
+    /**
+     * Gets the connection factory.
+     *
+     * @return the connection factory
+     */
+    public String getConnectionFactory() {
+        return connectionFactory;
+    }
+
+    /**
+     * Gets the initial context factory.
+     *
+     * @return the initial context factory
+     */
+    public String getInitialContextFactory() {
+        return initialContextFactory;
+    }
+
+    /**
+     * Gets the provider URL.
+     *
+     * @return the provider URL
+     */
+    public String getProviderURL() {
+        return providerURL;
+    }
+
+    /**
+     * Gets the security principal.
+     *
+     * @return the security principal
+     */
+    public String getSecurityPrincipal() {
+        return securityPrincipal;
+    }
+
+    /**
+     * Gets the security credentials.
+     *
+     * @return the security credentials
+     */
+    public String getSecurityCredentials() {
+        return securityCredentials;
+    }
+
+    /**
+     * Gets the producer topic.
+     *
+     * @return the producer topic
+     */
+    public String getProducerTopic() {
+        return producerTopic;
+    }
+
+    /**
+     * Gets the consumer topic.
+     *
+     * @return the consumer topic
+     */
+    public String getConsumerTopic() {
+        return consumerTopic;
+    }
+
+    /**
+     * Gets the consumer wait time.
+     *
+     * @return the consumer wait time
+     */
+    public long getConsumerWaitTime() {
+        return consumerWaitTime;
+    }
+
+    /**
+     * Sets the connection factory.
+     *
+     * @param connectionFactory the connection factory
+     */
+    public void setConnectionFactory(final String connectionFactory) {
+        this.connectionFactory = connectionFactory;
+    }
+
+    /**
+     * Sets the initial context factory.
+     *
+     * @param initialContextFactory the initial context factory
+     */
+    public void setInitialContextFactory(final String initialContextFactory) {
+        this.initialContextFactory = initialContextFactory;
+    }
+
+    /**
+     * Sets the provider URL.
+     *
+     * @param providerURL the provider URL
+     */
+    public void setProviderURL(final String providerURL) {
+        this.providerURL = providerURL;
+    }
+
+    /**
+     * Sets the security principal.
+     *
+     * @param securityPrincipal the security principal
+     */
+    public void setSecurityPrincipal(final String securityPrincipal) {
+        this.securityPrincipal = securityPrincipal;
+    }
+
+    /**
+     * Sets the security credentials.
+     *
+     * @param securityCredentials the security credentials
+     */
+    public void setSecurityCredentials(final String securityCredentials) {
+        this.securityCredentials = securityCredentials;
+    }
+
+    /**
+     * Sets the producer topic.
+     *
+     * @param producerTopic the producer topic
+     */
+    public void setProducerTopic(final String producerTopic) {
+        this.producerTopic = producerTopic;
+    }
+
+    /**
+     * Sets the consumer topic.
+     *
+     * @param consumerTopic the consumer topic
+     */
+    public void setConsumerTopic(final String consumerTopic) {
+        this.consumerTopic = consumerTopic;
+    }
+
+    /**
+     * Sets the consumer wait time.
+     *
+     * @param consumerWaitTime the consumer wait time
+     */
+    public void setConsumerWaitTime(final int consumerWaitTime) {
+        this.consumerWaitTime = consumerWaitTime;
+    }
+
+    /**
+     * Checks if is object message sending.
+     *
+     * @return true, if checks if is object message sending
+     */
+    public boolean isObjectMessageSending() {
+        return objectMessageSending;
+    }
+
+    /**
+     * Sets the object message sending.
+     *
+     * @param objectMessageSending the object message sending
+     */
+    public void setObjectMessageSending(final boolean objectMessageSending) {
+        this.objectMessageSending = objectMessageSending;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+     */
+    @Override
+    public String validate() {
+        final StringBuilder errorMessageBuilder = new StringBuilder();
+
+        errorMessageBuilder.append(super.validate());
+
+        if (initialContextFactory == null || initialContextFactory.trim().length() == 0) {
+            errorMessageBuilder
+                    .append("  initialContextFactory not specified, must be specified as a string that is a class"
+                            + " that implements the interface org.jboss.naming.remote.client.InitialContextFactory\n");
+        }
+
+        if (providerURL == null || providerURL.trim().length() == 0) {
+            errorMessageBuilder.append(
+                    "  providerURL not specified, must be specified as a URL string that specifies the location of "
+                            + "configuration information for the service provider to use such as remote://localhost:4447\n");
+        }
+
+        if (securityPrincipal == null || securityPrincipal.trim().length() == 0) {
+            errorMessageBuilder.append(
+                    "  securityPrincipal not specified, must be specified the identity of the principal for authenticating the caller to the service\n");
+        }
+
+        if (securityCredentials == null || securityCredentials.trim().length() == 0) {
+            errorMessageBuilder.append("  securityCredentials not specified, must be specified as "
+                    + "the credentials of the principal for authenticating the caller to the service\n");
+        }
+
+        if (producerTopic == null || producerTopic.trim().length() == 0) {
+            errorMessageBuilder.append(
+                    "  producerTopic not specified, must be a string that identifies the JMS topic on which Apex will send events\n");
+        }
+
+        if (consumerTopic == null || consumerTopic.trim().length() == 0) {
+            errorMessageBuilder.append(
+                    "  consumerTopic not specified, must be a string that identifies the JMS topic on which Apex will recieve events\n");
+        }
+
+        if (consumerWaitTime < 0) {
+            errorMessageBuilder.append("  consumerWaitTime [" + consumerWaitTime
+                    + "] invalid, must be specified as consumerWaitTime >= 0\n");
+        }
+
+        return errorMessageBuilder.toString();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-jms/src/main/java/org/onap/policy/apex/plugins/event/carrier/jms/package-info.java
new file mode 100644 (file)
index 0000000..115bc50
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Implements the APEX event carrier technology plugin for JMS.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.jms;
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/pom.xml
new file mode 100644 (file)
index 0000000..cd015bb
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+        <artifactId>plugins-event-carrier</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-carrier-kafka</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling events being transported over Kafka</description>
+
+    <properties>
+        <apex-plugins-event-carrier-kafka-dir>${project.basedir}/src</apex-plugins-event-carrier-kafka-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+            <version>0.10.2.1</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/ApexKafkaConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/ApexKafkaConsumer.java
new file mode 100644 (file)
index 0000000..3351a58
--- /dev/null
@@ -0,0 +1,198 @@
+/*-
+ * ============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.plugins.event.carrier.kafka;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an Apex event consumer that receives events using Kafka.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexKafkaConsumer implements ApexEventConsumer, Runnable {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexKafkaConsumer.class);
+
+    // The Kafka parameters read from the parameter service
+    private KAFKACarrierTechnologyParameters kafkaConsumerProperties;
+
+    // The event receiver that will receive events from this consumer
+    private ApexEventReceiver eventReceiver;
+
+    // The Kafka consumer used to receive events using Kafka
+    private KafkaConsumer<String, String> kafkaConsumer;
+
+    // The name for this consumer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    // The consumer thread and stopping flag
+    private Thread consumerThread;
+    private boolean stopOrderedFlag = false;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#init(java.lang.String,
+     * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters,
+     * org.onap.policy.apex.service.engine.event.ApexEventReceiver)
+     */
+    @Override
+    public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+            final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+        this.eventReceiver = incomingEventReceiver;
+        this.name = consumerName;
+
+        // Check and get the Kafka Properties
+        if (!(consumerParameters.getCarrierTechnologyParameters() instanceof KAFKACarrierTechnologyParameters)) {
+            LOGGER.warn("specified consumer properties of type \""
+                    + consumerParameters.getCarrierTechnologyParameters().getClass().getCanonicalName()
+                    + "\" are not applicable to a Kafka consumer");
+            throw new ApexEventException("specified consumer properties of type \""
+                    + consumerParameters.getCarrierTechnologyParameters().getClass().getCanonicalName()
+                    + "\" are not applicable to a Kafka consumer");
+        }
+        kafkaConsumerProperties =
+                (KAFKACarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+        // Kick off the Kafka consumer
+        kafkaConsumer = new KafkaConsumer<String, String>(kafkaConsumerProperties.getKafkaConsumerProperties());
+        kafkaConsumer.subscribe(kafkaConsumerProperties.getConsumerTopicList());
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("event receiver for " + this.getClass().getName() + ":" + this.name + " subscribed to topics: "
+                    + kafkaConsumerProperties.getConsumerTopicList());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+     */
+    @Override
+    public void start() {
+        // Configure and start the event reception thread
+        final String threadName = this.getClass().getName() + ":" + this.name;
+        consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+        consumerThread.setDaemon(true);
+        consumerThread.start();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        // Kick off the Kafka consumer
+        kafkaConsumer = new KafkaConsumer<String, String>(kafkaConsumerProperties.getKafkaConsumerProperties());
+        kafkaConsumer.subscribe(kafkaConsumerProperties.getConsumerTopicList());
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("event receiver for " + this.getClass().getName() + ":" + this.name + " subscribed to topics: "
+                    + kafkaConsumerProperties.getConsumerTopicList());
+        }
+
+        // The endless loop that receives events over Kafka
+        while (consumerThread.isAlive() && !stopOrderedFlag) {
+            try {
+                final ConsumerRecords<String, String> records =
+                        kafkaConsumer.poll(kafkaConsumerProperties.getConsumerPollTime());
+                for (final ConsumerRecord<String, String> record : records) {
+                    if (LOGGER.isTraceEnabled()) {
+                        LOGGER.trace("event received for {} for forwarding to Apex engine : {} {}",
+                                this.getClass().getName() + ":" + this.name, record.key(), record.value());
+                    }
+                    eventReceiver.receiveEvent(record.value());
+                }
+            } catch (final Exception e) {
+                LOGGER.warn("error receiving events on thread {}", consumerThread.getName(), e);
+            }
+        }
+
+        if (!consumerThread.isInterrupted()) {
+            kafkaConsumer.close();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#stop()
+     */
+    @Override
+    public void stop() {
+        stopOrderedFlag = true;
+
+        while (consumerThread.isAlive()) {
+            ThreadUtilities.sleep(kafkaConsumerProperties.getConsumerPollTime());
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/ApexKafkaProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/ApexKafkaProducer.java
new file mode 100644 (file)
index 0000000..fb851bc
--- /dev/null
@@ -0,0 +1,151 @@
+/*-
+ * ============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.plugins.event.carrier.kafka;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.Producer;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event producer that sends events using Kafka.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexKafkaProducer implements ApexEventProducer {
+
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexKafkaProducer.class);
+
+    // The Kafka parameters read from the parameter service
+    private KAFKACarrierTechnologyParameters kafkaProducerProperties;
+
+    // The Kafka Producer used to send events using Kafka
+    private Producer<String, Object> kafkaProducer;
+
+    // The name for this producer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    @Override
+    public void init(final String producerName, final EventHandlerParameters producerParameters)
+            throws ApexEventException {
+        this.name = producerName;
+
+        // Check and get the Kafka Properties
+        if (!(producerParameters.getCarrierTechnologyParameters() instanceof KAFKACarrierTechnologyParameters)) {
+            LOGGER.warn("specified producer properties are not applicable to a Kafka producer (" + this.name + ")");
+            throw new ApexEventException(
+                    "specified producer properties are not applicable to a Kafka producer (" + this.name + ")");
+        }
+        kafkaProducerProperties =
+                (KAFKACarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#sendEvent(long, java.lang.String,
+     * java.lang.Object)
+     */
+    @Override
+    public void sendEvent(final long executionId, final String eventName, final Object event) {
+        // Check if this is a synchronized event, if so we have received a reply
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        if (synchronousEventCache != null) {
+            synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+        }
+
+        // Kafka producer must be started in the same thread as it is stopped, so we must start it here
+        if (kafkaProducer == null) {
+            // Kick off the Kafka producer
+            kafkaProducer = new KafkaProducer<String, Object>(kafkaProducerProperties.getKafkaProducerProperties());
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("event producer " + this.name + " is ready to send to topics: "
+                        + kafkaProducerProperties.getProducerTopic());
+            }
+        }
+
+        kafkaProducer.send(new ProducerRecord<String, Object>(kafkaProducerProperties.getProducerTopic(), name, event));
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace("event sent from engine using {} to topic {} : {} ", this.name,
+                    kafkaProducerProperties.getProducerTopic(), event);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        if (kafkaProducer != null) {
+            kafkaProducer.flush();
+            kafkaProducer.close();
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/KAFKACarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/KAFKACarrierTechnologyParameters.java
new file mode 100644 (file)
index 0000000..2357b18
--- /dev/null
@@ -0,0 +1,396 @@
+/*-
+ * ============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.plugins.event.carrier.kafka;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Properties;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for Kafka as an event carrier technology.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class KAFKACarrierTechnologyParameters extends CarrierTechnologyParameters {
+    // @formatter:off
+    /** The label of this carrier technology. */
+    public static final String KAFKA_CARRIER_TECHNOLOGY_LABEL = "KAFKA";
+
+    /** The producer plugin class for the Kafka carrier technology. */
+    public static final String KAFKA_EVENT_PRODUCER_PLUGIN_CLASS = ApexKafkaProducer.class.getCanonicalName();
+
+    /** The consumer plugin class for the Kafka carrier technology. */
+    public static final String KAFKA_EVENT_CONSUMER_PLUGIN_CLASS = ApexKafkaConsumer.class.getCanonicalName();
+
+    // Default parameter values
+    private static final String   DEFAULT_ACKS                = "all";
+    private static final String   DEFAULT_BOOTSTRAP_SERVERS   = "localhost:9092";
+    private static final int      DEFAULT_RETRIES             = 0;
+    private static final int      DEFAULT_BATCH_SIZE          = 16384;
+    private static final int      DEFAULT_LINGER_TIME         = 1;
+    private static final long     DEFAULT_BUFFER_MEMORY       = 33554432;
+    private static final String   DEFAULT_GROUP_ID            = "default-group-id";
+    private static final boolean  DEFAULT_ENABLE_AUTO_COMMIT  = true;
+    private static final int      DEFAULT_AUTO_COMMIT_TIME    = 1000;
+    private static final int      DEFAULT_SESSION_TIMEOUT     = 30000;
+    private static final String   DEFAULT_PRODUCER_TOPIC      = "apex-out";
+    private static final int      DEFAULT_CONSUMER_POLL_TIME  = 100;
+    private static final String[] DEFAULT_CONSUMER_TOPIC_LIST = {"apex-in"};
+    private static final String   DEFAULT_KEY_SERIALIZER      = "org.apache.kafka.common.serialization.StringSerializer";
+    private static final String   DEFAULT_VALUE_SERIALIZER    = "org.apache.kafka.common.serialization.StringSerializer";
+    private static final String   DEFAULT_KEY_DESERIALIZER    = "org.apache.kafka.common.serialization.StringDeserializer";
+    private static final String   DEFAULT_VALUE_DESERIALIZER  = "org.apache.kafka.common.serialization.StringDeserializer";
+
+    // Parameter property map tokens
+    private static final String PROPERTY_BOOTSTRAP_SERVERS  = "bootstrap.servers";
+    private static final String PROPERTY_ACKS               = "acks";
+    private static final String PROPERTY_RETRIES            = "retries";
+    private static final String PROPERTY_BATCH_SIZE         = "batch.size";
+    private static final String PROPERTY_LINGER_TIME        = "linger.ms";
+    private static final String PROPERTY_BUFFER_MEMORY      = "buffer.memory";
+    private static final String PROPERTY_GROUP_ID           = "group.id";
+    private static final String PROPERTY_ENABLE_AUTO_COMMIT = "enable.auto.commit";
+    private static final String PROPERTY_AUTO_COMMIT_TIME   = "auto.commit.interval.ms";
+    private static final String PROPERTY_SESSION_TIMEOUT    = "session.timeout.ms";
+    private static final String PROPERTY_KEY_SERIALIZER     = "key.serializer";
+    private static final String PROPERTY_VALUE_SERIALIZER   = "value.serializer";
+    private static final String PROPERTY_KEY_DESERIALIZER   = "key.deserializer";
+    private static final String PROPERTY_VALUE_DESERIALIZER = "value.deserializer";
+
+    // kafka carrier parameters
+    private String   bootstrapServers  = DEFAULT_BOOTSTRAP_SERVERS;
+    private String   acks              = DEFAULT_ACKS;
+    private int      retries           = DEFAULT_RETRIES;
+    private int      batchSize         = DEFAULT_BATCH_SIZE;
+    private int      lingerTime        = DEFAULT_LINGER_TIME;
+    private long     bufferMemory      = DEFAULT_BUFFER_MEMORY;
+    private String   groupId           = DEFAULT_GROUP_ID;
+    private boolean  enableAutoCommit  = DEFAULT_ENABLE_AUTO_COMMIT;
+    private int      autoCommitTime    = DEFAULT_AUTO_COMMIT_TIME;
+    private int      sessionTimeout    = DEFAULT_SESSION_TIMEOUT;
+    private String   producerTopic     = DEFAULT_PRODUCER_TOPIC;
+    private int      consumerPollTime  = DEFAULT_CONSUMER_POLL_TIME;
+    private String[] consumerTopicList = DEFAULT_CONSUMER_TOPIC_LIST;
+    private String   keySerializer     = DEFAULT_KEY_SERIALIZER;
+    private String   valueSerializer   = DEFAULT_VALUE_SERIALIZER;
+    private String   keyDeserializer   = DEFAULT_KEY_DESERIALIZER;
+    private String   valueDeserializer = DEFAULT_VALUE_DESERIALIZER;
+    // @formatter:on
+
+    /**
+     * Constructor to create a kafka carrier technology parameters instance and register the instance with the parameter
+     * service.
+     */
+    public KAFKACarrierTechnologyParameters() {
+        super(KAFKACarrierTechnologyParameters.class.getCanonicalName());
+
+        // Set the carrier technology properties for the kafka carrier technology
+        this.setLabel(KAFKA_CARRIER_TECHNOLOGY_LABEL);
+        this.setEventProducerPluginClass(KAFKA_EVENT_PRODUCER_PLUGIN_CLASS);
+        this.setEventConsumerPluginClass(KAFKA_EVENT_CONSUMER_PLUGIN_CLASS);
+    }
+
+    /**
+     * Gets the kafka producer properties.
+     *
+     * @return the kafka producer properties
+     */
+    public Properties getKafkaProducerProperties() {
+        final Properties kafkaProperties = new Properties();
+
+        kafkaProperties.put(PROPERTY_BOOTSTRAP_SERVERS, bootstrapServers);
+        kafkaProperties.put(PROPERTY_ACKS, acks);
+        kafkaProperties.put(PROPERTY_RETRIES, retries);
+        kafkaProperties.put(PROPERTY_BATCH_SIZE, batchSize);
+        kafkaProperties.put(PROPERTY_LINGER_TIME, lingerTime);
+        kafkaProperties.put(PROPERTY_BUFFER_MEMORY, bufferMemory);
+        kafkaProperties.put(PROPERTY_KEY_SERIALIZER, keySerializer);
+        kafkaProperties.put(PROPERTY_VALUE_SERIALIZER, valueSerializer);
+
+        return kafkaProperties;
+    }
+
+    /**
+     * Gets the kafka consumer properties.
+     *
+     * @return the kafka consumer properties
+     */
+    public Properties getKafkaConsumerProperties() {
+        final Properties kafkaProperties = new Properties();
+
+        kafkaProperties.put(PROPERTY_BOOTSTRAP_SERVERS, bootstrapServers);
+        kafkaProperties.put(PROPERTY_GROUP_ID, groupId);
+        kafkaProperties.put(PROPERTY_ENABLE_AUTO_COMMIT, enableAutoCommit);
+        kafkaProperties.put(PROPERTY_AUTO_COMMIT_TIME, autoCommitTime);
+        kafkaProperties.put(PROPERTY_SESSION_TIMEOUT, sessionTimeout);
+        kafkaProperties.put(PROPERTY_KEY_DESERIALIZER, keyDeserializer);
+        kafkaProperties.put(PROPERTY_VALUE_DESERIALIZER, valueDeserializer);
+
+        return kafkaProperties;
+    }
+
+    /**
+     * Gets the bootstrap servers.
+     *
+     * @return the bootstrap servers
+     */
+    public String getBootstrapServers() {
+        return bootstrapServers;
+    }
+
+    /**
+     * Gets the acks.
+     *
+     * @return the acks
+     */
+    public String getAcks() {
+        return acks;
+    }
+
+    /**
+     * Gets the retries.
+     *
+     * @return the retries
+     */
+    public int getRetries() {
+        return retries;
+    }
+
+    /**
+     * Gets the batch size.
+     *
+     * @return the batch size
+     */
+    public int getBatchSize() {
+        return batchSize;
+    }
+
+    /**
+     * Gets the linger time.
+     *
+     * @return the linger time
+     */
+    public int getLingerTime() {
+        return lingerTime;
+    }
+
+    /**
+     * Gets the buffer memory.
+     *
+     * @return the buffer memory
+     */
+    public long getBufferMemory() {
+        return bufferMemory;
+    }
+
+    /**
+     * Gets the group id.
+     *
+     * @return the group id
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    /**
+     * Checks if is enable auto commit.
+     *
+     * @return true, if checks if is enable auto commit
+     */
+    public boolean isEnableAutoCommit() {
+        return enableAutoCommit;
+    }
+
+    /**
+     * Gets the auto commit time.
+     *
+     * @return the auto commit time
+     */
+    public int getAutoCommitTime() {
+        return autoCommitTime;
+    }
+
+    /**
+     * Gets the session timeout.
+     *
+     * @return the session timeout
+     */
+    public int getSessionTimeout() {
+        return sessionTimeout;
+    }
+
+    /**
+     * Gets the producer topic.
+     *
+     * @return the producer topic
+     */
+    public String getProducerTopic() {
+        return producerTopic;
+    }
+
+    /**
+     * Gets the consumer poll time.
+     *
+     * @return the consumer poll time
+     */
+    public long getConsumerPollTime() {
+        return consumerPollTime;
+    }
+
+    /**
+     * Gets the consumer topic list.
+     *
+     * @return the consumer topic list
+     */
+    public Collection<String> getConsumerTopicList() {
+        return Arrays.asList(consumerTopicList);
+    }
+
+    /**
+     * Gets the key serializer.
+     *
+     * @return the key serializer
+     */
+    public String getKeySerializer() {
+        return keySerializer;
+    }
+
+    /**
+     * Gets the value serializer.
+     *
+     * @return the value serializer
+     */
+    public String getValueSerializer() {
+        return valueSerializer;
+    }
+
+    /**
+     * Gets the key deserializer.
+     *
+     * @return the key deserializer
+     */
+    public String getKeyDeserializer() {
+        return keyDeserializer;
+    }
+
+    /**
+     * Gets the value deserializer.
+     *
+     * @return the value deserializer
+     */
+    public String getValueDeserializer() {
+        return valueDeserializer;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+     */
+    @Override
+    public String validate() {
+        final StringBuilder errorMessageBuilder = new StringBuilder();
+
+        errorMessageBuilder.append(super.validate());
+
+        if (bootstrapServers == null || bootstrapServers.trim().length() == 0) {
+            errorMessageBuilder
+                    .append("  bootstrapServers not specified, must be specified as a string of form host:port\n");
+        }
+
+        if (acks == null || acks.trim().length() == 0) {
+            errorMessageBuilder.append("  acks not specified, must be specified as a string with values [0|1|all]\n");
+        }
+
+        if (retries < 0) {
+            errorMessageBuilder.append("  retries [" + retries + "] invalid, must be specified as retries >= 0\n");
+        }
+
+        if (batchSize < 0) {
+            errorMessageBuilder
+                    .append("  batchSize [" + batchSize + "] invalid, must be specified as batchSize >= 0\n");
+        }
+
+        if (lingerTime < 0) {
+            errorMessageBuilder
+                    .append("  lingerTime [" + lingerTime + "] invalid, must be specified as lingerTime >= 0\n");
+        }
+
+        if (bufferMemory < 0) {
+            errorMessageBuilder
+                    .append("  bufferMemory [" + bufferMemory + "] invalid, must be specified as bufferMemory >= 0\n");
+        }
+
+        if (groupId == null || groupId.trim().length() == 0) {
+            errorMessageBuilder.append("  groupId not specified, must be specified as a string\n");
+        }
+
+        if (autoCommitTime < 0) {
+            errorMessageBuilder.append(
+                    "  autoCommitTime [" + autoCommitTime + "] invalid, must be specified as autoCommitTime >= 0\n");
+        }
+
+        if (sessionTimeout < 0) {
+            errorMessageBuilder.append(
+                    "  sessionTimeout [" + sessionTimeout + "] invalid, must be specified as sessionTimeout >= 0\n");
+        }
+
+        if (producerTopic == null || producerTopic.trim().length() == 0) {
+            errorMessageBuilder.append("  producerTopic not specified, must be specified as a string\n");
+        }
+
+        if (consumerPollTime < 0) {
+            errorMessageBuilder.append("  consumerPollTime [" + consumerPollTime
+                    + "] invalid, must be specified as consumerPollTime >= 0\n");
+        }
+
+        if (consumerTopicList == null || consumerTopicList.length == 0) {
+            errorMessageBuilder.append("  consumerTopicList not specified, must be specified as a list of strings\n");
+        }
+
+        for (final String consumerTopic : consumerTopicList) {
+            if (consumerTopic == null || consumerTopic.trim().length() == 0) {
+                errorMessageBuilder.append("  invalid consumer topic \"" + consumerTopic
+                        + "\" specified on consumerTopicList, consumer topics must be specified as strings\n");
+            }
+        }
+
+        if (keySerializer == null || keySerializer.trim().length() == 0) {
+            errorMessageBuilder.append("  keySerializer not specified, must be specified as a string\n");
+        }
+
+        if (valueSerializer == null || valueSerializer.trim().length() == 0) {
+            errorMessageBuilder.append("  valueSerializer not specified, must be specified as a string\n");
+        }
+
+        if (keyDeserializer == null || keyDeserializer.trim().length() == 0) {
+            errorMessageBuilder.append("  keyDeserializer not specified, must be specified as a string\n");
+        }
+
+        if (valueDeserializer == null || valueDeserializer.trim().length() == 0) {
+            errorMessageBuilder.append("  valueDeserializer not specified, must be specified as a string\n");
+        }
+
+        return errorMessageBuilder.toString();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-kafka/src/main/java/org/onap/policy/apex/plugins/event/carrier/kafka/package-info.java
new file mode 100644 (file)
index 0000000..f04aace
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Implements the APEX event carrier technology plugin for Kafka.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.kafka;
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/pom.xml
new file mode 100644 (file)
index 0000000..8be1131
--- /dev/null
@@ -0,0 +1,49 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+        <artifactId>plugins-event-carrier</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-carrier-restclient</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling events being transported over REST where Apex acts as a REST client</description>
+
+    <properties>
+        <apex-plugins-event-carrier-restclient-dir>${project.basedir}/src</apex-plugins-event-carrier-restclient-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>${version.jersey.core}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.services</groupId>
+            <artifactId>services-engine</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientConsumer.java
new file mode 100644 (file)
index 0000000..b9348d4
--- /dev/null
@@ -0,0 +1,233 @@
+/*-
+ * ============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.plugins.event.carrier.restclient;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.Response;
+
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an Apex event consumer that receives events from a REST server.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexRestClientConsumer implements ApexEventConsumer, Runnable {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestClientConsumer.class);
+
+    // The amount of time to wait in milliseconds between checks that the consumer thread has stopped
+    private static final long REST_CLIENT_WAIT_SLEEP_TIME = 50;
+
+    // The REST parameters read from the parameter service
+    private RESTClientCarrierTechnologyParameters restConsumerProperties;
+
+    // The event receiver that will receive events from this consumer
+    private ApexEventReceiver eventReceiver;
+
+    // The HTTP client that makes a REST call to get an input event for Apex
+    private Client client;
+
+    // The name for this consumer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    // The consumer thread and stopping flag
+    private Thread consumerThread;
+    private boolean stopOrderedFlag = false;
+
+    @Override
+    public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+            final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+        this.eventReceiver = incomingEventReceiver;
+        this.name = consumerName;
+
+        // Check and get the REST Properties
+        if (!(consumerParameters.getCarrierTechnologyParameters() instanceof RESTClientCarrierTechnologyParameters)) {
+            final String errorMessage =
+                    "specified consumer properties are not applicable to REST client consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        restConsumerProperties =
+                (RESTClientCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+        // Check if the HTTP method has been set
+        if (restConsumerProperties.getHttpMethod() == null) {
+            restConsumerProperties.setHttpMethod(RESTClientCarrierTechnologyParameters.CONSUMER_HTTP_METHOD);
+        }
+
+        if (!restConsumerProperties.getHttpMethod()
+                .equalsIgnoreCase(RESTClientCarrierTechnologyParameters.CONSUMER_HTTP_METHOD)) {
+            final String errorMessage = "specified HTTP method of \"" + restConsumerProperties.getHttpMethod()
+                    + "\" is invalid, only HTTP method \"GET\" is supported for event reception on REST client consumer ("
+                    + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Initialize the HTTP client
+        client = ClientBuilder.newClient();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+     */
+    @Override
+    public void start() {
+        // Configure and start the event reception thread
+        final String threadName = this.getClass().getName() + ":" + this.name;
+        consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+        consumerThread.setDaemon(true);
+        consumerThread.start();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        // The RequestRunner thread runs the get request for the event
+        Thread requestRunnerThread = null;
+
+        // The endless loop that receives events using REST calls
+        while (consumerThread.isAlive() && !stopOrderedFlag) {
+            // Create a new request if one is not in progress
+            if (requestRunnerThread == null || !requestRunnerThread.isAlive()) {
+                requestRunnerThread = new Thread(new RequestRunner());
+                requestRunnerThread.start();
+            }
+
+            ThreadUtilities.sleep(REST_CLIENT_WAIT_SLEEP_TIME);
+        }
+
+        client.close();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventConsumer#stop()
+     */
+    @Override
+    public void stop() {
+        stopOrderedFlag = true;
+
+        while (consumerThread.isAlive()) {
+            ThreadUtilities.sleep(REST_CLIENT_WAIT_SLEEP_TIME);
+        }
+    }
+
+    /**
+     * This class is used to start a thread for each request issued.
+     *
+     * @author Liam Fallon (liam.fallon@ericsson.com)
+     */
+    private class RequestRunner implements Runnable {
+        /*
+         * (non-Javadoc)
+         *
+         * @see java.lang.Runnable#run()
+         */
+        @Override
+        public void run() {
+            try {
+                final Response response =
+                        client.target(restConsumerProperties.getURL()).request("application/json").get();
+
+                // Check that the event request worked
+                if (response.getStatus() != Response.Status.OK.getStatusCode()) {
+                    final String errorMessage = "reception of event from URL \"" + restConsumerProperties.getURL()
+                            + "\" failed with status code " + response.getStatus() + " and message \""
+                            + response.readEntity(String.class) + "\"";
+                    throw new ApexEventRuntimeException(errorMessage);
+                }
+
+                // Get the event we received
+                final String eventJSONString = response.readEntity(String.class);
+
+                // Check there is content
+                if (eventJSONString == null || eventJSONString.trim().length() == 0) {
+                    final String errorMessage =
+                            "received an empty event from URL \"" + restConsumerProperties.getURL() + "\"";
+                    throw new ApexEventRuntimeException(errorMessage);
+                }
+
+                // Send the event into Apex
+                eventReceiver.receiveEvent(eventJSONString);
+            } catch (final Exception e) {
+                LOGGER.warn("error receiving events on thread {}", consumerThread.getName(), e);
+            }
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java
new file mode 100644 (file)
index 0000000..9d838f5
--- /dev/null
@@ -0,0 +1,191 @@
+/*-
+ * ============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.plugins.event.carrier.restclient;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event producer that sends events using REST.
+ *
+ * @author Joss Armstrong (joss.armstrong@ericsson.com)
+ *
+ */
+public class ApexRestClientProducer implements ApexEventProducer {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestClientProducer.class);
+
+    // The HTTP client that makes a REST call with an event from Apex
+    private Client client;
+
+    // The REST carrier properties
+    private RESTClientCarrierTechnologyParameters restProducerProperties;
+
+    // The name for this producer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String,
+     * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters)
+     */
+    @Override
+    public void init(final String producerName, final EventHandlerParameters producerParameters)
+            throws ApexEventException {
+        this.name = producerName;
+
+        // Check and get the REST Properties
+        if (!(producerParameters.getCarrierTechnologyParameters() instanceof RESTClientCarrierTechnologyParameters)) {
+            final String errorMessage =
+                    "specified consumer properties are not applicable to REST client producer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        restProducerProperties =
+                (RESTClientCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+
+        // Check if the HTTP method has been set
+        if (restProducerProperties.getHttpMethod() == null) {
+            restProducerProperties.setHttpMethod(RESTClientCarrierTechnologyParameters.DEFAULT_PRODUCER_HTTP_METHOD);
+        }
+
+        if (!restProducerProperties.getHttpMethod().equalsIgnoreCase("POST")
+                && !restProducerProperties.getHttpMethod().equalsIgnoreCase("PUT")) {
+            final String errorMessage = "specified HTTP method of \"" + restProducerProperties.getHttpMethod()
+                    + "\" is invalid, only HTTP methods \"POST\" and \"PUT\" are supproted for event sending on REST client producer ("
+                    + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Initialize the HTTP client
+        client = ClientBuilder.newClient();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang. String,
+     * java.lang.Object)
+     */
+    @Override
+    public void sendEvent(final long executionId, final String eventName, final Object event) {
+        // Check if this is a synchronized event, if so we have received a reply
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        if (synchronousEventCache != null) {
+            synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+        }
+
+        // Send the event as a REST request
+        final Response response = sendEventAsRESTRequest((String) event);
+
+        // Check that the request worked
+        if (response.getStatus() != Response.Status.OK.getStatusCode()) {
+            final String errorMessage = "send of event to URL \"" + restProducerProperties.getURL() + "\" using HTTP \""
+                    + restProducerProperties.getHttpMethod() + "\" failed with status code " + response.getStatus()
+                    + " and message \"" + response.readEntity(String.class) + "\", event:\n" + event;
+            LOGGER.warn(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+
+        if (LOGGER.isTraceEnabled()) {
+            LOGGER.trace("event sent from engine using {} to URL {} with HTTP {} : {} and response {} ", this.name,
+                    restProducerProperties.getURL(), restProducerProperties.getHttpMethod(), event, response);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        // Close the HTTP session
+        client.close();
+    }
+
+    /**
+     * Send the event as a JSON string as a REST request.
+     *
+     * @param event the event to send
+     * @return the response tot he JSON request
+     */
+    public Response sendEventAsRESTRequest(final String event) {
+        // We have already checked that it is a PUT or POST request
+        if (restProducerProperties.getHttpMethod().equalsIgnoreCase("POST")) {
+            return client.target(restProducerProperties.getURL()).request("application/json").post(Entity.json(event));
+        } else {
+            return client.target(restProducerProperties.getURL()).request("application/json").put(Entity.json(event));
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RESTClientCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RESTClientCarrierTechnologyParameters.java
new file mode 100644 (file)
index 0000000..e07593c
--- /dev/null
@@ -0,0 +1,134 @@
+/*-
+ * ============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.plugins.event.carrier.restclient;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for REST as an event carrier technology with Apex as a REST client.
+ *
+ * The parameters for this plugin are:
+ * <ol>
+ * <li>url: The URL that the Apex Rest client will connect to over REST for event reception or event sending. This
+ * parameter is mandatory.
+ * <li>httpMethod: The HTTP method to use when sending events over REST, legal values are POST (default) and PUT. When
+ * receiving events, the REST client plugin always uses the HTTP GET method.
+ * </ol>
+ *
+ * @author Joss Armstrong (joss.armstrong@ericsson.com)
+ */
+public class RESTClientCarrierTechnologyParameters extends CarrierTechnologyParameters {
+
+    /** The label of this carrier technology. */
+    public static final String RESTCLIENT_CARRIER_TECHNOLOGY_LABEL = "RESTCLIENT";
+
+    /** The producer plugin class for the REST carrier technology. */
+    public static final String RESTCLIENT_EVENT_PRODUCER_PLUGIN_CLASS = ApexRestClientProducer.class.getCanonicalName();
+
+    /** The consumer plugin class for the REST carrier technology. */
+    public static final String RESTCLIENT_EVENT_CONSUMER_PLUGIN_CLASS = ApexRestClientConsumer.class.getCanonicalName();
+
+    /** The default HTTP method for output of events. */
+    public static final String DEFAULT_PRODUCER_HTTP_METHOD = "POST";
+
+    /** The HTTP method for input of events. */
+    public static final String CONSUMER_HTTP_METHOD = "GET";
+
+    private String url = null;
+    private String httpMethod = null;
+
+    /**
+     * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter
+     * service.
+     */
+    public RESTClientCarrierTechnologyParameters() {
+        super(RESTClientCarrierTechnologyParameters.class.getCanonicalName());
+
+        // Set the carrier technology properties for the web socket carrier technology
+        this.setLabel(RESTCLIENT_CARRIER_TECHNOLOGY_LABEL);
+        this.setEventProducerPluginClass(RESTCLIENT_EVENT_PRODUCER_PLUGIN_CLASS);
+        this.setEventConsumerPluginClass(RESTCLIENT_EVENT_CONSUMER_PLUGIN_CLASS);
+
+    }
+
+    /**
+     * Gets the URL for the REST request.
+     *
+     * @return the URL
+     */
+    public String getURL() {
+        return url;
+    }
+
+    /**
+     * Sets the URL for the REST request.
+     *
+     * @param incomingURL the URL
+     */
+    public void setURL(final String incomingURL) {
+        this.url = incomingURL;
+    }
+
+    /**
+     * Gets the HTTP method to use for the REST request.
+     *
+     * @return the HTTP method
+     */
+    public String getHttpMethod() {
+        return httpMethod;
+    }
+
+    /**
+     * Sets the HTTP method to use for the REST request.
+     *
+     * @param httpMethod the HTTP method
+     */
+    public void setHttpMethod(final String httpMethod) {
+        this.httpMethod = httpMethod;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "RESTClientCarrierTechnologyParameters [url=" + url + ", httpMethod=" + httpMethod + "]";
+    }
+
+
+    /*
+     *
+     * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+     */
+    @Override
+    public String validate() {
+        final StringBuilder errorMessageBuilder = new StringBuilder();
+
+        // Check if the URL has been set for event output
+        if (getURL() == null) {
+            errorMessageBuilder.append("  no URL has been set for event sending on REST client");
+        }
+
+        return errorMessageBuilder.toString();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/package-info.java
new file mode 100644 (file)
index 0000000..e674bee
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * APEX REST consumer and producer plugins when APEX is acting as a REST client.
+ *
+ * @author Joss Armstrong (joss.armstrong@ericsson.com)
+ *
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.restclient;
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/pom.xml
new file mode 100644 (file)
index 0000000..8a54193
--- /dev/null
@@ -0,0 +1,67 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+        <artifactId>plugins-event-carrier</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-carrier-restrequestor</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling REST requests and responses</description>
+
+    <properties>
+        <apex-plugins-event-carrier-restrequestor-dir>${project.basedir}/src</apex-plugins-event-carrier-restrequestor-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>${version.jersey.core}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.services</groupId>
+            <artifactId>services-engine</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-grizzly2-http</artifactId>
+            <version>${version.grizzly2-http}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-executor</groupId>
+            <artifactId>plugins-executor-mvel</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.context</groupId>
+            <artifactId>context-test</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java
new file mode 100644 (file)
index 0000000..46e68ac
--- /dev/null
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.restrequestor;
+
+/**
+ * This class holds a record of a REST request for the REST requestor plugin
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexRestRequest {
+    private long executionId;
+    private String eventName;
+    private Object event;
+    private long timestamp;
+
+    public ApexRestRequest(final long executionId, final String eventName, final Object event) {
+        this.executionId = executionId;
+        this.eventName = eventName;
+        this.event = event;
+    }
+
+    public long getExecutionId() {
+        return executionId;
+    }
+
+    public String getEventName() {
+        return eventName;
+    }
+
+    public Object getEvent() {
+        return event;
+    }
+
+    public long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(final long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @Override
+    public String toString() {
+        return "ApexRestRequest [executionId=" + executionId + ", eventName=" + eventName + ", event=" + event
+                + ", timestamp=" + timestamp + "]";
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java
new file mode 100644 (file)
index 0000000..7350532
--- /dev/null
@@ -0,0 +1,416 @@
+/*-
+ * ============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.plugins.event.carrier.restrequestor;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters.HTTP_METHOD;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an Apex event consumer that issues a REST request and returns the REST response to APEX as an
+ * event.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexRestRequestorConsumer implements ApexEventConsumer, Runnable {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestRequestorConsumer.class);
+
+    // The amount of time to wait in milliseconds between checks that the consumer thread has stopped
+    private static final long REST_REQUESTOR_WAIT_SLEEP_TIME = 50;
+
+    // The REST parameters read from the parameter service
+    private RESTRequestorCarrierTechnologyParameters restConsumerProperties;
+
+    // The timeout for REST requests
+    private long restRequestTimeout = RESTRequestorCarrierTechnologyParameters.DEFAULT_REST_REQUEST_TIMEOUT;
+
+    // The event receiver that will receive events from this consumer
+    private ApexEventReceiver eventReceiver;
+
+    // The HTTP client that makes a REST call to get an input event for Apex
+    private Client client;
+
+    // The name for this consumer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    // The consumer thread and stopping flag
+    private Thread consumerThread;
+    private boolean stopOrderedFlag = false;
+
+    // Temporary request holder for incoming REST requests
+    private final BlockingQueue<ApexRestRequest> incomingRestRequestQueue = new LinkedBlockingQueue<>();
+
+    // Map of ongoing REST request threads indexed by the time they started at
+    private final Map<ApexRestRequest, RestRequestRunner> ongoingRestRequestMap = new ConcurrentHashMap<>();
+
+    // The number of events received to date
+    private Object eventsReceivedLock = new Object();
+    private Integer eventsReceived = 0;
+
+    // The number of the next request runner thread
+    private static long nextRequestRunnerThreadNo = 0;
+
+    @Override
+    public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+            final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+        this.eventReceiver = incomingEventReceiver;
+        this.name = consumerName;
+
+        // Check and get the REST Properties
+        if (!(consumerParameters
+                .getCarrierTechnologyParameters() instanceof RESTRequestorCarrierTechnologyParameters)) {
+            final String errorMessage =
+                    "specified consumer properties are not applicable to REST Requestor consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        restConsumerProperties =
+                (RESTRequestorCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+        // Check if we are in peered mode
+        if (!consumerParameters.isPeeredMode(EventHandlerPeeredMode.REQUESTOR)) {
+            final String errorMessage = "REST Requestor consumer (" + this.name
+                    + ") must run in peered requestor mode with a REST Requestor producer";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if the HTTP method has been set
+        if (restConsumerProperties.getHttpMethod() == null) {
+            restConsumerProperties
+                    .setHttpMethod(RESTRequestorCarrierTechnologyParameters.DEFAULT_REQUESTOR_HTTP_METHOD);
+        }
+
+        if (!(restConsumerProperties.getHttpMethod() instanceof HTTP_METHOD)) {
+            final String errorMessage = "specified HTTP method of \"" + restConsumerProperties.getHttpMethod()
+                    + "\" is invalid, only HTTP methods " + HTTP_METHOD.values()
+                    + " are valid on REST Requestor consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if the HTTP URL has been set
+        if (restConsumerProperties.getURL() == null) {
+            final String errorMessage = "no URL has been specified on REST Requestor consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if the HTTP URL is valid
+        try {
+            new URL(restConsumerProperties.getURL());
+        } catch (final Exception e) {
+            final String errorMessage = "invalid URL has been specified on REST Requestor consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage, e);
+        }
+
+        // Set the peer timeout to the default value if its not set
+        if (consumerParameters.getPeerTimeout(EventHandlerPeeredMode.REQUESTOR) != 0) {
+            restRequestTimeout = consumerParameters.getPeerTimeout(EventHandlerPeeredMode.REQUESTOR);
+        }
+
+        // Initialize the HTTP client
+        client = ClientBuilder.newClient();
+    }
+
+    /**
+     * Receive an incoming REST request from the peered REST Requestor producer and queue it
+     *
+     * @param restRequest the incoming rest request to queue
+     * @throws ApexEventRuntimeException on queueing errors
+     */
+    public void processRestRequest(final ApexRestRequest restRequest) {
+        // Push the event onto the queue for handling
+        try {
+            incomingRestRequestQueue.add(restRequest);
+        } catch (final Exception e) {
+            final String errorMessage =
+                    "could not queue request \"" + restRequest + "\" on REST Requestor consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+     */
+    @Override
+    public void start() {
+        // Configure and start the event reception thread
+        final String threadName = this.getClass().getName() + ":" + this.name;
+        consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+        consumerThread.setDaemon(true);
+        consumerThread.start();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the number of events received to date
+     *
+     * @return the number of events received
+     */
+    public int getEventsReceived() {
+        return eventsReceived;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        // The endless loop that receives events using REST calls
+        while (consumerThread.isAlive() && !stopOrderedFlag) {
+            try {
+                // Take the next event from the queue
+                final ApexRestRequest restRequest =
+                        incomingRestRequestQueue.poll(REST_REQUESTOR_WAIT_SLEEP_TIME, TimeUnit.MILLISECONDS);
+                if (restRequest == null) {
+                    // Poll timed out, check for request timeouts
+                    timeoutExpiredRequests();
+                    continue;
+                }
+
+                // Set the time stamp of the REST request
+                restRequest.setTimestamp(System.currentTimeMillis());
+
+                // Create a thread to process the REST request and place it on the map of ongoing requests
+                final RestRequestRunner restRequestRunner = new RestRequestRunner(restRequest);
+                ongoingRestRequestMap.put(restRequest, restRequestRunner);
+
+                // Start execution of the request
+                final Thread restRequestRunnerThread = new Thread(restRequestRunner);
+                restRequestRunnerThread.setName("RestRequestRunner_" + nextRequestRunnerThreadNo);
+                restRequestRunnerThread.start();
+            } catch (final InterruptedException e) {
+                LOGGER.debug("Thread interrupted, Reason {}", e.getMessage());
+                Thread.currentThread().interrupt();
+            }
+        }
+
+        client.close();
+    }
+
+    /**
+     * This method times out REST requests that have expired
+     */
+    private void timeoutExpiredRequests() {
+        // Hold a list of timed out requests
+        final List<ApexRestRequest> timedoutRequestList = new ArrayList<>();
+
+        // Check for timeouts
+        for (final Entry<ApexRestRequest, RestRequestRunner> requestEntry : ongoingRestRequestMap.entrySet()) {
+            if (System.currentTimeMillis() - requestEntry.getKey().getTimestamp() > restRequestTimeout) {
+                requestEntry.getValue().stop();
+                timedoutRequestList.add(requestEntry.getKey());
+            }
+        }
+
+        // Interrupt timed out requests and remove them from the ongoing map
+        for (final ApexRestRequest timedoutRequest : timedoutRequestList) {
+            final String errorMessage =
+                    "REST Requestor consumer (" + this.name + "), REST request timed out: " + timedoutRequest;
+            LOGGER.warn(errorMessage);
+
+            ongoingRestRequestMap.remove(timedoutRequest);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventConsumer#stop()
+     */
+    @Override
+    public void stop() {
+        stopOrderedFlag = true;
+
+        while (consumerThread.isAlive()) {
+            ThreadUtilities.sleep(REST_REQUESTOR_WAIT_SLEEP_TIME);
+        }
+    }
+
+    /**
+     * This class is used to start a thread for each request issued.
+     *
+     * @author Liam Fallon (liam.fallon@ericsson.com)
+     */
+    private class RestRequestRunner implements Runnable {
+        private static final String APPLICATION_JSON = "application/json";
+
+        // The REST request being processed by this thread
+        private final ApexRestRequest request;
+
+        // The thread executing the REST request
+        private Thread restRequestThread;
+
+        /**
+         * Constructor, initialise the request runner with the request
+         *
+         * @param request the request this runner will issue
+         */
+        private RestRequestRunner(final ApexRestRequest request) {
+            this.request = request;
+        }
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see java.lang.Runnable#run()
+         */
+        @Override
+        public void run() {
+            // Get the thread for the request
+            restRequestThread = Thread.currentThread();
+
+            try {
+                // Execute the REST request
+                final Response response = sendEventAsRESTRequest();
+
+                // Check that the event request worked
+                if (response.getStatus() != Response.Status.OK.getStatusCode()) {
+                    final String errorMessage = "reception of response to \"" + request + "\" from URL \""
+                            + restConsumerProperties.getURL() + "\" failed with status code " + response.getStatus()
+                            + " and message \"" + response.readEntity(String.class) + "\"";
+                    throw new ApexEventRuntimeException(errorMessage);
+                }
+
+                // Get the event we received
+                final String eventJSONString = response.readEntity(String.class);
+
+                // Check there is content
+                if (eventJSONString == null || eventJSONString.trim().length() == 0) {
+                    final String errorMessage = "received an enpty response to \"" + request + "\" from URL \""
+                            + restConsumerProperties.getURL() + "\"";
+                    throw new ApexEventRuntimeException(errorMessage);
+                }
+
+                // Send the event into Apex
+                eventReceiver.receiveEvent(request.getExecutionId(), eventJSONString);
+
+                synchronized (eventsReceivedLock) {
+                    eventsReceived++;
+                }
+            } catch (final Exception e) {
+                LOGGER.warn("error receiving events on thread {}", consumerThread.getName(), e);
+            } finally {
+                // Remove the request from the map of ongoing requests
+                ongoingRestRequestMap.remove(request);
+            }
+        }
+
+        /**
+         * Stop the REST request
+         */
+        private void stop() {
+            restRequestThread.interrupt();
+        }
+
+        /**
+         * Execute the REST request.
+         *
+         * @return the response to the REST request
+         */
+        public Response sendEventAsRESTRequest() {
+            switch (restConsumerProperties.getHttpMethod()) {
+                case GET:
+                    return client.target(restConsumerProperties.getURL()).request(APPLICATION_JSON).get();
+
+                case PUT:
+                    return client.target(restConsumerProperties.getURL()).request(APPLICATION_JSON)
+                            .put(Entity.json(request.getEvent()));
+
+                case POST:
+                    return client.target(restConsumerProperties.getURL()).request(APPLICATION_JSON)
+                            .post(Entity.json(request.getEvent()));
+
+                case DELETE:
+                    return client.target(restConsumerProperties.getURL()).request(APPLICATION_JSON).delete();
+            }
+
+            return null;
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java
new file mode 100644 (file)
index 0000000..12f1945
--- /dev/null
@@ -0,0 +1,195 @@
+/*-
+ * ============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.plugins.event.carrier.restrequestor;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event requestor that manages the producer side of a REST request.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ *
+ */
+public class ApexRestRequestorProducer implements ApexEventProducer {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestRequestorProducer.class);
+
+    // The REST carrier properties
+    private RESTRequestorCarrierTechnologyParameters restProducerProperties;
+
+    // The name for this producer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    // The number of events sent
+    private int eventsSent = 0;
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String,
+     * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters)
+     */
+    @Override
+    public void init(final String producerName, final EventHandlerParameters producerParameters)
+            throws ApexEventException {
+        this.name = producerName;
+
+        // Check and get the REST Properties
+        if (!(producerParameters
+                .getCarrierTechnologyParameters() instanceof RESTRequestorCarrierTechnologyParameters)) {
+            final String errorMessage =
+                    "specified consumer properties are not applicable to REST requestor producer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        restProducerProperties =
+                (RESTRequestorCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+
+        // Check if we are in peered mode
+        if (!producerParameters.isPeeredMode(EventHandlerPeeredMode.REQUESTOR)) {
+            final String errorMessage = "REST Requestor producer (" + this.name
+                    + ") must run in peered requestor mode with a REST Requestor consumer";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if the HTTP URL has been set
+        if (restProducerProperties.getURL() != null) {
+            final String errorMessage = "URL may not be specified on REST Requestor producer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if the HTTP method has been set
+        if (restProducerProperties.getHttpMethod() != null) {
+            final String errorMessage =
+                    "HTTP method may not be specified on REST Requestor producer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the number of events sent to date
+     *
+     * @return the number of events received
+     */
+    public int getEventsSent() {
+        return eventsSent;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters.eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang. String,
+     * java.lang.Object)
+     */
+    @Override
+    public void sendEvent(final long executionId, final String eventName, final Object event) {
+        // Check if this is a synchronized event, if so we have received a reply
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        if (synchronousEventCache != null) {
+            synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+        }
+
+        // Find the peered consumer for this producer
+        final PeeredReference peeredRequestorReference = peerReferenceMap.get(EventHandlerPeeredMode.REQUESTOR);
+        if (peeredRequestorReference != null) {
+            // Find the REST Response Consumer that will handle this request
+            final ApexEventConsumer consumer = peeredRequestorReference.getPeeredConsumer();
+            if (!(consumer instanceof ApexRestRequestorConsumer)) {
+                final String errorMessage = "send of event to URL \"" + restProducerProperties.getURL() + "\" failed,"
+                        + " REST response consumer is not an instance of ApexRestRequestorConsumer\n" + event;
+                LOGGER.warn(errorMessage);
+                throw new ApexEventRuntimeException(errorMessage);
+            }
+
+            // Use the consumer to handle this event
+            final ApexRestRequestorConsumer restRequstConsumer = (ApexRestRequestorConsumer) consumer;
+            restRequstConsumer.processRestRequest(new ApexRestRequest(executionId, eventName, event));
+
+            eventsSent++;
+        } else {
+            // No peered consumer defined
+            final String errorMessage = "send of event to URL \"" + restProducerProperties.getURL() + "\" failed,"
+                    + " REST response consumer is not defined\n" + event;
+            LOGGER.warn(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        // For REST requestor, all the implementation is in the consumer
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RESTRequestorCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RESTRequestorCarrierTechnologyParameters.java
new file mode 100644 (file)
index 0000000..eb58700
--- /dev/null
@@ -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.plugins.event.carrier.restrequestor;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for REST as an event carrier technology with Apex issuing a REST request and receiving a REST
+ * response.
+ *
+ * The parameters for this plugin are:
+ * <ol>
+ * <li>url: The URL that the Apex Rest Requestor will connect to over REST for REST request sending. This parameter is
+ * mandatory.
+ * <li>httpMethod: The HTTP method to use when making requests over REST, legal values are GET (default), POST, PUT, and
+ * DELETE.
+ * <li>restRequestTimeout: The time in milliseconds to wait for a REST request to complete.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class RESTRequestorCarrierTechnologyParameters extends CarrierTechnologyParameters {
+    /** The supported HTTP methods. */
+    public enum HTTP_METHOD {
+        GET, PUT, POST, DELETE
+    }
+
+    /** The label of this carrier technology. */
+    public static final String RESTREQUESTOR_CARRIER_TECHNOLOGY_LABEL = "RESTREQUESTOR";
+
+    /** The producer plugin class for the REST carrier technology. */
+    public static final String RESTREQUSTOR_EVENT_PRODUCER_PLUGIN_CLASS =
+            ApexRestRequestorProducer.class.getCanonicalName();
+
+    /** The consumer plugin class for the REST carrier technology. */
+    public static final String RESTREQUSTOR_EVENT_CONSUMER_PLUGIN_CLASS =
+            ApexRestRequestorConsumer.class.getCanonicalName();
+
+    /** The default HTTP method for request events. */
+    public static final HTTP_METHOD DEFAULT_REQUESTOR_HTTP_METHOD = HTTP_METHOD.GET;
+
+    /** The default timeout for REST requests. */
+    public static final long DEFAULT_REST_REQUEST_TIMEOUT = 500;
+
+    private String url = null;
+    private HTTP_METHOD httpMethod = null;
+
+    /**
+     * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter
+     * service.
+     */
+    public RESTRequestorCarrierTechnologyParameters() {
+        super(RESTRequestorCarrierTechnologyParameters.class.getCanonicalName());
+
+        // Set the carrier technology properties for the web socket carrier technology
+        this.setLabel(RESTREQUESTOR_CARRIER_TECHNOLOGY_LABEL);
+        this.setEventProducerPluginClass(RESTREQUSTOR_EVENT_PRODUCER_PLUGIN_CLASS);
+        this.setEventConsumerPluginClass(RESTREQUSTOR_EVENT_CONSUMER_PLUGIN_CLASS);
+    }
+
+    /**
+     * Gets the URL for the REST request.
+     *
+     * @return the URL
+     */
+    public String getURL() {
+        return url;
+    }
+
+    /**
+     * Sets the URL for the REST request.
+     *
+     * @param incomingURL the URL
+     */
+    public void setURL(final String incomingURL) {
+        this.url = incomingURL;
+    }
+
+    /**
+     * Gets the HTTP method to use for the REST request.
+     *
+     * @return the HTTP method
+     */
+    public HTTP_METHOD getHttpMethod() {
+        return httpMethod;
+    }
+
+    /**
+     * Sets the HTTP method to use for the REST request.
+     *
+     * @param httpMethod the HTTP method
+     */
+    public void setHttpMethod(final HTTP_METHOD httpMethod) {
+        this.httpMethod = httpMethod;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#toString()
+     */
+
+    @Override
+    public String toString() {
+        return "RESTRequestorCarrierTechnologyParameters [url=" + url + ", httpMethod=" + httpMethod + "]";
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+     */
+    @Override
+    public String validate() {
+        return "";
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/package-info.java
new file mode 100644 (file)
index 0000000..904de13
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * APEX REST consumer and producer plugins when APEX sends a REST request and receives a REST response to a REST server.
+ *
+ * @author Joss Armstrong (joss.armstrong@ericsson.com)
+ *
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.restrequestor;
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/apps/uservice/test/adapt/restrequestor/TestRESTREequestorEndpoint.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/apps/uservice/test/adapt/restrequestor/TestRESTREequestorEndpoint.java
new file mode 100644 (file)
index 0000000..d9569b1
--- /dev/null
@@ -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.apps.uservice.test.adapt.restrequestor;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.gson.Gson;
+
+import java.util.Map;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+
+@Path("/apex")
+public class TestRESTREequestorEndpoint {
+
+    private static Object counterLock = new Object();
+    private static int postMessagesReceived = 0;
+    private static int putMessagesReceived = 0;
+    private static int statMessagesReceived = 0;
+    private static int getMessagesReceived = 0;
+    private static int deleteMessagesReceived = 0;
+
+    private static String EVENT_STRING = "{\n" + "\"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"
+            + "\"name\": \"Event0100\",\n" + "\"version\": \"0.0.1\",\n" + "\"source\": \"REST_" + getMessagesReceived
+            + "\",\n" + "\"target\": \"apex\",\n" + "\"TestSlogan\": \"Test slogan for External Event0\",\n"
+            + "\"TestMatchCase\": 2,\n" + "\"TestTimestamp\": " + System.currentTimeMillis() + ",\n"
+            + "\"TestTemperature\": 9080.866\n" + "}";
+
+    public static void resetCounters() {
+        postMessagesReceived = 0;
+        putMessagesReceived = 0;
+        statMessagesReceived = 0;
+        getMessagesReceived = 0;
+        deleteMessagesReceived = 0;
+    }
+
+    @Path("/event/Stats")
+    @GET
+    public Response serviceGetStats() {
+        synchronized (counterLock) {
+            statMessagesReceived++;
+        }
+        return Response.status(200)
+                .entity("{\"GET\": " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived + ",\"POST\": "
+                        + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + ",\"DELETE\": "
+                        + deleteMessagesReceived + "}")
+                .build();
+    }
+
+    @Path("/event/GetEvent")
+    @GET
+    public Response serviceGetEvent() {
+        synchronized (counterLock) {
+            getMessagesReceived++;
+        }
+
+        return Response.status(200).entity(EVENT_STRING).build();
+    }
+
+    @Path("/event/GetEmptyEvent")
+    @GET
+    public Response serviceGetEmptyEvent() {
+        return Response.status(200).build();
+    }
+
+    @Path("/event/GetEventBadResponse")
+    @GET
+    public Response serviceGetEventBadResponse() {
+        return Response.status(400).build();
+    }
+
+    @Path("/event/PostEvent")
+    @POST
+    public Response servicePostRequest(final String jsonString) {
+        synchronized (counterLock) {
+            postMessagesReceived++;
+        }
+
+        @SuppressWarnings("unchecked")
+        final Map<String, Object> jsonMap = new Gson().fromJson(jsonString, Map.class);
+        assertTrue(jsonMap.containsKey("name"));
+        assertEquals("0.0.1", jsonMap.get("version"));
+        assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace"));
+        assertEquals("Act", jsonMap.get("source"));
+        assertEquals("Outside", jsonMap.get("target"));
+
+        return Response.status(200).entity(EVENT_STRING).build();
+    }
+
+    @Path("/event/PostEventBadResponse")
+    @POST
+    public Response servicePostRequestBadResponse(final String jsonString) {
+        return Response.status(400).build();
+    }
+
+    @Path("/event/PutEvent")
+    @PUT
+    public Response servicePutRequest(final String jsonString) {
+        synchronized (counterLock) {
+            putMessagesReceived++;
+        }
+
+        @SuppressWarnings("unchecked")
+        final Map<String, Object> jsonMap = new Gson().fromJson(jsonString, Map.class);
+        assertTrue(jsonMap.containsKey("name"));
+        assertEquals("0.0.1", jsonMap.get("version"));
+        assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace"));
+        assertEquals("Act", jsonMap.get("source"));
+        assertEquals("Outside", jsonMap.get("target"));
+
+        return Response.status(200).entity(EVENT_STRING).build();
+    }
+
+    @Path("/event/DeleteEvent")
+    @DELETE
+    public Response serviceDeleteRequest(final String jsonString) {
+        synchronized (counterLock) {
+            deleteMessagesReceived++;
+        }
+
+        return Response.status(200).entity(EVENT_STRING).build();
+    }
+
+    @Path("/event/DeleteEventBadResponse")
+    @DELETE
+    public Response serviceDeleteRequestBadResponse(final String jsonString) {
+        return Response.status(400).build();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/apps/uservice/test/adapt/restrequestor/TestRESTRequestor.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/apps/uservice/test/adapt/restrequestor/TestRESTRequestor.java
new file mode 100644 (file)
index 0000000..d4eb434
--- /dev/null
@@ -0,0 +1,291 @@
+/*-
+ * ============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.apps.uservice.test.adapt.restrequestor;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.gson.Gson;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URI;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.apex.core.infrastructure.messaging.MessagingException;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.service.engine.main.ApexMain;
+
+public class TestRESTRequestor {
+    private static final String BASE_URI = "http://localhost:32801/TestRESTRequestor";
+    private static HttpServer server;
+
+    private ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+    private ByteArrayOutputStream errContent = new ByteArrayOutputStream();
+
+    private final PrintStream stdout = System.out;
+    private final PrintStream stderr = System.err;
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        final ResourceConfig rc = new ResourceConfig(TestRESTREequestorEndpoint.class);
+        server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
+
+        while (!server.isStarted()) {
+            ThreadUtilities.sleep(50);
+        }
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        server.shutdownNow();
+
+        new File("src/test/resources/events/EventsOut.json").delete();
+        new File("src/test/resources/events/EventsOutMulti0.json").delete();
+        new File("src/test/resources/events/EventsOutMulti1.json").delete();
+    }
+
+    @Before
+    public void resetCounters() {
+        TestRESTREequestorEndpoint.resetCounters();
+    }
+
+    @Test
+    public void testRESTRequestorGet() throws MessagingException, ApexException, IOException {
+        final Client client = ClientBuilder.newClient();
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FileGet.json" };
+        final ApexMain apexMain = new ApexMain(args);
+
+        // Wait for the required amount of events to be received or for 10 seconds
+        Double getsSoFar = 0.0;
+        for (int i = 0; i < 40; i++) {
+            ThreadUtilities.sleep(100);
+
+            final Response response = client.target("http://localhost:32801/TestRESTRequestor/apex/event/Stats")
+                    .request("application/json").get();
+
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+            final String responseString = response.readEntity(String.class);
+
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> jsonMap = new Gson().fromJson(responseString, Map.class);
+            getsSoFar = Double.valueOf(jsonMap.get("GET").toString());
+
+            if (getsSoFar >= 50.0) {
+                break;
+            }
+        }
+
+        apexMain.shutdown();
+        client.close();
+
+        assertEquals(Double.valueOf(50.0), getsSoFar);
+    }
+
+    @Test
+    public void testRESTRequestorPut() throws MessagingException, ApexException, IOException {
+        final Client client = ClientBuilder.newClient();
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FilePut.json" };
+        final ApexMain apexMain = new ApexMain(args);
+
+        // Wait for the required amount of events to be received or for 10 seconds
+        Double putsSoFar = 0.0;
+        for (int i = 0; i < 40; i++) {
+            ThreadUtilities.sleep(100);
+
+            final Response response = client.target("http://localhost:32801/TestRESTRequestor/apex/event/Stats")
+                    .request("application/json").get();
+
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+            final String responseString = response.readEntity(String.class);
+
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> jsonMap = new Gson().fromJson(responseString, Map.class);
+            putsSoFar = Double.valueOf(jsonMap.get("PUT").toString());
+
+            if (putsSoFar >= 50.0) {
+                break;
+            }
+        }
+
+        apexMain.shutdown();
+        client.close();
+
+        assertEquals(Double.valueOf(50.0), putsSoFar);
+    }
+
+    @Test
+    public void testRESTRequestorPost() throws MessagingException, ApexException, IOException {
+        final Client client = ClientBuilder.newClient();
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FilePost.json" };
+        final ApexMain apexMain = new ApexMain(args);
+
+        // Wait for the required amount of events to be received or for 10 seconds
+        Double postsSoFar = 0.0;
+        for (int i = 0; i < 40; i++) {
+            ThreadUtilities.sleep(100);
+
+            final Response response = client.target("http://localhost:32801/TestRESTRequestor/apex/event/Stats")
+                    .request("application/json").get();
+
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+            final String responseString = response.readEntity(String.class);
+
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> jsonMap = new Gson().fromJson(responseString, Map.class);
+            postsSoFar = Double.valueOf(jsonMap.get("POST").toString());
+
+            if (postsSoFar >= 50.0) {
+                break;
+            }
+        }
+
+        apexMain.shutdown();
+        client.close();
+
+        assertEquals(Double.valueOf(50.0), postsSoFar);
+    }
+
+    @Test
+    public void testRESTRequestorDelete() throws MessagingException, ApexException, IOException {
+        final Client client = ClientBuilder.newClient();
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FileDelete.json" };
+        final ApexMain apexMain = new ApexMain(args);
+
+        // Wait for the required amount of events to be received or for 10 seconds
+        Double deletesSoFar = 0.0;
+        for (int i = 0; i < 40; i++) {
+            ThreadUtilities.sleep(100);
+
+            final Response response = client.target("http://localhost:32801/TestRESTRequestor/apex/event/Stats")
+                    .request("application/json").get();
+
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+            final String responseString = response.readEntity(String.class);
+
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> jsonMap = new Gson().fromJson(responseString, Map.class);
+            deletesSoFar = Double.valueOf(jsonMap.get("DELETE").toString());
+
+            if (deletesSoFar >= 50.0) {
+                break;
+            }
+        }
+
+        apexMain.shutdown();
+        client.close();
+
+        assertEquals(Double.valueOf(50.0), deletesSoFar);
+    }
+
+    @Test
+    public void testRESTRequestorMultiInputs() throws MessagingException, ApexException, IOException {
+        final Client client = ClientBuilder.newClient();
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FileGetMulti.json" };
+        final ApexMain apexMain = new ApexMain(args);
+
+        // Wait for the required amount of events to be received or for 10 seconds
+        Double getsSoFar = 0.0;
+        for (int i = 0; i < 40; i++) {
+            ThreadUtilities.sleep(100);
+
+            final Response response = client.target("http://localhost:32801/TestRESTRequestor/apex/event/Stats")
+                    .request("application/json").get();
+
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+            final String responseString = response.readEntity(String.class);
+
+            @SuppressWarnings("unchecked")
+            final Map<String, Object> jsonMap = new Gson().fromJson(responseString, Map.class);
+            getsSoFar = Double.valueOf(jsonMap.get("GET").toString());
+
+            if (getsSoFar >= 8.0) {
+                break;
+            }
+        }
+
+        apexMain.shutdown();
+        client.close();
+
+        assertEquals(Double.valueOf(8.0), getsSoFar);
+
+        ThreadUtilities.sleep(1000);
+    }
+
+    @Test
+    public void testRESTRequestorProducerAlone() throws MessagingException, ApexException, IOException {
+        System.setOut(new PrintStream(outContent));
+        System.setErr(new PrintStream(errContent));
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FileGetProducerAlone.json" };
+
+        final ApexMain apexMain = new ApexMain(args);
+        ThreadUtilities.sleep(200);
+        apexMain.shutdown();
+
+        final String outString = outContent.toString();
+
+        System.setOut(stdout);
+        System.setErr(stderr);
+
+        assertTrue(outString.contains(
+                "REST Requestor producer (RestRequestorProducer) must run in peered requestor mode with a REST Requestor consumer"));
+    }
+
+    @Test
+    public void testRESTRequestorConsumerAlone() throws MessagingException, ApexException, IOException {
+        System.setOut(new PrintStream(outContent));
+        System.setErr(new PrintStream(errContent));
+
+        final String[] args = { "src/test/resources/prodcons/File2RESTRequest2FileGetConsumerAlone.json" };
+
+        final ApexMain apexMain = new ApexMain(args);
+        ThreadUtilities.sleep(200);
+        apexMain.shutdown();
+
+        final String outString = outContent.toString();
+
+        System.setOut(stdout);
+        System.setErr(stderr);
+
+        assertTrue(outString.contains(
+                "event input for peered mode \"REQUESTOR\": peer \"RestRequestorProducer\" for event handler \"RestRequestorConsumer\" does not exist or is not defined as being synchronous"));
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/events/EventsIn.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/events/EventsIn.json
new file mode 100644 (file)
index 0000000..037c5ca
--- /dev/null
@@ -0,0 +1,550 @@
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/events/EventsInMulti.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/events/EventsInMulti.json
new file mode 100644 (file)
index 0000000..49325dd
--- /dev/null
@@ -0,0 +1,22 @@
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
+{
+  "nameSpace": "org.onap.policy.apex.sample.events",
+  "name": "Event0000",
+  "version": "0.0.1",
+  "source": "test",
+  "target": "apex",
+  "TestSlogan": "Test slogan for External Event0",
+  "TestMatchCase": 3,
+  "TestTimestamp": 1469781869271,
+  "TestTemperature": 8723.999
+}
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/policymodels/SamplePolicyModelMVEL.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/policymodels/SamplePolicyModelMVEL.json
new file mode 100644 (file)
index 0000000..c87b265
--- /dev/null
@@ -0,0 +1,6348 @@
+{
+   "apexPolicyModel" : {
+      "key" : {
+         "name" : "SamplePolicyModelMVEL",
+         "version" : "0.0.1"
+      },
+      "keyInformation" : {
+         "key" : {
+            "name" : "KeyInformation",
+            "version" : "0.0.1"
+         },
+         "keyInfoMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "Context",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Context",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "2708db15-3117-4ef5-ae06-44ad4bc72756",
+                  "description" : "Generated description for concept referred to by key \"Context:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0000",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0000",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "20f7f2d0-36e1-4134-93d9-8978e0ebb916",
+                  "description" : "Generated description for concept referred to by key \"Event0000:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0001",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0001",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "bfa262fc-f59d-4b05-af44-a5b5c218b314",
+                  "description" : "Generated description for concept referred to by key \"Event0001:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0002",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0002",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "84eeac88-5031-4487-b67a-5a3ae13c1a89",
+                  "description" : "Generated description for concept referred to by key \"Event0002:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0003",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0003",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "7a46a411-1715-48d8-9e70-9b5d14bbbed4",
+                  "description" : "Generated description for concept referred to by key \"Event0003:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0004",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0004",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "da0ba1b4-f654-4e99-97b5-595de84cb3dc",
+                  "description" : "Generated description for concept referred to by key \"Event0004:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0100",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0100",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "1267b311-60e2-48a7-8d0e-23c4ea21d863",
+                  "description" : "Generated description for concept referred to by key \"Event0100:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0101",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0101",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "84013070-ff2e-4295-acbd-4128f0509040",
+                  "description" : "Generated description for concept referred to by key \"Event0101:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0102",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0102",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "6fb7761e-b86f-47fc-8e19-6a116600764e",
+                  "description" : "Generated description for concept referred to by key \"Event0102:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0103",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0103",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "141cc707-009c-4e3b-a0f8-c346f074f590",
+                  "description" : "Generated description for concept referred to by key \"Event0103:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0104",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0104",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "98f4d09f-ff73-4385-8876-df6d04b552cc",
+                  "description" : "Generated description for concept referred to by key \"Event0104:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Events",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Events",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "889f6414-bc4d-4f29-b7af-175e63d23ac5",
+                  "description" : "Generated description for concept referred to by key \"Events:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "ExternalContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "64e4911c-5aed-467f-be19-277fb6170857",
+                  "description" : "Generated description for concept referred to by key \"ExternalContextAlbum:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "GlobalContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "cb6a1892-8c3c-44df-b8a7-0e5a333ff9eb",
+                  "description" : "Generated description for concept referred to by key \"GlobalContextAlbum:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "KeyInformation",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "KeyInformation",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "f3126983-e26c-491f-8738-c57784ca4026",
+                  "description" : "Generated description for concept referred to by key \"KeyInformation:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Policies",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policies",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "b20a18d5-c419-4e90-8519-9c8f8b3ce2ab",
+                  "description" : "Generated description for concept referred to by key \"Policies:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policy0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "28943e99-871b-482b-953f-cfa7138da02c",
+                  "description" : "Generated description for concept referred to by key \"Policy0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy0ContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "2b1b738b-70f6-4b45-9d3c-a7e889b49993",
+                  "description" : "Generated description for concept referred to by key \"Policy0ContextAlbum:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policy1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "798ee6ea-f349-41bb-a281-7e4c22184e8c",
+                  "description" : "Generated description for concept referred to by key \"Policy1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy1ContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "eb9568d5-d95f-4713-9622-d95ef4cf81c3",
+                  "description" : "Generated description for concept referred to by key \"Policy1ContextAlbum:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "SamplePolicyModelMVEL",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "SamplePolicyModelMVEL",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "10979d21-947f-4920-83ae-63b827e8e80f",
+                  "description" : "Generated description for concept referred to by key \"SamplePolicyModelMVEL:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "cb65d7fe-8d86-463c-aa16-0f4e6138d705",
+                  "description" : "Generated description for concept referred to by key \"Task_Act0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "ea2b4e7a-1a79-440c-9cf0-6fddaad64c0c",
+                  "description" : "Generated description for concept referred to by key \"Task_Act1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act2",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "269e1d08-9ab4-48b8-8854-b65deb9d41b1",
+                  "description" : "Generated description for concept referred to by key \"Task_Act2:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act3",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "f9c4a91d-92aa-49ce-9b65-ab2378f6b048",
+                  "description" : "Generated description for concept referred to by key \"Task_Act3:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "7fde2446-ce2a-4bc2-a675-96496c387c88",
+                  "description" : "Generated description for concept referred to by key \"Task_Decide0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "bc185db6-f18f-4fdd-b5b4-37d14b57f463",
+                  "description" : "Generated description for concept referred to by key \"Task_Decide1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide2",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "2c1e2ede-d67c-4845-90ac-a4d53311bfbb",
+                  "description" : "Generated description for concept referred to by key \"Task_Decide2:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide3",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "1d1645a2-2852-4296-9f22-8f31ebe5386a",
+                  "description" : "Generated description for concept referred to by key \"Task_Decide3:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "f3739d83-a029-4ad8-a0b9-e5a028b369b2",
+                  "description" : "Generated description for concept referred to by key \"Task_Establish0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "5351a5a5-4134-44fd-9a6f-fd37dbfc8aa7",
+                  "description" : "Generated description for concept referred to by key \"Task_Establish1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish2",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "4206bb68-e710-4a01-aade-3e34771da63b",
+                  "description" : "Generated description for concept referred to by key \"Task_Establish2:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish3",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "cbaab234-b586-4f63-986e-ed0b317b6c66",
+                  "description" : "Generated description for concept referred to by key \"Task_Establish3:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match0",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "24dbc71b-8773-4393-9c36-a5f4991e0f55",
+                  "description" : "Generated description for concept referred to by key \"Task_Match0:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match1",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "42ecd25d-e8cb-48e4-890a-b0616528cf10",
+                  "description" : "Generated description for concept referred to by key \"Task_Match1:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match2",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "7e691294-a816-42f8-b124-9b5eac70b116",
+                  "description" : "Generated description for concept referred to by key \"Task_Match2:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match3",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "bc7cad3c-85a5-40b4-9eda-51ac2387af05",
+                  "description" : "Generated description for concept referred to by key \"Task_Match3:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "Tasks",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Tasks",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "4386403d-b23c-4c3e-bc14-5d581f9de2f5",
+                  "description" : "Generated description for concept referred to by key \"Tasks:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestCase",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestCase",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "901a80ab-dd46-4697-b818-f669b9f9bce9",
+                  "description" : "Generated description for concept referred to by key \"TestCase:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem000",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem000",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "cfd19e5d-ab54-4e54-b4e5-1c5eaa832622",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem000:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem001",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem001",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "42c27d27-878d-4e9d-a139-e60c98f1c747",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem001:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem002",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem002",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "83919fa0-ed4d-4981-908f-79913734a0f5",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem002:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem003",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem003",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "194882b0-d987-4200-b82a-2c015605279b",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem003:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem004",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem004",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "948d345b-39c3-4436-8036-ac9e5c561977",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem004:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem005",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem005",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "fdad8cb5-4375-4bbf-9ffc-1e5ed8f4bae6",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem005:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem006",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem006",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "5243c0ba-5c50-4835-a885-6cd988252bb7",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem006:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem007",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem007",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "29f0b15f-f7c3-46e5-98d7-59a34a677968",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem007:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem008",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem008",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "aac96de5-9f3c-452c-855f-e556cc807351",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem008:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem009",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem009",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "7fdc1cc3-08c7-42a4-92a9-39e172fe2f1f",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem009:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem00A",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem00A",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "cf60cca6-a2e8-4371-b0e5-85ecaae44acc",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem00A:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem00B",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem00B",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "1671f996-e14e-407d-a503-f4de09f0785b",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem00B:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem00C",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem00C",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "814c4c28-9027-4516-9598-adc75fafa92a",
+                  "description" : "Generated description for concept referred to by key \"TestContextItem00C:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestDatatypes",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestDatatypes",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "33e81d08-a62b-40ce-b7ff-50734427ebf9",
+                  "description" : "Generated description for concept referred to by key \"TestDatatypes:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestExternalContextItem",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestExternalContextItem",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "5cd74351-8e27-4dee-a379-86124db50383",
+                  "description" : "Generated description for concept referred to by key \"TestExternalContextItem:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestGlobalContextItem",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestGlobalContextItem",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "e8c9a056-5e95-4e14-bc96-0c0d13a34b18",
+                  "description" : "Generated description for concept referred to by key \"TestGlobalContextItem:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestPolicyContextItem",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestPolicyContextItem",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "92489659-02f3-4cb2-b25f-a6234ad71d36",
+                  "description" : "Generated description for concept referred to by key \"TestPolicyContextItem:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestSlogan",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestSlogan",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "1c3b9345-32c2-4f7e-94ce-be36d0775e9e",
+                  "description" : "Generated description for concept referred to by key \"TestSlogan:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestTemperature",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestTemperature",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "9e719a99-1d73-4d40-b097-c9622b9ea2b4",
+                  "description" : "Generated description for concept referred to by key \"TestTemperature:0.0.1\""
+               }
+            }, {
+               "key" : {
+                  "name" : "TestTimestamp",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestTimestamp",
+                     "version" : "0.0.1"
+                  },
+                  "UUID" : "3bcc8ef1-4cc5-4b7f-9dc4-83046d4a2a5d",
+                  "description" : "Generated description for concept referred to by key \"TestTimestamp:0.0.1\""
+               }
+            } ]
+         }
+      },
+      "policies" : {
+         "key" : {
+            "name" : "Policies",
+            "version" : "0.0.1"
+         },
+         "policyMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "Policy0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "policyKey" : {
+                     "name" : "Policy0",
+                     "version" : "0.0.1"
+                  },
+                  "template" : "MEDA",
+                  "state" : {
+                     "entry" : [ {
+                        "key" : "Act",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Act"
+                           },
+                           "trigger" : {
+                              "name" : "Event0003",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Act_NULL",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0004",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "NULL",
+                                       "parentKeyVersion" : "0.0.0",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "NULL"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Act1",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Act0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act0_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Act1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act1_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Act2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act2_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Act3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act3_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     }, {
+                        "key" : "Decide",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Decide"
+                           },
+                           "trigger" : {
+                              "name" : "Event0002",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Decide_Act",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0003",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "Act"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "ExternalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "Policy0ContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Decide3",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Decide0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide0_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Decide1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide1_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Decide2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide2_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Decide3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide3_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     }, {
+                        "key" : "Establish",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Establish"
+                           },
+                           "trigger" : {
+                              "name" : "Event0001",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Establish_Decide",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0002",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "Decide"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "ExternalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "Policy1ContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Establish2",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Establish0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish0_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Establish1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish1_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Establish2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish2_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Establish3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish3_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     }, {
+                        "key" : "Match",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Match"
+                           },
+                           "trigger" : {
+                              "name" : "Event0000",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Match_Establish",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0001",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "Establish"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "Policy0ContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Match0",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Match0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match0_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Match1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match1_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Match2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match2_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Match3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match3_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy0",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     } ]
+                  },
+                  "firstState" : "Match"
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "policyKey" : {
+                     "name" : "Policy1",
+                     "version" : "0.0.1"
+                  },
+                  "template" : "MEDA",
+                  "state" : {
+                     "entry" : [ {
+                        "key" : "Act",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Act"
+                           },
+                           "trigger" : {
+                              "name" : "Event0103",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Act_NULL",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0104",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "NULL",
+                                       "parentKeyVersion" : "0.0.0",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "NULL"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Act0",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Act0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act0_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Act1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act1_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Act2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act2_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Act3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Task_Act3_DIRECT_Act_NULL"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Act",
+                                       "localName" : "Act_NULL"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     }, {
+                        "key" : "Decide",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Decide"
+                           },
+                           "trigger" : {
+                              "name" : "Event0102",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Decide_Act",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0103",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "Act"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "ExternalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "Policy1ContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Decide3",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Decide0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide0_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Decide1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide1_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Decide2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide2_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Decide3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Task_Decide3_DIRECT_Decide_Act"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Decide",
+                                       "localName" : "Decide_Act"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     }, {
+                        "key" : "Establish",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Establish"
+                           },
+                           "trigger" : {
+                              "name" : "Event0101",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Establish_Decide",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0102",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "Decide"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "ExternalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "Policy1ContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Establish1",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Establish0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish0_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Establish1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish1_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Establish2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish2_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Establish3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Task_Establish3_DIRECT_Establish_Decide"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Establish",
+                                       "localName" : "Establish_Decide"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     }, {
+                        "key" : "Match",
+                        "value" : {
+                           "stateKey" : {
+                              "parentKeyName" : "Policy1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Match"
+                           },
+                           "trigger" : {
+                              "name" : "Event0100",
+                              "version" : "0.0.1"
+                           },
+                           "stateOutputs" : {
+                              "entry" : [ {
+                                 "key" : "Match_Establish",
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    },
+                                    "outgoingEvent" : {
+                                       "name" : "Event0101",
+                                       "version" : "0.0.1"
+                                    },
+                                    "nextState" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "NULL",
+                                       "localName" : "Establish"
+                                    }
+                                 }
+                              } ]
+                           },
+                           "contextAlbumReference" : [ {
+                              "name" : "ExternalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "GlobalContextAlbum",
+                              "version" : "0.0.1"
+                           }, {
+                              "name" : "Policy1ContextAlbum",
+                              "version" : "0.0.1"
+                           } ],
+                           "taskSelectionLogic" : {
+                              "key" : "TaskSelectionLigic",
+                              "logicFlavour" : "MVEL",
+                              "logic" : "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;"
+                           },
+                           "stateFinalizerLogicMap" : {
+                              "entry" : [ ]
+                           },
+                           "defaultTask" : {
+                              "name" : "Task_Match3",
+                              "version" : "0.0.1"
+                           },
+                           "taskReferences" : {
+                              "entry" : [ {
+                                 "key" : {
+                                    "name" : "Task_Match0",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match0_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Match1",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match1_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Match2",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match2_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              }, {
+                                 "key" : {
+                                    "name" : "Task_Match3",
+                                    "version" : "0.0.1"
+                                 },
+                                 "value" : {
+                                    "key" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Task_Match3_DIRECT_Match_Establish"
+                                    },
+                                    "outputType" : "DIRECT",
+                                    "output" : {
+                                       "parentKeyName" : "Policy1",
+                                       "parentKeyVersion" : "0.0.1",
+                                       "parentLocalName" : "Match",
+                                       "localName" : "Match_Establish"
+                                    }
+                                 }
+                              } ]
+                           }
+                        }
+                     } ]
+                  },
+                  "firstState" : "Match"
+               }
+            } ]
+         }
+      },
+      "tasks" : {
+         "key" : {
+            "name" : "Tasks",
+            "version" : "0.0.1"
+         },
+         "taskMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "Task_Act0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act0",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestActCaseSelected",
+                        "value" : {
+                           "key" : "TestActCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestActStateTime",
+                        "value" : {
+                           "key" : "TestActStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     }, {
+                        "key" : "Parameter2",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter2"
+                           },
+                           "defaultValue" : "DefaultValue2"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act1",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestActCaseSelected",
+                        "value" : {
+                           "key" : "TestActCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestActStateTime",
+                        "value" : {
+                           "key" : "TestActStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act2",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestActCaseSelected",
+                        "value" : {
+                           "key" : "TestActCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestActStateTime",
+                        "value" : {
+                           "key" : "TestActStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act2",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Act3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Act3",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestActCaseSelected",
+                        "value" : {
+                           "key" : "TestActCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestActStateTime",
+                        "value" : {
+                           "key" : "TestActStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Act3",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide0",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     }, {
+                        "key" : "Parameter2",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter2"
+                           },
+                           "defaultValue" : "DefaultValue2"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide1",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide2",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide2",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Decide3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Decide3",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Decide3",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish0",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     }, {
+                        "key" : "Parameter2",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter2"
+                           },
+                           "defaultValue" : "DefaultValue2"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish1",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish2",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish2",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Establish3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Establish3",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Establish3",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match0",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match0",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     }, {
+                        "key" : "Parameter2",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match0",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter2"
+                           },
+                           "defaultValue" : "DefaultValue2"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match1",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match1",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     }, {
+                        "key" : "Parameter1",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match1",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter1"
+                           },
+                           "defaultValue" : "DefaultValue1"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match2",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match2",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match2",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Task_Match3",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Task_Match3",
+                     "version" : "0.0.1"
+                  },
+                  "inputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "outputFields" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  },
+                  "taskParameters" : {
+                     "entry" : [ {
+                        "key" : "Parameter0",
+                        "value" : {
+                           "key" : {
+                              "parentKeyName" : "Task_Match3",
+                              "parentKeyVersion" : "0.0.1",
+                              "parentLocalName" : "NULL",
+                              "localName" : "Parameter0"
+                           },
+                           "defaultValue" : "DefaultValue0"
+                        }
+                     } ]
+                  },
+                  "contextAlbumReference" : [ {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  }, {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  } ],
+                  "taskLogic" : {
+                     "key" : "_TaskLogic",
+                     "logicFlavour" : "MVEL",
+                     "logic" : "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;"
+                  }
+               }
+            } ]
+         }
+      },
+      "events" : {
+         "key" : {
+            "name" : "Events",
+            "version" : "0.0.1"
+         },
+         "eventMap" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "Event0000",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0000",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Outside",
+                  "target" : "Match",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0001",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0001",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Match",
+                  "target" : "Establish",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0002",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0002",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Establish",
+                  "target" : "Decide",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0003",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0003",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Decide",
+                  "target" : "Act",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0004",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0004",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Act",
+                  "target" : "Outside",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestActCaseSelected",
+                        "value" : {
+                           "key" : "TestActCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestActStateTime",
+                        "value" : {
+                           "key" : "TestActStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0100",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0100",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Outside",
+                  "target" : "Match",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0101",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0101",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Match",
+                  "target" : "Establish",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0102",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0102",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Establish",
+                  "target" : "Decide",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0103",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0103",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Decide",
+                  "target" : "Act",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Event0104",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Event0104",
+                     "version" : "0.0.1"
+                  },
+                  "nameSpace" : "org.onap.policy.apex.sample.events",
+                  "source" : "Act",
+                  "target" : "Outside",
+                  "parameter" : {
+                     "entry" : [ {
+                        "key" : "TestActCaseSelected",
+                        "value" : {
+                           "key" : "TestActCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestActStateTime",
+                        "value" : {
+                           "key" : "TestActStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideCaseSelected",
+                        "value" : {
+                           "key" : "TestDecideCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestDecideStateTime",
+                        "value" : {
+                           "key" : "TestDecideStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishCaseSelected",
+                        "value" : {
+                           "key" : "TestEstablishCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestEstablishStateTime",
+                        "value" : {
+                           "key" : "TestEstablishStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCase",
+                        "value" : {
+                           "key" : "TestMatchCase",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchCaseSelected",
+                        "value" : {
+                           "key" : "TestMatchCaseSelected",
+                           "fieldSchemaKey" : {
+                              "name" : "TestCase",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestMatchStateTime",
+                        "value" : {
+                           "key" : "TestMatchStateTime",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestSlogan",
+                        "value" : {
+                           "key" : "TestSlogan",
+                           "fieldSchemaKey" : {
+                              "name" : "TestSlogan",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTemperature",
+                        "value" : {
+                           "key" : "TestTemperature",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTemperature",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     }, {
+                        "key" : "TestTimestamp",
+                        "value" : {
+                           "key" : "TestTimestamp",
+                           "fieldSchemaKey" : {
+                              "name" : "TestTimestamp",
+                              "version" : "0.0.1"
+                           }
+                        }
+                     } ]
+                  }
+               }
+            } ]
+         }
+      },
+      "albums" : {
+         "key" : {
+            "name" : "Context",
+            "version" : "0.0.1"
+         },
+         "albums" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "ExternalContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "ExternalContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "scope" : "EXTERNAL",
+                  "isWritable" : false,
+                  "itemSchema" : {
+                     "name" : "TestExternalContextItem",
+                     "version" : "0.0.1"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "GlobalContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "GlobalContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "scope" : "GLOBAL",
+                  "isWritable" : true,
+                  "itemSchema" : {
+                     "name" : "TestGlobalContextItem",
+                     "version" : "0.0.1"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy0ContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policy0ContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "scope" : "APPLICATION",
+                  "isWritable" : true,
+                  "itemSchema" : {
+                     "name" : "TestPolicyContextItem",
+                     "version" : "0.0.1"
+                  }
+               }
+            }, {
+               "key" : {
+                  "name" : "Policy1ContextAlbum",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "Policy1ContextAlbum",
+                     "version" : "0.0.1"
+                  },
+                  "scope" : "APPLICATION",
+                  "isWritable" : true,
+                  "itemSchema" : {
+                     "name" : "TestPolicyContextItem",
+                     "version" : "0.0.1"
+                  }
+               }
+            } ]
+         }
+      },
+      "schemas" : {
+         "key" : {
+            "name" : "TestDatatypes",
+            "version" : "0.0.1"
+         },
+         "schemas" : {
+            "entry" : [ {
+               "key" : {
+                  "name" : "TestCase",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestCase",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "java.lang.Byte"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem000",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem000",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem000"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem001",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem001",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem001"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem002",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem002",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem002"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem003",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem003",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem003"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem004",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem004",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem004"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem005",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem005",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem005"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem006",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem006",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem006"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem007",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem007",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem007"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem008",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem008",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem008"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem009",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem009",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem009"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem00A",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem00A",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem00A"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem00B",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem00B",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem00B"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestContextItem00C",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestContextItem00C",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestContextItem00C"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestExternalContextItem",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestExternalContextItem",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestExternalContextItem"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestGlobalContextItem",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestGlobalContextItem",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestGlobalContextItem"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestPolicyContextItem",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestPolicyContextItem",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "org.onap.policy.apex.context.test.concepts.TestPolicyContextItem"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestSlogan",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestSlogan",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "java.lang.String"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestTemperature",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestTemperature",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "java.lang.Double"
+               }
+            }, {
+               "key" : {
+                  "name" : "TestTimestamp",
+                  "version" : "0.0.1"
+               },
+               "value" : {
+                  "key" : {
+                     "name" : "TestTimestamp",
+                     "version" : "0.0.1"
+                  },
+                  "schemaFlavour" : "Java",
+                  "schemaDefinition" : "java.lang.Long"
+               }
+            } ]
+         }
+      }
+   }
+}
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileDelete.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileDelete.json
new file mode 100644 (file)
index 0000000..6e12c0b
--- /dev/null
@@ -0,0 +1,75 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsIn.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/DeleteEvent",
+                                       "httpMethod": "DELETE",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer",
+                       "requestorTimeout": 500
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorConsumer",
+                       "requestorTimeout": 500
+               },
+               "FileProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOut.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGet.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGet.json
new file mode 100644 (file)
index 0000000..d0879eb
--- /dev/null
@@ -0,0 +1,75 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsIn.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/GetEvent",
+                                       "httpMethod": "GET",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer",
+                       "requestorTimeout": 500
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorConsumer",
+                       "requestorTimeout": 500
+               },
+               "FileProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOut.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetConsumerAlone.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetConsumerAlone.json
new file mode 100644 (file)
index 0000000..b957b61
--- /dev/null
@@ -0,0 +1,71 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsIn.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/GetEvent",
+                                       "httpMethod": "GET",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer",
+                       "requestorTimeout": 500
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "FileProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOut.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetMulti.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetMulti.json
new file mode 100644 (file)
index 0000000..ba1c997
--- /dev/null
@@ -0,0 +1,129 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer0": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsInMulti.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer0": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/GetEvent",
+                                       "httpMethod": "GET",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer0",
+                       "requestorTimeout": 500
+               },
+               "FileConsumer1": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsInMulti.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer1": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/GetEvent",
+                                       "httpMethod": "GET",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer1",
+                       "requestorTimeout": 500
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer0": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorConsumer0",
+                       "requestorTimeout": 500
+               },
+               "FileProducer0": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOutMulti0.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               },
+               "RestRequestorProducer1": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorConsumer1",
+                       "requestorTimeout": 500
+               },
+               "FileProducer1": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOutMulti1.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetProducerAlone.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FileGetProducerAlone.json
new file mode 100644 (file)
index 0000000..a635e6c
--- /dev/null
@@ -0,0 +1,54 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsIn.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004"
+               },
+               "FileProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOut.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FilePost.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FilePost.json
new file mode 100644 (file)
index 0000000..9db89ce
--- /dev/null
@@ -0,0 +1,75 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsIn.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/PostEvent",
+                                       "httpMethod": "POST",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer",
+                       "requestorTimeout": 500
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorConsumer",
+                       "requestorTimeout": 500
+               },
+               "FileProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOut.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FilePut.json b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/resources/prodcons/File2RESTRequest2FilePut.json
new file mode 100644 (file)
index 0000000..3eebe3d
--- /dev/null
@@ -0,0 +1,75 @@
+{
+       "engineServiceParameters": {
+               "name": "MyApexEngine",
+               "version": "0.0.1",
+               "id": 45,
+               "instanceCount": 4,
+               "deploymentPort": 12561,
+               "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json",
+               "engineParameters": {
+                       "executorParameters": {
+                               "MVEL": {
+                                       "parameterClassName": "org.onap.policy.apex.plugins.executor.mvel.MVELExecutorParameters"
+                               }
+                       }
+               }
+       },
+       "eventInputParameters": {
+               "FileConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsIn.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       }
+               },
+               "RestRequestorConsumer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters",
+                               "parameters": {
+                                       "url": "http://localhost:32801/TestRESTRequestor/apex/event/PutEvent",
+                                       "httpMethod": "PUT",
+                                       "restRequestTimeout": 2000
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0100",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorProducer",
+                       "requestorTimeout": 500
+               }
+       },
+       "eventOutputParameters": {
+               "RestRequestorProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "RESTREQUESTOR",
+                               "parameterClassName": "org.onap.policy.apex.plugins.event.carrier.restrequestor.RESTRequestorCarrierTechnologyParameters"
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0004",
+                       "requestorMode": true,
+                       "requestorPeer": "RestRequestorConsumer",
+                       "requestorTimeout": 500
+               },
+               "FileProducer": {
+                       "carrierTechnologyParameters": {
+                               "carrierTechnology": "FILE",
+                               "parameters": {
+                                       "fileName": "src/test/resources/events/EventsOut.json"
+                               }
+                       },
+                       "eventProtocolParameters": {
+                               "eventProtocol": "JSON"
+                       },
+                       "eventNameFilter": "Event0104"
+               }
+       }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/pom.xml
new file mode 100644 (file)
index 0000000..6439089
--- /dev/null
@@ -0,0 +1,59 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+        <artifactId>plugins-event-carrier</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-carrier-restserver</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling events being transported over REST where Apex acts as a REST server</description>
+
+    <properties>
+        <apex-plugins-event-carrier-restserver-dir>${project.basedir}/src</apex-plugins-event-carrier-restserver-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.services</groupId>
+            <artifactId>services-engine</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>${version.jersey.core}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-grizzly2-http</artifactId>
+            <version>${version.grizzly2-http}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-servlet-core</artifactId>
+            <version>2.25.1</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerConsumer.java
new file mode 100644 (file)
index 0000000..71bf80f
--- /dev/null
@@ -0,0 +1,281 @@
+/*-
+ * ============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.plugins.event.carrier.restserver;
+
+import java.net.URI;
+import java.util.EnumMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.ws.rs.core.Response;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class implements an Apex event consumer that receives events from a REST server.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexRestServerConsumer implements ApexEventConsumer, Runnable {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestServerConsumer.class);
+
+    private static final String BASE_URI_TEMPLATE = "http://%s:%d/apex";
+
+    // The amount of time to wait in milliseconds between checks that the consumer thread has stopped
+    private static final long REST_SERVER_CONSUMER_WAIT_SLEEP_TIME = 50;
+
+    // The REST parameters read from the parameter service
+    private RESTServerCarrierTechnologyParameters restConsumerProperties;
+
+    // The event receiver that will receive events from this consumer
+    private ApexEventReceiver eventReceiver;
+
+    // The name for this consumer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    // The consumer thread and stopping flag
+    private Thread consumerThread;
+    private boolean stopOrderedFlag = false;
+
+    // The local HTTP server to use for REST call reception if we are running a local Grizzly server
+    private HttpServer server;
+
+    // Holds the next identifier for event execution.
+    private static AtomicLong nextExecutionID = new AtomicLong(0L);
+
+    /**
+     * Private utility to get the next candidate value for a Execution ID. This value will always be unique in a single
+     * JVM
+     *
+     * @return the next candidate value for a Execution ID
+     */
+    private static synchronized long getNextExecutionID() {
+        return nextExecutionID.getAndIncrement();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#init(java.lang.String,
+     * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters,
+     * org.onap.policy.apex.service.engine.event.ApexEventReceiver)
+     */
+    @Override
+    public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+            final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+        this.eventReceiver = incomingEventReceiver;
+        this.name = consumerName;
+
+        // Check and get the REST Properties
+        if (!(consumerParameters.getCarrierTechnologyParameters() instanceof RESTServerCarrierTechnologyParameters)) {
+            final String errorMessage =
+                    "specified consumer properties are not applicable to REST Server consumer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        restConsumerProperties =
+                (RESTServerCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+        // Check if we are in synchronous mode
+        if (!consumerParameters.isPeeredMode(EventHandlerPeeredMode.SYNCHRONOUS)) {
+            final String errorMessage =
+                    "REST Server consumer (" + this.name + ") must run in synchronous mode with a REST Server producer";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if we're in standalone mode
+        if (restConsumerProperties.isStandalone()) {
+            // Check if host and port are defined
+            if (restConsumerProperties.getHost() == null || restConsumerProperties.getPort() == -1) {
+                final String errorMessage =
+                        "the parameters \"host\" and \"port\" must be defined for REST Server consumer (" + this.name
+                                + ") in standalone mode";
+                LOGGER.warn(errorMessage);
+                throw new ApexEventException(errorMessage);
+            }
+
+            // Compose the URI for the standalone server
+            final String baseURI = String.format(BASE_URI_TEMPLATE, restConsumerProperties.getHost(),
+                    restConsumerProperties.getPort());
+
+            // Instantiate the standalone server
+            final ResourceConfig rc = new ResourceConfig(RestServerEndpoint.class);
+            server = GrizzlyHttpServerFactory.createHttpServer(URI.create(baseURI), rc);
+
+            while (!server.isStarted()) {
+                ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+            }
+        }
+
+        // Register this consumer with the REST server end point
+        RestServerEndpoint.registerApexRestServerConsumer(this.name, this);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+     */
+    @Override
+    public void start() {
+        // Configure and start the event reception thread
+        final String threadName = this.getClass().getName() + ":" + this.name;
+        consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+        consumerThread.setDaemon(true);
+        consumerThread.start();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /**
+     * Receive an event for processing in Apex.
+     *
+     * @param event the event to receive
+     * @return the response from Apex
+     */
+    public Response receiveEvent(final String event) {
+        // Get an execution ID for the event
+        final long executionId = getNextExecutionID();
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug(name + ": sending event " + name + '_' + executionId + " to Apex, event=" + event);
+        }
+
+        try {
+            // Send the event into Apex
+            eventReceiver.receiveEvent(executionId, event);
+        } catch (final Exception e) {
+            final String errorMessage = "error receiving events on event consumer " + name + ", " + e.getMessage();
+            LOGGER.warn(errorMessage);
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
+                    .entity("{'errorMessage', '" + errorMessage + "'}").build();
+        }
+
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        // Wait until the event is in the cache of events sent to apex
+        do {
+            ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+        } while (!synchronousEventCache.existsEventToApex(executionId));
+
+        // Now wait for the reply or for the event to time put
+        do {
+            ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+
+            // Check if we have received an answer from Apex
+            if (synchronousEventCache.existsEventFromApex(executionId)) {
+                // We have received a response event, read and remove the response event and remove the sent event from
+                // the cache
+                final Object responseEvent = synchronousEventCache.removeCachedEventFromApexIfExists(executionId);
+                synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+
+                // Return the event as a response to the call
+                return Response.status(Response.Status.OK.getStatusCode()).entity(responseEvent.toString()).build();
+            }
+        } while (synchronousEventCache.existsEventToApex(executionId));
+
+        // The event timed out
+        final String errorMessage = "processing of event on event consumer " + name + " timed out, event=" + event;
+        LOGGER.warn(errorMessage);
+        return Response.status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
+                .entity("{'errorMessage', '" + errorMessage + "'}").build();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        // Keep the consumer thread alive until it is shut down. We do not currently do anything in the thread but may
+        // do supervision in the future
+        while (consumerThread.isAlive() && !stopOrderedFlag) {
+            ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+        }
+
+        if (server != null) {
+            server.shutdown();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.consumer.ApexEventConsumer#stop()
+     */
+    @Override
+    public void stop() {
+        stopOrderedFlag = true;
+
+        while (consumerThread.isAlive()) {
+            ThreadUtilities.sleep(REST_SERVER_CONSUMER_WAIT_SLEEP_TIME);
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/ApexRestServerProducer.java
new file mode 100644 (file)
index 0000000..e51482c
--- /dev/null
@@ -0,0 +1,167 @@
+/*-
+ * ============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.plugins.event.carrier.restserver;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event producer that sends events using REST.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ *
+ */
+public class ApexRestServerProducer implements ApexEventProducer {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexRestServerProducer.class);
+
+    // The REST carrier properties
+    private RESTServerCarrierTechnologyParameters restProducerProperties;
+
+    // The name for this producer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String,
+     * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters)
+     */
+    @Override
+    public void init(final String producerName, final EventHandlerParameters producerParameters)
+            throws ApexEventException {
+        this.name = producerName;
+
+        // Check and get the REST Properties
+        if (!(producerParameters.getCarrierTechnologyParameters() instanceof RESTServerCarrierTechnologyParameters)) {
+            final String errorMessage =
+                    "specified producer properties are not applicable to REST Server producer (" + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+        restProducerProperties =
+                (RESTServerCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+
+        // Check if host and port are defined
+        if (restProducerProperties.getHost() != null || restProducerProperties.getPort() != -1
+                || restProducerProperties.isStandalone()) {
+            final String errorMessage =
+                    "the parameters \"host\", \"port\", and \"standalone\" are illegal on REST Server producer ("
+                            + this.name + ")";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Check if we are in synchronous mode
+        if (!producerParameters.isPeeredMode(EventHandlerPeeredMode.SYNCHRONOUS)) {
+            final String errorMessage =
+                    "REST Server producer (" + this.name + ") must run in synchronous mode with a REST Server consumer";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang. String,
+     * java.lang.Object)
+     */
+    @Override
+    public void sendEvent(final long executionId, final String eventName, final Object event) {
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug(name + ": event " + executionId + ':' + eventName + " recevied from Apex, event=" + event);
+        }
+
+        // If we are not synchronized, then exit
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        if (synchronousEventCache == null) {
+            return;
+        }
+
+        // We see all events on the receiver, even those that are not replies to events sent by the synchronized
+        // consumer of this producer, ignore those
+        // events
+        if (!synchronousEventCache.existsEventToApex(executionId)) {
+            return;
+        }
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug(name + ": event " + executionId + ':' + eventName + " is a reply to a REST server call from "
+                    + name);
+        }
+
+        // Add the event to the received event cache
+        synchronousEventCache.cacheSynchronizedEventFromApex(executionId, event);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {}
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RESTServerCarrierTechnologyParameters.java
new file mode 100644 (file)
index 0000000..47e31ff
--- /dev/null
@@ -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.plugins.event.carrier.restserver;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for REST as an event carrier technology with Apex as a REST client.
+ *
+ * The parameters for this plugin are:
+ * <ol>
+ * <li>standalone: A flag indicating if APEX should start a standalone HTTP server to process REST requests (true) or
+ * whether it should use an underlying servlet infrastructure such as Apache Tomcat (False). This parameter is legal
+ * only on REST server event inputs.
+ * <li>host: The host name to use when setting up a standalone HTTP server. This parameter is legal only on REST server
+ * event inputs in standalone mode.
+ * <li>port: The port to use when setting up a standalone HTTP server. This parameter is legal only on REST server event
+ * inputs in standalone mode.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class RESTServerCarrierTechnologyParameters extends CarrierTechnologyParameters {
+    // @formatter:off
+    private static final int MIN_USER_PORT =  1024;
+    private static final int MAX_USER_PORT = 65535;
+
+    /** The label of this carrier technology. */
+    public static final String RESTSERVER_CARRIER_TECHNOLOGY_LABEL = "RESTSERVER";
+
+    /** The producer plugin class for the REST carrier technology. */
+    public static final String RESTSERVER_EVENT_PRODUCER_PLUGIN_CLASS = ApexRestServerProducer.class.getCanonicalName();
+
+    /** The consumer plugin class for the REST carrier technology. */
+    public static final String RESTSERVER_EVENT_CONSUMER_PLUGIN_CLASS = ApexRestServerConsumer.class.getCanonicalName();
+
+    // REST server parameters
+    private boolean standalone = false;
+    private String  host       = null;
+    private int     port       = -1;
+    // @formatter:on
+
+    /**
+     * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter
+     * service.
+     */
+    public RESTServerCarrierTechnologyParameters() {
+        super(RESTServerCarrierTechnologyParameters.class.getCanonicalName());
+
+        // Set the carrier technology properties for the web socket carrier technology
+        this.setLabel(RESTSERVER_CARRIER_TECHNOLOGY_LABEL);
+        this.setEventProducerPluginClass(RESTSERVER_EVENT_PRODUCER_PLUGIN_CLASS);
+        this.setEventConsumerPluginClass(RESTSERVER_EVENT_CONSUMER_PLUGIN_CLASS);
+    }
+
+    /**
+     * Check if the REST server is running in standalone mode or is using an underlying servlet infrastructure to manage
+     * requests.
+     *
+     * @return true if in standalone mode
+     */
+    public boolean isStandalone() {
+        return standalone;
+    }
+
+    /**
+     * Gets the host.
+     *
+     * @return the host
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Gets the port.
+     *
+     * @return the port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+     */
+    @Override
+    public String validate() {
+        final StringBuilder errorMessageBuilder = new StringBuilder();
+
+        errorMessageBuilder.append(super.validate());
+
+        // Check if host is defined, it is only defined on REST server consumers
+        if (standalone) {
+            if (host != null) {
+                if (host.trim().length() == 0) {
+                    errorMessageBuilder.append("  host not specified, must be host as a string\n");
+                }
+            }
+
+            // Check if port is defined, it is only defined on REST server consumers
+            if (port != -1) {
+                if (port < MIN_USER_PORT || port > MAX_USER_PORT) {
+                    errorMessageBuilder
+                            .append("  port [" + port + "] invalid, must be specified as 1024 <= port <= 6535\n");
+                }
+            }
+        } else {
+            if (host != null || port != -1) {
+                errorMessageBuilder.append("  host and port are specified only in standalone mode\n");
+            }
+        }
+
+        return errorMessageBuilder.toString();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/RestServerEndpoint.java
new file mode 100644 (file)
index 0000000..beee10f
--- /dev/null
@@ -0,0 +1,150 @@
+/*-
+ * ============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.plugins.event.carrier.restserver;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The Class RestServerEndpoint is the end point servlet class for handling REST requests and responses to and from
+ * Apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+@Path("/{eventInput}")
+@Produces({ MediaType.APPLICATION_JSON })
+@Consumes({ MediaType.APPLICATION_JSON })
+public class RestServerEndpoint {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(RestServerEndpoint.class);
+
+    // Statistics on the amount of HTTP messages handled
+    private static int getMessagesReceived = 0;
+    private static int postEventMessagesReceived = 0;
+    private static int putEventMessagesReceived = 0;
+
+    // This map is used to hold all the REST server event inputs. This is used to determine which consumer to send input
+    // events to
+    private static Map<String, ApexRestServerConsumer> consumerMap =
+            new LinkedHashMap<String, ApexRestServerConsumer>();
+
+    // The ID of this event input. This gets injected from the URL.
+    @PathParam("eventInput")
+    private String eventInputID = null;
+
+    /**
+     * Register an Apex consumer with the REST server end point.
+     *
+     * @param consumerEventInputID The event input ID that indicates this consumer shoud be used
+     * @param consumer The consumer to register
+     */
+    public static void registerApexRestServerConsumer(final String consumerEventInputID,
+            final ApexRestServerConsumer consumer) {
+        consumerMap.put(consumerEventInputID, consumer);
+    }
+
+    /**
+     * Get statistics on apex REST event handling.
+     *
+     * @return the response
+     */
+    @Path("/Status")
+    @GET
+    public Response serviceGetStats() {
+        getMessagesReceived++;
+        return Response.status(Response.Status.OK.getStatusCode())
+                .entity("{\n" + "\"INPUTS\": \"" + consumerMap.keySet() + "\",\n" + "\"STAT\": " + getMessagesReceived
+                        + ",\n" + "\"POST\": " + postEventMessagesReceived + ",\n" + "\"PUT\":  "
+                        + putEventMessagesReceived + "\n}")
+                .build();
+    }
+
+    /**
+     * Service post request, an incoming event over RETS to Apex.
+     *
+     * @param jsonString the JSON string containing the data coming in on the REST call
+     * @return the response event to the request
+     */
+    @Path("/EventIn")
+    @POST
+    public Response servicePostRequest(final String jsonString) {
+        postEventMessagesReceived++;
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("event input " + eventInputID + ", received POST of event \"" + jsonString + "\"");
+        }
+
+        // Common handler method for POST and PUT requests
+        return handleEvent(jsonString);
+    }
+
+    /**
+     * Service put request, an incoming event over RETS to Apex.
+     *
+     * @param jsonString the JSON string containing the data coming in on the REST call
+     * @return the response event to the request
+     */
+    @Path("/EventIn")
+    @PUT
+    public Response servicePutRequest(final String jsonString) {
+        putEventMessagesReceived++;
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("event input \"" + eventInputID + "\", received PUT of event \"" + jsonString + "\"");
+        }
+
+        // Common handler method for POST and PUT requests
+        return handleEvent(jsonString);
+    }
+
+    /**
+     * Common event handler for events received on POST and PUT messages.
+     *
+     * @param jsonString the JSON string containing the data coming in on the REST call
+     * @return the response event to the request
+     */
+    private Response handleEvent(final String jsonString) {
+        // Find the correct consumer for this REST message
+        final ApexRestServerConsumer eventConsumer = consumerMap.get(eventInputID);
+        if (eventConsumer == null) {
+            final String errorMessage =
+                    "event input " + eventInputID + " is not defined in the Apex configuration file";
+            LOGGER.warn(errorMessage);
+            return Response.status(Response.Status.BAD_REQUEST.getStatusCode())
+                    .entity("{'errorMessage', '" + errorMessage + "'}").build();
+        }
+
+        return eventConsumer.receiveEvent(jsonString);
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/main/java/org/onap/policy/apex/plugins/event/carrier/restserver/package-info.java
new file mode 100644 (file)
index 0000000..98a1c4b
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * APEX REST consumer and producer plugins when APEX is acting as a REST client.
+ *
+ * @author Joss Armstrong (joss.armstrong@ericsson.com)
+ *
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.restserver;
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restserver/src/test/resources/logback-test.xml
new file mode 100644 (file)
index 0000000..dc591b1
--- /dev/null
@@ -0,0 +1,50 @@
+<?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>
+
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_DIR}/apex.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.plugins.event.carrier.restserver" level="trace" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+</configuration>
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/pom.xml b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/pom.xml
new file mode 100644 (file)
index 0000000..f6068aa
--- /dev/null
@@ -0,0 +1,36 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+        <artifactId>plugins-event-carrier</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-carrier-websocket</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling events being transported over web sockets</description>
+
+    <properties>
+        <apex-plugins-event-carrier-websocket-dir>${project.basedir}/src</apex-plugins-event-carrier-websocket-dir>
+    </properties>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/ApexWebSocketConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/ApexWebSocketConsumer.java
new file mode 100644 (file)
index 0000000..f2c5945
--- /dev/null
@@ -0,0 +1,195 @@
+/*-
+ * ============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.plugins.event.carrier.websocket;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.onap.policy.apex.core.infrastructure.messaging.MessagingException;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageClient;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageListener;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageServer;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessager;
+import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.service.engine.event.ApexEventConsumer;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation an Apex event consumer that receives events using Kafka.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexWebSocketConsumer implements ApexEventConsumer, WSStringMessageListener, Runnable {
+    private static final int WEB_SOCKET_WAIT_SLEEP_TIME = 100;
+
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexWebSocketConsumer.class);
+
+    // The Web Socket properties
+    private WEBSOCKETCarrierTechnologyParameters webSocketConsumerProperties;
+
+    // The web socket messager, may be WS a server or a client
+    private WSStringMessager wsStringMessager;
+
+    // The event receiver that will receive events from this consumer
+    private ApexEventReceiver eventReceiver;
+
+    // The name for this consumer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    // The consumer thread and stopping flag
+    private Thread consumerThread;
+    private boolean stopOrderedFlag = false;
+
+    // The number of events read to date
+    private int eventsRead = 0;
+
+    @Override
+    public void init(final String consumerName, final EventHandlerParameters consumerParameters,
+            final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
+        this.eventReceiver = incomingEventReceiver;
+        this.name = consumerName;
+
+        // Check and get the Kafka Properties
+        if (!(consumerParameters.getCarrierTechnologyParameters() instanceof WEBSOCKETCarrierTechnologyParameters)) {
+            LOGGER.warn("specified consumer properties are not applicable to a web socket consumer");
+            throw new ApexEventException("specified consumer properties are not applicable to a web socket consumer");
+        }
+        webSocketConsumerProperties =
+                (WEBSOCKETCarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters();
+
+        // Check if this is a server or a client Web Socket
+        if (webSocketConsumerProperties.isWsClient()) {
+            // Create a WS client
+            wsStringMessager = new WSStringMessageClient(webSocketConsumerProperties.getHost(),
+                    webSocketConsumerProperties.getPort());
+        } else {
+            wsStringMessager = new WSStringMessageServer(webSocketConsumerProperties.getPort());
+        }
+
+        // Start reception of event strings on the web socket
+        try {
+            wsStringMessager.start(this);
+        } catch (final MessagingException e) {
+            LOGGER.warn("could not start web socket consumer");
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start()
+     */
+    @Override
+    public void start() {
+        // Configure and start the event reception thread
+        final String threadName = this.getClass().getName() + ":" + this.name;
+        consumerThread = new ApplicationThreadFactory(threadName).newThread(this);
+        consumerThread.setDaemon(true);
+        consumerThread.start();
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        while (consumerThread.isAlive() && !stopOrderedFlag) {
+            ThreadUtilities.sleep(WEB_SOCKET_WAIT_SLEEP_TIME);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        if (wsStringMessager != null) {
+            wsStringMessager.stop();
+        }
+        stopOrderedFlag = true;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageListener#receiveString(java.
+     * lang. String)
+     */
+    @Override
+    public void receiveString(final String eventString) {
+        try {
+            eventReceiver.receiveEvent(eventString);
+            eventsRead++;
+        } catch (final Exception e) {
+            final String errorMessage = "Error sending event " + name + '_' + eventsRead + ", " + e.getMessage()
+                    + ", event:\n" + eventString;
+            LOGGER.warn(errorMessage);
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/ApexWebSocketProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/ApexWebSocketProducer.java
new file mode 100644 (file)
index 0000000..1fd1468
--- /dev/null
@@ -0,0 +1,166 @@
+/*-
+ * ============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.plugins.event.carrier.websocket;
+
+import java.util.EnumMap;
+import java.util.Map;
+
+import org.onap.policy.apex.core.infrastructure.messaging.MessagingException;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageClient;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageListener;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageServer;
+import org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessager;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProducer;
+import org.onap.policy.apex.service.engine.event.PeeredReference;
+import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
+import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Concrete implementation of an Apex event producer that sends events using a web socket.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexWebSocketProducer implements ApexEventProducer, WSStringMessageListener {
+    // Get a reference to the logger
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApexWebSocketProducer.class);
+
+    // The Web Socket properties
+    private WEBSOCKETCarrierTechnologyParameters webSocketProducerProperties;
+
+    // The web socket messager, may be WS a server or a client
+    private WSStringMessager wsStringMessager;
+
+    // The name for this producer
+    private String name = null;
+
+    // The peer references for this event handler
+    private Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = new EnumMap<>(EventHandlerPeeredMode.class);
+
+    @Override
+    public void init(final String producerName, final EventHandlerParameters producerParameters)
+            throws ApexEventException {
+        this.name = producerName;
+
+        // Check and get the web socket Properties
+        if (!(producerParameters.getCarrierTechnologyParameters() instanceof WEBSOCKETCarrierTechnologyParameters)) {
+            LOGGER.warn(
+                    "specified producer properties for " + this.name + "are not applicable to a web socket producer");
+            throw new ApexEventException("specified producer properties are not applicable to a web socket producer");
+        }
+        webSocketProducerProperties =
+                (WEBSOCKETCarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters();
+
+        // Check if this is a server or a client Web Socket
+        if (webSocketProducerProperties.isWsClient()) {
+            // Create a WS client
+            wsStringMessager = new WSStringMessageClient(webSocketProducerProperties.getHost(),
+                    webSocketProducerProperties.getPort());
+        } else {
+            wsStringMessager = new WSStringMessageServer(webSocketProducerProperties.getPort());
+        }
+
+        // Start reception of event strings on the web socket
+        try {
+            wsStringMessager.start(this);
+        } catch (final MessagingException e) {
+            LOGGER.warn("could not start web socket producer (" + this.name + ")");
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName()
+     */
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode)
+     */
+    @Override
+    public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) {
+        return peerReferenceMap.get(peeredMode);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap.policy.apex.service.
+     * parameters. eventhandler.EventHandlerPeeredMode, org.onap.policy.apex.service.engine.event.PeeredReference)
+     */
+    @Override
+    public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {
+        peerReferenceMap.put(peeredMode, peeredReference);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#sendEvent(long, java.lang.String,
+     * java.lang.Object)
+     */
+    @Override
+    public void sendEvent(final long executionId, final String eventName, final Object event) {
+        // Check if this is a synchronized event, if so we have received a reply
+        final SynchronousEventCache synchronousEventCache =
+                (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS);
+        if (synchronousEventCache != null) {
+            synchronousEventCache.removeCachedEventToApexIfExists(executionId);
+        }
+
+        wsStringMessager.sendString((String) event);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop()
+     */
+    @Override
+    public void stop() {
+        if (wsStringMessager != null) {
+            wsStringMessager.stop();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.core.infrastructure.messaging.stringmessaging.WSStringMessageListener#receiveString(java.
+     * lang. String)
+     */
+    @Override
+    public void receiveString(final String messageString) {
+        LOGGER.warn("received message \"" + messageString + "\" on web socket producer (" + this.name
+                + ") , no messages should be received on a web socket producer");
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/WEBSOCKETCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/WEBSOCKETCarrierTechnologyParameters.java
new file mode 100644 (file)
index 0000000..e8009a5
--- /dev/null
@@ -0,0 +1,115 @@
+/*-
+ * ============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.plugins.event.carrier.websocket;
+
+import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
+
+/**
+ * Apex parameters for Kafka as an event carrier technology.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class WEBSOCKETCarrierTechnologyParameters extends CarrierTechnologyParameters {
+    // @formatter:off
+    private static final int MIN_USER_PORT =  1024;
+    private static final int MAX_USER_PORT = 65535;
+
+    /** The label of this carrier technology. */
+    public static final String WEB_SCOKET_CARRIER_TECHNOLOGY_LABEL = "WEBSOCKET";
+
+    /** The producer plugin class for the web socket carrier technology. */
+    public static final String WEB_SCOKET_EVENT_PRODUCER_PLUGIN_CLASS = ApexWebSocketProducer.class.getCanonicalName();
+
+    /** The consumer plugin class for the web socket carrier technology. */
+    public static final String KWEB_SCOKET_EVENT_CONSUMER_PLUGIN_CLASS = ApexWebSocketConsumer.class.getCanonicalName();
+
+    // Default parameter values
+    private static final String DEFAULT_HOST = "localhost";
+    private static final int    DEFAULT_PORT = -1;
+
+    // Web socket parameters
+    private boolean wsClient = true;
+    private String  host     = DEFAULT_HOST;
+    private int     port     = DEFAULT_PORT;
+    // @formatter:on
+
+    /**
+     * Constructor to create a web socket carrier technology parameters instance and register the instance with the
+     * parameter service.
+     */
+    public WEBSOCKETCarrierTechnologyParameters() {
+        super(WEBSOCKETCarrierTechnologyParameters.class.getCanonicalName());
+
+        // Set the carrier technology properties for the web socket carrier technology
+        this.setLabel(WEB_SCOKET_CARRIER_TECHNOLOGY_LABEL);
+        this.setEventProducerPluginClass(WEB_SCOKET_EVENT_PRODUCER_PLUGIN_CLASS);
+        this.setEventConsumerPluginClass(KWEB_SCOKET_EVENT_CONSUMER_PLUGIN_CLASS);
+    }
+
+    /**
+     * Gets the host.
+     *
+     * @return the host
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Gets the port.
+     *
+     * @return the port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Checks if is ws client.
+     *
+     * @return true, if checks if is ws client
+     */
+    public boolean isWsClient() {
+        return wsClient;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate()
+     */
+    @Override
+    public String validate() {
+        final StringBuilder errorMessageBuilder = new StringBuilder();
+
+        errorMessageBuilder.append(super.validate());
+
+        if (wsClient && (host == null || host.trim().length() == 0)) {
+            errorMessageBuilder.append("  host not specified, must be host as a string\n");
+        }
+
+        if (port < MIN_USER_PORT || port > MAX_USER_PORT) {
+            errorMessageBuilder.append("  port [" + port + "] invalid, must be specified as 1024 <= port <= 6535\n");
+        }
+
+        return errorMessageBuilder.toString();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/package-info.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-websocket/src/main/java/org/onap/policy/apex/plugins/event/carrier/websocket/package-info.java
new file mode 100644 (file)
index 0000000..9555ea4
--- /dev/null
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Implements the APEX event carrier technology plugin for web sockets.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.plugins.event.carrier.websocket;
diff --git a/plugins/plugins-event/plugins-event-carrier/pom.xml b/plugins/plugins-event/plugins-event-carrier/pom.xml
new file mode 100644 (file)
index 0000000..c8ce3a7
--- /dev/null
@@ -0,0 +1,48 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event</groupId>
+        <artifactId>plugins-event</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-carrier</groupId>
+    <artifactId>plugins-event-carrier</artifactId>
+    <packaging>pom</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>Plugins for 3pps that carry events</description>
+
+    <properties>
+        <apex-plugins-event-carrier-dir>${project.basedir}/src</apex-plugins-event-carrier-dir>
+    </properties>
+
+    <modules>
+        <module>plugins-event-carrier-kafka</module>
+        <module>plugins-event-carrier-websocket</module>
+        <module>plugins-event-carrier-jms</module>
+        <module>plugins-event-carrier-restclient</module>
+        <module>plugins-event-carrier-restserver</module>
+        <module>plugins-event-carrier-restrequestor</module>
+    </modules>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/pom.xml b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/pom.xml
new file mode 100644 (file)
index 0000000..9832895
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-protocol</groupId>
+        <artifactId>plugins-event-protocol</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-protocol-jms</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugins for handling events that are being transported as JMS messages</description>
+
+    <properties>
+        <apex-plugins-event-protocol-jms-dir>${project.basedir}/src</apex-plugins-event-protocol-jms-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.jms</groupId>
+            <artifactId>javax.jms-api</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/Apex2JMSObjectEventConverter.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/Apex2JMSObjectEventConverter.java
new file mode 100644 (file)
index 0000000..52c6784
--- /dev/null
@@ -0,0 +1,148 @@
+/*-
+ * ============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.plugins.event.protocol.jms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jms.ObjectMessage;
+
+import org.onap.policy.apex.service.engine.event.ApexEvent;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class Apex2JMSObjectEventConverter converts {@link ApexEvent} instances into string instances of
+ * {@link javax.jms.ObjectMessage} message events for JMS.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class Apex2JMSObjectEventConverter implements ApexEventProtocolConverter {
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(Apex2JMSObjectEventConverter.class);
+
+    // JMS event protocol parameters on the consumer (JMS->Apex) sides
+    private JMSObjectEventProtocolParameters eventProtocolParameters = null;
+
+    /**
+     * Constructor to create the Apex to JMS Object converter.
+     *
+     * @throws ApexEventException the apex event exception
+     */
+    public Apex2JMSObjectEventConverter() throws ApexEventException {}
+
+    @Override
+    public void init(final EventProtocolParameters parameters) {
+        // Check if properties have been set for JMS object event conversion as a consumer. They may not be set because
+        // JMS may not be in use
+        // on both sides of Apex
+        if (!(parameters instanceof JMSObjectEventProtocolParameters)) {
+            final String errormessage = "specified Event Protocol Parameters properties of type \""
+                    + parameters.getClass().getCanonicalName() + "\" are not applicable to a "
+                    + Apex2JMSObjectEventConverter.class.getName() + " converter";
+            LOGGER.error(errormessage);
+        } else {
+            this.eventProtocolParameters = (JMSObjectEventProtocolParameters) parameters;
+        }
+
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, java.lang.Object)
+     */
+    @Override
+    public List<ApexEvent> toApexEvent(final String eventName, final Object eventObject) throws ApexEventException {
+        // Check if this is an ObjectMessage from JMS
+        if (!(eventObject instanceof ObjectMessage)) {
+            final String errorMessage = "message \"" + eventObject + "\" received from JMS is not an instance of \""
+                    + ObjectMessage.class.getCanonicalName() + "\"";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+
+        // Get the object from the object message
+        final ObjectMessage objectMessage = (ObjectMessage) eventObject;
+        Object jmsIncomingObject;
+        try {
+            jmsIncomingObject = objectMessage.getObject();
+        } catch (final Exception e) {
+            final String errorMessage = "object contained in message \"" + eventObject
+                    + "\" received from JMS could not be retrieved as a Java object";
+            LOGGER.debug(errorMessage, e);
+            throw new ApexEventRuntimeException(errorMessage, e);
+        }
+
+        // Check that the consumer parameters for JMS->Apex messaging have been set
+        if (eventProtocolParameters == null) {
+            final String errorMessage =
+                    "consumer parameters for JMS events consumed by Apex are not set in the Apex configuration for this engine";
+            LOGGER.debug(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+
+        // Create the Apex event
+        // @formatter:off
+        final ApexEvent apexEvent = new ApexEvent(
+                jmsIncomingObject.getClass().getSimpleName() + eventProtocolParameters.getIncomingEventSuffix(),
+                eventProtocolParameters.getIncomingEventVersion(),
+                jmsIncomingObject.toString().getClass().getPackage().getName(),
+                eventProtocolParameters.getIncomingEventSource(),
+                eventProtocolParameters.getIncomingEventTarget());
+        // @formattter:on
+
+        // Set the data on the apex event as the incoming object
+        apexEvent.put(jmsIncomingObject.getClass().getSimpleName(), jmsIncomingObject);
+
+        // Return the event in a single element
+        final ArrayList<ApexEvent> eventList = new ArrayList<ApexEvent>();
+        eventList.add(apexEvent);
+        return eventList;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy.apex.service.engine.event.ApexEvent)
+     */
+    @Override
+    public Object fromApexEvent(final ApexEvent apexEvent) throws ApexEventException {
+        // Check the Apex event
+        if (apexEvent == null) {
+            LOGGER.warn("event processing failed, Apex event is null");
+            throw new ApexEventException("event processing failed, Apex event is null");
+        }
+
+        // Check that the Apex event has a single parameter
+        if (apexEvent.size() != 1) {
+            final String errorMessage = "event processing failed, Apex event must have one and only one parameter for JMS Object handling";
+            LOGGER.warn(errorMessage);
+            throw new ApexEventException(errorMessage);
+        }
+
+        // Return the single object from the Apex event message
+        return apexEvent.values().iterator().next();
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/Apex2JMSTextEventConverter.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/Apex2JMSTextEventConverter.java
new file mode 100644 (file)
index 0000000..f488431
--- /dev/null
@@ -0,0 +1,100 @@
+/*-
+ * ============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.plugins.event.protocol.jms;
+
+import java.util.List;
+
+import javax.jms.TextMessage;
+
+import org.onap.policy.apex.service.engine.event.ApexEvent;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.Apex2JSONEventConverter;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class Apex2JMSTextEventConverter converts {@link ApexEvent} instances into string instances of
+ * {@link javax.jms.TextMessage} message events for JMS. It is a proxy for the built in
+ * {@link org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.Apex2JSONEventConverter} plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class Apex2JMSTextEventConverter extends Apex2JSONEventConverter {
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(Apex2JMSTextEventConverter.class);
+
+    /**
+     * Constructor to create the Apex to JMS Object converter.
+     *
+     * @throws ApexEventException the apex event exception
+     */
+    public Apex2JMSTextEventConverter() throws ApexEventException {}
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, java.lang.Object)
+     */
+    @Override
+    public List<ApexEvent> toApexEvent(final String eventName, final Object eventObject) throws ApexEventException {
+        // Check if this is an TextMessage from JMS
+        if (!(eventObject instanceof TextMessage)) {
+            final String errorMessage = "message \"" + eventObject + "\" received from JMS is not an instance of \""
+                    + TextMessage.class.getCanonicalName() + "\"";
+            LOGGER.debug(errorMessage);
+            throw new ApexEventRuntimeException(errorMessage);
+        }
+
+        // Get the string from the object message
+        final TextMessage textMessage = (TextMessage) eventObject;
+        String jmsString;
+        try {
+            jmsString = textMessage.getText();
+        } catch (final Exception e) {
+            final String errorMessage = "object contained in message \"" + eventObject
+                    + "\" received from JMS could not be retrieved as a Java String";
+            LOGGER.debug(errorMessage, e);
+            throw new ApexEventRuntimeException(errorMessage, e);
+        }
+
+        // Use the generic JSON plugin from here
+        return super.toApexEvent(eventName, jmsString);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy.apex.service.engine.
+     * event. ApexEvent)
+     */
+    @Override
+    public Object fromApexEvent(final ApexEvent apexEvent) throws ApexEventException {
+        // Check the Apex event
+        if (apexEvent == null) {
+            LOGGER.warn("event processing failed, Apex event is null");
+            throw new ApexEventException("event processing failed, Apex event is null");
+        }
+
+        // Return the Apex event as a string object
+        return super.fromApexEvent(apexEvent);
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/JMSObjectEventProtocolParameters.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/JMSObjectEventProtocolParameters.java
new file mode 100644 (file)
index 0000000..c2baff8
--- /dev/null
@@ -0,0 +1,127 @@
+/*-
+ * ============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.plugins.event.protocol.jms;
+
+import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters;
+
+/**
+ * Event protocol parameters for JMS Object messages as an event protocol.
+ *
+ * <p>
+ * On reception of an a JMS {@link javax.jms.ObjectMessage}, the JMS Object plugin unmarshals the message as follows:
+ * <ol>
+ * <li>It extracts the Java object from the {@link javax.jms.ObjectMessage} instance.
+ * <li>It creates an {@link org.onap.policy.apex.service.engine.event.ApexEvent} instance to hold the java object.
+ * <li>It sets the name of the Apex event to be the simple class name of the incoming Java object and appends the value
+ * of the {@code incomingEventSuffix} parameter to it.
+ * <li>It sets the version of the incoming event to the value of the {@code incomingEventVersion} parameter.
+ * <li>It sets the name space of the incoming event to be the value of the package of the class of the incoming Java
+ * object.
+ * <li>It sets the source of the incoming event to the value of the {@code incomingEventSource} parameter.
+ * <li>It sets the target of the incoming event to the value of the {@code incomingEventTarget} parameter.
+ * <li>It puts a single entry into the Apex event map with the the simple class name of the incoming Java object being
+ * the key of the entry and the actual incoming object as the value of the entry.
+ * </ol>
+ * <p>
+ * When sending an object to JMS, the plugin expects to receive an Apex event with a single entry. The plugin marshals
+ * the value of that entry to an object that can be sent by JMS as a {@link javax.jms.ObjectMessage} instance.
+ * <p>
+ * The parameters for this plugin are:
+ * <ol>
+ * <li>incomingEventSuffix: The suffix to append to the simple name of incoming Java class instances when they are
+ * encapsulated in Apex events. The parameter defaults to the string value {@code IncomingEvent}.
+ * <li>incomingEventVersion: The event version to use for incoming Java class instances when they are encapsulated in
+ * Apex events. The parameter defaults to the string value {@code 1.0.0}.
+ * <li>incomingEventSource: The event source to use for incoming Java class instances when they are encapsulated in Apex
+ * events. The parameter defaults to the string value {@code JMS}.
+ * <li>incomingEventTarget: The event target to use for incoming Java class instances when they are encapsulated in Apex
+ * events. The parameter defaults to the string value {@code Apex}.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JMSObjectEventProtocolParameters extends EventProtocolParameters {
+    /** The label of this event protocol. */
+    public static final String JMS_OBJECT_EVENT_PROTOCOL_LABEL = "JMSOBJECT";
+
+    //@formatter:off
+    // Default parameter values
+    private static final String   DEFAULT_INCOMING_EVENT_SUFFIX  = "IncomingEvent";
+    private static final String   DEFAULT_INCOMING_EVENT_VERSION = "1.0.0";
+    private static final String   DEFAULT_INCOMING_EVENT_SOURCE  = "JMS";
+    private static final String   DEFAULT_INCOMING_EVENT_TARGET  = "Apex";
+
+    // JMS carrier parameters
+    private String incomingEventSuffix   = DEFAULT_INCOMING_EVENT_SUFFIX;
+    private String incomingEventVersion  = DEFAULT_INCOMING_EVENT_VERSION;
+    private String incomingEventSource   = DEFAULT_INCOMING_EVENT_SOURCE;
+    private String incomingEventTarget   = DEFAULT_INCOMING_EVENT_TARGET;
+    //@formatter:off
+
+    /**
+     * Constructor to create a JSON event protocol parameter instance and register the instance with the parameter service.
+     */
+    public JMSObjectEventProtocolParameters() {
+        super(JMSObjectEventProtocolParameters.class.getCanonicalName());
+
+        // Set the event protocol properties for the JMS Text event protocol
+        this.setLabel(JMS_OBJECT_EVENT_PROTOCOL_LABEL);
+
+        // Set the event protocol plugin class
+        this.setEventProtocolPluginClass(Apex2JMSObjectEventConverter.class.getCanonicalName());
+    }
+
+    /**
+     * Gets the incoming event version.
+     *
+     * @return the incoming event version
+     */
+    public String getIncomingEventVersion() {
+        return incomingEventVersion;
+    }
+
+    /**
+     * Gets the incoming event source.
+     *
+     * @return the incoming event source
+     */
+    public String getIncomingEventSource() {
+        return incomingEventSource;
+    }
+
+    /**
+     * Gets the incoming event target.
+     *
+     * @return the incoming event target
+     */
+    public String getIncomingEventTarget() {
+        return incomingEventTarget;
+    }
+
+    /**
+     * Gets the incoming event suffix.
+     *
+     * @return the incoming event suffix
+     */
+    public String getIncomingEventSuffix() {
+        return incomingEventSuffix;
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/JMSTextEventProtocolParameters.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/JMSTextEventProtocolParameters.java
new file mode 100644 (file)
index 0000000..8ddc648
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * ============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.plugins.event.protocol.jms;
+
+import org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters;
+
+/**
+ * Event protocol parameters for JMS Text messages as an event protocol.
+ * <p>
+ * Text messages received and sent over JMS in ~Text format are assumed to be in a JSON format that Apex can understand.
+ * Therefore this plugin is a subclass of the built in JSON event protocol plugin.
+ * <p>
+ * On reception of a JMS {@link javax.jms.TextMessage} message, the JMS Text plugin unmarshals the message the JMS text
+ * message and passes it to its JSON superclass unmarshaling for processing.
+ * <p>
+ * When sending an Apex event, the plugin uses its underlying JSON superclass to marshal the event to a JSON string and
+ * passes that string to the JSON carrier plugin for sending.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JMSTextEventProtocolParameters extends JSONEventProtocolParameters {
+    /** The label of this event protocol. */
+    public static final String JMS_TEXT_EVENT_PROTOCOL_LABEL = "JMSTEXT";
+
+    /**
+     * Constructor to create a JSON event protocol parameter instance and register the instance with the parameter
+     * service.
+     */
+    public JMSTextEventProtocolParameters() {
+        super(JMSTextEventProtocolParameters.class.getCanonicalName(), JMS_TEXT_EVENT_PROTOCOL_LABEL);
+
+        // Set the event protocol properties for the JMS Text event protocol
+        this.setLabel(JMS_TEXT_EVENT_PROTOCOL_LABEL);
+
+        // Set the event protocol plugin class
+        this.setEventProtocolPluginClass(Apex2JMSTextEventConverter.class.getCanonicalName());
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/package-info.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-jms/src/main/java/org/onap/policy/apex/plugins/event/protocol/jms/package-info.java
new file mode 100644 (file)
index 0000000..92d6d07
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============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 implementations of Apex event protocol converter plugins for JMS event protocols that are implementations of
+ * {@link javax.jms.Message}.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.plugins.event.protocol.jms;
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/pom.xml b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/pom.xml
new file mode 100644 (file)
index 0000000..fd2be45
--- /dev/null
@@ -0,0 +1,104 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-protocol</groupId>
+        <artifactId>plugins-event-protocol</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-event-protocol-xml</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for handling events that are being transported in XML format</description>
+
+    <properties>
+        <apex-plugins-event-protocol-xml-dir>${project.basedir}/src</apex-plugins-event-protocol-xml-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jvnet.jaxb2.maven2</groupId>
+            <artifactId>maven-jaxb2-plugin</artifactId>
+            <version>0.13.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jvnet.jaxb2_commons</groupId>
+            <artifactId>jaxb2-basics-runtime</artifactId>
+            <version>1.11.1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jvnet.jaxb2.maven2</groupId>
+                <artifactId>maven-jaxb2-plugin</artifactId>
+                <version>0.13.2</version>
+                <configuration>
+                    <schemaDirectory>src/main/resources/xml</schemaDirectory>
+                    <schemaFiles>apex-event.xsd</schemaFiles>
+                    <bindingDirectory>src/main/resources/xml</bindingDirectory>
+                    <bindingFiles>apex-event.xjb</bindingFiles>
+                    <generatePackage>org.onap.policy.apex.plugins.event.protocol.xml.jaxb</generatePackage>
+                    <extension>true</extension>
+                    <addGeneratedAnnotation>true</addGeneratedAnnotation>
+                    <readOnly>true</readOnly>
+                    <verbose>true</verbose>
+                    <plugins>
+                        <plugin>
+                            <groupId>org.jvnet.jaxb2_commons</groupId>
+                            <artifactId>jaxb2-basics</artifactId>
+                            <version>1.11.1</version>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.jvnet.jaxb2_commons</groupId>
+                            <artifactId>jaxb2-basics-annotate</artifactId>
+                            <version>1.0.2</version>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.jvnet.jaxb2_commons</groupId>
+                            <artifactId>jaxb2-value-constructor</artifactId>
+                            <version>3.0</version>
+                        </plugin>
+                    </plugins>
+                    <args>
+                        <arg>-Xannotate</arg>
+                        <arg>-XtoString</arg>
+                        <arg>-Xmergeable</arg>
+                        <arg>-Xcopyable</arg>
+                        <arg>-Xequals</arg>
+                        <arg>-XhashCode</arg>
+                        <arg>-Xvalue-constructor</arg>
+                    </args>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>generate</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/Apex2XMLEventConverter.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/Apex2XMLEventConverter.java
new file mode 100644 (file)
index 0000000..01a57ca
--- /dev/null
@@ -0,0 +1,206 @@
+/*-
+ * ============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.plugins.event.protocol.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.onap.policy.apex.model.utilities.ResourceUtils;
+import org.onap.policy.apex.plugins.event.protocol.xml.jaxb.ObjectFactory;
+import org.onap.policy.apex.plugins.event.protocol.xml.jaxb.XMLApexEvent;
+import org.onap.policy.apex.plugins.event.protocol.xml.jaxb.XMLApexEventData;
+import org.onap.policy.apex.service.engine.event.ApexEvent;
+import org.onap.policy.apex.service.engine.event.ApexEventException;
+import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
+import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+import org.xml.sax.SAXException;
+
+/**
+ * The Class Apex2XMLEventConverter converts {@link ApexEvent} instances into string instances of {@link XMLApexEvent}
+ * that are XML representations of Apex events defined in JAXB.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class Apex2XMLEventConverter implements ApexEventProtocolConverter {
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(Apex2XMLEventConverter.class);
+
+    private static final String MODEL_SCHEMA_NAME = "xml/apex-event.xsd";
+
+    // XML Unmarshaller and marshaller and object factory for events
+    private Unmarshaller unmarshaller;
+    private Marshaller marshaller;
+    private ObjectFactory objectFactory = new ObjectFactory();
+
+    /**
+     * Constructor to create the Apex to XML converter.
+     *
+     * @throws ApexEventException the apex event exception
+     */
+    public Apex2XMLEventConverter() throws ApexEventException {
+        try {
+            final URL schemaURL = ResourceUtils.getURLResource(MODEL_SCHEMA_NAME);
+            final Schema apexEventSchema =
+                    SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(schemaURL);
+
+            final JAXBContext jaxbContext = JAXBContext.newInstance(XMLApexEvent.class);
+
+            // Set up the unmarshaller to carry out validation
+            unmarshaller = jaxbContext.createUnmarshaller();
+            unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
+            unmarshaller.setSchema(apexEventSchema);
+
+            // Set up the marshaller
+            marshaller = jaxbContext.createMarshaller();
+            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+            marshaller.setSchema(apexEventSchema);
+        } catch (JAXBException | SAXException e) {
+            LOGGER.error("Unable to set up marshalling and unmarshalling for XML events", e);
+            throw new ApexEventException("Unable to set up marshalling and unmarshalling for XML events", e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter#init(org.onap.policy.apex.service.
+     * parameters. eventprotocol.EventProtocolParameters)
+     */
+    @Override
+    public void init(final EventProtocolParameters parameters) {}
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, java.lang.Object)
+     */
+    @Override
+    public List<ApexEvent> toApexEvent(final String eventName, final Object eventObject) throws ApexEventException {
+        // Check the XML event
+        if (eventObject == null) {
+            LOGGER.warn("event processing failed, XML event is null");
+            throw new ApexEventException("event processing failed, XML event is null");
+        }
+
+        // Cast the event to a string, if our conversion is correctly configured, this cast should always work
+        String xmlEventString = null;
+        try {
+            xmlEventString = (String) eventObject;
+        } catch (final Exception e) {
+            final String errorMessage = "error converting event \"" + eventObject + "\" to a string";
+            LOGGER.debug(errorMessage, e);
+            throw new ApexEventRuntimeException(errorMessage, e);
+        }
+
+        // The XML event
+        XMLApexEvent xmlApexEvent = null;
+
+        // Use JAXB to read and verify the event from the XML string
+        try {
+            final StreamSource source = new StreamSource(new ByteArrayInputStream(xmlEventString.getBytes()));
+            final JAXBElement<XMLApexEvent> rootElement = unmarshaller.unmarshal(source, XMLApexEvent.class);
+            xmlApexEvent = rootElement.getValue();
+        } catch (final JAXBException e) {
+            LOGGER.warn("Unable to unmarshal Apex XML event\n" + xmlEventString, e);
+            throw new ApexEventException("Unable to unmarshal Apex XML event\n" + xmlEventString, e);
+        }
+
+        // Create the Apex event
+        final ApexEvent apexEvent = new ApexEvent(xmlApexEvent.getName(), xmlApexEvent.getVersion(),
+                xmlApexEvent.getNameSpace(), xmlApexEvent.getSource(), xmlApexEvent.getTarget());
+
+        // Set the data on the apex event
+        for (final XMLApexEventData xmlData : xmlApexEvent.getData()) {
+            apexEvent.put(xmlData.getKey(), xmlData.getValue());
+        }
+
+        // Return the event in a single element
+        final ArrayList<ApexEvent> eventList = new ArrayList<ApexEvent>();
+        eventList.add(apexEvent);
+        return eventList;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy.apex.service.engine.
+     * event. ApexEvent)
+     */
+    @Override
+    public String fromApexEvent(final ApexEvent apexEvent) throws ApexEventException {
+        // Check the Apex event
+        if (apexEvent == null) {
+            LOGGER.warn("event processing failed, Apex event is null");
+            throw new ApexEventException("event processing failed, Apex event is null");
+        }
+
+        // Get the Apex event data
+        final List<XMLApexEventData> xmlDataList = new ArrayList<XMLApexEventData>();
+
+        try {
+            for (final Entry<String, Object> apexDataEntry : apexEvent.entrySet()) {
+                // Add an XML event data item
+                if (apexDataEntry.getValue() != null) {
+                    xmlDataList.add(new XMLApexEventData(apexDataEntry.getKey(), apexDataEntry.getValue().toString()));
+                } else {
+                    xmlDataList.add(new XMLApexEventData(apexDataEntry.getKey(), ""));
+                }
+            }
+        } catch (final Exception e) {
+            LOGGER.warn("Unable to transfer Apex event data to XML\n" + apexEvent, e);
+            throw new ApexEventException("Unable to transfer Apex event data to XML\n" + apexEvent, e);
+        }
+
+        // Create the XML event
+        final XMLApexEvent xmlApexEvent = new XMLApexEvent(apexEvent.getName(), apexEvent.getVersion(),
+                apexEvent.getNameSpace(), apexEvent.getSource(), apexEvent.getTarget(), xmlDataList);
+
+        // Write the event into a DOM document
+        try {
+            // Marshal the event into XML
+            final StringWriter writer = new StringWriter();
+            marshaller.marshal(objectFactory.createXmlApexEvent(xmlApexEvent), writer);
+
+            // Return the event as XML in a string
+            return writer.toString();
+        } catch (final JAXBException e) {
+            LOGGER.warn("Unable to unmarshal Apex event to XML\n" + apexEvent, e);
+            throw new ApexEventException("Unable to unmarshal Apex event to XML\n" + apexEvent, e);
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/XMLEventProtocolParameters.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/XMLEventProtocolParameters.java
new file mode 100644 (file)
index 0000000..e96a3f5
--- /dev/null
@@ -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.plugins.event.protocol.xml;
+
+import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextTokenDelimitedParameters;
+
+/**
+ * Event protocol parameters for XML as an event protocol.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class XMLEventProtocolParameters extends EventProtocolTextTokenDelimitedParameters {
+    /** The label of this carrier technology. */
+    public static final String XML_EVENT_PROTOCOL_LABEL = "XML";
+
+    // Constants for the text delimiter token
+    private static final String XML_TEXT_DELIMITER_TOKEN = "<?xml";
+
+    /**
+     * Constructor to create a JSON event protocol parameter instance and register the instance with the parameter
+     * service.
+     */
+    public XMLEventProtocolParameters() {
+        super(XMLEventProtocolParameters.class.getCanonicalName());
+
+        // Set the event protocol properties for the XML event protocol
+        this.setLabel(XML_EVENT_PROTOCOL_LABEL);
+
+        // Set the starting and ending delimiters for text blocks of XML events
+        this.setDelimiterToken(XML_TEXT_DELIMITER_TOKEN);
+
+        // Set the event protocol plugin class
+        this.setEventProtocolPluginClass(Apex2XMLEventConverter.class.getCanonicalName());
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/package-info.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/java/org/onap/policy/apex/plugins/event/protocol/xml/package-info.java
new file mode 100644 (file)
index 0000000..4f97265
--- /dev/null
@@ -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 the implementation of the APEX event protocol converter plugin for events in XML format.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.plugins.event.protocol.xml;
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/resources/xml/apex-event.xjb b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/resources/xml/apex-event.xjb
new file mode 100644 (file)
index 0000000..fa334c4
--- /dev/null
@@ -0,0 +1,39 @@
+<?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=========================================================
+-->
+
+<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+       xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:annox="http://annox.dev.java.net"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
+       version="2.1">
+
+       <!--jaxb:globalBindings generateIsSetMethod="true">
+               <xjc:serializable uid="1" />
+               <xjc:javaType name="java.lang.String" xmlType="xs:string"
+                       adapter="org.onap.policy.apex.core.model.xml.StringTrimAdapter" />
+       </jaxb:globalBindings-->
+
+       <jaxb:bindings schemaLocation="apex-event.xsd" node="/xs:schema">
+               <jaxb:bindings node="xs:complexType[@name='XMLApexEvent']"> <annox:annotate> 
+                       <annox:annotate annox:class="java.lang.SuppressWarnings" value="all" /> </annox:annotate> 
+                       </jaxb:bindings>
+       </jaxb:bindings>
+</jaxb:bindings>
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/resources/xml/apex-event.xsd b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/main/resources/xml/apex-event.xsd
new file mode 100644 (file)
index 0000000..c831455
--- /dev/null
@@ -0,0 +1,119 @@
+<?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=========================================================
+-->
+
+<schema targetNamespace="http://www.onap.org/policy/apex-pdp/apexevent" elementFormDefault="qualified"
+    xmlns="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+    xmlns:basic="http://jaxb2-commons.dev.java.net/basic"
+    xmlns:copyable="http://jaxb2-commons.dev.java.net/basic/copyable"
+    xmlns:equals="http://jaxb2-commons.dev.java.net/basic/equals"
+    xmlns:hashCode="http://jaxb2-commons.dev.java.net/basic/hashCode"
+    xmlns:mergeable="http://jaxb2-commons.dev.java.net/basic/mergeable"
+    xmlns:toString="http://jaxb2-commons.dev.java.net/basic/toString"
+    jaxb:extensionBindingPrefixes="xjc basic copyable equals hashCode mergeable toString"
+    xmlns:apexev="http://www.onap.org/policy/apex-pdp/apexevent" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+    jaxb:version="2.0">
+
+    <annotation>
+        <documentation>An event that comes into or is emitted out of an Apex system.
+        </documentation>
+    </annotation>
+
+    <annotation>
+        <appinfo>
+            <jaxb:globalBindings generateIsSetMethod="true">
+                <xjc:serializable uid="1" />
+            </jaxb:globalBindings>
+        </appinfo>
+    </annotation>
+
+    <complexType name="XMLApexEvent">
+        <annotation>
+            <documentation>An event that comes into or goes out of an Apex system</documentation>
+        </annotation>
+        <sequence>
+            <element name="name" maxOccurs="1" minOccurs="1">
+                <simpleType>
+                    <restriction base="string">
+                        <pattern value="[A-Za-z0-9\-_:]+"></pattern>
+                    </restriction>
+                </simpleType>
+            </element>
+            <element name="version" maxOccurs="1" minOccurs="1">
+                <simpleType>
+                    <restriction base="string">
+                        <pattern value="[0-9.]+"></pattern>
+                    </restriction>
+                </simpleType>
+            </element>
+            <element name="nameSpace" maxOccurs="1" minOccurs="1">
+                <simpleType>
+                    <restriction base="string">
+                        <minLength value="1"></minLength>
+                    </restriction>
+                </simpleType>
+            </element>
+            <element name="source" maxOccurs="1" minOccurs="0">
+                <simpleType>
+                    <restriction base="string">
+                        <minLength value="0"></minLength>
+                    </restriction>
+                </simpleType>
+            </element>
+            <element name="target" maxOccurs="1" minOccurs="0">
+                <simpleType>
+                    <restriction base="string">
+                        <minLength value="0"></minLength>
+                    </restriction>
+                </simpleType>
+            </element>
+            <element name="data" type="apexev:XMLApexEventData" maxOccurs="unbounded" minOccurs="0">
+            </element>
+        </sequence>
+    </complexType>
+
+    <element name="xmlApexEvent" type="apexev:XMLApexEvent"></element>
+
+    <complexType name="XMLApexEventData">
+        <annotation>
+            <documentation>
+                A single data item of an Apex event.
+            </documentation>
+        </annotation>
+        <sequence>
+            <element name="key" maxOccurs="1" minOccurs="1">
+                <simpleType>
+                    <restriction base="string">
+                        <pattern value="[A-Za-z0-9\-_:]+"></pattern>
+                    </restriction>
+                </simpleType>
+            </element>
+            <element name="value" maxOccurs="1" minOccurs="1">
+                <simpleType>
+                    <restriction base="string">
+                        <minLength value="0"></minLength>
+                    </restriction>
+                </simpleType>
+            </element>
+        </sequence>
+    </complexType>
+
+
+</schema>
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/TestXMLEventHandler.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/TestXMLEventHandler.java
new file mode 100644 (file)
index 0000000..a62cc24
--- /dev/null
@@ -0,0 +1,147 @@
+/*-
+ * ============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.plugins.event.protocol.xml;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.service.engine.event.ApexEvent;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class TestApexXMLEventHandlerURL.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestXMLEventHandler {
+    private static final XLogger logger = XLoggerFactory.getXLogger(TestXMLEventHandler.class);
+
+    /**
+     * Test XML to apex event.
+     *
+     * @throws ApexException on Apex event handling errors
+     */
+    @Test
+    public void testXMLtoApexEvent() throws ApexException {
+        try {
+            final Apex2XMLEventConverter xmlEventConverter = new Apex2XMLEventConverter();
+            assertNotNull(xmlEventConverter);
+
+            final String apexEventXMLStringIn = XMLEventGenerator.xmlEvent();
+
+            logger.debug("input event\n" + apexEventXMLStringIn);
+
+            for (final ApexEvent apexEvent : xmlEventConverter.toApexEvent("XMLEventName", apexEventXMLStringIn)) {
+                assertNotNull(apexEvent);
+
+                logger.debug(apexEvent.toString());
+
+                assertTrue(apexEvent.getName().equals("Event0000") || apexEvent.getName().equals("Event0100"));
+                assertTrue(apexEvent.getVersion().equals("0.0.1"));
+                assertTrue(apexEvent.getNameSpace().equals("org.onap.policy.apex.sample.events"));
+                assertTrue(apexEvent.getSource().equals("test"));
+                assertTrue(apexEvent.getTarget().equals("apex"));
+                assertTrue(apexEvent.get("TestSlogan").toString().startsWith("Test slogan for External Event"));
+
+                final Object testMatchCaseSelected = apexEvent.get("TestMatchCaseSelected");
+                assertTrue(testMatchCaseSelected == null);
+            }
+        } catch (final Exception e) {
+            e.printStackTrace();
+            throw new ApexException("Exception reading Apex event xml file", e);
+        }
+    }
+
+    /**
+     * Test apex event to xml.
+     *
+     * @throws ApexException on Apex event handling errors
+     */
+    @Test
+    public void testApexEventToXML() throws ApexException {
+        try {
+            final Apex2XMLEventConverter xmlEventConverter = new Apex2XMLEventConverter();
+            assertNotNull(xmlEventConverter);
+
+            final Date event0000StartTime = new Date();
+            final Map<String, Object> event0000DataMap = new HashMap<String, Object>();
+            event0000DataMap.put("TestSlogan", "This is a test slogan");
+            event0000DataMap.put("TestMatchCase", 12345);
+            event0000DataMap.put("TestTimestamp", event0000StartTime.getTime());
+            event0000DataMap.put("TestTemperature", 34.5445667);
+
+            final ApexEvent apexEvent0000 =
+                    new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.sample.events", "test", "apex");
+            apexEvent0000.putAll(event0000DataMap);
+
+            final String apexEvent0000XMLString = xmlEventConverter.fromApexEvent(apexEvent0000);
+
+            logger.debug(apexEvent0000XMLString);
+
+            assertTrue(apexEvent0000XMLString.contains("<name>Event0000</name>"));
+            assertTrue(apexEvent0000XMLString.contains("<version>0.0.1</version>"));
+            assertTrue(apexEvent0000XMLString.contains("<value>This is a test slogan</value>"));
+            assertTrue(apexEvent0000XMLString.contains("<value>12345</value>"));
+            assertTrue(apexEvent0000XMLString.contains("<value>" + event0000StartTime.getTime() + "</value>"));
+            assertTrue(apexEvent0000XMLString.contains("<value>34.5445667</value>"));
+
+            final Date event0004StartTime = new Date(1434363272000L);
+            final Map<String, Object> event0004DataMap = new HashMap<String, Object>();
+            event0004DataMap.put("TestSlogan", "Test slogan for External Event");
+            event0004DataMap.put("TestMatchCase", new Integer(2));
+            event0004DataMap.put("TestTimestamp", new Long(event0004StartTime.getTime()));
+            event0004DataMap.put("TestTemperature", new Double(1064.43));
+            event0004DataMap.put("TestMatchCaseSelected", new Integer(2));
+            event0004DataMap.put("TestMatchStateTime", new Long(1434370506078L));
+            event0004DataMap.put("TestEstablishCaseSelected", new Integer(0));
+            event0004DataMap.put("TestEstablishStateTime", new Long(1434370506085L));
+            event0004DataMap.put("TestDecideCaseSelected", new Integer(3));
+            event0004DataMap.put("TestDecideStateTime", new Long(1434370506092L));
+            event0004DataMap.put("TestActCaseSelected", new Integer(2));
+            event0004DataMap.put("TestActStateTime", new Long(1434370506095L));
+
+            final ApexEvent apexEvent0004 =
+                    new ApexEvent("Event0004", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+            apexEvent0004.putAll(event0004DataMap);
+
+            final String apexEvent0004XMLString = xmlEventConverter.fromApexEvent(apexEvent0004);
+
+            logger.debug(apexEvent0004XMLString);
+
+            assertTrue(apexEvent0004XMLString.contains("<name>Event0004</name>"));
+            assertTrue(apexEvent0004XMLString.contains("<version>0.0.1</version>"));
+            assertTrue(apexEvent0004XMLString.contains("<value>Test slogan for External Event</value>"));
+            assertTrue(apexEvent0004XMLString.contains("<value>1434370506078</value>"));
+            assertTrue(apexEvent0004XMLString.contains("<value>" + event0004StartTime.getTime() + "</value>"));
+            assertTrue(apexEvent0004XMLString.contains("<value>1064.43</value>"));
+        } catch (final Exception e) {
+            e.printStackTrace();
+            throw new ApexException("Exception reading Apex event xml file", e);
+        }
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/TestXMLTaggedEventConsumer.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/TestXMLTaggedEventConsumer.java
new file mode 100644 (file)
index 0000000..761357a
--- /dev/null
@@ -0,0 +1,336 @@
+/*-
+ * ============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.plugins.event.protocol.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Test;
+import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.HeaderDelimitedTextBlockReader;
+import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.TextBlock;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestXMLTaggedEventConsumer {
+    @Test
+    public void testGarbageTextLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream("hello there".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertNull(textBlock.getText());
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testPartialEventLine() throws IOException {
+        final InputStream xmlInputStream =
+                new ByteArrayInputStream("1469781869268</TestTimestamp></MainTag>".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertNull(textBlock.getText());
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(), "<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventGarbageBeforeLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventGarbageBeforeAfterLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>Rubbish".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventGarbageAfterLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>Rubbish".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>Rubbish");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testGarbageTextMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream("hello\nthere".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testPartialEventMultiLine() throws IOException {
+        final InputStream xmlInputStream =
+                new ByteArrayInputStream("1469781869268\n</TestTimestamp>\n</MainTag>".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\n\n".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventGarbageBeforeMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\n\n".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventGarbageBeforeAfterMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish\n\n"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventGarbageAfterMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testPartialEventsLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "1469781869268</TestTimestamp></MainTag><?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp>"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsGarbageBeforeLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag><?xml><MainTag><TestTimestamp>"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsGarbageBeforeAfterLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>Rubbish<?xml><MainTag><TestTimestamp>\nRefuse"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsGarbageAfterLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>Rubbish<?xml><MainTag><TestTimestamp>Refuse"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml><MainTag><TestTimestamp>1469781869268</TestTimestamp></MainTag>Rubbish<?xml><MainTag><TestTimestamp>Refuse");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testPartialEventsMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "1469781869268\n</TestTimestamp>\n</MainTag>\n<?xml>\n<MainTag>\n<TestTimestamp>".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(), "<?xml>\n<MainTag>\n<TestTimestamp>");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\n"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>");
+        assertFalse(textBlock.isEndOfText());
+
+        textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsGarbageBeforeMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\n\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\n"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>");
+        assertFalse(textBlock.isEndOfText());
+
+        textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsGarbageBeforeAfterMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "Garbage\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish\n<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRefuse\n"
+                        .getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish");
+        assertFalse(textBlock.isEndOfText());
+
+        textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRefuse");
+        assertTrue(textBlock.isEndOfText());
+    }
+
+    @Test
+    public void testFullEventsGarbageAfterMultiLine() throws IOException {
+        final InputStream xmlInputStream = new ByteArrayInputStream(
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish".getBytes());
+
+        final HeaderDelimitedTextBlockReader xmlTaggedReader = new HeaderDelimitedTextBlockReader("<?xml");
+        xmlTaggedReader.init(xmlInputStream);
+
+        final TextBlock textBlock = xmlTaggedReader.readTextBlock();
+        assertEquals(textBlock.getText(),
+                "<?xml>\n<MainTag>\n<TestTimestamp>1469781869268</TestTimestamp>\n</MainTag>\nRubbish");
+        assertTrue(textBlock.isEndOfText());
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/XMLEventGenerator.java b/plugins/plugins-event/plugins-event-protocol/plugins-event-protocol-xml/src/test/java/org/onap/policy/apex/plugins/event/protocol/xml/XMLEventGenerator.java
new file mode 100644 (file)
index 0000000..765f098
--- /dev/null
@@ -0,0 +1,104 @@
+/*-
+ * ============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.plugins.event.protocol.xml;
+
+import java.util.Random;
+
+/**
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class XMLEventGenerator {
+    private static int nextEventNo = 0;
+
+    public static String xmlEvents(final int eventCount) {
+        final StringBuilder builder = new StringBuilder();
+
+        for (int i = 0; i < eventCount; i++) {
+            if (i > 0) {
+                builder.append("\n");
+            }
+            builder.append(xmlEvent());
+        }
+
+        return builder.toString();
+    }
+
+    public static String xmlEvent() {
+        final Random rand = new Random();
+
+        final StringBuilder builder = new StringBuilder();
+
+        int nextEventNo = rand.nextInt(2);
+        final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100");
+        final int nextMatchCase = rand.nextInt(4);
+        final float nextTestTemperature = rand.nextFloat() * 10000;
+
+        builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+        builder.append("<xmlApexEvent xmlns=\"http://www.onap.org/policy/apex-pdp/apexevent\">\n");
+
+        builder.append("  <name>" + eventName + "</name>\n");
+        builder.append("  <version>0.0.1</version>\n");
+        builder.append("  <nameSpace>org.onap.policy.apex.sample.events</nameSpace>\n");
+        builder.append("  <source>test</source>\n");
+        builder.append("  <target>apex</target>\n");
+        builder.append("  <data>\n");
+        builder.append("    <key>TestSlogan</key>\n");
+        builder.append("    <value>Test slogan for External Event" + (nextEventNo++) + "</value>\n");
+        builder.append("  </data>\n");
+        builder.append("  <data>\n");
+        builder.append("    <key>TestMatchCase</key>\n");
+        builder.append("       <value>" + nextMatchCase + "</value>\n");
+        builder.append("  </data>\n");
+        builder.append("  <data>\n");
+        builder.append("    <key>TestTimestamp</key>\n");
+        builder.append("    <value>" + System.currentTimeMillis() + "</value>\n");
+        builder.append("  </data>\n");
+        builder.append("  <data>\n");
+        builder.append("    <key>TestTemperature</key>\n");
+        builder.append("    <value>" + nextTestTemperature + "</value>\n");
+        builder.append("  </data>\n");
+        builder.append("</xmlApexEvent>");
+
+        return builder.toString();
+    }
+
+    public static void main(final String[] args) {
+        if (args.length != 1) {
+            System.err.println("usage EventGenerator #events");
+            return;
+        }
+
+        int eventCount = 0;
+        try {
+            eventCount = Integer.parseInt(args[0]);
+        } catch (final Exception e) {
+            System.err.println("usage EventGenerator #events");
+            e.printStackTrace();
+            return;
+        }
+
+        System.out.println(xmlEvents(eventCount));
+    }
+
+    public static int getNextEventNo() {
+        return nextEventNo;
+    }
+}
diff --git a/plugins/plugins-event/plugins-event-protocol/pom.xml b/plugins/plugins-event/plugins-event-protocol/pom.xml
new file mode 100644 (file)
index 0000000..563a4f6
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-event</groupId>
+        <artifactId>plugins-event</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.onap.policy.apex-pdp.plugins.plugins-event.plugins-event-protocol</groupId>
+    <artifactId>plugins-event-protocol</artifactId>
+    <packaging>pom</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>Plugins for protocols that events are carried in</description>
+
+    <properties>
+        <apex-plugins-event-protocol-dir>${project.basedir}/src</apex-plugins-event-protocol-dir>
+    </properties>
+
+    <modules>
+        <module>plugins-event-protocol-jms</module>
+        <module>plugins-event-protocol-xml</module>
+    </modules>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-event/pom.xml b/plugins/plugins-event/pom.xml
new file mode 100644 (file)
index 0000000..c48b8ae
--- /dev/null
@@ -0,0 +1,48 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins</groupId>
+        <artifactId>plugins</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.onap.policy.apex-pdp.plugins.plugins-event</groupId>
+    <artifactId>plugins-event</artifactId>
+    <packaging>pom</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>Plugins for 3pps that carry events and protocol formats of events</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.services</groupId>
+            <artifactId>services-engine</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <modules>
+        <module>plugins-event-carrier</module>
+        <module>plugins-event-protocol</module>
+    </modules>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-executor/plugins-executor-mvel/pom.xml b/plugins/plugins-executor/plugins-executor-mvel/pom.xml
new file mode 100644 (file)
index 0000000..a8b2c7d
--- /dev/null
@@ -0,0 +1,44 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins.plugins-executor</groupId>
+        <artifactId>plugins-executor</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plugins-executor-mvel</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] Plugin for execution of Mvel logic in Apex</description>
+
+    <properties>
+        <apex-plugins-executor-mvel-dir>${project.basedir}/src</apex-plugins-executor-mvel-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.mvel</groupId>
+            <artifactId>mvel2</artifactId>
+            <version>2.3.1.Final</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MVELExecutorParameters.java b/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MVELExecutorParameters.java
new file mode 100644 (file)
index 0000000..21d1242
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============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.plugins.executor.mvel;
+
+import org.onap.policy.apex.core.engine.ExecutorParameters;
+
+/**
+ * This class provides executor parameters for the MVEL Executor plugin. It specifies the classes that provide the MVEL
+ * implementations of the abstract classes {@link org.onap.policy.apex.core.engine.executor.TaskExecutor},
+ * {@link org.onap.policy.apex.core.engine.executor.TaskSelectExecutor}, and
+ * {@link org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor}.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class MVELExecutorParameters extends ExecutorParameters {
+    /**
+     * Constructor that sets the abstract implementation classes.
+     */
+    public MVELExecutorParameters() {
+        this.setTaskExecutorPluginClass(MvelTaskExecutor.class.getCanonicalName());
+        this.setTaskSelectionExecutorPluginClass(MvelTaskSelectExecutor.class.getCanonicalName());
+        this.setStateFinalizerExecutorPluginClass(MvelStateFinalizerExecutor.class.getCanonicalName());
+    }
+}
diff --git a/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelStateFinalizerExecutor.java b/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelStateFinalizerExecutor.java
new file mode 100644 (file)
index 0000000..8cd76a9
--- /dev/null
@@ -0,0 +1,118 @@
+/*-
+ * ============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.plugins.executor.mvel;
+
+import static org.onap.policy.apex.model.utilities.Assertions.argumentNotNull;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mvel2.MVEL;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.core.engine.executor.StateFinalizerExecutor;
+import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class MvelStateFinalizerExecutor is the state finalizer executor for state finalizer logic written in MVEL.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class MvelStateFinalizerExecutor extends StateFinalizerExecutor {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(MvelStateFinalizerExecutor.class);
+
+    // The MVEL code
+    private Serializable compiled = null;
+
+    /**
+     * Prepares the state finalizer for processing.
+     *
+     * @throws StateMachineException thrown when a state machine execution error occurs
+     */
+    @Override
+    public void prepare() throws StateMachineException {
+        // Call generic prepare logic
+        super.prepare();
+
+        // Compile the MVEL code
+        try {
+            compiled = MVEL.compileExpression(getSubject().getLogic());
+        } catch (final Exception e) {
+            LOGGER.warn("failed to compile MVEL code for state " + getSubject().getKey().getID(), e);
+            throw new StateMachineException("failed to compile MVEL code for state " + getSubject().getKey().getID(),
+                    e);
+        }
+    }
+
+    /**
+     * Executes the executor for the state finalizer logic in a sequential manner.
+     *
+     * @param executionID the execution ID for the current APEX policy execution
+     * @param incomingFields the incoming fields for finalisation
+     * @return The state output for the state
+     * @throws StateMachineException on an execution error
+     * @throws ContextException on context errors
+     */
+    @Override
+    public String execute(final long executionID, final Map<String, Object> incomingFields)
+            throws StateMachineException, ContextException {
+        // Do execution pre work
+        executePre(executionID, incomingFields);
+
+        // Check and execute the MVEL logic
+        argumentNotNull(compiled, "MVEL state finalizer logic not compiled.");
+
+        boolean returnValue = false;
+        try {
+            // Execute the MVEL code
+            returnValue =
+                    (boolean) MVEL.executeExpression(compiled, getExecutionContext(), new HashMap<String, Object>());
+        } catch (final Exception e) {
+            LOGGER.warn("failed to execute MVEL code for state " + getSubject().getKey().getID(), e);
+            throw new StateMachineException("failed to execute MVEL code for state " + getSubject().getKey().getID(),
+                    e);
+        }
+
+        // Do the execution post work
+        executePost(returnValue);
+
+        // Send back the return event
+        if (returnValue) {
+            return getOutgoing();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Cleans up the state finalizer after processing.
+     *
+     * @throws StateMachineException thrown when a state machine execution error occurs
+     */
+    @Override
+    public void cleanUp() throws StateMachineException {
+        LOGGER.debug("cleanUp:" + getSubject().getKey().getID() + "," + getSubject().getLogicFlavour() + ","
+                + getSubject().getLogic());
+    }
+}
diff --git a/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelTaskExecutor.java b/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelTaskExecutor.java
new file mode 100644 (file)
index 0000000..8599eab
--- /dev/null
@@ -0,0 +1,117 @@
+/*-
+ * ============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.plugins.executor.mvel;
+
+import static org.onap.policy.apex.model.utilities.Assertions.argumentNotNull;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mvel2.MVEL;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.core.engine.executor.TaskExecutor;
+import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class MvelTaskExecutor is the task executor for task logic written in MVEL.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class MvelTaskExecutor extends TaskExecutor {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(MvelTaskExecutor.class);
+
+    // The MVEL code
+    private Serializable compiled = null;
+
+    /**
+     * Prepares the task for processing.
+     *
+     * @throws StateMachineException thrown when a state machine execution error occurs
+     */
+    @Override
+    public void prepare() throws StateMachineException {
+        // Call generic prepare logic
+        super.prepare();
+
+        // Compile the MVEL code
+        try {
+            compiled = MVEL.compileExpression(getSubject().getTaskLogic().getLogic());
+        } catch (final Exception e) {
+            LOGGER.warn("failed to compile MVEL code for task " + getSubject().getKey().getID(), e);
+            throw new StateMachineException("failed to compile MVEL code for task " + getSubject().getKey().getID(), e);
+        }
+        argumentNotNull(compiled, "MVEL task not compiled.");
+    }
+
+    /**
+     * Executes the executor for the task in a sequential manner.
+     *
+     * @param executionID the execution ID for the current APEX policy execution
+     * @param incomingFields the incoming fields
+     * @return The outgoing fields
+     * @throws StateMachineException on an execution error
+     * @throws ContextException on context errors
+     */
+    @Override
+    public Map<String, Object> execute(final long executionID, final Map<String, Object> incomingFields)
+            throws StateMachineException, ContextException {
+        // Do execution pre work
+        executePre(executionID, incomingFields);
+
+        // Check and execute the MVEL logic
+        argumentNotNull(compiled, "MVEL task not compiled.");
+        boolean returnValue = false;
+
+        try {
+            // Execute the MVEL code
+            returnValue =
+                    (boolean) MVEL.executeExpression(compiled, getExecutionContext(), new HashMap<String, Object>());
+        } catch (final Exception e) {
+            LOGGER.warn("failed to execute MVEL code for task " + getSubject().getKey().getID(), e);
+            throw new StateMachineException("failed to execute MVEL code for task " + getSubject().getKey().getID(), e);
+        }
+
+        // Do the execution post work
+        executePost(returnValue);
+
+        // Send back the return event
+        if (returnValue) {
+            return getOutgoing();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Cleans up the task after processing.
+     *
+     * @throws StateMachineException thrown when a state machine execution error occurs
+     */
+    @Override
+    public void cleanUp() throws StateMachineException {
+        LOGGER.debug("cleanUp:" + getSubject().getKey().getID() + "," + getSubject().getTaskLogic().getLogicFlavour()
+                + "," + getSubject().getTaskLogic().getLogic());
+    }
+}
diff --git a/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelTaskSelectExecutor.java b/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/MvelTaskSelectExecutor.java
new file mode 100644 (file)
index 0000000..3cb5d9b
--- /dev/null
@@ -0,0 +1,120 @@
+/*-
+ * ============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.plugins.executor.mvel;
+
+import static org.onap.policy.apex.model.utilities.Assertions.argumentNotNull;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+import org.mvel2.MVEL;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.core.engine.event.EnEvent;
+import org.onap.policy.apex.core.engine.executor.TaskSelectExecutor;
+import org.onap.policy.apex.core.engine.executor.exception.StateMachineException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class MvelTaskSelectExecutor is the task selection executor for task selection logic written in MVEL.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class MvelTaskSelectExecutor extends TaskSelectExecutor {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(MvelTaskSelectExecutor.class);
+
+    // The MVEL code
+    private Serializable compiled = null;
+
+    /**
+     * Prepares the task for processing.
+     *
+     * @throws StateMachineException thrown when a state machine execution error occurs
+     */
+    @Override
+    public void prepare() throws StateMachineException {
+        // Call generic prepare logic
+        super.prepare();
+
+        // Compile the MVEL code
+        try {
+            compiled = MVEL.compileExpression(getSubject().getTaskSelectionLogic().getLogic());
+        } catch (final Exception e) {
+            LOGGER.warn("failed to compile MVEL code for state " + getSubject().getKey().getID(), e);
+            throw new StateMachineException("failed to compile MVEL code for state " + getSubject().getKey().getID(),
+                    e);
+        }
+    }
+
+    /**
+     * Executes the executor for the task in a sequential manner.
+     *
+     * @param executionID the execution ID for the current APEX policy execution
+     * @param incomingEvent the incoming event
+     * @return The outgoing event
+     * @throws StateMachineException on an execution error
+     * @throws ContextException on context errors
+     */
+    @Override
+    public AxArtifactKey execute(final long executionID, final EnEvent incomingEvent)
+            throws StateMachineException, ContextException {
+        // Do execution pre work
+        executePre(executionID, incomingEvent);
+
+        // Check and execute the MVEL logic
+        argumentNotNull(compiled, "MVEL task not compiled.");
+
+        boolean returnValue = false;
+        try {
+            // Execute the MVEL code
+            returnValue =
+                    (boolean) MVEL.executeExpression(compiled, getExecutionContext(), new HashMap<String, Object>());
+        } catch (final Exception e) {
+            LOGGER.warn("failed to execute MVEL code for state " + getSubject().getKey().getID(), e);
+            throw new StateMachineException("failed to execute MVEL code for state " + getSubject().getKey().getID(),
+                    e);
+        }
+
+        // Do the execution post work
+        executePost(returnValue);
+
+        // Send back the return event
+        if (returnValue) {
+            return getOutgoing();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Cleans up the task after processing.
+     *
+     * @throws StateMachineException thrown when a state machine execution error occurs
+     */
+    @Override
+    public void cleanUp() throws StateMachineException {
+        LOGGER.debug("cleanUp:" + getSubject().getKey().getID() + ","
+                + getSubject().getTaskSelectionLogic().getLogicFlavour() + ","
+                + getSubject().getTaskSelectionLogic().getLogic());
+    }
+}
diff --git a/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/package-info.java b/plugins/plugins-executor/plugins-executor-mvel/src/main/java/org/onap/policy/apex/plugins/executor/mvel/package-info.java
new file mode 100644 (file)
index 0000000..8e8ab88
--- /dev/null
@@ -0,0 +1,30 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * Implements the MVEL executor plugin for APEX, providing extensions of the abstract classes
+ * {@link com.ericsson.apex.core.engine.executor.TaskExecutor},
+ * {@link com.ericsson.apex.core.engine.executor.TaskSelectExecutor}, and
+ * {@link com.ericsson.apex.core.engine.executor.StateFinalizerExecutor}.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.plugins.executor.mvel;
diff --git a/plugins/plugins-executor/pom.xml b/plugins/plugins-executor/pom.xml
new file mode 100644 (file)
index 0000000..e18fd17
--- /dev/null
@@ -0,0 +1,81 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.plugins</groupId>
+        <artifactId>plugins</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.onap.policy.apex-pdp.plugins.plugins-executor</groupId>
+    <artifactId>plugins-executor</artifactId>
+    <packaging>pom</packaging>
+
+    <name>${project.artifactId}</name>
+    <description>Plugins for logic execution in Apex</description>
+
+    <properties>
+        <apex-plugins-executor-dir>${project.basedir}/src</apex-plugins-executor-dir>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.core</groupId>
+            <artifactId>core-engine</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>apexDefault</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <modules>
+                <module>plugins-executor-mvel</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>apexTests</id>
+            <activation>
+                <property>
+                    <name>apexTests</name>
+                </property>
+            </activation>
+            <modules>
+                <module>plugins-executor-mvel</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>apexAll</id>
+            <activation>
+                <property>
+                    <name>apexAll</name>
+                </property>
+            </activation>
+            <modules>
+                <module>plugins-executor-mvel</module>
+            </modules>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file
index f9afef8..73bcdfa 100644 (file)
 
     <properties>
         <version.hazelcast>3.8.3</version.hazelcast>
+        <version.jersey.core>2.25.1</version.jersey.core>
+        <version.grizzly2-http>2.25.1</version.grizzly2-http>
     </properties>
 
     <modules>
         <module>plugins-context</module>
+        <module>plugins-event</module>
+        <module>plugins-executor</module>
     </modules>
 </project>
\ No newline at end of file