diff --git a/testsuites/integration/integration-uservice-test/pom.xml b/testsuites/integration/integration-uservice-test/pom.xml
index 5c595e5..b139f24 100644
--- a/testsuites/integration/integration-uservice-test/pom.xml
+++ b/testsuites/integration/integration-uservice-test/pom.xml
@@ -68,6 +68,12 @@
             <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.plugins.plugins-context.plugins-context-distribution</groupId>
             <artifactId>plugins-context-distribution-infinispan</artifactId>
             <version>${project.version}</version>
diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/kafka/TestKafka2Kafka.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/kafka/TestKafka2Kafka.java
index 5c8eb7e..7afef53 100644
--- a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/kafka/TestKafka2Kafka.java
+++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/kafka/TestKafka2Kafka.java
@@ -41,9 +41,9 @@
  * The Class TestKafka2Kafka tests Kafka event sending and reception.
  */
 public class TestKafka2Kafka {
-    private static final long MAX_TEST_LENGTH = 60000;
+    private static final long MAX_TEST_LENGTH = 300000;
 
-    private static final int EVENT_COUNT = 100;
+    private static final int EVENT_COUNT = 25;
     private static final int EVENT_INTERVAL = 20;
 
     /**
@@ -131,7 +131,7 @@
             ThreadUtilities.sleep(EVENT_INTERVAL);
         }
 
-        ThreadUtilities.sleep(1000);
+        ThreadUtilities.sleep(3000);
 
         apexMain.shutdown();
         subscriber.shutdown();
diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java
index 9a9b48b..69bcf87 100644
--- a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java
+++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/adapt/restclient/TestFile2Rest.java
@@ -156,8 +156,8 @@
         Response response = null;
 
         // Wait for the required amount of events to be received or for 10 seconds
-        for (int i = 0; i < 100; i++) {
-            ThreadUtilities.sleep(100);
+        for (int i = 0; i < 20; i++) {
+            ThreadUtilities.sleep(300);
             response = client.target("http://localhost:32801/TestFile2Rest/apex/event/Stats")
                             .request("application/json").get();
 
@@ -169,7 +169,7 @@
 
             @SuppressWarnings("unchecked")
             final Map<String, Object> jsonMap = new Gson().fromJson(responseString, Map.class);
-            if ((double) jsonMap.get("PUT") == 100) {
+            if ((double) jsonMap.get("PUT") == 20) {
                 break;
             }
         }
diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/engine/ApexServiceModelUpdateTest.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/engine/ApexServiceModelUpdateTest.java
new file mode 100644
index 0000000..ff6a3a2
--- /dev/null
+++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/engine/ApexServiceModelUpdateTest.java
@@ -0,0 +1,422 @@
+/*-
+ * ============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.testsuites.integration.uservice.engine;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.apex.context.parameters.ContextParameterConstants;
+import org.onap.policy.apex.context.parameters.ContextParameters;
+import org.onap.policy.apex.context.parameters.DistributorParameters;
+import org.onap.policy.apex.context.parameters.LockManagerParameters;
+import org.onap.policy.apex.context.parameters.PersistorParameters;
+import org.onap.policy.apex.context.parameters.SchemaParameters;
+import org.onap.policy.apex.core.engine.EngineParameterConstants;
+import org.onap.policy.apex.core.engine.EngineParameters;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters;
+import org.onap.policy.apex.plugins.executor.mvel.MvelExecutorParameters;
+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.runtime.ApexEventListener;
+import org.onap.policy.apex.service.engine.runtime.EngineService;
+import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface;
+import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl;
+import org.onap.policy.apex.service.parameters.ApexParameterConstants;
+import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
+import org.onap.policy.apex.testsuites.integration.common.model.SampleDomainModelFactory;
+import org.onap.policy.common.parameters.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ApexServiceTest.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexServiceModelUpdateTest {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexServiceModelUpdateTest.class);
+
+    private final AxArtifactKey engineServiceKey = new AxArtifactKey("Machine-1_process-1_engine-1", "0.0.0");
+    private final EngineServiceParameters parameters = new EngineServiceParameters();
+    private EngineService service = null;
+    private TestListener listener = null;
+    private int actionEventsReceived = 0;
+
+    private AxPolicyModel apexSamplePolicyModel = null;
+    private String apexSampleModelString;
+
+    /**
+     * Set up parameters.
+     */
+    @Before
+    public void setupParameters() {
+        ParameterService.register(new SchemaParameters());
+        ParameterService.register(new ContextParameters());
+        ParameterService.register(new DistributorParameters());
+        ParameterService.register(new LockManagerParameters());
+        ParameterService.register(new PersistorParameters());
+        ParameterService.register(new EngineServiceParameters());
+
+        EngineParameters engineParameters = new EngineParameters();
+        engineParameters.getExecutorParameterMap().put("JAVASCRIPT", new JavascriptExecutorParameters());
+        ParameterService.register(engineParameters);
+    }
+
+    /**
+     * Clear down parameters.
+     */
+    @After
+    public void teardownParameters() {
+        ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME);
+        ParameterService.deregister(ApexParameterConstants.ENGINE_SERVICE_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
+    }
+
+    /**
+     * Sets up the test by creating an engine and reading in the test policy.
+     *
+     * @throws ApexException if something goes wrong
+     * @throws IOException on IO exceptions
+     */
+    @Before
+    public void setUp() throws ApexException, IOException {
+        // create engine with 3 threads
+        parameters.setInstanceCount(3);
+        parameters.setName(engineServiceKey.getName());
+        parameters.setVersion(engineServiceKey.getVersion());
+        parameters.setId(100);
+        parameters.getEngineParameters().getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
+        service = EngineServiceImpl.create(parameters);
+
+        LOGGER.debug("Running TestApexEngine. . .");
+
+        apexSamplePolicyModel = new SampleDomainModelFactory().getSamplePolicyModel("JAVASCRIPT");
+        assertNotNull(apexSamplePolicyModel);
+
+        apexSampleModelString = getModelString(apexSamplePolicyModel);
+
+        // create engine
+        listener = new TestListener();
+        service.registerActionListener("MyListener", listener);
+    }
+
+    /**
+     * Tear down the the test infrastructure.
+     *
+     * @throws ApexException if there is an error
+     */
+    @After
+    public void tearDown() throws Exception {
+        if (service != null) {
+            service.stop();
+        }
+        service = null;
+    }
+
+    /**
+     * Test start with no model.
+     */
+    @Test
+    public void testNoModelStart() {
+        try {
+            service.startAll();
+            fail("Engine should not start with no model");
+        } catch (final Exception e) {
+            e.printStackTrace();
+            assertEquals("start()<-Machine-1_process-1_engine-1-0:0.0.0,STOPPED,  cannot start engine, "
+                            + "engine has not been initialized, its model is not loaded", e.getMessage());
+        }
+    }
+
+    /**
+     * Test model update with string model without force.
+     *
+     * @throws ApexException if there is an error
+     */
+    @Test
+    public void testModelUpdateStringNewNoForce() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexSampleModelString, false);
+
+        assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
+    }
+
+    /**
+     * Test model update with string model with force.
+     *
+     * @throws ApexException if there is an error
+     */
+    @Test
+    public void testModelUpdateStringNewForce() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexSampleModelString, true);
+
+        assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
+    }
+
+    /**
+     * Test model update with a new string model without force.
+     *
+     * @throws ApexException if there is an error
+     */
+    @Test
+    public void testModelUpdateStringNewNewNoForce() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexSampleModelString, false);
+
+        assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
+
+        sendEvents();
+
+        service.updateModel(parameters.getEngineKey(), apexSampleModelString, false);
+        assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
+
+        sendEvents();
+    }
+
+    /**
+     * Test incompatible model update with a model object without force.
+     *
+     * @throws ApexException if there is an error
+     */
+    @Test
+    public void testModelUpdateIncoNoForce() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexSamplePolicyModel, false);
+
+        assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
+
+        // Different model name, incompatible
+        final AxPolicyModel incoPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
+        incoPolicyModel0.getKey().setName("INCOMPATIBLE");
+
+        try {
+            service.updateModel(parameters.getEngineKey(), incoPolicyModel0, false);
+            fail("model update should fail on incompatible model without force being true");
+        } catch (final Exception e) {
+            System.err.println(e.getMessage());
+            assertEquals("apex model update failed, supplied model with key \"INCOMPATIBLE:0.0.1\" is not a compatible "
+                            + "model update from the existing engine model "
+                            + "with key \"SamplePolicyModelJAVASCRIPT:0.0.1\"", e.getMessage());
+        }
+
+        // Still on old model
+        sendEvents();
+
+        // Different major version, incompatible
+        final AxPolicyModel incoPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
+        incoPolicyModel1.getKey().setVersion("1.0.1");
+
+        try {
+            service.updateModel(parameters.getEngineKey(), incoPolicyModel1, false);
+            fail("model update should fail on incompatible model without force being true");
+        } catch (final Exception e) {
+            System.err.println(e.getMessage());
+            e.printStackTrace();
+            assertEquals("apex model update failed, supplied model with key \"SamplePolicyModelJAVASCRIPT:1.0.1\" "
+                            + "is not a compatible model update from the existing engine model with key "
+                            + "\"SamplePolicyModelJAVASCRIPT:0.0.1\"", e.getMessage());
+        }
+
+        // Still on old model
+        sendEvents();
+
+        // Different minor version, compatible
+        final AxPolicyModel coPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
+        coPolicyModel0.getKey().setVersion("0.1.0");
+        service.updateModel(parameters.getEngineKey(), coPolicyModel0, false);
+
+        // On new compatible model
+        sendEvents();
+
+        // Different patch version, compatible
+        final AxPolicyModel coPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
+        coPolicyModel1.getKey().setVersion("0.0.2");
+        service.updateModel(parameters.getEngineKey(), coPolicyModel1, false);
+
+        // On new compatible model
+        sendEvents();
+
+    }
+
+    /**
+     * Test incompatible model update with a model object with force.
+     *
+     * @throws ApexException if there is an error
+     */
+    @Test
+    public void testModelUpdateIncoForce() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexSamplePolicyModel, false);
+
+        assertEquals(apexSamplePolicyModel.getKey(), ModelService.getModel(AxPolicyModel.class).getKey());
+
+        // Different model name, incompatible
+        final AxPolicyModel incoPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
+        incoPolicyModel0.getKey().setName("INCOMPATIBLE");
+        service.updateModel(parameters.getEngineKey(), incoPolicyModel0, true);
+
+        // On updated model
+        sendEvents();
+
+        // Different major version, incompatible
+        final AxPolicyModel incoPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
+        incoPolicyModel1.getKey().setVersion("1.0.1");
+        service.updateModel(parameters.getEngineKey(), incoPolicyModel1, true);
+
+        // On updated model
+        sendEvents();
+
+        // Different minor version, compatible
+        final AxPolicyModel coPolicyModel0 = new AxPolicyModel(apexSamplePolicyModel);
+        coPolicyModel0.getKey().setVersion("0.1.0");
+        service.updateModel(parameters.getEngineKey(), coPolicyModel0, true);
+
+        // On new compatible model
+        sendEvents();
+
+        // Different patch version, compatible
+        final AxPolicyModel coPolicyModel1 = new AxPolicyModel(apexSamplePolicyModel);
+        coPolicyModel1.getKey().setVersion("0.0.2");
+        service.updateModel(parameters.getEngineKey(), coPolicyModel1, true);
+
+        // On new compatible model
+        sendEvents();
+
+    }
+
+    /**
+     * Utility method to send some events into the test engine.
+     * 
+     * @throws ApexEventException if there is an error
+     */
+    private void sendEvents() throws ApexEventException {
+        final EngineServiceEventInterface engineServiceEventInterface = service.getEngineServiceEventInterface();
+
+        // Send some events
+        final Date testStartTime = new Date();
+        final Map<String, Object> eventDataMap = new HashMap<String, Object>();
+        eventDataMap.put("TestSlogan", "This is a test slogan");
+        eventDataMap.put("TestMatchCase", (byte) 123);
+        eventDataMap.put("TestTimestamp", testStartTime.getTime());
+        eventDataMap.put("TestTemperature", 34.5445667);
+
+        final ApexEvent event = new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events",
+                        "test", "apex");
+        event.putAll(eventDataMap);
+        engineServiceEventInterface.sendEvent(event);
+
+        final ApexEvent event2 = new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events",
+                        "test", "apex");
+        event2.putAll(eventDataMap);
+        engineServiceEventInterface.sendEvent(event2);
+
+        // Wait for results
+        while (actionEventsReceived < 2) {
+            ThreadUtilities.sleep(100);
+        }
+        ThreadUtilities.sleep(500);
+    }
+
+    /**
+     * The listener interface for receiving test events. The class that is interested in processing a test event
+     * implements this interface, and the object created with that class is registered with a component using the
+     * component's <code>addTestListener</code> method. When the test event occurs, that object's appropriate method is
+     * invoked.
+     *
+     * @see TestEvent
+     */
+    private final class TestListener implements ApexEventListener {
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see org.onap.policy.apex.service.engine.runtime.ApexEventListener#onApexEvent(org.onap.policy
+         * .apex.service.engine.event.ApexEvent)
+         */
+        @Override
+        public synchronized void onApexEvent(final ApexEvent event) {
+            LOGGER.debug("result 1 is:" + event);
+            checkResult(event);
+            actionEventsReceived++;
+
+            final Date testStartTime = new Date((Long) event.get("TestTimestamp"));
+            final Date testEndTime = new Date();
+
+            LOGGER.info("policy execution time: " + (testEndTime.getTime() - testStartTime.getTime()) + "ms");
+        }
+
+        /**
+         * Check result.
+         *
+         * @param result the result
+         */
+        private void checkResult(final ApexEvent result) {
+            assertTrue(result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104"));
+
+            assertTrue(result.get("TestSlogan").equals("This is a test slogan"));
+            assertTrue(result.get("TestMatchCase").equals(new Byte((byte) 123)));
+            assertTrue(result.get("TestTemperature").equals(34.5445667));
+            assertTrue(((byte) result.get("TestMatchCaseSelected")) >= 0
+                            && ((byte) result.get("TestMatchCaseSelected") <= 3));
+            assertTrue(((byte) result.get("TestEstablishCaseSelected")) >= 0
+                            && ((byte) result.get("TestEstablishCaseSelected") <= 3));
+            assertTrue(((byte) result.get("TestDecideCaseSelected")) >= 0
+                            && ((byte) result.get("TestDecideCaseSelected") <= 3));
+            assertTrue(((byte) result.get("TestActCaseSelected")) >= 0
+                            && ((byte) result.get("TestActCaseSelected") <= 3));
+        }
+    }
+    
+
+    /**
+     * Gets the model string.
+     *
+     * @param policyModel the eca policy model
+     * @return the model string
+     * @throws ApexModelException the apex model exception
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private String getModelString(final AxPolicyModel policyModel) throws ApexModelException, IOException {
+        try (final ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream()) {
+            new ApexModelWriter<AxPolicyModel>(AxPolicyModel.class).write(policyModel, baOutputStream);
+            return baOutputStream.toString();
+        }
+    }
+}
diff --git a/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/engine/ApexServiceTest.java b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/engine/ApexServiceTest.java
new file mode 100644
index 0000000..f8e9f2c
--- /dev/null
+++ b/testsuites/integration/integration-uservice-test/src/test/java/org/onap/policy/apex/testsuites/integration/uservice/engine/ApexServiceTest.java
@@ -0,0 +1,535 @@
+/*-
+ * ============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.testsuites.integration.uservice.engine;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.apex.context.parameters.ContextParameterConstants;
+import org.onap.policy.apex.context.parameters.ContextParameters;
+import org.onap.policy.apex.context.parameters.DistributorParameters;
+import org.onap.policy.apex.context.parameters.LockManagerParameters;
+import org.onap.policy.apex.context.parameters.PersistorParameters;
+import org.onap.policy.apex.context.parameters.SchemaParameters;
+import org.onap.policy.apex.core.engine.EngineParameterConstants;
+import org.onap.policy.apex.core.engine.EngineParameters;
+import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter;
+import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel;
+import org.onap.policy.apex.plugins.executor.javascript.JavascriptExecutorParameters;
+import org.onap.policy.apex.plugins.executor.mvel.MvelExecutorParameters;
+import org.onap.policy.apex.service.engine.event.ApexEvent;
+import org.onap.policy.apex.service.engine.runtime.ApexEventListener;
+import org.onap.policy.apex.service.engine.runtime.EngineService;
+import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface;
+import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl;
+import org.onap.policy.apex.service.parameters.ApexParameterConstants;
+import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters;
+import org.onap.policy.apex.testsuites.integration.common.model.SampleDomainModelFactory;
+import org.onap.policy.common.parameters.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ApexServiceTest.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ApexServiceTest {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexServiceTest.class);
+
+    private static final long MAX_STOP_WAIT = 5000; // 5 sec
+    private static final long MAX_START_WAIT = 5000; // 5 sec
+    private static final long MAX_RECV_WAIT = 5000; // 5 sec
+
+    private static final AxArtifactKey engineServiceKey = new AxArtifactKey("Machine-1_process-1_engine-1", "0.0.0");
+    private static final EngineServiceParameters parameters = new EngineServiceParameters();
+    private static EngineService service = null;
+    private static TestListener listener = null;
+    private static AxPolicyModel apexPolicyModel = null;
+    private static int actionEventsReceived = 0;
+
+    private static String apexModelString;
+
+    private boolean waitFlag = true;
+
+    /**
+     * Sets the up.
+     *
+     * @throws Exception the exception
+     */
+    @BeforeClass
+    public static void setUp() throws Exception {
+        // create engine with 3 threads
+        parameters.setInstanceCount(3);
+        parameters.setName(engineServiceKey.getName());
+        parameters.setVersion(engineServiceKey.getVersion());
+        parameters.setId(100);
+        parameters.getEngineParameters().getExecutorParameterMap().put("MVEL", new MvelExecutorParameters());
+        service = EngineServiceImpl.create(parameters);
+
+
+        LOGGER.debug("Running TestApexEngine. . .");
+
+        apexPolicyModel = new SampleDomainModelFactory().getSamplePolicyModel("JAVASCRIPT");
+        assertNotNull(apexPolicyModel);
+
+        apexModelString = getModelString(apexPolicyModel);
+
+        // create engine
+        listener = new TestListener();
+        service.registerActionListener("Listener", listener);
+    }
+
+    /**
+     * Set up parameters.
+     */
+    @Before
+    public void setupParameters() {
+        ParameterService.register(new SchemaParameters());
+        ParameterService.register(new ContextParameters());
+        ParameterService.register(new DistributorParameters());
+        ParameterService.register(new LockManagerParameters());
+        ParameterService.register(new PersistorParameters());
+        ParameterService.register(new EngineServiceParameters());
+        
+        EngineParameters engineParameters = new EngineParameters();
+        engineParameters.getExecutorParameterMap().put("JAVASCRIPT", new JavascriptExecutorParameters());
+        ParameterService.register(engineParameters);
+    }
+    
+    /**
+     * Clear down parameters.
+     */
+    @After
+    public void teardownParameters() {
+        ParameterService.deregister(EngineParameterConstants.MAIN_GROUP_NAME);
+        ParameterService.deregister(ApexParameterConstants.ENGINE_SERVICE_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.PERSISTENCE_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.LOCKING_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.DISTRIBUTOR_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.MAIN_GROUP_NAME);
+        ParameterService.deregister(ContextParameterConstants.SCHEMA_GROUP_NAME);
+    }
+    
+    /**
+     * Update the engine then test the engine with 2 sample events.
+     *
+     * @throws ApexException if there is a problem
+     */
+    @Test
+    public void testExecutionSet1() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexModelString, true);
+
+        final long starttime = System.currentTimeMillis();
+        for (final AxArtifactKey engineKey : service.getEngineKeys()) {
+            LOGGER.info("{}", service.getStatus(engineKey));
+        }
+        while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStarted()) {
+            fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
+        }
+
+        final EngineServiceEventInterface engineServiceEventInterface = service.getEngineServiceEventInterface();
+
+        // Send some events
+        final Date testStartTime = new Date();
+        final Map<String, Object> eventDataMap = new HashMap<String, Object>();
+        eventDataMap.put("TestSlogan", "This is a test slogan");
+        eventDataMap.put("TestMatchCase", (byte) 123);
+        eventDataMap.put("TestTimestamp", testStartTime.getTime());
+        eventDataMap.put("TestTemperature", 34.5445667);
+
+        final ApexEvent event =
+                new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event.setExecutionId(System.nanoTime());
+        event.putAll(eventDataMap);
+        engineServiceEventInterface.sendEvent(event);
+
+        final ApexEvent event2 =
+                new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event2.setExecutionId(System.nanoTime());
+        event2.putAll(eventDataMap);
+        engineServiceEventInterface.sendEvent(event2);
+
+        // Wait for results
+        final long recvtime = System.currentTimeMillis();
+        while (actionEventsReceived < 2 && System.currentTimeMillis() - recvtime < MAX_RECV_WAIT) {
+            ThreadUtilities.sleep(100);
+        }
+        ThreadUtilities.sleep(500);
+        assertEquals(2, actionEventsReceived);
+        actionEventsReceived = 0;
+
+
+        // Stop all engines on this engine service
+        final long stoptime = System.currentTimeMillis();
+        service.stop();
+        while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStopped()) {
+            fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
+        }
+    }
+
+    /**
+     * Update the engine then test the engine with 2 sample events.
+     *
+     * @throws ApexException if there is a problem
+     */
+    @Test
+    public void testExecutionSet1Sync() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexModelString, true);
+
+        final long starttime = System.currentTimeMillis();
+        for (final AxArtifactKey engineKey : service.getEngineKeys()) {
+            LOGGER.info("{}", service.getStatus(engineKey));
+        }
+        while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStarted()) {
+            fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
+        }
+
+        // Send some events
+        final Date testStartTime = new Date();
+        final Map<String, Object> eventDataMap = new HashMap<String, Object>();
+        eventDataMap.put("TestSlogan", "This is a test slogan");
+        eventDataMap.put("TestMatchCase", (byte) 123);
+        eventDataMap.put("TestTimestamp", testStartTime.getTime());
+        eventDataMap.put("TestTemperature", 34.5445667);
+
+        final ApexEvent event1 =
+                new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event1.putAll(eventDataMap);
+        event1.setExecutionId(System.nanoTime());
+
+        final ApexEventListener myEventListener1 = new ApexEventListener() {
+            @Override
+            public void onApexEvent(final ApexEvent responseEvent) {
+                assertNotNull("Synchronous sendEventWait failed", responseEvent);
+                assertEquals(event1.getExecutionId(), responseEvent.getExecutionId());
+                waitFlag = false;
+            }
+        };
+
+        waitFlag = true;
+        service.registerActionListener("Listener1", myEventListener1);
+        service.getEngineServiceEventInterface().sendEvent(event1);
+
+        while (waitFlag) {
+            ThreadUtilities.sleep(100);
+        }
+
+        final ApexEvent event2 =
+                new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event2.setExecutionId(System.nanoTime());
+        event2.putAll(eventDataMap);
+
+        final ApexEventListener myEventListener2 = new ApexEventListener() {
+            @Override
+            public void onApexEvent(final ApexEvent responseEvent) {
+                assertNotNull("Synchronous sendEventWait failed", responseEvent);
+                assertEquals(event2.getExecutionId(), responseEvent.getExecutionId());
+                assertEquals(2, actionEventsReceived);
+                waitFlag = false;
+            }
+        };
+
+        waitFlag = true;
+        service.deregisterActionListener("Listener1");
+        service.registerActionListener("Listener2", myEventListener2);
+        service.getEngineServiceEventInterface().sendEvent(event2);
+
+        while (waitFlag) {
+            ThreadUtilities.sleep(100);
+        }
+        service.deregisterActionListener("Listener2");
+
+        actionEventsReceived = 0;
+
+        // Stop all engines on this engine service
+        final long stoptime = System.currentTimeMillis();
+        service.stop();
+        while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStopped()) {
+            fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
+        }
+    }
+
+    /**
+     * Update the engine then test the engine with 2 sample events - again.
+     *
+     * @throws ApexException if there is a problem
+     */
+    @Test
+    public void testExecutionSet2() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexModelString, true);
+
+        final long starttime = System.currentTimeMillis();
+        for (final AxArtifactKey engineKey : service.getEngineKeys()) {
+            LOGGER.info("{}", service.getStatus(engineKey));
+        }
+        while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStarted()) {
+            fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
+        }
+
+        final EngineServiceEventInterface engineServiceEventInterface = service.getEngineServiceEventInterface();
+
+        // Send some events
+        final Date testStartTime = new Date();
+        final Map<String, Object> eventDataMap = new HashMap<String, Object>();
+        eventDataMap.put("TestSlogan", "This is a test slogan");
+        eventDataMap.put("TestMatchCase", (byte) 123);
+        eventDataMap.put("TestTimestamp", testStartTime.getTime());
+        eventDataMap.put("TestTemperature", 34.5445667);
+
+        final ApexEvent event =
+                new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event.setExecutionId(System.nanoTime());
+        event.putAll(eventDataMap);
+        engineServiceEventInterface.sendEvent(event);
+
+        final ApexEvent event2 =
+                new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event2.setExecutionId(System.nanoTime());
+        event2.putAll(eventDataMap);
+        engineServiceEventInterface.sendEvent(event2);
+
+        // Wait for results
+        final long recvtime = System.currentTimeMillis();
+        while (actionEventsReceived < 2 && System.currentTimeMillis() - recvtime < MAX_RECV_WAIT) {
+            ThreadUtilities.sleep(100);
+        }
+        ThreadUtilities.sleep(500);
+        assertEquals(2, actionEventsReceived);
+        actionEventsReceived = 0;
+
+        // Stop all engines on this engine service
+        final long stoptime = System.currentTimeMillis();
+        service.stop();
+        while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStopped()) {
+            fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
+        }
+    }
+
+    /**
+     * Update the engine then test the engine with 2 sample events - again.
+     *
+     * @throws ApexException if there is a problem
+     */
+    @Test
+    public void testExecutionSet2Sync() throws ApexException {
+        service.updateModel(parameters.getEngineKey(), apexModelString, true);
+
+        final long starttime = System.currentTimeMillis();
+        for (final AxArtifactKey engineKey : service.getEngineKeys()) {
+            LOGGER.info("{}", service.getStatus(engineKey));
+        }
+        while (!service.isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStarted()) {
+            fail("Apex Service " + service.getKey() + " failed to start after " + MAX_START_WAIT + " ms");
+        }
+
+        // Send some events
+        final Date testStartTime = new Date();
+        final Map<String, Object> eventDataMap = new HashMap<String, Object>();
+        eventDataMap.put("TestSlogan", "This is a test slogan");
+        eventDataMap.put("TestMatchCase", (byte) 123);
+        eventDataMap.put("TestTimestamp", testStartTime.getTime());
+        eventDataMap.put("TestTemperature", 34.5445667);
+
+        final ApexEvent event1 =
+                new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event1.putAll(eventDataMap);
+
+        final ApexEventListener myEventListener1 = new ApexEventListener() {
+            @Override
+            public void onApexEvent(final ApexEvent responseEvent) {
+                assertNotNull("Synchronous sendEventWait failed", responseEvent);
+                assertEquals(event1.getExecutionId(), responseEvent.getExecutionId());
+                waitFlag = false;
+            }
+        };
+
+        waitFlag = true;
+        service.registerActionListener("Listener1", myEventListener1);
+        service.getEngineServiceEventInterface().sendEvent(event1);
+
+        while (waitFlag) {
+            ThreadUtilities.sleep(100);
+        }
+
+        final ApexEvent event2 =
+                new ApexEvent("Event0100", "0.0.1", "org.onap.policy.apex.domains.sample.events", "test", "apex");
+        event2.putAll(eventDataMap);
+
+        final ApexEventListener myEventListener2 = new ApexEventListener() {
+            @Override
+            public void onApexEvent(final ApexEvent responseEvent) {
+                assertNotNull("Synchronous sendEventWait failed", responseEvent);
+                assertEquals(event2.getExecutionId(), responseEvent.getExecutionId());
+                waitFlag = false;
+            }
+        };
+
+        waitFlag = true;
+        service.registerActionListener("Listener2", myEventListener2);
+        service.deregisterActionListener("Listener1");
+        service.getEngineServiceEventInterface().sendEvent(event2);
+
+        while (waitFlag) {
+            ThreadUtilities.sleep(100);
+        }
+
+        service.deregisterActionListener("Listener2");
+
+        assertEquals(2, actionEventsReceived);
+
+        actionEventsReceived = 0;
+
+        // Stop all engines on this engine service
+        final long stoptime = System.currentTimeMillis();
+        service.stop();
+        while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStopped()) {
+            fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
+        }
+    }
+
+    /**
+     * Tear down the the test infrastructure.
+     *
+     * @throws ApexException if there is an error
+     */
+    @AfterClass
+    public static void tearDown() throws Exception {
+        // Stop all engines on this engine service
+        final long stoptime = System.currentTimeMillis();
+        service.stop();
+        while (!service.isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT) {
+            ThreadUtilities.sleep(200);
+        }
+        if (!service.isStopped()) {
+            fail("Apex Service " + service.getKey() + " failed to stop after " + MAX_STOP_WAIT + " ms");
+        }
+        service = null;
+    }
+
+    /**
+     * The listener interface for receiving test events. The class that is interested in processing
+     * a test event implements this interface, and the object created with that class is registered
+     * with a component using the component's <code>addTestListener</code> method. When the test
+     * event occurs, that object's appropriate method is invoked.
+     *
+     * @see TestEvent
+     */
+    private static final class TestListener implements ApexEventListener {
+
+        /*
+         * (non-Javadoc)
+         *
+         * @see
+         * org.onap.policy.apex.service.engine.runtime.ApexEventListener#onApexEvent(org.onap.policy
+         * .apex.service.engine.event.ApexEvent)
+         */
+        @Override
+        public synchronized void onApexEvent(final ApexEvent event) {
+            LOGGER.debug("result 1 is:" + event);
+            checkResult(event);
+            actionEventsReceived++;
+
+            final Date testStartTime = new Date((Long) event.get("TestTimestamp"));
+            final Date testEndTime = new Date();
+
+            LOGGER.info("policy execution time: " + (testEndTime.getTime() - testStartTime.getTime()) + "ms");
+        }
+
+        /**
+         * Check result.
+         *
+         * @param result the result
+         */
+        private void checkResult(final ApexEvent result) {
+            assertTrue(result.getName().startsWith("Event0004") || result.getName().startsWith("Event0104"));
+
+            assertTrue(result.get("TestSlogan").equals("This is a test slogan"));
+            assertTrue(result.get("TestMatchCase").equals(new Byte((byte) 123)));
+            assertTrue(result.get("TestTemperature").equals(34.5445667));
+            assertTrue(((byte) result.get("TestMatchCaseSelected")) >= 0
+                    && ((byte) result.get("TestMatchCaseSelected") <= 3));
+            assertTrue(((byte) result.get("TestEstablishCaseSelected")) >= 0
+                    && ((byte) result.get("TestEstablishCaseSelected") <= 3));
+            assertTrue(((byte) result.get("TestDecideCaseSelected")) >= 0
+                    && ((byte) result.get("TestDecideCaseSelected") <= 3));
+            assertTrue(
+                    ((byte) result.get("TestActCaseSelected")) >= 0 && ((byte) result.get("TestActCaseSelected") <= 3));
+        }
+    }
+
+    /**
+     * Gets the model string.
+     *
+     * @param policyModel the eca policy model
+     * @return the model string
+     * @throws ApexModelException the apex model exception
+     * @throws IOException Signals that an I/O exception has occurred.
+     */
+    private static String getModelString(final AxPolicyModel policyModel) throws ApexModelException, IOException {
+        try (final ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream()) {
+            new ApexModelWriter<AxPolicyModel>(AxPolicyModel.class).write(policyModel, baOutputStream);
+            return baOutputStream.toString();
+        }
+    }
+}
