Refactoring existing integration tests

Change-Id: I1aedd94d5197b8c6513fc701e9df2aab4edec088
Issue-ID: POLICY-865
Signed-off-by: waqas.ikram <waqas.ikram@ericsson.com>
diff --git a/testsuites/integration/integration-context-metrics/pom.xml b/testsuites/integration/integration-context-metrics/pom.xml
new file mode 100644
index 0000000..47a1083
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/pom.xml
@@ -0,0 +1,71 @@
+<!--
+  ============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.testsuites.integration</groupId>
+        <artifactId>integration</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>integration-context-metrics</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] module to calculate metrics using various plugins</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.core</groupId>
+            <artifactId>core-infrastructure</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.context</groupId>
+            <artifactId>context-test-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-distribution</groupId>
+            <artifactId>context-distribution-hazelcast</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-distribution</groupId>
+            <artifactId>context-distribution-infinispan</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-locking</groupId>
+            <artifactId>context-locking-curator</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-locking</groupId>
+            <artifactId>context-locking-hazelcast</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <version>3.2.0</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetrics.java b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetrics.java
new file mode 100644
index 0000000..cbe06ed
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetrics.java
@@ -0,0 +1,525 @@
+/*-
+ * ============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.context.metrics;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.onap.policy.apex.context.ContextAlbum;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.impl.distribution.DistributorFactory;
+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.test.concepts.TestContextLongItem;
+import org.onap.policy.apex.context.test.factory.TestContextAlbumFactory;
+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.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters;
+import org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManagerParameters;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class concurrentContextMetrics tests concurrent use of context.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ConcurrentContextMetrics {
+    private static final int NUM_ARGS = 8;
+    private static final int ARG_LABEL = 0;
+    private static final int ARG_JVM_COUNT = 1;
+    private static final int ARG_THREAD_COUNT = 2;
+    private static final int ARG_ITERATIONS = 3;
+    private static final int ARG_ARRAY_SIZE = 4;
+    private static final int ARG_LOCK_TYPE = 5;
+    private static final int ARG_ZOOKEEPER_ADDRESS = 6;
+    private static final int ARG_INTERACTIVE = 7;
+
+    private static final int TIME_10_MS = 10;
+
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextMetrics.class);
+
+    // Test parameters
+    private String testLabel = null;
+    private int jvmCount = -1;
+    private int threadCount = -1;
+    private int threadLoops = -1;
+    private int longArraySize = -1;
+    private int lockType = -1;
+    private String zookeeperAddress = null;
+    private long total = -1;
+    private boolean interactive = false;
+
+    // The context distributor and map used by each test
+    private Distributor contextDistributor = null;
+    private ContextAlbum lTypeAlbum = null;
+
+    private final DateFormat dateFormat = new SimpleDateFormat("yyyy,MM,dd,HH,mm,ss,S");
+
+    /**
+     * The main method.
+     *
+     * @param args the args
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    public static void main(final String[] args) throws ApexModelException, IOException, ApexException {
+        if (args.length != NUM_ARGS) {
+            System.err.println(
+                    "usage: ConcurrentContextMetrics testLabel jvmCount threadCount threadLoops longArraySize lockType zookeeperAddress interactive");
+            return;
+        }
+        // @formatter:off
+        final ConcurrentContextMetrics concurrentContextMetrics = new ConcurrentContextMetrics(
+                args[ARG_LABEL],
+                Integer.valueOf(args[ARG_JVM_COUNT]),
+                Integer.valueOf(args[ARG_THREAD_COUNT]),
+                Integer.valueOf(args[ARG_ITERATIONS]),
+                Integer.valueOf(args[ARG_ARRAY_SIZE]),
+                Integer.valueOf(args[ARG_LOCK_TYPE]),
+                args[ARG_ZOOKEEPER_ADDRESS],
+                Boolean.valueOf(args[ARG_INTERACTIVE]));
+        // @formatter:on
+
+        concurrentContextMetrics.concurrentContextMetricsJVMLocal();
+        concurrentContextMetrics.concurrentContextMetricsCurator();
+        concurrentContextMetrics.concurrentContextMetricsHazelcast();
+        concurrentContextMetrics.concurrentContextMetricsHazelcastMultiJVMHazelcastLock();
+        concurrentContextMetrics.concurrentContextMetricsInfinispanMultiJVMHazelcastlock();
+        concurrentContextMetrics.concurrentContextMetricsInfinispanMultiJVMCuratorLock();
+        concurrentContextMetrics.concurrentContextMetricsHazelcastMultiJVMCuratorLock();
+    }
+
+    /**
+     * The Constructor.
+     *
+     * @param testLabel the test label
+     * @param jvmCount the jvm count
+     * @param threadCount the thread count
+     * @param threadLoops the thread loops
+     * @param longArraySize the long array size
+     * @param lockType the lock type
+     * @param zookeeperAddress the zookeeper address
+     * @param interactive the interactive
+     */
+    // CHECKSTYLE:OFF: checkstyle:parameterNumber
+    public ConcurrentContextMetrics(final String testLabel, final int jvmCount, final int threadCount,
+            final int threadLoops, final int longArraySize, final int lockType, final String zookeeperAddress,
+            final boolean interactive) {
+        // CHECKSTYLE:ON: checkstyle:parameterNumber
+        super();
+        this.testLabel = testLabel;
+        this.jvmCount = jvmCount;
+        this.threadCount = threadCount;
+        this.threadLoops = threadLoops;
+        this.longArraySize = longArraySize;
+        this.lockType = lockType;
+        this.zookeeperAddress = zookeeperAddress;
+        this.interactive = interactive;
+    }
+
+    /**
+     * Concurrent context metrics JVM local.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsJVMLocal() throws ApexModelException, IOException, ApexException {
+        if (jvmCount != 1) {
+            return;
+        }
+
+        LOGGER.debug("Running concurrentContextMetricsJVMLocalVarSet metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters()
+                .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS);
+        contextParameters.getLockManagerParameters()
+                .setPluginClass(LockManagerParameters.DEFAULT_LOCK_MANAGER_PLUGIN_CLASS);
+        runConcurrentContextMetrics("JVMLocal");
+
+        LOGGER.debug("Ran concurrentContextMetricsJVMLocalVarSet metrics");
+    }
+
+    /**
+     * Concurrent context metrics hazelcast.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsHazelcast() throws ApexModelException, IOException, ApexException {
+        if (jvmCount != 1) {
+            return;
+        }
+
+        LOGGER.debug("Running concurrentContextMetricsHazelcast metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters()
+                .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS);
+        contextParameters.getLockManagerParameters()
+                .setPluginClass("org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager");
+        runConcurrentContextMetrics("Hazelcast");
+
+        LOGGER.debug("Ran concurrentContextMetricsHazelcast metrics");
+    }
+
+    /**
+     * Concurrent context metrics curator.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsCurator() throws ApexModelException, IOException, ApexException {
+        if (jvmCount != 1) {
+            return;
+        }
+
+        LOGGER.debug("Running concurrentContextMetricsCurator metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters()
+                .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS);
+
+        final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters();
+        curatorParameters.setPluginClass("org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager");
+        contextParameters.setLockManagerParameters(curatorParameters);
+        curatorParameters.setZookeeperAddress(zookeeperAddress);
+
+        runConcurrentContextMetrics("Curator");
+
+        LOGGER.debug("Ran concurrentContextMetricsCurator metrics");
+    }
+
+    /**
+     * Concurrent context metrics hazelcast multi JVM hazelcast lock.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsHazelcastMultiJVMHazelcastLock()
+            throws ApexModelException, IOException, ApexException {
+        LOGGER.debug("Running concurrentContextMetricsHazelcastMultiJVMHazelcastLock metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters().setPluginClass(
+                "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor");
+        contextParameters.getLockManagerParameters()
+                .setPluginClass("org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager");
+        runConcurrentContextMetrics("HazelcastMultiJVMHazelcastLock");
+
+        LOGGER.debug("Ran concurrentContextMetricsHazelcastMultiJVMHazelcastLock metrics");
+    }
+
+    /**
+     * Concurrent context metrics infinispan multi JVM hazelcastlock.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsInfinispanMultiJVMHazelcastlock()
+            throws ApexModelException, IOException, ApexException {
+        LOGGER.debug("Running concurrentContextMetricsInfinispanMultiJVMHazelcastlock metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters().setPluginClass(
+                "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor");
+        contextParameters.getLockManagerParameters()
+                .setPluginClass("org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager");
+
+        final InfinispanDistributorParameters infinispanParameters = new InfinispanDistributorParameters();
+        contextParameters.setDistributorParameters(infinispanParameters);
+
+        runConcurrentContextMetrics("InfinispanMultiJVMHazelcastlock");
+
+        LOGGER.debug("Ran concurrentContextMetricsInfinispanMultiJVMHazelcastlock metrics");
+    }
+
+    /**
+     * Concurrent context metrics infinispan multi JVM curator lock.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsInfinispanMultiJVMCuratorLock()
+            throws ApexModelException, IOException, ApexException {
+        LOGGER.debug("Running concurrentContextMetricsInfinispanMultiJVMCuratorLock metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters().setPluginClass(
+                "org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor");
+
+        final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters();
+        curatorParameters.setPluginClass("org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager");
+        contextParameters.setLockManagerParameters(curatorParameters);
+        curatorParameters.setZookeeperAddress(zookeeperAddress);
+
+        final InfinispanDistributorParameters infinispanParameters = new InfinispanDistributorParameters();
+        contextParameters.setDistributorParameters(infinispanParameters);
+
+        runConcurrentContextMetrics("InfinispanMultiJVMCuratorLock");
+
+        LOGGER.debug("Ran concurrentContextMetricsInfinispanMultiJVMCuratorLock metrics");
+    }
+
+    /**
+     * Concurrent context metrics hazelcast multi JVM curator lock.
+     *
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void concurrentContextMetricsHazelcastMultiJVMCuratorLock()
+            throws ApexModelException, IOException, ApexException {
+        LOGGER.debug("Running concurrentContextMetricsHazelcastMultiJVMCuratorLock metrics . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters().setPluginClass(
+                "org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor");
+
+        final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters();
+        curatorParameters.setPluginClass("org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager");
+        contextParameters.setLockManagerParameters(curatorParameters);
+        curatorParameters.setZookeeperAddress(zookeeperAddress);
+
+        runConcurrentContextMetrics("HazelcastMultiJVMCuratorLock");
+
+        LOGGER.debug("Ran concurrentContextMetricsHazelcastMultiJVMCuratorLock metrics");
+    }
+
+    /**
+     * Run concurrent context metrics.
+     *
+     * @param testName the test name
+     * @throws ApexModelException the apex model exception
+     * @throws IOException the IO exception
+     * @throws ApexException the apex exception
+     */
+    private void runConcurrentContextMetrics(final String testName)
+            throws ApexModelException, IOException, ApexException {
+        total = -1;
+        outMetricLine(testName, "Init");
+
+        try {
+            setupContext();
+        } catch (final Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+
+        outMetricLine(testName, "Start");
+
+        Thread[] threadArray;
+
+        // Check if we have a single JVM or multiple JVMs
+        int runningThreadCount = -1;
+        if (jvmCount == 1) {
+            threadArray = new Thread[threadCount];
+
+            // Run everything in this JVM
+            for (int t = 0; t < threadCount; t++) {
+                threadArray[t] =
+                        new Thread(new ConcurrentContextMetricsThread(0, t, threadLoops, longArraySize, lockType));
+                threadArray[t].setName(testLabel + "_" + testName + ":concurrentContextMetricsThread_0_" + t);
+                threadArray[t].start();
+            }
+
+            outMetricLine(testName, "Running");
+            runningThreadCount = threadCount;
+        } else {
+            threadArray = new Thread[jvmCount];
+
+            final ConcurrentContextMetricsJVMThread[] jvmArray = new ConcurrentContextMetricsJVMThread[jvmCount];
+            // Spawn JVMs to run the tests
+            for (int j = 0; j < jvmCount; j++) {
+                jvmArray[j] = new ConcurrentContextMetricsJVMThread(testLabel + "_" + testName, j, threadCount,
+                        threadLoops, longArraySize, lockType);
+                threadArray[j] = new Thread(jvmArray[j]);
+                threadArray[j].setName(testLabel + "_" + testName + ":concurrentContextMetricsJVMThread_" + j);
+                threadArray[j].start();
+            }
+
+            boolean allReadyToGo;
+            do {
+                ThreadUtilities.sleep(TIME_10_MS);
+                allReadyToGo = true;
+                for (int j = 0; j < jvmCount; j++) {
+                    if (!jvmArray[j].isReadyToGo()) {
+                        allReadyToGo = false;
+                        break;
+                    }
+                }
+            } while (!allReadyToGo);
+
+            outMetricLine(testName, "Ready");
+            if (interactive) {
+                System.in.read();
+            }
+            outMetricLine(testName, "Running");
+
+            for (int j = 0; j < jvmCount; j++) {
+                jvmArray[j].offYouGo();
+            }
+
+            boolean allFinished;
+            do {
+                ThreadUtilities.sleep(TIME_10_MS);
+                allFinished = true;
+                for (int j = 0; j < jvmCount; j++) {
+                    if (!jvmArray[j].isAllFinished()) {
+                        allFinished = false;
+                        break;
+                    }
+                }
+            } while (!allFinished);
+
+            outMetricLine(testName, "Completed");
+
+            verifyContext(testName);
+
+            for (int j = 0; j < jvmCount; j++) {
+                jvmArray[j].finishItOut();
+            }
+
+            runningThreadCount = jvmCount;
+        }
+
+        boolean allFinished;
+        do {
+            ThreadUtilities.sleep(TIME_10_MS);
+            allFinished = true;
+            for (int i = 0; i < runningThreadCount; i++) {
+                if (threadArray[i].isAlive()) {
+                    allFinished = false;
+                    break;
+                }
+            }
+        } while (!allFinished);
+
+        if (jvmCount == 1) {
+            outMetricLine(testName, "Completed");
+            verifyContext(testName);
+        }
+
+        clearContext(testName);
+    }
+
+    /**
+     * Setup context.
+     *
+     * @throws ContextException the context exception
+     */
+    private void setupContext() throws ContextException {
+        final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor", "0.0.1");
+        contextDistributor = new DistributorFactory().getDistributor(distributorKey);
+
+        final AxArtifactKey[] usedArtifactStackArray = {new AxArtifactKey("testC-top", "0.0.1"),
+                new AxArtifactKey("testC-next", "0.0.1"), new AxArtifactKey("testC-bot", "0.0.1")};
+
+        final AxContextModel albumsModel = TestContextAlbumFactory.createMultiAlbumsContextModel();
+        contextDistributor.registerModel(albumsModel);
+
+        lTypeAlbum = contextDistributor.createContextAlbum(new AxArtifactKey("LTypeContextAlbum", "0.0.1"));
+        assert (lTypeAlbum != null);
+        lTypeAlbum.setUserArtifactStack(usedArtifactStackArray);
+
+        for (int i = 0; i < longArraySize; i++) {
+            final String longKey = Integer.toString(i);
+            final TestContextLongItem longItem = new TestContextLongItem();
+            longItem.setLongValue(0);
+            lTypeAlbum.put(longKey, longItem);
+        }
+    }
+
+    /**
+     * Verify context.
+     *
+     * @param testName the test name
+     * @throws ContextException the context exception
+     */
+    private void verifyContext(final String testName) throws ContextException {
+        total = 0;
+
+        try {
+            for (int i = 0; i < longArraySize; i++) {
+                total += ((TestContextLongItem) lTypeAlbum.get(Integer.toString(i))).getLongValue();
+            }
+
+            outMetricLine(testName, "Totaled");
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+
+        if (lockType == 2) {
+            if (total == jvmCount * threadCount * threadLoops) {
+                outMetricLine(testName, "VerifiedOK");
+            } else {
+                outMetricLine(testName, "VerifiedFail");
+            }
+        } else {
+            if (total == 0) {
+                outMetricLine(testName, "VerifiedOK");
+            } else {
+                outMetricLine(testName, "VerifiedFail");
+            }
+        }
+    }
+
+    /**
+     * Clear context.
+     *
+     * @param testName the test name
+     * @throws ContextException the context exception
+     */
+    private void clearContext(final String testName) throws ContextException {
+        contextDistributor.clear();
+        contextDistributor = null;
+
+        outMetricLine(testName, "Cleared");
+    }
+
+    /**
+     * Out metric line.
+     *
+     * @param testName the test name
+     * @param testPhase the test phase
+     */
+    public void outMetricLine(final String testName, final String testPhase) {
+        System.out.println("ContextMetrics," + dateFormat.format(new Date()) + "," + System.currentTimeMillis() + ","
+                + testLabel + "," + testName + "," + testPhase + "," + jvmCount + "," + threadCount + "," + threadLoops
+                + "," + longArraySize + "," + lockType + "," + total);
+    }
+}
diff --git a/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsJVM.java b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsJVM.java
new file mode 100644
index 0000000..ed81e39
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsJVM.java
@@ -0,0 +1,212 @@
+/*-
+ * ============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.context.metrics;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+import org.onap.policy.apex.context.ContextAlbum;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.impl.distribution.DistributorFactory;
+import org.onap.policy.apex.context.test.factory.TestContextAlbumFactory;
+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.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+
+/**
+ * The Class ConcurrentContextMetricsJVM rins in its own JVM to test concurrent context updates and
+ * lockings across JVMs.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class ConcurrentContextMetricsJVM {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextMetricsJVM.class);
+
+    private static final int NUM_ARGS = 6;
+    private static final int ARG_JVM_NO = 1;
+    private static final int ARG_THREAD_COUNT = 2;
+    private static final int ARG_ITERATIONS = 3;
+    private static final int ARG_ARRAY_SIZE = 4;
+    private static final int ARG_LOCK_TYPE = 5;
+
+    private static final int WAIT_10_MS = 10;
+
+    /**
+     * The Constructor for this class.
+     *
+     * @param testType the test type
+     * @param jvmNo the jvm no
+     * @param threadCount the thread count
+     * @param threadLoops the thread loops
+     * @param longArraySize the long array size
+     * @param lockType the lock type
+     * @throws ApexException the apex exception
+     * @throws IOException the IO exception
+     */
+    private ConcurrentContextMetricsJVM(final String testType, final int jvmNo, final int threadCount,
+            final int threadLoops, final int longArraySize, final int lockType) throws ApexException, IOException {
+        LOGGER.debug("starting JVMs and threads . . .");
+
+        final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
+
+        // Set up the distributor for this JVM
+        final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor", "0.0.1");
+        final Distributor contextDistributor = new DistributorFactory().getDistributor(distributorKey);
+
+        final AxArtifactKey[] usedArtifactStackArray = {new AxArtifactKey("testC-top_" + jvmNo, "0.0.1"),
+                new AxArtifactKey("testC-next_" + jvmNo, "0.0.1"), new AxArtifactKey("testC-bot_" + jvmNo, "0.0.1")};
+
+        final AxContextModel testAxContextModel = TestContextAlbumFactory.createLongContextModel();
+        contextDistributor.registerModel(testAxContextModel);
+        final ContextAlbum testContextAlbum =
+                contextDistributor.createContextAlbum(new AxArtifactKey("LongSameTypeContextAlbum", "0.0.1"));
+        Assertions.argumentNotNull(testContextAlbum, "testContextAlbum may not be null");
+        testContextAlbum.setUserArtifactStack(usedArtifactStackArray);
+
+        final Thread[] threadArray = new Thread[threadCount];
+
+        for (int t = 0; t < threadCount; t++) {
+            threadArray[t] =
+                    new Thread(new ConcurrentContextMetricsThread(jvmNo, t, threadLoops, longArraySize, lockType));
+            threadArray[t].setName(testType + ":ConcurrentContextMetricsThread_" + jvmNo + "_" + t);
+            threadArray[t].start();
+            LOGGER.debug("started thread " + threadArray[t].getName());
+        }
+
+        System.out.println("ReadyToGo");
+        while (true) {
+            final String goLine = bufferedReader.readLine();
+            if (!goLine.trim().equals("OffYouGo")) {
+                throw new IOException("Expected OffYouGo");
+            }
+            break;
+        }
+
+        boolean allFinished;
+        do {
+            allFinished = true;
+            for (int t = 0; t < threadCount; t++) {
+                if (threadArray[t].isAlive()) {
+                    allFinished = false;
+                    ThreadUtilities.sleep(WAIT_10_MS);
+                    break;
+                }
+            }
+        } while (!allFinished);
+
+        System.out.println("AllFinished");
+        while (true) {
+            final String goLine = bufferedReader.readLine();
+            if (!goLine.trim().equals("FinishItOut")) {
+                throw new IOException("Expected FinishItOut");
+            }
+            break;
+        }
+
+        LOGGER.debug("threads finished");
+        contextDistributor.clear();
+    }
+
+    /**
+     * The main method.
+     *
+     * @param args the args
+     * @throws JsonSyntaxException the json syntax exception
+     * @throws ClassNotFoundException the class not found exception
+     */
+    @SuppressWarnings("unchecked")
+    public static void main(final String[] args) throws JsonSyntaxException, ClassNotFoundException {
+        if (args.length < NUM_ARGS || (args.length % 2 != 0)) {
+            LOGGER.error("invalid arguments: " + Arrays.toString(args));
+            LOGGER.error(
+                    "usage: ConcurrentContextMetricsJVM testLabel jvmNo threadCount threadLoops longArraySize lockType [parameterKey parameterJson].... ");
+            return;
+        }
+
+        int jvmNo = -1;
+        int threadCount = -1;
+        int threadLoops = -1;
+        int longArraySize = -1;
+        int lockType = -1;
+
+        try {
+            jvmNo = Integer.parseInt(args[ARG_JVM_NO]);
+        } catch (final Exception e) {
+            LOGGER.error("invalid argument jvmNo", e);
+            return;
+        }
+
+        try {
+            threadCount = Integer.parseInt(args[ARG_THREAD_COUNT]);
+        } catch (final Exception e) {
+            LOGGER.error("invalid argument threadCount", e);
+            return;
+        }
+
+        try {
+            threadLoops = Integer.parseInt(args[ARG_ITERATIONS]);
+        } catch (final Exception e) {
+            LOGGER.error("invalid argument threadLoops", e);
+            return;
+        }
+
+        try {
+            longArraySize = Integer.parseInt(args[ARG_ARRAY_SIZE]);
+        } catch (final Exception e) {
+            LOGGER.error("invalid argument longArraySize", e);
+            return;
+        }
+
+        try {
+            lockType = Integer.parseInt(args[ARG_LOCK_TYPE]);
+        } catch (final Exception e) {
+            LOGGER.error("invalid argument lockType", e);
+            return;
+        }
+
+        for (int p = NUM_ARGS; p < args.length - 1; p += 2) {
+            @SuppressWarnings("rawtypes")
+            final Class parametersClass = Class.forName(args[p]);
+            final AbstractParameters parameters =
+                    (AbstractParameters) new Gson().fromJson(args[p + 1], parametersClass);
+            ParameterService.registerParameters(parametersClass, parameters);
+        }
+
+        try {
+            new ConcurrentContextMetricsJVM(args[0], jvmNo, threadCount, threadLoops, longArraySize, lockType);
+        } catch (final Exception e) {
+            LOGGER.error("error running test in JVM", e);
+            return;
+        }
+    }
+}
diff --git a/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsJVMThread.java b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsJVMThread.java
new file mode 100644
index 0000000..64bc0ca
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsJVMThread.java
@@ -0,0 +1,187 @@
+/*-
+ * ============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.context.metrics;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+import com.google.gson.Gson;
+
+/**
+ * The Class ConcurrentContextMetricsJVMThread gets metrics for concurrent use of context.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ConcurrentContextMetricsJVMThread implements Runnable {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextMetricsJVMThread.class);
+
+    private final String testType;
+    private final int jvm;
+    private final int threadCount;
+    private final int threadLoops;
+    private final int longArraySize;
+    private final int lockType;
+
+    private boolean readyToGo = false;
+    private boolean allFinished = false;
+
+    private PrintWriter processWriter;
+
+    /**
+     * The Constructor.
+     *
+     * @param testType the test type
+     * @param jvm the jvm
+     * @param threadCount the thread count
+     * @param threadLoops the thread loops
+     * @param longArraySize the long array size
+     * @param lockType the lock type
+     * @throws ApexException the apex exception
+     */
+    public ConcurrentContextMetricsJVMThread(final String testType, final int jvm, final int threadCount,
+            final int threadLoops, final int longArraySize, final int lockType) throws ApexException {
+        this.testType = testType;
+        this.jvm = jvm;
+        this.threadCount = threadCount;
+        this.threadLoops = threadLoops;
+        this.longArraySize = longArraySize;
+        this.lockType = lockType;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        final List<String> commandList = new ArrayList<>();
+        commandList.add(System.getProperty("java.home") + System.getProperty("file.separator") + "bin"
+                + System.getProperty("file.separator") + "java");
+        commandList.add("-cp");
+        commandList.add(System.getProperty("java.class.path"));
+        for (final Entry<Object, Object> property : System.getProperties().entrySet()) {
+            if (property.getKey().toString().startsWith("APEX")
+                    || property.getKey().toString().equals("java.net.preferIPv4Stack")
+                    || property.getKey().toString().equals("jgroups.bind_addr")) {
+                commandList.add("-D" + property.getKey().toString() + "=" + property.getValue().toString());
+            }
+        }
+        commandList.add("org.onap.policy.apex.plugins.context.metrics.ConcurrentContextMetricsJVM");
+        commandList.add(testType);
+        commandList.add(new Integer(jvm).toString());
+        commandList.add(new Integer(threadCount).toString());
+        commandList.add(new Integer(threadLoops).toString());
+        commandList.add(new Integer(longArraySize).toString());
+        commandList.add(new Integer(lockType).toString());
+
+        for (final Entry<Class<?>, AbstractParameters> parameterServiceEntry : ParameterService.getAll()) {
+            commandList.add(parameterServiceEntry.getKey().getCanonicalName());
+            commandList.add(new Gson().toJson(parameterServiceEntry.getValue()));
+        }
+
+        LOGGER.info("starting JVM " + jvm);
+
+        // Run the JVM
+        final ProcessBuilder processBuilder = new ProcessBuilder(commandList);
+        processBuilder.redirectErrorStream(true);
+        Process process;
+
+        try {
+            process = processBuilder.start();
+
+            final InputStream is = process.getInputStream();
+            processWriter = new PrintWriter(process.getOutputStream());
+            final InputStreamReader isr = new InputStreamReader(is);
+            final BufferedReader br = new BufferedReader(isr);
+
+            String line;
+
+            LOGGER.info("JVM Output for command " + commandList + "\n");
+            while ((line = br.readLine()) != null) {
+                LOGGER.info(line);
+
+                if (line.trim().equals("ReadyToGo")) {
+                    readyToGo = true;
+                } else if (line.trim().equals("AllFinished")) {
+                    allFinished = true;
+                }
+            }
+
+            // Wait to get exit value
+            try {
+                final int exitValue = process.waitFor();
+                LOGGER.info("\n\nJVM " + jvm + " finished, exit value is " + exitValue);
+            } catch (final InterruptedException e) {
+                e.printStackTrace();
+            }
+        } catch (final IOException e1) {
+            e1.printStackTrace();
+        }
+    }
+
+    /**
+     * Checks if is ready to go.
+     *
+     * @return true, if checks if is ready to go
+     */
+    public boolean isReadyToGo() {
+        return readyToGo;
+    }
+
+    /**
+     * Checks if is all finished.
+     *
+     * @return true, if checks if is all finished
+     */
+    public boolean isAllFinished() {
+        return allFinished;
+    }
+
+    /**
+     * Off you go.
+     */
+    public void offYouGo() {
+        processWriter.println("OffYouGo");
+        processWriter.flush();
+    }
+
+    /**
+     * Finish it out.
+     */
+    public void finishItOut() {
+        processWriter.println("FinishItOut");
+        processWriter.flush();
+    }
+}
diff --git a/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsThread.java b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsThread.java
new file mode 100644
index 0000000..e207832
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/ConcurrentContextMetricsThread.java
@@ -0,0 +1,170 @@
+/*-
+ * ============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.context.metrics;
+
+import java.util.Random;
+
+import org.onap.policy.apex.context.ContextAlbum;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.impl.distribution.DistributorFactory;
+import org.onap.policy.apex.context.test.concepts.TestContextLongItem;
+import org.onap.policy.apex.context.test.factory.TestContextAlbumFactory;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ConcurrentContextMetricsThread gets metrics for concurrent use of context.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ConcurrentContextMetricsThread implements Runnable {
+    // Logger for this class
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ConcurrentContextMetricsThread.class);
+    private final Distributor contextDistributor;
+    private final int jvm;
+    private final int instance;
+    private final int threadLoops;
+    private final int longArraySize;
+    private final int lockType;
+
+    /**
+     * The Constructor.
+     *
+     * @param jvm the jvm
+     * @param instance the instance
+     * @param threadLoops the thread loops
+     * @param longArraySize the long array size
+     * @param lockType the lock type
+     * @throws ApexException the apex exception
+     */
+    public ConcurrentContextMetricsThread(final int jvm, final int instance, final int threadLoops,
+            final int longArraySize, final int lockType) throws ApexException {
+        this.jvm = jvm;
+        this.instance = instance;
+        this.threadLoops = threadLoops;
+        this.longArraySize = longArraySize;
+        this.lockType = lockType;
+
+        final AxArtifactKey distributorKey = new AxArtifactKey("ApexDistributor_" + jvm + "_" + instance, "0.0.1");
+        contextDistributor = new DistributorFactory().getDistributor(distributorKey);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Runnable#run()
+     */
+    @Override
+    public void run() {
+        LOGGER.info("running ConcurrentContextMetricsThread_" + jvm + "_" + instance + " . . .");
+
+        ContextAlbum lTypeAlbum = null;
+        try {
+            final AxContextModel axTestContextModel = TestContextAlbumFactory.createMultiAlbumsContextModel();
+            contextDistributor.registerModel(axTestContextModel);
+            lTypeAlbum = contextDistributor.createContextAlbum(new AxArtifactKey("LTypeContextAlbum", "0.0.1"));
+        } catch (final Exception e) {
+            LOGGER.error("could not get the test context album", e);
+            LOGGER.error("failed ConcurrentContextMetricsThread_" + jvm + "_" + instance);
+            return;
+        }
+
+        if (lTypeAlbum == null) {
+            LOGGER.error("could not find the test context album");
+            LOGGER.error("failed ConcurrentContextMetricsThread_" + jvm + "_" + instance);
+            return;
+        }
+
+        final AxArtifactKey[] usedArtifactStackArray =
+                {new AxArtifactKey("testCC-top", "0.0.1"), new AxArtifactKey("testCC-" + instance, "0.0.1")};
+
+        lTypeAlbum.setUserArtifactStack(usedArtifactStackArray);
+
+        final Random rand = new Random();
+
+        for (int i = 0; i < threadLoops; i++) {
+            // Get the next random entry to use
+            final String nextLongKey = Integer.toString(rand.nextInt(longArraySize));
+
+            if (lockType == 0) {
+                final TestContextLongItem item = (TestContextLongItem) lTypeAlbum.get(nextLongKey);
+                final long value = item.getLongValue();
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("lock type=" + lockType + ", value=" + value);
+                }
+                continue;
+            }
+
+            if (lockType == 1) {
+                try {
+                    lTypeAlbum.lockForReading(nextLongKey);
+                } catch (final ContextException e) {
+                    LOGGER.error("could not acquire read lock on context album, key=" + nextLongKey, e);
+                    continue;
+                }
+
+                final TestContextLongItem item = (TestContextLongItem) lTypeAlbum.get(nextLongKey);
+                final long value = item.getLongValue();
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("lock type=" + lockType + ", value=" + value);
+                }
+
+                try {
+                    lTypeAlbum.unlockForReading(nextLongKey);
+                } catch (final ContextException e) {
+                    LOGGER.error("could not release read lock on context album, key=" + nextLongKey, e);
+                }
+
+                continue;
+            }
+
+            if (lockType == 2) {
+                try {
+                    lTypeAlbum.lockForWriting(nextLongKey);
+                } catch (final ContextException e) {
+                    LOGGER.error("could not acquire write lock on context album, key=" + nextLongKey, e);
+                    continue;
+                }
+
+                final TestContextLongItem item = (TestContextLongItem) lTypeAlbum.get(nextLongKey);
+                long value = item.getLongValue();
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("lock type=" + lockType + ", value=" + value);
+                }
+                item.setLongValue(++value);
+                lTypeAlbum.put(nextLongKey, item);
+
+                try {
+                    lTypeAlbum.unlockForWriting(nextLongKey);
+                } catch (final ContextException e) {
+                    LOGGER.error("could not release write lock on context album, key=" + nextLongKey, e);
+                }
+                continue;
+            }
+        }
+
+        LOGGER.info("completed ConcurrentContextMetricsThread_" + jvm + "_" + instance);
+    }
+}
diff --git a/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/package-info.java b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/package-info.java
new file mode 100644
index 0000000..5e916b6d
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/main/java/org/onap/policy/apex/plugins/context/metrics/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Used to get metrics on the performance of Context Album performance for various types of
+ * distribution and locking mechanisms in APEX.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.policy.apex.plugins.context.metrics;
diff --git a/testsuites/integration/integration-context-metrics/src/test/java/org/onap/policy/apex/plugins/context/metrics/TestMetrics.java b/testsuites/integration/integration-context-metrics/src/test/java/org/onap/policy/apex/plugins/context/metrics/TestMetrics.java
new file mode 100644
index 0000000..5607f87
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/test/java/org/onap/policy/apex/plugins/context/metrics/TestMetrics.java
@@ -0,0 +1,57 @@
+/*-
+ * ============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.context.metrics;
+
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+
+import org.apache.curator.test.TestingServer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestMetrics {
+    // Zookeeper test server
+    TestingServer zkTestServer;
+
+    @Before
+    public void beforeTest() throws Exception {
+        zkTestServer = new TestingServer(62181);
+    }
+
+    @After
+    public void afterTest() throws IOException {
+        zkTestServer.stop();
+    }
+
+    @Test
+    public void getSingleJVMMetrics() {
+        final String[] args = {"singleJVMTestNL", "1", "32", "1000", "65536", "0", "localhost:62181", "false"};
+
+        try {
+            ConcurrentContextMetrics.main(args);
+        } catch (final Exception e) {
+            fail("Metrics test failed");
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/testsuites/integration/integration-context-metrics/src/test/resources/hazelcast/hazelcast.xml b/testsuites/integration/integration-context-metrics/src/test/resources/hazelcast/hazelcast.xml
new file mode 100644
index 0000000..84da495
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/test/resources/hazelcast/hazelcast.xml
@@ -0,0 +1,643 @@
+<?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=========================================================
+-->
+
+<hazelcast xmlns="http://www.hazelcast.com/schema/config"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<group>
+		<name>HazelcastGroup3.0EVAL</name>
+		<password>password3.0EVAL</password>
+	</group>
+	<network>
+		<port auto-increment="true">5706</port>
+		<join>
+			<multicast enabled="false">
+				<multicast-group>224.2.2.10</multicast-group>
+				<multicast-port>54327</multicast-port>
+			</multicast>
+			<tcp-ip enabled="true">
+				<members>10.0.0.0</members>
+				<!-- members>192.168.219.141</members-->
+			</tcp-ip>
+		</join>
+		<interfaces enabled="false">
+			<!-- This value will allow hazelcast to run locally from the IDE -->
+			<interface>127.0.0.*</interface>
+		</interfaces>
+	</network>
+	<properties>
+		<property name="hazelcast.icmp.enabled">true</property>
+		<property name="hazelcast.logging.type">slf4j</property>
+		<!-- disable the hazelcast shutdown hook - prefer to control the shutdown 
+			in code -->
+		<property name="hazelcast.shutdownhook.enabled">false</property>
+		<property name="hazelcast.graceful.shutdown.max.wait">60</property>
+	</properties>
+	<executor-service>
+		<pool-size>16</pool-size>
+	</executor-service>
+	<queue name="default">
+		<!-- Maximum size of the queue. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>100000</max-size>
+		<!-- Maximum number of seconds for each item to stay in the queue. Items 
+			that are not consumed in <time-to-live-seconds> will automatically get evicted 
+			from the queue. Any integer between 0 and Integer.MAX_VALUE. 0 means infinite. 
+			Default is 0. -->
+	</queue>
+	<map name="default">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>0</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>25</eviction-percentage>
+	</map>
+	<map name="L_ATTACH-Map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>LRU</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>1000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>5</eviction-percentage>
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>0</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.loading.service.buffer.L_ATTACHLoader</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>60000</write-delay-seconds> </map-store> -->
+
+
+	</map>
+	<map name="CTUM-Map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>LRU</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>1000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>5</eviction-percentage>
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>7200</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.loading.service.buffer.CTUMLoader</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>3600</write-delay-seconds> </map-store> -->
+
+	</map>
+	<map name="L_HANDOVER-Map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>LRU</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>1000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>5</eviction-percentage>
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>3600</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.base.publishing.hazelcast.L_ATTACHStore</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+	</map>
+
+	<map name="L_SERVICE_REQUEST-Map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>LRU</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>1000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>5</eviction-percentage>
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>7200</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.base.publishing.hazelcast.L_HandoverStore</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+	</map>
+	<map name="CommonCache">
+
+
+		<!-- Number of async-backups. If 1 is set as the backup-count for example, 
+			then all entries of the map will be copied to another JVM for fail-safety. 
+			Valid numbers are 0 (no backup), 1, 2, 3. -->
+		<async-backup-count>1</async-backup-count>
+
+		<!-- Can we read the local backup entries? Default value is false for strong 
+			consistency. Being able to read backup data will give you greater performance. -->
+		<read-backup-data>true</read-backup-data>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>LRU</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>3000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>5</eviction-percentage>
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>7200</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.base.publishing.hazelcast.L_HandoverStore</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+	</map>
+
+
+	<map name="Topology-Map">
+
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>2</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>10000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>0</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.loading.service.buffer.TopologyCacheLoader</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+
+	</map>
+	<map name="Protocol-cause-code-Map">
+		<near-cache>
+			<!-- Maximum number of seconds for each entry to stay in the near cache. 
+				Entries that are older than <time-to-live-seconds> will get automatically 
+				evicted from the near cache. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means infinite. Default is 0. -->
+			<time-to-live-seconds>0</time-to-live-seconds>
+
+			<!-- Maximum number of seconds each entry can stay in the near cache as 
+				untouched (not-read). Entries that are not read (touched) more than <max-idle-seconds> 
+				value will get removed from the near cache. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means Integer.MAX_VALUE. Default is 0. -->
+			<max-idle-seconds>0</max-idle-seconds>
+
+			<!-- Valid values are: NONE (no extra eviction, <time-to-live-seconds> 
+				may still apply), LRU (Least Recently Used), LFU (Least Frequently Used). 
+				NONE is the default. Regardless of the eviction policy used, <time-to-live-seconds> 
+				will still apply. -->
+			<eviction-policy>NONE</eviction-policy>
+
+			<!-- Maximum size of the near cache. When max size is reached, cache is 
+				evicted based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means Integer.MAX_VALUE. Default is 0. -->
+			<max-size>2000</max-size>
+
+			<!-- Should the cached entries get evicted if the entries are changed 
+				(updated or removed). true of false. Default is true. -->
+			<invalidate-on-change>true</invalidate-on-change>
+
+		</near-cache>
+
+
+
+	</map>
+	<map name="SessionId_Map">
+
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>10000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>60</time-to-live-seconds>
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.loading.service.buffer.TopologyCacheLoader</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+	</map>
+	<map name="gpeh-reasons-Map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>2</backup-count>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+		<near-cache>
+			<!-- Number of backups. If 1 is set as the backup-count for example, then 
+				all entries of the map will be copied to another JVM for fail-safety. Valid 
+				numbers are 0 (no backup), 1, 2, 3. -->
+			<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), 
+				LFU (Least Frequently Used). NONE is the default. -->
+			<eviction-policy>NONE</eviction-policy>
+			<!-- Maximum size of the map. When max size is reached, map is evicted 
+				based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means Integer.MAX_VALUE. Default is 0. -->
+			<max-size>1000</max-size>
+
+
+			<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+				that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+				will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means infinite. Default is 0. -->
+			<time-to-live-seconds>0</time-to-live-seconds>
+		</near-cache>
+	</map>
+	<map name="tac-imei-Map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>2</backup-count>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+		<near-cache>
+			<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), 
+				LFU (Least Frequently Used). NONE is the default. -->
+			<eviction-policy>NONE</eviction-policy>
+			<!-- Maximum size of the map. When max size is reached, map is evicted 
+				based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means Integer.MAX_VALUE. Default is 0. -->
+			<max-size>10000</max-size>
+
+			<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+				that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+				will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+				0 means infinite. Default is 0. -->
+			<time-to-live-seconds>0</time-to-live-seconds>
+		</near-cache>
+	</map>
+
+	<map name="CORE-DATA-Map">
+
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>2</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>10000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>0</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.loading.service.buffer.TopologyCacheLoader</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+
+	</map>
+	<map name="IMSI-APN-Map">
+
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>2</backup-count>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>10000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>0</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.loading.service.buffer.TopologyCacheLoader</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+
+	</map>
+	<map name="CommonDataCache">
+
+
+		<!-- Number of async-backups. If 1 is set as the backup-count for example, 
+			then all entries of the map will be copied to another JVM for fail-safety. 
+			Valid numbers are 0 (no backup), 1, 2, 3. -->
+		<async-backup-count>1</async-backup-count>
+
+		<!-- Can we read the local backup entries? Default value is false for strong 
+			consistency. Being able to read backup data will give you greater performance. -->
+		<read-backup-data>true</read-backup-data>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>LRU</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>3000000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>5</eviction-percentage>
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>7200</time-to-live-seconds>
+
+		<!-- <map-store enabled="true"> Name of the class implementing MapLoader 
+			and/or MapStore. The class should implement at least of these interfaces 
+			and contain no-argument constructor. Note that the inner classes are not 
+			supported. <class-name>com.ericsson.xstream.base.publishing.hazelcast.L_HandoverStore</class-name> 
+			Number of seconds to delay to call the MapStore.store(key, value). If the 
+			value is zero then it is write-through so MapStore.store(key, value) will 
+			be called as soon as the entry is updated. Otherwise it is write-behind so 
+			updates will be stored after write-delay-seconds value by calling Hazelcast.storeAll(map). 
+			Default value is 0. <write-delay-seconds>5</write-delay-seconds> </map-store> -->
+
+
+	</map>
+
+
+	<queue name="raw-distributer-queue">
+		<!-- Maximum size of the queue. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>100000</max-size>
+	</queue>
+	<map name="queue-map">
+
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>0</backup-count>
+
+	</map>
+
+	<map name="radio-correlation-config-Map">
+		<backup-count>2</backup-count>
+		<eviction-policy>NONE</eviction-policy>
+		<max-size>50</max-size>
+		<eviction-percentage>0</eviction-percentage>
+		<time-to-live-seconds>0</time-to-live-seconds>
+	</map>
+
+	<map name="xstream-configuration-map">
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>0</backup-count>
+		<time-to-live-seconds>100000</time-to-live-seconds>
+	</map>
+
+	<map name="TOPIC-TASK-MAP">
+
+		<async-backup-count>3</async-backup-count>
+
+		<read-backup-data>true</read-backup-data>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>1000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>0</time-to-live-seconds>
+	</map>
+	<map name="TOPIC-REGISTRY">
+
+		<async-backup-count>3</async-backup-count>
+
+		<read-backup-data>true</read-backup-data>
+		<!-- Valid values are: NONE (no eviction), LRU (Least Recently Used), LFU 
+			(Least Frequiently Used). NONE is the default. -->
+		<eviction-policy>NONE</eviction-policy>
+		<!-- Maximum size of the map. When max size is reached, map is evicted 
+			based on the policy defined. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>1000</max-size>
+		<!-- When max. size is reached, specified percentage of the map will be 
+			evicted. Any integer between 0 and 100. If 25 is set for example, 25% of 
+			the entries will get evicted. -->
+		<eviction-percentage>0</eviction-percentage>
+
+
+
+		<!-- Maximum number of seconds for each entry to stay in the map. Entries 
+			that are older than <time-to-live-seconds> and not updated for <time-to-live-seconds> 
+			will get automatically evicted from the map. Any integer between 0 and Integer.MAX_VALUE. 
+			0 means infinite. Default is 0. -->
+		<time-to-live-seconds>0</time-to-live-seconds>
+	</map>
+	<queue name="Pooled-Topic-Request-Queue">
+		<!-- Maximum size of the queue.Any integer between 0 and Integer.MAX_VALUE. 
+			0 means Integer.MAX_VALUE. Default is 0. -->
+		<max-size>100000</max-size>
+	</queue>
+	<map name="Pooled-Topic-Request-Queue-Backup-map">
+
+		<!-- Number of backups. If 1 is set as the backup-count for example, then 
+			all entries of the map will be copied to another JVM for fail-safety. Valid 
+			numbers are 0 (no backup), 1, 2, 3. -->
+		<backup-count>1</backup-count>
+		<eviction-policy>NONE</eviction-policy>
+		<time-to-live-seconds>0</time-to-live-seconds>
+	</map>
+
+</hazelcast>
diff --git a/testsuites/integration/integration-context-metrics/src/test/resources/infinispan/infinispan.xml b/testsuites/integration/integration-context-metrics/src/test/resources/infinispan/infinispan.xml
new file mode 100644
index 0000000..a854133
--- /dev/null
+++ b/testsuites/integration/integration-context-metrics/src/test/resources/infinispan/infinispan.xml
@@ -0,0 +1,42 @@
+<?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=========================================================
+-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+
+<infinispan xmlns="urn:infinispan:config:8.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:infinispan:config:8.0 http://infinispan.org/schemas/infinispan-config-8.0.xsd">
+	<jgroups>
+		<stack-file name="external-file" path="default-configs/default-jgroups-tcp.xml" />
+	</jgroups>
+
+	<cache-container name="ApexCacheContainer" default-cache="TestContext_0.0.1">
+		<transport cluster="apexCluster" stack="external-file" />
+		<jmx />
+		<replicated-cache name="LargeContextMap_0.0.1" mode="SYNC" statistics="true">
+			<state-transfer enabled="true" />
+		</replicated-cache>
+		<replicated-cache name="LongSameTypeContextMap_0.0.1" mode="SYNC" statistics="true">
+			<state-transfer enabled="true" />
+		</replicated-cache>
+		<replicated-cache name="TestContext_0.0.1" mode="SYNC">
+			<state-transfer enabled="true" />
+		</replicated-cache>
+	</cache-container>
+</infinispan>
diff --git a/testsuites/integration/integration-context-test/pom.xml b/testsuites/integration/integration-context-test/pom.xml
new file mode 100644
index 0000000..8c62339
--- /dev/null
+++ b/testsuites/integration/integration-context-test/pom.xml
@@ -0,0 +1,88 @@
+<!--
+  ============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.testsuites.integration</groupId>
+        <artifactId>integration</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>integration-context-test</artifactId>
+    <name>${project.artifactId}</name>
+    <description>[${project.parent.artifactId}] module to run context tests using various plugins, multi-threads and multi-JVMs</description>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.core</groupId>
+            <artifactId>core-infrastructure</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-distribution</groupId>
+            <artifactId>context-distribution-hazelcast</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-distribution</groupId>
+            <artifactId>context-distribution-infinispan</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-locking</groupId>
+            <artifactId>context-locking-curator</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.plugins.plugins-context.context-locking</groupId>
+            <artifactId>context-locking-hazelcast</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.context</groupId>
+            <artifactId>context-test-utils</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.curator</groupId>
+            <artifactId>curator-test</artifactId>
+            <version>4.0.0</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/testsuites/integration/integration-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java b/testsuites/integration/integration-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java
new file mode 100644
index 0000000..7a3a29c
--- /dev/null
+++ b/testsuites/integration/integration-context-test/src/test/java/org/onap/policy/apex/plugins/context/test/locking/TestConcurrentContext.java
@@ -0,0 +1,316 @@
+/*-
+ * ============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.context.test.locking;
+
+import static org.junit.Assert.assertEquals;
+import static org.onap.policy.apex.context.parameters.DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.TreeSet;
+
+import org.apache.zookeeper.server.NIOServerCnxnFactory;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.onap.policy.apex.context.impl.distribution.jvmlocal.JVMLocalDistributor;
+import org.onap.policy.apex.context.impl.locking.jvmlocal.JVMLocalLockManager;
+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.test.locking.ConcurrentContext;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.handling.ApexModelException;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.plugins.context.distribution.hazelcast.HazelcastContextDistributor;
+import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanContextDistributor;
+import org.onap.policy.apex.plugins.context.distribution.infinispan.InfinispanDistributorParameters;
+import org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManager;
+import org.onap.policy.apex.plugins.context.locking.curator.CuratorLockManagerParameters;
+import org.onap.policy.apex.plugins.context.locking.hazelcast.HazelcastLockManager;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+import com.hazelcast.config.Config;
+
+/**
+ * The Class TestConcurrentContext tests concurrent use of context.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class TestConcurrentContext {
+    // Logger for this class
+    private static final XLogger logger = XLoggerFactory.getXLogger(TestConcurrentContext.class);
+
+    // Test parameters
+    private static final String ZOOKEEPER_ADDRESS = "127.0.0.1";
+    private static final int ZOOKEEPER_START_PORT = 62181;
+    private static final int TEST_JVM_COUNT_SINGLE_JVM = 1;
+    private static final int TEST_JVM_COUNT_MULTI_JVM = 3;
+    private static final int TEST_THREAD_COUNT_SINGLE_JVM = 64;
+    private static final int TEST_THREAD_COUNT_MULTI_JVM = 20;
+    private static final int TEST_THREAD_LOOPS = 100;
+
+    private NIOServerCnxnFactory zookeeperFactory;
+
+    // We need to increment the Zookeeper port because sometimes the port is not released at the end
+    // of the test for a few seconds.
+    private static int nextZookeeperPort = ZOOKEEPER_START_PORT;
+    private int zookeeperPort;
+
+    @Rule
+    public final TemporaryFolder folder = new TemporaryFolder();
+
+    @BeforeClass
+    public static void configure() throws Exception {
+        System.setProperty("java.net.preferIPv4Stack", "true");
+        System.setProperty("hazelcast.config", "src/test/resources/hazelcast/hazelcast.xml");
+
+        // The JGroups IP address must be set to a real (not loopback) IP address for Infinispan to
+        // work. IN order to ensure that all
+        // the JVMs in a test pick up the same IP address, this function sets the address to be the
+        // first non-loopback IPv4 address
+        // on a host
+        final TreeSet<String> ipAddressSet = new TreeSet<String>();
+
+        final Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
+        for (final NetworkInterface netint : Collections.list(nets)) {
+            final Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
+            for (final InetAddress inetAddress : Collections.list(inetAddresses)) {
+                // Look for real IPv4 internet addresses
+                if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == 4) {
+                    ipAddressSet.add(inetAddress.getHostAddress());
+                }
+            }
+        }
+
+        if (ipAddressSet.size() == 0) {
+            throw new Exception("cound not find real IP address for test");
+        }
+        System.out.println("For Infinispan, setting jgroups.tcp.address to: " + ipAddressSet.first());
+        System.setProperty("jgroups.tcp.address", ipAddressSet.first());
+
+        final Config config = new Config();
+        config.getNetworkConfig().setPublicAddress(ipAddressSet.first());
+        config.getNetworkConfig().getInterfaces().addInterface(ipAddressSet.first());
+    }
+
+    @AfterClass
+    public static void teardown() throws IOException {}
+
+    private void startZookeeperServer() throws IOException, InterruptedException {
+        final File zookeeperDirectory = folder.newFolder("zookeeperDirectory");
+
+        zookeeperPort = nextZookeeperPort++;
+
+        final ZooKeeperServer server = new ZooKeeperServer(zookeeperDirectory, zookeeperDirectory, 5000);
+        zookeeperFactory = new NIOServerCnxnFactory();
+        zookeeperFactory.configure(new InetSocketAddress(zookeeperPort), 100);
+
+        zookeeperFactory.startup(server);
+    }
+
+    private void stopZookeeperServer() {
+        zookeeperFactory.shutdown();
+    }
+
+    @Test
+    public void testConcurrentContextJVMLocalVarSet() throws ApexModelException, IOException, ApexException {
+        logger.debug("Running testConcurrentContextJVMLocalVarSet test . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getLockManagerParameters().setPluginClass(JVMLocalLockManager.class.getCanonicalName());
+        final long result = new ConcurrentContext().testConcurrentContext("JVMLocalVarSet", TEST_JVM_COUNT_SINGLE_JVM,
+                TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result);
+
+        logger.debug("Ran testConcurrentContextJVMLocalVarSet test");
+    }
+
+    @Test
+    public void testConcurrentContextJVMLocalNoVarSet() throws ApexModelException, IOException, ApexException {
+        logger.debug("Running testConcurrentContextJVMLocalNoVarSet test . . .");
+
+        new ContextParameters();
+        final long result = new ConcurrentContext().testConcurrentContext("JVMLocalNoVarSet", TEST_JVM_COUNT_SINGLE_JVM,
+                TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result);
+
+        logger.debug("Ran testConcurrentContextJVMLocalNoVarSet test");
+    }
+
+    @Test
+    public void testConcurrentContextMultiJVMNoLock() throws ApexModelException, IOException, ApexException {
+        logger.debug("Running testConcurrentContextMultiJVMNoLock test . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters().setPluginClass(JVMLocalDistributor.class.getCanonicalName());
+        contextParameters.getLockManagerParameters().setPluginClass(JVMLocalLockManager.class.getCanonicalName());
+
+        final long result = new ConcurrentContext().testConcurrentContext("testConcurrentContextMultiJVMNoLock",
+                TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS);
+
+        // No concurrent map so result will be zero
+        assertEquals(0, result);
+
+        logger.debug("Ran testConcurrentContextMultiJVMNoLock test");
+    }
+
+    @Test
+    public void testConcurrentContextHazelcastLock() throws ApexModelException, IOException, ApexException {
+        logger.debug("Running testConcurrentContextHazelcastLock test . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters().setPluginClass(DEFAULT_DISTRIBUTOR_PLUGIN_CLASS);
+        contextParameters.getLockManagerParameters().setPluginClass(HazelcastLockManager.class.getCanonicalName());
+        final long result = new ConcurrentContext().testConcurrentContext("HazelcastLock", TEST_JVM_COUNT_SINGLE_JVM,
+                TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result);
+        logger.debug("Ran testConcurrentContextHazelcastLock test");
+    }
+
+    @Test
+    public void testConcurrentContextCuratorLock()
+            throws ApexModelException, IOException, ApexException, InterruptedException {
+        logger.debug("Running testConcurrentContextCuratorLock test . . .");
+
+        startZookeeperServer();
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters()
+                .setPluginClass(DistributorParameters.DEFAULT_DISTRIBUTOR_PLUGIN_CLASS);
+
+        final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters();
+        curatorParameters.setPluginClass(CuratorLockManager.class.getCanonicalName());
+        curatorParameters.setZookeeperAddress(ZOOKEEPER_ADDRESS + ":" + zookeeperPort);
+        contextParameters.setLockManagerParameters(curatorParameters);
+        ParameterService.registerParameters(LockManagerParameters.class, curatorParameters);
+
+        final long result = new ConcurrentContext().testConcurrentContext("CuratorLock", TEST_JVM_COUNT_SINGLE_JVM,
+                TEST_THREAD_COUNT_SINGLE_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_SINGLE_JVM * TEST_THREAD_COUNT_SINGLE_JVM * TEST_THREAD_LOOPS, result);
+
+        stopZookeeperServer();
+        logger.debug("Ran testConcurrentContextCuratorLock test");
+    }
+
+    @Test
+    public void testConcurrentContextHazelcastMultiJVMHazelcastLock()
+            throws ApexModelException, IOException, ApexException {
+        logger.debug("Running testConcurrentContextHazelcastMultiJVMHazelcastLock test . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters()
+                .setPluginClass(HazelcastContextDistributor.class.getCanonicalName());
+        contextParameters.getLockManagerParameters().setPluginClass(HazelcastLockManager.class.getCanonicalName());
+        final long result = new ConcurrentContext().testConcurrentContext("HazelcastMultiHazelcastlock",
+                TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result);
+        logger.debug("Ran testConcurrentContextHazelcastMultiJVMHazelcastLock test");
+    }
+
+    @Test
+    public void testConcurrentContextInfinispanMultiJVMHazelcastlock()
+            throws ApexModelException, IOException, ApexException {
+        logger.debug("Running testConcurrentContextInfinispanMultiJVMHazelcastlock test . . .");
+
+        final ContextParameters contextParameters = new ContextParameters();
+        final InfinispanDistributorParameters infinispanParameters = new InfinispanDistributorParameters();
+        infinispanParameters.setPluginClass(InfinispanContextDistributor.class.getCanonicalName());
+        infinispanParameters.setConfigFile("infinispan/infinispan-context-test.xml");
+        contextParameters.setDistributorParameters(infinispanParameters);
+        contextParameters.getLockManagerParameters().setPluginClass(HazelcastLockManager.class.getCanonicalName());
+
+        final long result = new ConcurrentContext().testConcurrentContext("InfinispanMultiHazelcastlock",
+                TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result);
+        logger.debug("Ran testConcurrentContextInfinispanMultiJVMHazelcastlock test");
+    }
+
+    @Test
+    public void testConcurrentContextInfinispanMultiJVMCuratorLock()
+            throws ApexModelException, IOException, ApexException, InterruptedException {
+        logger.debug("Running testConcurrentContextInfinispanMultiJVMCuratorLock test . . .");
+
+        startZookeeperServer();
+
+        final ContextParameters contextParameters = new ContextParameters();
+        final InfinispanDistributorParameters infinispanParameters = new InfinispanDistributorParameters();
+        infinispanParameters.setPluginClass(InfinispanContextDistributor.class.getCanonicalName());
+        infinispanParameters.setConfigFile("infinispan/infinispan-context-test.xml");
+        contextParameters.setDistributorParameters(infinispanParameters);
+
+        final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters();
+        curatorParameters.setPluginClass(CuratorLockManager.class.getCanonicalName());
+        curatorParameters.setZookeeperAddress(ZOOKEEPER_ADDRESS + ":" + zookeeperPort);
+        contextParameters.setLockManagerParameters(curatorParameters);
+        ParameterService.registerParameters(LockManagerParameters.class, curatorParameters);
+
+        final long result = new ConcurrentContext().testConcurrentContext("InfinispanMultiCuratorLock",
+                TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result);
+
+        stopZookeeperServer();
+
+        logger.debug("Ran testConcurrentContextInfinispanMultiJVMCuratorLock test");
+    }
+
+    @Test
+    public void testConcurrentContextHazelcastMultiJVMCuratorLock()
+            throws ApexModelException, IOException, ApexException, InterruptedException {
+        logger.debug("Running testConcurrentContextHazelcastMultiJVMCuratorLock test . . .");
+
+        startZookeeperServer();
+
+        final ContextParameters contextParameters = new ContextParameters();
+        contextParameters.getDistributorParameters()
+                .setPluginClass(HazelcastContextDistributor.class.getCanonicalName());
+
+        final CuratorLockManagerParameters curatorParameters = new CuratorLockManagerParameters();
+        curatorParameters.setPluginClass(CuratorLockManager.class.getCanonicalName());
+        curatorParameters.setZookeeperAddress(ZOOKEEPER_ADDRESS + ":" + zookeeperPort);
+        contextParameters.setLockManagerParameters(curatorParameters);
+        ParameterService.registerParameters(LockManagerParameters.class, curatorParameters);
+
+        final long result = new ConcurrentContext().testConcurrentContext("HazelcastMultiCuratorLock",
+                TEST_JVM_COUNT_MULTI_JVM, TEST_THREAD_COUNT_MULTI_JVM, TEST_THREAD_LOOPS);
+
+        assertEquals(TEST_JVM_COUNT_MULTI_JVM * TEST_THREAD_COUNT_MULTI_JVM * TEST_THREAD_LOOPS, result);
+
+        stopZookeeperServer();
+        logger.debug("Ran testConcurrentContextHazelcastMultiJVMCuratorLock test");
+    }
+}
diff --git a/testsuites/integration/integration-context-test/src/test/resources/hazelcast/hazelcast.xml b/testsuites/integration/integration-context-test/src/test/resources/hazelcast/hazelcast.xml
new file mode 100644
index 0000000..d69f24b
--- /dev/null
+++ b/testsuites/integration/integration-context-test/src/test/resources/hazelcast/hazelcast.xml
@@ -0,0 +1,54 @@
+<?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=========================================================
+-->
+
+<hazelcast xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <group>
+        <name>ApexHazelcastGroup</name>
+        <password>ApexHazelcastGroupPassword</password>
+    </group>
+    <network>
+        <port auto-increment="true">5706</port>
+        <join>
+            <multicast enabled="false">
+                <multicast-group>224.2.2.10</multicast-group>
+                <multicast-port>54327</multicast-port>
+            </multicast>
+            <tcp-ip enabled="true">
+                <members>127.0.0.1</members>
+            </tcp-ip>
+        </join>
+        <interfaces enabled="false">
+			<!-- This value will allow hazelcast to run locally from the IDE -->
+            <interface>127.0.0.*</interface>
+        </interfaces>
+    </network>
+    <properties>
+        <property name="hazelcast.icmp.enabled">true</property>
+        <property name="hazelcast.logging.type">slf4j</property>
+		<!-- disable the hazelcast shutdown hook - prefer to control the shutdown 
+			in code -->
+        <property name="hazelcast.shutdownhook.enabled">false</property>
+        <property name="hazelcast.graceful.shutdown.max.wait">60</property>
+    </properties>
+    <executor-service>
+        <pool-size>16</pool-size>
+    </executor-service>
+</hazelcast>
diff --git a/testsuites/integration/integration-context-test/src/test/resources/infinispan/default-jgroups-tcp.xml b/testsuites/integration/integration-context-test/src/test/resources/infinispan/default-jgroups-tcp.xml
new file mode 100644
index 0000000..028cf1d
--- /dev/null
+++ b/testsuites/integration/integration-context-test/src/test/resources/infinispan/default-jgroups-tcp.xml
@@ -0,0 +1,76 @@
+<?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=========================================================
+-->
+
+<config xmlns="urn:org:jgroups"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups-4.0.xsd">
+   <TCP bind_addr="${jgroups.tcp.address:127.0.0.1}"
+        bind_port="${jgroups.tcp.port:7800}"
+        enable_diagnostics="false"
+        thread_naming_pattern="pl"
+        send_buf_size="640k"
+        sock_conn_timeout="300"
+        bundler_type="no-bundler"
+
+        thread_pool.min_threads="${jgroups.thread_pool.min_threads:0}"
+        thread_pool.max_threads="${jgroups.thread_pool.max_threads:200}"
+        thread_pool.keep_alive_time="60000"
+   />
+   <MPING bind_addr="${jgroups.tcp.address:127.0.0.1}"
+          mcast_addr="${jgroups.mping.mcast_addr:228.2.4.6}"
+          mcast_port="${jgroups.mping.mcast_port:43366}"
+          ip_ttl="${jgroups.udp.ip_ttl:2}" 
+   />
+   <MERGE3 min_interval="10000" 
+           max_interval="30000" 
+   />
+   <FD_SOCK />
+   <FD_ALL timeout="60000" 
+           interval="15000" 
+           timeout_check_interval="5000" 
+   />
+   <VERIFY_SUSPECT timeout="5000" />
+   <pbcast.NAKACK2 use_mcast_xmit="false"
+                   xmit_interval="100"
+                   xmit_table_num_rows="50"
+                   xmit_table_msgs_per_row="1024"
+                   xmit_table_max_compaction_time="30000"
+                   resend_last_seqno="true"
+   />
+   <UNICAST3 xmit_interval="100"
+             xmit_table_num_rows="50"
+             xmit_table_msgs_per_row="1024"
+             xmit_table_max_compaction_time="30000"
+             conn_expiry_timeout="0"
+   />
+   <pbcast.STABLE stability_delay="500"
+                  desired_avg_gossip="5000"
+                  max_bytes="1M"
+   />
+   <pbcast.GMS print_local_addr="false"
+               install_view_locally_first="true"
+               join_timeout="${jgroups.join_timeout:5000}"
+   />
+   <MFC max_credits="2m" 
+        min_threshold="0.40"
+   />
+   <FRAG3/>
+</config>
diff --git a/testsuites/integration/integration-context-test/src/test/resources/infinispan/default-jgroups-udp.xml b/testsuites/integration/integration-context-test/src/test/resources/infinispan/default-jgroups-udp.xml
new file mode 100644
index 0000000..17ba5ea
--- /dev/null
+++ b/testsuites/integration/integration-context-test/src/test/resources/infinispan/default-jgroups-udp.xml
@@ -0,0 +1,79 @@
+<?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=========================================================
+-->
+
+<config xmlns="urn:org:jgroups"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups-4.0.xsd">
+   <UDP mcast_addr="${jgroups.udp.mcast_addr:228.6.7.8}"
+        mcast_port="${jgroups.udp.mcast_port:46655}"
+        ucast_send_buf_size="1m"
+        mcast_send_buf_size="1m"
+        ucast_recv_buf_size="20m"
+        mcast_recv_buf_size="25m"
+        ip_ttl="${jgroups.ip_ttl:2}"
+        thread_naming_pattern="pl"
+        enable_diagnostics="false"
+        bundler_type="no-bundler"
+        max_bundle_size="8500"
+
+        thread_pool.min_threads="${jgroups.thread_pool.min_threads:0}"
+        thread_pool.max_threads="${jgroups.thread_pool.max_threads:200}"
+        thread_pool.keep_alive_time="60000"
+   />
+   <PING />
+   <MERGE3 min_interval="10000" 
+           max_interval="30000" 
+   />
+   <FD_SOCK />
+   <FD_ALL timeout="60000" 
+           interval="15000" 
+           timeout_check_interval="5000" 
+   />
+   <VERIFY_SUSPECT timeout="5000" 
+   />
+   <pbcast.NAKACK2 xmit_interval="100"
+                   xmit_table_num_rows="50"
+                   xmit_table_msgs_per_row="1024"
+                   xmit_table_max_compaction_time="30000"
+                   resend_last_seqno="true"
+   />
+   <UNICAST3 xmit_interval="100"
+             xmit_table_num_rows="50"
+             xmit_table_msgs_per_row="1024"
+             xmit_table_max_compaction_time="30000"
+             conn_expiry_timeout="0"
+   />
+   <pbcast.STABLE stability_delay="500"
+                  desired_avg_gossip="5000"
+                  max_bytes="1M"
+   />
+   <pbcast.GMS print_local_addr="false"
+               install_view_locally_first="true"
+               join_timeout="${jgroups.join_timeout:5000}"
+   />
+   <UFC max_credits="2m" 
+        min_threshold="0.40"
+   />
+   <MFC max_credits="2m" 
+        min_threshold="0.40"
+   />
+   <FRAG3 frag_size="8000"/>
+</config>
diff --git a/testsuites/integration/integration-context-test/src/test/resources/infinispan/infinispan-context-test.xml b/testsuites/integration/integration-context-test/src/test/resources/infinispan/infinispan-context-test.xml
new file mode 100644
index 0000000..9fa7a2a
--- /dev/null
+++ b/testsuites/integration/integration-context-test/src/test/resources/infinispan/infinispan-context-test.xml
@@ -0,0 +1,35 @@
+<?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=========================================================
+-->
+
+<infinispan xmlns="urn:infinispan:config:8.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="urn:infinispan:config:8.0 http://infinispan.org/schemas/infinispan-config-8.0.xsd">
+    <jgroups>
+        <stack-file name="tcpStack" path="infinispan/default-jgroups-tcp.xml" />
+    </jgroups>
+
+    <cache-container name="ApexCacheContainer" default-cache="LTypeContextAlbum_0.0.1">
+        <transport cluster="apexCluster" stack="tcpStack" />
+        <jmx />
+        <replicated-cache name="LTypeContextAlbum_0.0.1" mode="SYNC" statistics="true">
+            <state-transfer enabled="true" />
+        </replicated-cache>
+    </cache-container>
+</infinispan>
diff --git a/testsuites/integration/integration-context-test/src/test/resources/logback-test.xml b/testsuites/integration/integration-context-test/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..7fd818d
--- /dev/null
+++ b/testsuites/integration/integration-context-test/src/test/resources/logback-test.xml
@@ -0,0 +1,76 @@
+<?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>
+
+	<logger name="org.apache.zookeeper.ClientCnxn" level="OFF" additivity="false">
+		<appender-ref ref="STDOUT" />
+	</logger>
+	
+	<appender name="FILE"
+		class="ch.qos.logback.core.FileAppender">
+		<file>${LOG_DIR}/apex.log</file>
+		<encoder>
+			<pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+				%logger{26} - %msg %n %ex{full}</pattern>
+		</encoder>
+	</appender>
+
+	<appender name="CTXT_FILE"
+		class="ch.qos.logback.core.FileAppender">
+		<file>${LOG_DIR}/apex_ctxt.log</file>
+		<encoder>
+			<pattern>%d %-5relative [procId=${processId}] [%thread] %-5level
+				%logger{26} - %msg %n %ex{full}</pattern>
+		</encoder>
+	</appender>
+
+    <logger name="org.infinispan" level="info" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <logger name="com.ericsson.apex.context.monitoring" level="TRACE" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+    
+    <logger name="com.ericsson.apex.context.monitoring" level="TRACE" additivity="false">
+        <appender-ref ref="CTXT_FILE" />
+    </logger>
+    
+    <logger name="org.jgroups" level="off" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+
+    <root level="info">
+        <appender-ref ref="STDOUT" />
+    </root>
+
+</configuration>
diff --git a/testsuites/integration/integration-uservice-test/pom.xml b/testsuites/integration/integration-uservice-test/pom.xml
index 5eeeeff..8fe5164 100644
--- a/testsuites/integration/integration-uservice-test/pom.xml
+++ b/testsuites/integration/integration-uservice-test/pom.xml
@@ -48,7 +48,7 @@
         </dependency>
         <dependency>
             <groupId>org.onap.policy.apex-pdp.context</groupId>
-            <artifactId>context-test</artifactId>
+            <artifactId>context-test-utils</artifactId>
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
@@ -209,6 +209,12 @@
             <artifactId>jersey-container-servlet-core</artifactId>
             <version>${version.jersey.core}</version>
         </dependency>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.context</groupId>
+            <artifactId>context-test-utils</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/testsuites/integration/pom.xml b/testsuites/integration/pom.xml
index 4e6bec7..366556c 100644
--- a/testsuites/integration/pom.xml
+++ b/testsuites/integration/pom.xml
@@ -31,8 +31,43 @@
     <artifactId>integration</artifactId>
     <packaging>pom</packaging>
 
-    <modules>
-        <module>integration-common</module>
-        <module>integration-uservice-test</module>
-    </modules>
+    <profiles>
+        <profile>
+            <id>apexDefault</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <modules>
+                <module>integration-common</module>
+                <module>integration-uservice-test</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>apexMetrics</id>
+            <activation>
+                <property>
+                    <name>apexMetrics</name>
+                </property>
+            </activation>
+            <modules>
+                <module>integration-common</module>
+                <module>integration-uservice-test</module>
+                <module>integration-context-metrics</module>
+            </modules>
+        </profile>
+        <profile>
+            <id>apexAll</id>
+            <activation>
+                <property>
+                    <name>apexAll</name>
+                </property>
+            </activation>
+            <modules>
+                <module>integration-common</module>
+                <module>integration-uservice-test</module>
+                <module>integration-context-test</module>
+                <module>integration-context-metrics</module>
+            </modules>
+        </profile>
+    </profiles>
 </project>
\ No newline at end of file