summaryrefslogtreecommitdiffstats
path: root/context/context-management/src/main/java
diff options
context:
space:
mode:
authorramverma <ram.krishna.verma@ericsson.com>2018-05-29 15:25:49 +0100
committerramverma <ram.krishna.verma@ericsson.com>2018-05-30 16:52:18 +0100
commit10d58cde1f75ea0ddf0cdc0746d858e0a077980d (patch)
treee455a00f665d24f228522c222a4b46753e9ed6af /context/context-management/src/main/java
parent55d93a12cc5575c872724f48585304b5eec77fea (diff)
Adding apex context module
Change-Id: I1284c2ba4c41a9cf721e141e096d1021be599a2d Issue-ID: POLICY-857 Signed-off-by: ramverma <ram.krishna.verma@ericsson.com>
Diffstat (limited to 'context/context-management/src/main/java')
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java127
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java51
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java51
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java140
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java88
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java79
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java119
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java486
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java326
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java86
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java116
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java70
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/package-info.java27
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java28
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java225
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java84
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java56
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/package-info.java27
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java26
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java28
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java83
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java100
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java28
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java28
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java169
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java119
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java214
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java38
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/package-info.java27
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java29
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java210
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/package-info.java27
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java29
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java146
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java85
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java85
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java120
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java81
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java87
-rw-r--r--context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java28
40 files changed, 3973 insertions, 0 deletions
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java
new file mode 100644
index 000000000..73ef668a0
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextAlbum.java
@@ -0,0 +1,127 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import java.util.Map;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+
+/**
+ * The Interface ContextAlbum is implemented by all classes that manage context in Apex. Context albums may store
+ * context in memory, on disk, in a repository or in a mechanism such as a distributed map.
+ * <p>
+ * A context album uses plugins to handle its context schemas, its distribution, its locking, and its persistence.
+ * <p>
+ * The schema that defines the items in a context album is interpreted by a plugin that implements the
+ * {@link SchemaHelper} interface. The schema helper uses the schema definition to provide new instances for a context
+ * album. By default, context albums use Java schemas.
+ * <p>
+ * Context albums may be shared across an arbitrary number of JVMs using a distribution mechanism. Apex context
+ * distributed context albums using plugins that implement the {@link Distributor} interface. By default, context albums
+ * use JVM local distribution, that is context albums are only available in a single JVM
+ * <p>
+ * Items in a context album may be locked across all distributed instances of an album. Apex locks instances on context
+ * albums using the distributed locking mechanism in a plugin that implements the {@link LockManager} interface. By
+ * default, context albums use Java locking local to a single JVM on each context album instance.
+ * <p>
+ * Context albums may be persisted to disk, database, or any other repository. Apex persists context albums using the
+ * persistence mechanism in a plugin that implements the {@link Persistor} interface. By default, context albums use a
+ * dummy persistor plugin that does not persist context albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface ContextAlbum extends Map<String, Object> {
+ /**
+ * Gets the key of the context album instance.
+ *
+ * @return the key
+ */
+ AxArtifactKey getKey();
+
+ /**
+ * Gets the name of the context album instance.
+ *
+ * @return the name
+ */
+ String getName();
+
+ /**
+ * Get the current context album with values.
+ *
+ * @return the current context runtime values
+ */
+ AxContextAlbum getAlbumDefinition();
+
+ /**
+ * Get the schema helper for the technology that is handling the schema for this album.
+ *
+ * @return the schema helper
+ */
+ SchemaHelper getSchemaHelper();
+
+ /**
+ * Place a read lock on a key in this album across the entire cluster.
+ *
+ * @param key The key to lock
+ * @throws ContextException on locking errors
+ */
+ void lockForReading(String key) throws ContextException;
+
+ /**
+ * Place a write lock on a key in this album across the entire cluster.
+ *
+ * @param key The key to lock
+ * @throws ContextException on locking errors
+ */
+ void lockForWriting(String key) throws ContextException;
+
+ /**
+ * Release the the read lock on a key in this album across the entire cluster.
+ *
+ * @param key The key to unlock
+ * @throws ContextException on locking errors
+ */
+ void unlockForReading(String key) throws ContextException;
+
+ /**
+ * Release the the write lock on a key in this album across the entire cluster.
+ *
+ * @param key The key to unlock
+ * @throws ContextException on locking errors
+ */
+ void unlockForWriting(String key) throws ContextException;
+
+ /**
+ * Set the stack of artifact keys currently using this context item.
+ *
+ * @param userArtifactStack the keys of the artifacts using the context album at the moment
+ */
+ void setUserArtifactStack(AxConcept[] userArtifactStack);
+
+ /**
+ * Flush the context album to the distribution and persistence mechanism.
+ *
+ * @throws ContextException On context flush errors
+ */
+ void flush() throws ContextException;
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java
new file mode 100644
index 000000000..de5cec051
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+
+/**
+ * This exception will be called if an error occurs in an Apex context item.
+ *
+ * @author Liam Fallon
+ */
+public class ContextException extends ApexException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex context exception with a message.
+ *
+ * @param message the message
+ */
+ public ContextException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex context exception with a message and a caused by exception.
+ *
+ * @param message the message
+ * @param e the exception that caused this exception to be thrown
+ */
+ public ContextException(final String message, final Exception e) {
+ super(message, e);
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java
new file mode 100644
index 000000000..b2aa017e5
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/ContextRuntimeException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException;
+
+/**
+ * This exception will be called if an error occurs in an Apex context item.
+ *
+ * @author Liam Fallon
+ */
+public class ContextRuntimeException extends ApexRuntimeException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ /**
+ * Instantiates a new apex context exception with a message.
+ *
+ * @param message the message
+ */
+ public ContextRuntimeException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new apex context exception with a message and a caused by exception.
+ *
+ * @param message the message
+ * @param e the exception that caused this exception to be thrown
+ */
+ public ContextRuntimeException(final String message, final Exception e) {
+ super(message, e);
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java
new file mode 100644
index 000000000..a17313882
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/Distributor.java
@@ -0,0 +1,140 @@
+/*-
+ * ============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.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+
+/**
+ * This interface is implemented by plugin classes that distribute context albums in Apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface Distributor {
+
+ /**
+ * Initialize the distributor with its properties.
+ *
+ * @param key The key that identifies this distributor
+ * @throws ContextException On errors initializing the distributor
+ */
+ void init(AxArtifactKey key) throws ContextException;
+
+ /**
+ * Shut down distributor.
+ *
+ * @throws ContextException On errors initializing the distributor
+ */
+ void shutdown() throws ContextException;
+
+ /**
+ * Get the key of the distributor.
+ *
+ * @return the contextSetKey
+ */
+ AxArtifactKey getKey();
+
+ /**
+ * Register the context model and its sub models with the model service.
+ *
+ * @param contextModel the context model to register
+ * @throws ContextException on model registration errors
+ */
+ void registerModel(AxContextModel contextModel) throws ContextException;
+
+ /**
+ * Create a context album on a distributor, the distributor looks up the album and initialize it. The
+ * {@link AxContextAlbum} is used to check that the album in the distributor matches the album definition we expect
+ * to get.
+ *
+ * @param axContextAlbumKey the key of the model context album for this context album
+ * @return the context album
+ * @throws ContextException if the album cannot be initialised
+ */
+ ContextAlbum createContextAlbum(AxArtifactKey axContextAlbumKey) throws ContextException;
+
+ /**
+ * Remove a context album from a distributor.
+ *
+ * @param contextAlbum The album to remove
+ * @throws ContextException if the album cannot be removed
+ */
+ void removeContextAlbum(AxContextAlbum contextAlbum) throws ContextException;
+
+ /**
+ * Flush all context albums owned by the distributor to the distribution mechanism.
+ *
+ * @throws ContextException on context flushing errors
+ */
+ void flush() throws ContextException;
+
+ /**
+ * Flush a context album owned by the distributor to the distribution mechanism.
+ *
+ * @param contextAlbum the context album to flush
+ * @throws ContextException on errors in flushing the context album
+ */
+ void flushContextAlbum(ContextAlbum contextAlbum) throws ContextException;
+
+ /**
+ * Place a read lock on an item in an album across the entire cluster.
+ *
+ * @param albumKey The key of the album containing the item
+ * @param keyOnMap The key on the album to lock
+ * @throws ContextException on locking errors
+ */
+ void lockForReading(AxArtifactKey albumKey, String keyOnMap) throws ContextException;
+
+ /**
+ * Place a write lock on an album item across the entire cluster.
+ *
+ * @param albumKey The key of the album containing the item
+ * @param key The key on the album to lock
+ * @throws ContextException on locking errors
+ */
+ void lockForWriting(AxArtifactKey albumKey, String key) throws ContextException;
+
+ /**
+ * Release the read lock on a key across the entire cluster.
+ *
+ * @param albumKey The key of the album containing the item
+ * @param key The key on the album to unlock
+ * @throws ContextException on locking errors
+ */
+ void unlockForReading(AxArtifactKey albumKey, String key) throws ContextException;
+
+ /**
+ * Release the write lock on a key across the entire cluster.
+ *
+ * @param albumKey The key of the album containing the item
+ * @param key The key on the album to unlock
+ * @throws ContextException on locking errors
+ */
+ void unlockForWriting(AxArtifactKey albumKey, String key) throws ContextException;
+
+ /**
+ * Clear all the context from the context distributor.
+ *
+ * @throws ContextException on context clearing exceptions
+ */
+ void clear() throws ContextException;
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java b/context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java
new file mode 100644
index 000000000..8ccf54424
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/LockManager.java
@@ -0,0 +1,88 @@
+/*-
+ * ============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.context;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+
+/**
+ * This interface provides a facade to hide implementation details of various lock managers that may be used to manage
+ * locking of context items.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface LockManager {
+
+ /**
+ * Initialize the lock manager with its properties.
+ *
+ * @param key The key of this lock manager
+ * @throws ContextException On errors initializing the persistor
+ */
+ void init(AxArtifactKey key) throws ContextException;
+
+ /**
+ * Get the key of the lock manager.
+ *
+ * @return the managers key
+ */
+ AxArtifactKey getKey();
+
+ /**
+ * Place a read lock on a lock type and key across the entire cluster.
+ *
+ * @param lockTypeKey The key of the map where the context item to lock is
+ * @param lockKey The key on the map to lock
+ * @throws ContextException on locking errors
+ */
+ void lockForReading(String lockTypeKey, String lockKey) throws ContextException;
+
+ /**
+ * Place a write lock on a lock type and key across the entire cluster.
+ *
+ * @param lockTypeKey The key of the map where the context item to lock is
+ * @param lockKey The key on the map to lock
+ * @throws ContextException on locking errors
+ */
+ void lockForWriting(String lockTypeKey, String lockKey) throws ContextException;
+
+ /**
+ * Release a read lock on a lock type and key across the entire cluster.
+ *
+ * @param lockTypeKey The key of the map where the context item to lock is
+ * @param lockKey The key on the map to lock
+ * @throws ContextException on locking errors
+ */
+ void unlockForReading(String lockTypeKey, String lockKey) throws ContextException;
+
+ /**
+ * Release a write lock on a lock type and key across the entire cluster.
+ *
+ * @param lockTypeKey The key of the map where the context item to lock is
+ * @param lockKey The key on the map to lock
+ * @throws ContextException on locking errors
+ */
+ void unlockForWriting(String lockTypeKey, String lockKey) throws ContextException;
+
+ /**
+ * Shut down the lock manager and clear any connections or data it is using.
+ */
+ void shutdown();
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java
new file mode 100644
index 000000000..d3218a34b
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/Persistor.java
@@ -0,0 +1,79 @@
+/*-
+ * ============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.context;
+
+import java.util.Set;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This interface is implemented by plugin classes that persist Context Albums in Apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface Persistor {
+
+ /**
+ * Initialize the persistor with its properties.
+ *
+ * @param key The key that identifies this persistor
+ * @throws ContextException On errors initializing the persistor
+ */
+ void init(AxArtifactKey key) throws ContextException;
+
+ /**
+ * Get the key of the persistor.
+ *
+ * @return the contextSetKey
+ */
+ AxArtifactKey getKey();
+
+ /**
+ * Read a context item from the persistence mechanism.
+ *
+ * @param key the key of the context item
+ * @param contextItemClassName the name of the context item class, a subclass of {@link AxContextSchema}
+ * @return the context item that has been read
+ * @throws ContextException on persistence read errors
+ */
+ AxContextSchema readContextItem(AxReferenceKey key, Class<?> contextItemClassName) throws ContextException;
+
+ /**
+ * Read all the values of a particular type from persistence.
+ *
+ * @param ownerKey the owner key
+ * @param contextItemClassName The class name of the objects to return
+ * @return the set of context item values read from persistence or null if none were found
+ * @throws ContextException On read errors
+ */
+ Set<AxContextSchema> readContextItems(AxArtifactKey ownerKey, Class<?> contextItemClassName)
+ throws ContextException;
+
+ /**
+ * Write a context item value to the persistence mechanism.
+ *
+ * @param contextItem the context item
+ * @return the context item that has been written
+ */
+ Object writeContextItem(Object contextItem);
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java
new file mode 100644
index 000000000..aa6ea9ffe
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/SchemaHelper.java
@@ -0,0 +1,119 @@
+/*-
+ * ============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.context;
+
+import com.google.gson.JsonElement;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This interface is implemented by plugin classes that use a particular schema to convert Apex context objects to an
+ * understandable form.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public interface SchemaHelper {
+
+ /**
+ * Initialize the schema helper with its properties.
+ *
+ * @param userKey The key that identifies the user of the schema helper
+ * @param schema the schema
+ * @throws ContextRuntimeException the context runtime exception
+ */
+ void init(AxKey userKey, AxContextSchema schema) throws ContextRuntimeException;
+
+ /**
+ * Get the user key of the schema helper.
+ *
+ * @return the user key
+ */
+ AxKey getUserKey();
+
+ /**
+ * Get the schema of the schema helper.
+ *
+ * @return the schema
+ */
+ AxContextSchema getSchema();
+
+ /**
+ * The Java class that this schema produces on the Java side.
+ *
+ * @return the schema class
+ */
+ Class<?> getSchemaClass();
+
+ /**
+ * The Java class that handles the schema for the schema technology in use.
+ *
+ * @return the schema object
+ */
+ Object getSchemaObject();
+
+ /**
+ * Create a new instance of the schema class using whatever schema technology is being used.
+ *
+ * @return the new instance
+ */
+ Object createNewInstance();
+
+ /**
+ * Create a new instance of the schema class using whatever schema technology is being used.
+ *
+ * @param stringValue the string represents the value the new instance should have
+ * @return the new instance
+ */
+ Object createNewInstance(String stringValue);
+
+ /**
+ * Create a new instance of the schema class from a GSON JsonElement using whatever schema technology is being used.
+ *
+ * @param jsonElement the JSON element that holds the Json representation of the object
+ * @return the new instance
+ */
+ Object createNewInstance(JsonElement jsonElement);
+
+ /**
+ * Unmarshal an object in schema format into a Java object.
+ *
+ * @param object the object as a Java object
+ * @return the object in schema format
+ */
+ Object unmarshal(Object object);
+
+ /**
+ * Marshal a Java object into Json format.
+ *
+ * @param schemaObject the object in schema format
+ * @return the object as a Json string
+ */
+ String marshal2Json(Object schemaObject);
+
+ /**
+ * Marshal a Java object into a GSON json element.
+ *
+ * @param schemaObject the object in schema format
+ * @return the object as a GSON Json element
+ */
+ JsonElement marshal2JsonElement(Object schemaObject);
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java
new file mode 100644
index 000000000..a68271609
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/ContextAlbumImpl.java
@@ -0,0 +1,486 @@
+/*-
+ * ============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.context.impl;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.onap.policy.apex.context.ContextAlbum;
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory;
+import org.onap.policy.apex.context.monitoring.ContextMonitor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ContextAlbumImpl implements the methods on the {@link ContextAlbum} interface. It implements the getters
+ * and setters on the {@link Map} and uses the {@link Distributor} to handle distribution and locking.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class ContextAlbumImpl implements ContextAlbum {
+ // Logger for this class
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ContextAlbumImpl.class);
+
+ // The definition of this context album
+ private final AxContextAlbum albumDefinition;
+
+ /// The map holding the items and their values for this context album
+ private final Map<String, Object> albumMap;
+
+ // The artifact stack of the artifacts currently using the context album
+ private AxConcept[] userArtifactStack = null;
+
+ // The context distributor we are using
+ private final Distributor distributor;
+
+ // The schema helper that handles translations of Java objects for this album
+ private SchemaHelper schemaHelper;
+
+ // The context monitor for this context album
+ private ContextMonitor monitor = null;
+
+ /**
+ * Constructor, instantiate the context album.
+ *
+ * @param albumDefinition The model definition of this context album
+ * @param distributor The context distributor passed to us to distribute context across ContextAlbum instances
+ * @param albumMap the album map
+ * @throws ContextException on errors creating context albums
+ */
+ public ContextAlbumImpl(final AxContextAlbum albumDefinition, final Distributor distributor,
+ final Map<String, Object> albumMap) throws ContextException {
+ this.albumDefinition = albumDefinition;
+
+ // Use the context distributor passed to us
+ this.distributor = distributor;
+
+ // The map to use to store objects
+ this.albumMap = albumMap;
+
+ try {
+ // Get a schema helper to manage the translations between objects on the album map for this album
+ schemaHelper = new SchemaHelperFactory().createSchemaHelper(albumDefinition.getKey(),
+ albumDefinition.getItemSchema());
+ } catch (final ContextRuntimeException e) {
+ final String resultString = "could not initiate schema management for context album " + albumDefinition;
+ LOGGER.warn(resultString, e);
+ throw new ContextException(resultString, e);
+ }
+
+ // Create the context monitor
+ monitor = new ContextMonitor();
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return albumDefinition.getKey();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#getName()
+ */
+ @Override
+ public String getName() {
+ return albumDefinition.getKey().getName();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#getAxContextAlbum()
+ */
+ @Override
+ public AxContextAlbum getAlbumDefinition() {
+ return albumDefinition;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#getSchemaHelper()
+ */
+ @Override
+ public SchemaHelper getSchemaHelper() {
+ return schemaHelper;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#lockForReading(java.lang.String)
+ */
+ @Override
+ public void lockForReading(final String keyOnAlbum) throws ContextException {
+ distributor.lockForReading(albumDefinition.getKey(), keyOnAlbum);
+ monitor.monitorReadLock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+ userArtifactStack);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#lockForWriting(java.lang.String)
+ */
+ @Override
+ public void lockForWriting(final String keyOnAlbum) throws ContextException {
+ distributor.lockForWriting(albumDefinition.getKey(), keyOnAlbum);
+ monitor.monitorWriteLock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+ userArtifactStack);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#unlockForReading(java.lang.String)
+ */
+ @Override
+ public void unlockForReading(final String keyOnAlbum) throws ContextException {
+ distributor.unlockForReading(albumDefinition.getKey(), keyOnAlbum);
+ monitor.monitorReadUnlock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+ userArtifactStack);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#unlockForWriting(java.lang.String)
+ */
+ @Override
+ public void unlockForWriting(final String keyOnAlbum) throws ContextException {
+ distributor.unlockForWriting(albumDefinition.getKey(), keyOnAlbum);
+ monitor.monitorWriteUnlock(albumDefinition.getKey(), albumDefinition.getItemSchema(), keyOnAlbum,
+ userArtifactStack);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.context.ContextAlbum#setUserArtifactStack(org.onap.policy.apex.model.basicmodel.concepts.
+ * AxConcept [])
+ */
+ @Override
+ public void setUserArtifactStack(final AxConcept[] userArtifactStack) {
+ this.userArtifactStack = userArtifactStack;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextAlbum#flush()
+ */
+ @Override
+ public void flush() throws ContextException {
+ distributor.flushContextAlbum(this);
+ }
+
+ /*
+ * The Map interface
+ */
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#size()
+ */
+ @Override
+ public int size() {
+ return albumMap.size();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#isEmpty()
+ */
+ @Override
+ public boolean isEmpty() {
+ return albumMap.isEmpty();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#containsKey(java.lang.Object)
+ */
+ @Override
+ public boolean containsKey(final Object key) {
+ if (key == null) {
+ LOGGER.warn("null values are illegal on method parameter \"key\"");
+ throw new ContextRuntimeException("null values are illegal on method parameter \"key\"");
+ }
+
+ return albumMap.containsKey(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#containsValue(java.lang.Object)
+ */
+ @Override
+ public boolean containsValue(final Object value) {
+ if (value == null) {
+ LOGGER.warn("null values are illegal on method parameter \"value\"");
+ throw new ContextRuntimeException("null values are illegal on method parameter \"value\"");
+ }
+
+ return albumMap.containsValue(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#get(java.lang.Object)
+ */
+ @Override
+ public Object get(final Object key) {
+ if (key == null) {
+ final String returnString =
+ "album \"" + albumDefinition.getID() + "\" null keys are illegal on keys for get()";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ final Object item = albumMap.get(key);
+ if (item == null) {
+ return null;
+ }
+
+ // Get the context value and monitor it
+ monitor.monitorGet(albumDefinition.getKey(), albumDefinition.getItemSchema(), key.toString(), item,
+ userArtifactStack);
+ return item;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#keySet()
+ */
+ @Override
+ public Set<String> keySet() {
+ return albumMap.keySet();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#values()
+ */
+ @Override
+ public Collection<Object> values() {
+ // Build the key set and return it
+ final ArrayList<Object> valueList = new ArrayList<>();
+
+ for (final Entry<String, Object> contextAlbumEntry : albumMap.entrySet()) {
+ final Object item = contextAlbumEntry.getValue();
+ monitor.monitorGet(albumDefinition.getKey(), albumDefinition.getItemSchema(), contextAlbumEntry.getKey(),
+ item, userArtifactStack);
+ valueList.add(contextAlbumEntry.getValue());
+ }
+
+ return valueList;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#entrySet()
+ */
+ @Override
+ public Set<Entry<String, Object>> entrySet() {
+ // Build the entry set and return it
+ final Set<Entry<String, Object>> entrySet = new HashSet<>();
+
+ for (final Entry<String, Object> contextAlbumEntry : albumMap.entrySet()) {
+ final Object item = contextAlbumEntry.getValue();
+ monitor.monitorGet(albumDefinition.getKey(), albumDefinition.getItemSchema(), contextAlbumEntry.getKey(),
+ item, userArtifactStack);
+ entrySet.add(new SimpleEntry<>(contextAlbumEntry.getKey(), contextAlbumEntry.getValue()));
+ }
+
+ return entrySet;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public Object put(final String key, final Object incomingValue) {
+ if (key == null) {
+ final String returnString =
+ "album \"" + albumDefinition.getID() + "\" null keys are illegal on keys for put()";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ if (incomingValue == null) {
+ final String returnString = "album \"" + albumDefinition.getID() + "\" null values are illegal on key \""
+ + key + "\" for put()";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ if (!albumDefinition.isWritable()) {
+ final String returnString = "album \"" + albumDefinition.getID()
+ + "\" put() not allowed on read only albums for key=\"" + key + "\", value=\"" + incomingValue;
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ try {
+ // Translate the object to a schema object
+ final Object valueToPut = schemaHelper.unmarshal(incomingValue);
+
+ // Check if the key is already in the map
+ if (albumMap.containsKey(key)) {
+ // Update the value in the context item and in the context value map
+ monitor.monitorSet(albumDefinition.getKey(), albumDefinition.getItemSchema(), key, incomingValue,
+ userArtifactStack);
+ } else {
+ // Update the value in the context item and in the context value map
+ monitor.monitorInit(albumDefinition.getKey(), albumDefinition.getItemSchema(), key, incomingValue,
+ userArtifactStack);
+ }
+
+ // Put the translated value on the map and return the old map value
+ return albumMap.put(key, valueToPut);
+ } catch (final ContextRuntimeException e) {
+ final String returnString = "Failed to set context value for key \"" + key + "\" in album \""
+ + albumDefinition.getID() + "\": " + e.getMessage();
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#putAll(java.util.Map)
+ */
+ @Override
+ public void putAll(final Map<? extends String, ? extends Object> incomingContextAlbum) {
+ if (!albumDefinition.isWritable()) {
+ final String returnString =
+ "album \"" + albumDefinition.getID() + "\" putAll() not allowed on read only albums";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ // Sanity check on incoming context
+ Assertions.argumentNotNull(incomingContextAlbum, ContextRuntimeException.class,
+ "cannot update context, context album is null");
+
+ // Iterate over the incoming context
+ for (final Entry<String, Object> entry : albumMap.entrySet()) {
+ synchronized (albumDefinition) {
+ // Get the key for the incoming name
+ final Object incomingDataItem = incomingContextAlbum.get(entry.getKey());
+ if (incomingDataItem != null) {
+ // Update the value the context album
+ put(entry.getKey(), incomingDataItem);
+ }
+ }
+ }
+
+ // Put all the objects on the context album
+ for (final Entry<? extends String, ? extends Object> incomingMapEntry : incomingContextAlbum.entrySet()) {
+ // Put the entry on the map
+ this.put(incomingMapEntry.getKey(), incomingMapEntry.getValue());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#remove(java.lang.Object)
+ */
+ @Override
+ public Object remove(final Object key) {
+ if (!albumDefinition.isWritable()) {
+ final String returnString = "album \"" + albumDefinition.getID()
+ + "\" remove() not allowed on read only albums for key=\"" + key;
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ if (key == null) {
+ LOGGER.warn("null values are illegal on method parameter \"key\"");
+ throw new ContextRuntimeException("null values are illegal on method parameter \"keyID\"");
+ }
+
+ // Delete the item
+ final Object removedValue = albumMap.remove(key);
+ monitor.monitorDelete(albumDefinition.getKey(), albumDefinition.getItemSchema(), key.toString(), removedValue,
+ userArtifactStack);
+
+ // Return the value of the deleted item
+ return removedValue;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Map#clear()
+ */
+ @Override
+ public void clear() {
+ if (!albumDefinition.isWritable()) {
+ final String returnString =
+ "album \"" + albumDefinition.getID() + "\" clear() not allowed on read only albums";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ // Monitor deletion of each item
+ for (final Entry<String, Object> contextAlbumEntry : albumMap.entrySet()) {
+ final Object item = contextAlbumEntry.getValue();
+ monitor.monitorDelete(albumDefinition.getKey(), albumDefinition.getItemSchema(), contextAlbumEntry.getKey(),
+ item, userArtifactStack);
+ }
+
+ // Clear the map
+ albumMap.clear();
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java
new file mode 100644
index 000000000..e5a45b203
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/AbstractDistributor.java
@@ -0,0 +1,326 @@
+/*-
+ * ============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.context.impl.distribution;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+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.LockManager;
+import org.onap.policy.apex.context.Persistor;
+import org.onap.policy.apex.context.impl.ContextAlbumImpl;
+import org.onap.policy.apex.context.impl.locking.LockManagerFactory;
+import org.onap.policy.apex.context.impl.persistence.PersistorFactory;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextModel;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This context distributor implements the mechanism-neutral parts of a context distributor.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AbstractDistributor implements Distributor {
+
+ // Logger for this class
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractDistributor.class);
+
+ // The key of this distributor
+ private AxArtifactKey key = null;
+
+ // The context albums for this context set indexed by their keys
+ private static Map<AxArtifactKey, ContextAlbum> albumMaps =
+ Collections.synchronizedMap(new HashMap<AxArtifactKey, ContextAlbum>());
+
+ // Lock manager for this distributor
+ private static LockManager lockManager = null;
+
+ // Hold a persistor for this distributor
+ private Persistor persistor = null;
+
+ // Hold a flush timer for this context distributor
+ private static DistributorFlushTimerTask flushTimer = null;
+
+ /**
+ * Create an instance of an abstract Context Distributor.
+ */
+ public AbstractDistributor() {
+ LOGGER.entry("AbstractContextDistributor()");
+ LOGGER.exit("AbstractContextDistributor()");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextDistributor#init(org.onap.policy.apex.model.basicmodel.concepts.
+ * AxArtifactKey)
+ */
+ @Override
+ public void init(final AxArtifactKey distributorKey) throws ContextException {
+ LOGGER.entry("init(" + distributorKey + ")");
+
+ // Record parameters and key
+ this.key = distributorKey;
+
+ // Create the lock manager if it doesn't already exist
+ if (lockManager == null) {
+ lockManager = new LockManagerFactory().createLockManager(key);
+ }
+
+ // Set up flushing on the context distributor if its not set up already
+ if (flushTimer == null) {
+ flushTimer = new DistributorFlushTimerTask(this);
+ }
+
+ // Create a new persistor for this key
+ persistor = new PersistorFactory().createPersistor(key);
+ LOGGER.exit("init(" + key + ")");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextDistributor#shutdown()
+ */
+ @Override
+ public abstract void shutdown();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.ContextDistributor#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /**
+ * Create a context album using whatever underlying mechanism we are using for albums.
+ *
+ * @param contextAlbumKey The key of the album
+ * @return The album as a string-object map
+ */
+ public abstract Map<String, Object> getContextAlbumMap(AxArtifactKey contextAlbumKey);
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.Distributor#registerModel(org.onap.policy.apex.model.contextmodel.concepts.
+ * AxContextModel)
+ */
+ @Override
+ public void registerModel(final AxContextModel contextModel) throws ContextException {
+ ModelService.registerModel(AxKeyInformation.class, contextModel.getKeyInformation());
+ ModelService.registerModel(AxContextSchemas.class, contextModel.getSchemas());
+ ModelService.registerModel(AxContextAlbums.class, contextModel.getAlbums());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.core.context.ContextDistributor#createContextAlbum(org.onap.policy.apex.core.basicmodel.
+ * concepts. AxArtifactKey)
+ */
+ @Override
+ public synchronized ContextAlbum createContextAlbum(final AxArtifactKey axContextAlbumKey) throws ContextException {
+ // Get the context album definition
+ final AxContextAlbum album = ModelService.getModel(AxContextAlbums.class).get(axContextAlbumKey);
+ if (album == null) {
+ final String resultString = "context album " + axContextAlbumKey.getID() + " does not exist";
+ LOGGER.warn(resultString);
+ throw new ContextException(resultString);
+ }
+
+ // Check if the context album is valid
+ final AxValidationResult result = album.validate(new AxValidationResult());
+ if (!result.isValid()) {
+ final String resultString =
+ "context album definition for " + album.getKey().getID() + " is invalid" + result;
+ LOGGER.warn(resultString);
+ throw new ContextException(resultString);
+ }
+
+ // Get the schema of the context album
+ final AxContextSchema schema = ModelService.getModel(AxContextSchemas.class).get(album.getItemSchema());
+ if (schema == null) {
+ final String resultString = "schema \"" + album.getItemSchema().getID() + "\" for context album "
+ + album.getKey().getID() + " does not exist";
+ LOGGER.warn(resultString);
+ throw new ContextException(resultString);
+ }
+
+ // Check if the map has already been instantiated
+ if (!albumMaps.containsKey(album.getKey())) {
+ // Instantiate the album map for this context album that we'll distribute using the distribution mechanism
+ final Map<String, Object> newContextAlbumMap = getContextAlbumMap(album.getKey());
+
+ // The distributed context album will have content from another process instance if the album exists in
+ // another process,
+ // if not, we have to try to read the content from persistence
+ if (newContextAlbumMap.isEmpty()) {
+ // Read entries from persistence
+ // TODO: READ ITEMS FROM PRESISTENCE!!!!
+ }
+
+ // Create the context album and put the context album object onto the distributor
+ albumMaps.put(album.getKey(), new ContextAlbumImpl(album, this, newContextAlbumMap));
+ }
+
+ return albumMaps.get(album.getKey());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.core.context.ContextDistributor#removeContextAlbum(org.onap.policy.apex.core.basicmodel.
+ * concepts. AxArtifactKey)
+ */
+ @Override
+ public void removeContextAlbum(final AxContextAlbum contextAlbum) throws ContextException {
+ // Check if the map already exists, if not return
+ if (!albumMaps.containsKey(contextAlbum.getKey())) {
+ LOGGER.warn("map remove failed, supplied map is null");
+ throw new ContextException("map update failed, supplied map is null");
+ }
+
+ // Remove the map from the distributor
+ albumMaps.remove(contextAlbum.getKey());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#flush()
+ */
+ @Override
+ public void flush() throws ContextException {
+ // Flush all the maps
+ for (final Entry<AxArtifactKey, ContextAlbum> distributorMapEntry : albumMaps.entrySet()) {
+ // Let the persistor write each of the entries
+ for (final Object contextItem : distributorMapEntry.getValue().values()) {
+ LOGGER.debug(contextItem.toString());
+ // persistor.writeContextItem((AxContextSchema) contextItem);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#flushContextAlbum(org.onap.policy.apex.core.context.
+ * ContextAlbum)
+ */
+ @Override
+ public void flushContextAlbum(final ContextAlbum contextAlbum) throws ContextException {
+ // Check if the map already exists, if not return
+ if (!albumMaps.containsKey(contextAlbum.getKey())) {
+ LOGGER.warn("map flush failed, supplied map is null");
+ throw new ContextException("map flush failed, supplied map is null");
+ }
+
+ // Let the persistor flush the items on the map
+ for (final Object contextItem : albumMaps.get(contextAlbum.getKey()).values()) {
+ persistor.writeContextItem(contextItem);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#lockForReading(java.lang.String)
+ */
+ @Override
+ public synchronized void lockForReading(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+ // Lock using the lock manager
+ lockManager.lockForReading(mapKey.getID(), itemKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#lockForWriting(java.lang.String)
+ */
+ @Override
+ public synchronized void lockForWriting(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+ // Lock using the lock manager
+ lockManager.lockForWriting(mapKey.getID(), itemKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#unlockForReading(java.lang.String)
+ */
+ @Override
+ public void unlockForReading(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+ // Unlock using the lock manager
+ lockManager.unlockForReading(mapKey.getID(), itemKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#unlockForWriting(java.lang.String)
+ */
+ @Override
+ public void unlockForWriting(final AxArtifactKey mapKey, final String itemKey) throws ContextException {
+ // Unlock using the lock manager
+ lockManager.unlockForWriting(mapKey.getID(), itemKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.ContextDistributor#clear()
+ */
+ @Override
+ public void clear() {
+ // Shut down the lock manager
+ if (lockManager != null) {
+ lockManager.shutdown();
+ lockManager = null;
+ }
+
+ albumMaps.clear();
+
+ // Turn off the flush timer
+ flushTimer.cancel();
+
+ // Shut down the specialization of the context distributor
+ shutdown();
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java
new file mode 100644
index 000000000..1af13cbea
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFactory.java
@@ -0,0 +1,86 @@
+/*-
+ * ============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.context.impl.distribution;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.parameters.DistributorParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a context distributor for the particular type of distribution mechanism configured for use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class DistributorFactory {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(DistributorFactory.class);
+
+ /**
+ * Get a context distributor for a given context set key.
+ *
+ * @param key The key for the distributor
+ * @return a context distributor
+ * @throws ContextException on context distributor creation errors
+ */
+ public Distributor getDistributor(final AxArtifactKey key) throws ContextException {
+ LOGGER.entry("Distributor factory, key=" + key);
+
+ Assertions.argumentNotNull(key, ContextException.class, "Parameter \"key\" may not be null");
+
+ // Get the class for the distributor using reflection
+ final DistributorParameters distributorParameters = ParameterService.getParameters(DistributorParameters.class);
+ final String pluginClass = distributorParameters.getPluginClass();
+ Object contextDistributorObject = null;
+ try {
+ contextDistributorObject = Class.forName(pluginClass).newInstance();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ LOGGER.error(
+ "Apex context distributor class not found for context distributor plugin \"" + pluginClass + "\"",
+ e);
+ throw new ContextException(
+ "Apex context distributor class not found for context distributor plugin \"" + pluginClass + "\"",
+ e);
+ }
+
+ // Check the class is a distributor
+ if (!(contextDistributorObject instanceof Distributor)) {
+ final String returnString = "Specified Apex context distributor plugin class \"" + pluginClass
+ + "\" does not implement the ContextDistributor interface";
+ LOGGER.error(returnString);
+ throw new ContextException(returnString);
+ }
+
+ // The context Distributor to return
+ final Distributor contextDistributor = (Distributor) contextDistributorObject;
+
+ // Lock and load the context distributor
+ contextDistributor.init(key);
+
+ LOGGER.exit(
+ "Distributor factory, key=" + key + ", selected distributor of class " + contextDistributor.getClass());
+ return contextDistributor;
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java
new file mode 100644
index 000000000..467d43f9d
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/DistributorFlushTimerTask.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.distribution;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Distributor;
+import org.onap.policy.apex.context.parameters.PersistorParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to periodically flush a context distributor.
+ *
+ * @author eeilfn
+ */
+public class DistributorFlushTimerTask extends TimerTask {
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(DistributorFlushTimerTask.class);
+
+ // The timer for flushing
+ private Timer timer = null;
+
+ // The context distributor to flush
+ private final Distributor contextDistributor;
+
+ // Timing information
+ private long period = 0;
+ private long flushCount = 0;
+
+ /**
+ * Constructor, save a reference to the event stream handler.
+ *
+ * @param contextDistributor the distributor that this timer task is flushing
+ * @throws ContextException On flush setup errors
+ */
+ public DistributorFlushTimerTask(final Distributor contextDistributor) throws ContextException {
+ // Save the context distributor and period
+ this.contextDistributor = contextDistributor;
+
+ // Set the period for persistence flushing
+ final PersistorParameters persistorParameters = ParameterService.getParameters(PersistorParameters.class);
+ period = persistorParameters.getFlushPeriod();
+
+ // Set up the timer
+ timer = new Timer(DistributorFlushTimerTask.class.getSimpleName(), true);
+ timer.schedule(this, period, period);
+
+ LOGGER.debug("context distributor " + contextDistributor.getKey().getID() + " flushing set up with interval: "
+ + period + "ms");
+ }
+
+ /**
+ * Flush the context distributor.
+ */
+ @Override
+ public void run() {
+ // Increment the flush counter
+ flushCount++;
+
+ LOGGER.debug("context distributor " + contextDistributor.getKey().getID() + " flushing: period=" + period
+ + ": count=" + flushCount);
+ try {
+ contextDistributor.flush();
+ LOGGER.debug("context distributor " + contextDistributor.getKey().getID() + " flushed: period=" + period
+ + ": count=" + flushCount);
+ } catch (final ContextException e) {
+ LOGGER.error("flush error on context distributor " + contextDistributor.getKey().getID() + ": period="
+ + period + ": count=" + flushCount, e);
+ }
+ }
+
+ /**
+ * Cancel the timer.
+ *
+ * @return true, if cancel
+ */
+ @Override
+ public boolean cancel() {
+ // Cancel the timer
+ if (timer != null) {
+ timer.cancel();
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "ContextDistributorFlushTimerTask [period=" + period + ", flushCount=" + flushCount + "]";
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java
new file mode 100644
index 000000000..dc6637227
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/JVMLocalDistributor.java
@@ -0,0 +1,70 @@
+/*-
+ * ============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.context.impl.distribution.jvmlocal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.policy.apex.context.impl.distribution.AbstractDistributor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This context distributor distributes context across threads in a single JVM. It holds context in memory in a map.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JVMLocalDistributor extends AbstractDistributor {
+ // Logger for this class
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(JVMLocalDistributor.class);
+
+ /**
+ * Create an instance of a JVM Local Context Distributor.
+ */
+ public JVMLocalDistributor() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.context.impl.distribution.AbstractDistributor#getContextAlbumMap(org.onap.policy.apex.model.
+ * basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public Map<String, Object> getContextAlbumMap(final AxArtifactKey contextMapKey) {
+ LOGGER.debug("create map: " + contextMapKey.getID());
+ return Collections.synchronizedMap(new HashMap<String, Object>());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.impl.distribution.AbstractDistributor#shutdown()
+ */
+ @Override
+ public void shutdown() {
+ // No specific shutdown for the JVMLocalContextDistributor
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/package-info.java
new file mode 100644
index 000000000..d96420034
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/jvmlocal/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=========================================================
+ */
+
+/**
+ * Provides the JVM local default context distribution mechanism for APEX.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.distribution.jvmlocal;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java
new file mode 100644
index 000000000..9b21eed51
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/distribution/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context album distribution that uses a distribution plugin to distribute items in APEX
+ * context albums. It also provides a default JVM local distribution plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.distribution;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java
new file mode 100644
index 000000000..4f197e2d3
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/AbstractLockManager.java
@@ -0,0 +1,225 @@
+/*-
+ * ============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.context.impl.locking;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.LockManager;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class implements the {@link LockManager} functionality that is common across all implementations. Lock managers
+ * for specific lock mechanisms specialize this class.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AbstractLockManager implements LockManager {
+ // Logger for this class
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractLockManager.class);
+
+ // The key of this lock manager
+ private AxArtifactKey key = null;
+
+ // Map of locks in use on this distributor for each context map
+ private final Map<String, Map<String, ReadWriteLock>> lockMaps =
+ Collections.synchronizedMap(new HashMap<String, Map<String, ReadWriteLock>>());
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.LockManager#init(org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public void init(final AxArtifactKey lockManagerKey) throws ContextException {
+ this.key = lockManagerKey;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.LockManager#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.LockManager#lockForReading(org.onap.policy.apex.core.model.concepts.
+ * AxArtifactKey, java.lang.String)
+ */
+ @Override
+ public synchronized void lockForReading(final String lockTypeKey, final String lockKey) throws ContextException {
+ LOGGER.entry("lockForReading(" + lockTypeKey + "_" + lockKey + ")");
+
+ // Find the lock or create a new one
+ final ReadWriteLock lock = getLock(lockTypeKey, lockKey, true);
+
+ try {
+ lock.readLock().lock();
+ LOGGER.exit("lockForReading(" + lockTypeKey + "_" + lockKey + ")");
+ } catch (final Exception e) {
+ LOGGER.warn("error acquiring read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ throw new ContextException(
+ "error acquiring read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.LockManager#lockForWriting(java.lang.String, java.lang.String)
+ */
+ @Override
+ public synchronized void lockForWriting(final String lockTypeKey, final String lockKey) throws ContextException {
+ LOGGER.entry("lockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+
+ // Find the lock or create a new one
+ final ReadWriteLock lock = getLock(lockTypeKey, lockKey, true);
+
+ try {
+ lock.writeLock().lock();
+ LOGGER.exit("lockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+ } catch (final Exception e) {
+ LOGGER.warn("error acquiring write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ throw new ContextException(
+ "error acquiring write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.LockManager#unlockForReading(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void unlockForReading(final String lockTypeKey, final String lockKey) throws ContextException {
+ LOGGER.entry("unlockForReading(" + lockTypeKey + "_" + lockKey + ")");
+
+ // Find the lock
+ final ReadWriteLock lock = getLock(lockTypeKey, lockKey, false);
+
+ try {
+ lock.readLock().unlock();
+ LOGGER.exit("unlockForReading(" + lockTypeKey + "_" + lockKey + ")");
+ } catch (final Exception e) {
+ LOGGER.warn("error releasing read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ throw new ContextException(
+ "error releasing read lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.LockManager#unlockForWriting(java.lang.String, java.lang.String)
+ */
+ @Override
+ public void unlockForWriting(final String lockTypeKey, final String lockKey) throws ContextException {
+ LOGGER.entry("unlockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+
+ // Find the lock
+ final ReadWriteLock lock = getLock(lockTypeKey, lockKey, false);
+
+ try {
+ lock.writeLock().unlock();
+ LOGGER.exit("unlockForWriting(" + lockTypeKey + "_" + lockKey + ")");
+ } catch (final Exception e) {
+ LOGGER.warn("error releasing write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ throw new ContextException(
+ "error releasing write lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.LockManager#shutdown()
+ */
+ @Override
+ public abstract void shutdown();
+
+ /**
+ * Get a reentrant read write lock from whatever locking mechanism is in use.
+ *
+ * @param lockId The unique ID of the lock.
+ * @return The lock
+ * @throws ContextException On errors getting a lock
+ */
+ protected abstract ReadWriteLock getReentrantReadWriteLock(String lockId) throws ContextException;
+
+ /**
+ * Get a lock for a context item in a context map.
+ *
+ * @param lockTypeKey The key of the map where the context item to lock is
+ * @param lockKey The key on the map to lock
+ * @param createMode if true, create a lock if it does not exist
+ * @return The lock
+ * @throws ContextException On errors getting the lock
+ */
+ private ReadWriteLock getLock(final String lockTypeKey, final String lockKey, final boolean createMode)
+ throws ContextException {
+ // Check if we have a lock type map for this lock type yet
+ if (!lockMaps.containsKey(lockTypeKey)) {
+ // Create a lock type map for the lock type
+ lockMaps.put(lockTypeKey, Collections.synchronizedMap(new HashMap<String, ReadWriteLock>()));
+ }
+
+ // Find or create a lock in the lock map
+ ReadWriteLock lock = lockMaps.get(lockTypeKey).get(lockKey);
+ if (lock != null) {
+ return lock;
+ }
+
+ // Should we create a lock?
+ if (!createMode) {
+ LOGGER.warn("error getting lock on context map " + lockTypeKey + " context item " + lockKey
+ + ", lock does not exist");
+ throw new ContextException("error getting lock on context map " + lockTypeKey + " context item " + lockKey
+ + ", lock does not exist");
+ }
+
+ try {
+ // Create the lock using the specialization of this abstract class
+ lock = getReentrantReadWriteLock(lockTypeKey + "_" + lockKey);
+
+ // Add the lock to the lock map
+ lockMaps.get(lockTypeKey).put(lockKey, lock);
+
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("created lock " + lockTypeKey + "_" + lockKey);
+ }
+ return lock;
+ } catch (final Exception e) {
+ LOGGER.warn("error getting lock on context map " + lockTypeKey + " context item " + lockKey, e);
+ throw new ContextException("error getting lock on context map " + lockTypeKey + " context item " + lockKey,
+ e);
+ }
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java
new file mode 100644
index 000000000..f3f4a6240
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/LockManagerFactory.java
@@ -0,0 +1,84 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.locking;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.LockManager;
+import org.onap.policy.apex.context.parameters.LockManagerParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a {@link LockManager} for the particular type of locking mechanism that has been configured for
+ * use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class LockManagerFactory {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(LockManagerFactory.class);
+
+ /**
+ * Return a {@link LockManager} for the particular type of locking mechanism configured for use.
+ *
+ * @param key The key for the lock manager
+ * @return a lock manager that can generate locks using some underlying mechanism
+ * @throws ContextException on errors in getting a lock manager
+ */
+ public LockManager createLockManager(final AxArtifactKey key) throws ContextException {
+ LOGGER.entry("Lock Manager factory, key=" + key);
+
+ final LockManagerParameters lockManagerParameters = ParameterService.getParameters(LockManagerParameters.class);
+
+ // Get the class for the lock manager using reflection
+ Object lockManagerObject = null;
+ final String pluginClass = lockManagerParameters.getPluginClass();
+ try {
+ lockManagerObject = Class.forName(pluginClass).newInstance();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ LOGGER.error(
+ "Apex context lock manager class not found for context lock manager plugin \"" + pluginClass + "\"",
+ e);
+ throw new ContextException(
+ "Apex context lock manager class not found for context lock manager plugin \"" + pluginClass + "\"",
+ e);
+ }
+
+ // Check the class is a lock manager
+ if (!(lockManagerObject instanceof LockManager)) {
+ LOGGER.error("Specified Apex context lock manager plugin class \"" + pluginClass
+ + "\" does not implement the LockManager interface");
+ throw new ContextException("Specified Apex context lock manager plugin class \"" + pluginClass
+ + "\" does not implement the LockManager interface");
+ }
+
+ // The context lock manager to return
+ final LockManager lockManager = (LockManager) lockManagerObject;
+
+ // Lock and load (OK sorry!!!) the lock manager
+ lockManager.init(key);
+
+ LOGGER.exit("Lock manager factory, key=" + key + ", selected lock manager of class " + lockManager.getClass());
+ return lockManager;
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java
new file mode 100644
index 000000000..5e71557b8
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/JVMLocalLockManager.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.locking.jvmlocal;
+
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.impl.locking.AbstractLockManager;
+
+/**
+ * A lock manager that returns locks that have a range of just the local JVM. The implementation uses a Jav
+ * {@link ReentrantReadWriteLock} as the lock for context album items.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JVMLocalLockManager extends AbstractLockManager {
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.core.context.impl.locking.AbstractLockManager#getReentrantReadWriteLock(java.lang.String)
+ */
+ @Override
+ public ReadWriteLock getReentrantReadWriteLock(final String lockId) throws ContextException {
+ return new ReentrantReadWriteLock();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.LockManager#shutdown()
+ */
+ @Override
+ public void shutdown() {
+ // Nothing to do for this lock manager
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/package-info.java
new file mode 100644
index 000000000..f1ac5cf19
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/jvmlocal/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=========================================================
+ */
+
+/**
+ * Provides the JVM local default context lock management mechanism for apex.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.locking.jvmlocal;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java
new file mode 100644
index 000000000..1a467275d
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/locking/package-info.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context album lock management that uses a lock management plugin to lock items items in
+ * Apex context albums. It also provides a default JVM local lock management plugin.
+ */
+
+package org.onap.policy.apex.context.impl.locking;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java
new file mode 100644
index 000000000..989827bd3
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of APEX context schemas and APEX context albums. It provides default implementations of
+ * context schema handling and context album distribution, locking, and persistence.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java
new file mode 100644
index 000000000..af6f922d3
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/PersistorFactory.java
@@ -0,0 +1,83 @@
+/*-
+ * ============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.context.impl.persistence;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Persistor;
+import org.onap.policy.apex.context.parameters.PersistorParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a persistor for the particular type of persistor mechanism that has been configured for use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PersistorFactory {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(PersistorFactory.class);
+
+ /**
+ * Return a persistor for the persistence mechanism configured for use.
+ *
+ * @param key The key for the persistor
+ * @return a persistor
+ * @throws ContextException on invalid persistor types
+ */
+ public Persistor createPersistor(final AxArtifactKey key) throws ContextException {
+ LOGGER.entry("persistor factory, key=" + key);
+ Assertions.argumentNotNull(key, ContextException.class, "Parameter \"key\" may not be null");
+
+ final PersistorParameters persistorParameters = ParameterService.getParameters(PersistorParameters.class);
+
+ // Get the class for the persistor using reflection
+ Object persistorObject = null;
+ final String pluginClass = persistorParameters.getPluginClass();
+ try {
+ persistorObject = Class.forName(pluginClass).newInstance();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ LOGGER.error("Apex context persistor class not found for context persistor plugin \"" + pluginClass + "\"",
+ e);
+ throw new ContextException(
+ "Apex context persistor class not found for context persistor plugin \"" + pluginClass + "\"", e);
+ }
+
+ // Check the class is a persistor
+ if (!(persistorObject instanceof Persistor)) {
+ LOGGER.error("Specified Apex context persistor plugin class \"" + pluginClass
+ + "\" does not implement the ContextDistributor interface");
+ throw new ContextException("Specified Apex context persistor plugin class \"" + pluginClass
+ + "\" does not implement the ContextDistributor interface");
+ }
+
+ // The persistor to return
+ final Persistor persistor = (Persistor) persistorObject;
+
+ // Lock and load the persistor
+ persistor.init(key);
+
+ LOGGER.exit("Persistor factory, key=" + key + ", selected persistor of class " + persistor.getClass());
+ return persistor;
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java
new file mode 100644
index 000000000..b875978be
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/EphemeralPersistor.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.impl.persistence.ephemeral;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.onap.policy.apex.context.ContextException;
+import org.onap.policy.apex.context.Persistor;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+
+/**
+ * This class acts as an "in memory" persistor for a single JVM. It just initiates stubs the Persistor interface and
+ * does not persist anything.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class EphemeralPersistor implements Persistor {
+
+ // The key of this persistor
+ private AxArtifactKey key;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.Persistor#init(org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public void init(final AxArtifactKey persistorKey) throws ContextException {
+ this.key = persistorKey;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.Persistor#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.Persistor#readContextItem(org.onap.policy.apex.core.basicmodel.concepts.
+ * AxReferenceKey, java.lang.Class)
+ */
+ @Override
+ public AxContextSchema readContextItem(final AxReferenceKey itemKey, final Class<?> contextItemClass) {
+ // Can't read from this persistor as nothing is persisted
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.core.context.Persistor#readContextItems(org.onap.policy.apex.core.basicmodel.concepts.
+ * AxArtifactKey, java.lang.Class)
+ */
+ @Override
+ public Set<AxContextSchema> readContextItems(final AxArtifactKey ownerKey, final Class<?> contextItemClass)
+ throws ContextException {
+ // No reading from persistence on the Ephemeral persistor, return an empty set
+ return new TreeSet<>();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.onap.policy.apex.core.context.Persistor#writeContextItem(org.onap.policy.apex.core.contextmodel.concepts.
+ * AxContextItem)
+ */
+ @Override
+ public Object writeContextItem(final Object contextItem) {
+ // No writing to persistence on the Ephemeral persistor
+ return contextItem;
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java
new file mode 100644
index 000000000..2d31d21bd
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/ephemeral/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides the JVM local default context persistence mechanism for APEX, which is in fact a dummy persistor that just
+ * stubs the Persistor interface and does not persist anything.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.persistence.ephemeral;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java
new file mode 100644
index 000000000..d450dd80c
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/persistence/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides an implementation of context album persistence that uses a persistence plugin to lock items items in APEX
+ * context albums. It also provides a default JVM local persistence plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.persistence;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java
new file mode 100644
index 000000000..83d1b6ba5
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/AbstractSchemaHelper.java
@@ -0,0 +1,169 @@
+/*-
+ * ============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.context.impl.schema;
+
+import java.lang.reflect.Constructor;
+
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class implements the {@link SchemaHelper} functionality that is common across all implementations. Schema
+ * helpers for specific schema mechanisms specialize this class.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public abstract class AbstractSchemaHelper implements SchemaHelper {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(AbstractSchemaHelper.class);
+
+ // The key of the user of this schema helper
+ private AxKey userKey = null;
+
+ // The schema of this schema helper
+ private AxContextSchema schema = null;
+
+ // The class of objects for this schema
+ private Class<?> schemaClass;
+
+ /**
+ * Sets the schema class for the schema, designed jots to be called by sub classes.
+ *
+ * @param schemaClass the Java class that is used to hold items of this schema
+ */
+ protected void setSchemaClass(final Class<?> schemaClass) {
+ this.schemaClass = schemaClass;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#init(org.onap.policy.apex.model.basicmodel.concepts.AxKey,
+ * org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema)
+ */
+ @Override
+ public void init(final AxKey incomingUserKey, final AxContextSchema incomingSchema) throws ContextRuntimeException {
+ Assertions.argumentNotNull(incomingUserKey, ContextRuntimeException.class, "incomingUserKey may not be null");
+ Assertions.argumentNotNull(incomingSchema, ContextRuntimeException.class, "incomingSchema may not be null");
+
+ this.userKey = incomingUserKey;
+ this.schema = incomingSchema;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#getKey()
+ */
+ @Override
+ public AxKey getUserKey() {
+ return userKey;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#getSchema()
+ */
+ @Override
+ public AxContextSchema getSchema() {
+ return schema;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#getSchemaClass()
+ */
+ @Override
+ public Class<?> getSchemaClass() {
+ return schemaClass;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#getSchemaObject()
+ */
+ @Override
+ public Object getSchemaObject() {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#createNewInstance()
+ */
+ @Override
+ public Object createNewInstance() {
+ if (schemaClass == null) {
+ final String returnString =
+ userKey.getID() + ": could not create an instance, schema class for the schema is null";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ try {
+ return schemaClass.newInstance();
+ } catch (final Exception e) {
+ final String returnString =
+ userKey.getID() + ": could not create an instance of class \"" + schemaClass.getCanonicalName()
+ + "\" using the default constructor \"" + schemaClass.getSimpleName() + "()\"";
+ LOGGER.warn(returnString, e);
+ throw new ContextRuntimeException(returnString, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#createNewInstance(java.lang.String)
+ */
+ @Override
+ public Object createNewInstance(final String stringValue) {
+ if (schemaClass == null) {
+ final String returnString =
+ userKey.getID() + ": could not create an instance, schema class for the schema is null";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+
+ try {
+ // Find a string constructor
+ final Constructor<?> stringConstructor = schemaClass.getConstructor(String.class);
+
+ // Invoke the constructor
+ return stringConstructor.newInstance(stringValue);
+ } catch (final Exception e) {
+ final String returnString =
+ userKey.getID() + ": could not create an instance of class \"" + schemaClass.getCanonicalName()
+ + "\" using the string constructor \"" + schemaClass.getSimpleName() + "(String)\"";
+ LOGGER.warn(returnString, e);
+ throw new ContextRuntimeException(returnString);
+ }
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java
new file mode 100644
index 000000000..7252d3772
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/SchemaHelperFactory.java
@@ -0,0 +1,119 @@
+/*-
+ * ============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.context.impl.schema;
+
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.SchemaHelper;
+import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
+import org.onap.policy.apex.context.parameters.SchemaParameters;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class returns a {@link SchemaHelper} for the particular type of schema mechanism configured for use.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SchemaHelperFactory {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(SchemaHelperFactory.class);
+
+ /**
+ * Return a {@link SchemaHelper} for the particular type of schema mechanism configured for use.
+ *
+ * @param owningEntityKey The key of the entity that owns the schema helper
+ * @param schemaKey The key of the schema the schema helper is operating on
+ * @return a lock schema that can handle translation of objects in a particular schema format
+ * @throws ContextRuntimeException the context runtime exception
+ */
+ public SchemaHelper createSchemaHelper(final AxKey owningEntityKey, final AxArtifactKey schemaKey)
+ throws ContextRuntimeException {
+ LOGGER.entry("schema helper factory, owningEntityKey=" + owningEntityKey);
+ Assertions.argumentNotNull(owningEntityKey, ContextRuntimeException.class,
+ "Parameter \"owningEntityKey\" may not be null");
+ Assertions.argumentNotNull(schemaKey, ContextRuntimeException.class, "Parameter \"schemaKey\" may not be null");
+
+ // Get the schema for items in the album
+ final AxContextSchema schema = ModelService.getModel(AxContextSchemas.class).get(schemaKey);
+ if (schema == null) {
+ final String resultString =
+ "schema \"" + schemaKey.getID() + "\" for entity " + owningEntityKey.getID() + " does not exist";
+ LOGGER.warn(resultString);
+ throw new ContextRuntimeException(resultString);
+ }
+
+ // Get the schema class using the parameter service
+ final SchemaParameters schemaParameters = ParameterService.getParameters(SchemaParameters.class);
+ if (schemaParameters == null) {
+ final String resultString = "context schema parameters \"" + SchemaParameters.class.getCanonicalName()
+ + "\" not found in parameter service";
+ LOGGER.warn(resultString);
+ throw new ContextRuntimeException(resultString);
+ }
+
+ // Get the class for the schema helper from the schema parameters
+ final SchemaHelperParameters schemaHelperParameters =
+ schemaParameters.getSchemaHelperParameters(schema.getSchemaFlavour());
+ if (schemaHelperParameters == null) {
+ final String resultString = "context schema helper parameters not found for context schema \""
+ + schema.getSchemaFlavour() + "\"";
+ LOGGER.warn(resultString);
+ throw new ContextRuntimeException(resultString);
+ }
+
+ // Get the class for the schema helper using reflection
+ Object schemaHelperObject = null;
+ final String pluginClass = schemaHelperParameters.getSchemaHelperPluginClass();
+ try {
+ schemaHelperObject = Class.forName(pluginClass).newInstance();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ final String resultString = "Apex context schema helper class not found for context schema helper plugin \""
+ + pluginClass + "\"";
+ LOGGER.warn(resultString, e);
+ throw new ContextRuntimeException(resultString, e);
+ }
+
+ // Check the class is a schema helper
+ if (!(schemaHelperObject instanceof SchemaHelper)) {
+ final String resultString = "Specified Apex context schema helper plugin class \"" + pluginClass
+ + "\" does not implement the SchemaHelper interface";
+ LOGGER.warn(resultString);
+ throw new ContextRuntimeException(resultString);
+ }
+
+ // The context schema helper to return
+ final SchemaHelper schemaHelper = (SchemaHelper) schemaHelperObject;
+
+ // Lock and load the schema helper
+ schemaHelper.init(owningEntityKey.getKey(), schema);
+
+ LOGGER.exit("Schema Helper factory, owningEntityKey=" + owningEntityKey + ", selected schema helper of class "
+ + schemaHelper.getClass());
+ return schemaHelper;
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java
new file mode 100644
index 000000000..b89efbf91
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelper.java
@@ -0,0 +1,214 @@
+/*-
+ * ============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.context.impl.schema.java;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.policy.apex.context.ContextRuntimeException;
+import org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper;
+import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
+import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.policy.apex.model.utilities.typeutils.TypeBuilder;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class implements translation to and from Apex distributed objects and Java objects when a Java schema is used.
+ * It creates schema items as Java objects and marshals and unmarshals these objects in various formats. All objects
+ * must be of the type of Java class defined in the schema.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JavaSchemaHelper extends AbstractSchemaHelper {
+ // Get a reference to the logger
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(JavaSchemaHelper.class);
+
+ // This map defines the built in types in types in Java
+ // @formatter:off
+ private static final Map<String, Class<?>> BUILT_IN_MAP = new HashMap<>();
+ {
+ BUILT_IN_MAP.put("int", Integer .TYPE);
+ BUILT_IN_MAP.put("long", Long .TYPE);
+ BUILT_IN_MAP.put("double", Double .TYPE);
+ BUILT_IN_MAP.put("float", Float .TYPE);
+ BUILT_IN_MAP.put("bool", Boolean .TYPE);
+ BUILT_IN_MAP.put("char", Character.TYPE);
+ BUILT_IN_MAP.put("byte", Byte .TYPE);
+ BUILT_IN_MAP.put("void", Void .TYPE);
+ BUILT_IN_MAP.put("short", Short .TYPE);
+ }
+ // @formatter:on
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper#init(org.onap.policy.apex.model.basicmodel.
+ * concepts. AxKey, org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema)
+ */
+ @Override
+ public void init(final AxKey userKey, final AxContextSchema schema) throws ContextRuntimeException {
+ super.init(userKey, schema);
+
+ final String javatype = schema.getSchema();
+ // For Java, the schema is the Java class canonical path
+
+ try {
+ setSchemaClass(TypeBuilder.getJavaTypeClass(schema.getSchema()));
+ } catch (final IllegalArgumentException e) {
+
+ String resultSting = userKey.getID() + ": class/type " + schema.getSchema() + " for context schema \""
+ + schema.getID() + "\" not found.";
+ if (JavaSchemaHelper.BUILT_IN_MAP.get(javatype) != null) {
+ resultSting += " Primitive types are not supported. Use the appropriate Java boxing type instead.";
+ } else {
+ resultSting += " Check the class path of the JVM";
+ }
+ LOGGER.warn(resultSting);
+ throw new ContextRuntimeException(resultSting, e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#createNewInstance(com.google.gson.JsonElement)
+ */
+ @Override
+ public Object createNewInstance(final JsonElement jsonElement) {
+ final String elementJsonString = new Gson().toJson(jsonElement);
+
+ return new Gson().fromJson(elementJsonString, this.getSchemaClass());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#object2SchemaObject(java.lang.Object)
+ */
+ @Override
+ public Object unmarshal(final Object object) {
+ if (object == null) {
+ return null;
+ }
+
+ // If the object is an instance of the incoming object, carry on
+ if (object.getClass().equals(getSchemaClass())) {
+ return object;
+ }
+
+ // For numeric types, do a numeric conversion
+ if (Number.class.isAssignableFrom(getSchemaClass())) {
+ return numericConversion(object);
+ }
+
+ if (getSchemaClass().isAssignableFrom(object.getClass())) {
+ return object;
+ } else {
+ return stringConversion(object);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#schemaObject2Json(java.lang.Object)
+ */
+ @Override
+ public String marshal2Json(final Object schemaObject) {
+ if (schemaObject == null) {
+ return "null";
+ }
+
+ // Check the incoming object is of a correct class
+ if (getSchemaClass().isAssignableFrom(schemaObject.getClass())) {
+ // Use Gson to translate the object
+ return new Gson().toJson(schemaObject);
+ } else {
+ final String returnString = getUserKey().getID() + ": object \"" + schemaObject.toString()
+ + "\" of class \"" + schemaObject.getClass().getCanonicalName() + "\" not compatible with class \""
+ + getSchemaClass().getCanonicalName() + "\"";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.context.SchemaHelper#marshal2JsonElement(java.lang.Object)
+ */
+ @Override
+ public JsonElement marshal2JsonElement(final Object schemaObject) {
+ // Use Gson to marshal the schema object into a Json element to return
+ return new Gson().toJsonTree(schemaObject, getSchemaClass());
+ }
+
+ /**
+ * Do a numeric conversion between numeric types.
+ *
+ * @param object The incoming numeric object
+ * @return The converted object
+ */
+ private Object numericConversion(final Object object) {
+ // Check if the incoming object is a number, if not do a string conversion
+ if (object instanceof Number) {
+ if (getSchemaClass().isAssignableFrom(Byte.class)) {
+ return ((Number) object).byteValue();
+ } else if (getSchemaClass().isAssignableFrom(Integer.class)) {
+ return ((Number) object).intValue();
+ } else if (getSchemaClass().isAssignableFrom(Long.class)) {
+ return ((Number) object).longValue();
+ } else if (getSchemaClass().isAssignableFrom(Float.class)) {
+ return ((Number) object).floatValue();
+ } else if (getSchemaClass().isAssignableFrom(Double.class)) {
+ return ((Number) object).doubleValue();
+ }
+ }
+
+ // OK, we'll try and convert from a string representation of the incoming object
+ return stringConversion(object);
+ }
+
+ /**
+ * Do a string conversion to the class type.
+ *
+ * @param object The incoming numeric object
+ * @return The converted object
+ */
+ private Object stringConversion(final Object object) {
+ // OK, we'll try and convert from a string representation of the incoming object
+ try {
+ final Constructor<?> stringConstructor = getSchemaClass().getConstructor(String.class);
+ return stringConstructor.newInstance(object.toString());
+ } catch (final Exception e) {
+ final String returnString = getUserKey().getID() + ": object \"" + object.toString() + "\" of class \""
+ + object.getClass().getCanonicalName() + "\" not compatible with class \""
+ + getSchemaClass().getCanonicalName() + "\"";
+ LOGGER.warn(returnString);
+ throw new ContextRuntimeException(returnString);
+ }
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java
new file mode 100644
index 000000000..18339d8db
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/JavaSchemaHelperParameters.java
@@ -0,0 +1,38 @@
+/*-
+ * ============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.context.impl.schema.java;
+
+import org.onap.policy.apex.context.parameters.SchemaHelperParameters;
+
+/**
+ * The Schema helper parameter class for the Java schema helper is an empty parameter class that acts as a placeholder.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class JavaSchemaHelperParameters extends SchemaHelperParameters {
+
+ /**
+ * The Constructor.
+ */
+ public JavaSchemaHelperParameters() {
+ this.setSchemaHelperPluginClass(JavaSchemaHelper.class.getCanonicalName());
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/package-info.java
new file mode 100644
index 000000000..052981379
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/java/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=========================================================
+ */
+
+/**
+ * Provides the Java schema helper for APEX, which manages context items that are Java objects.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.schema.java;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java
new file mode 100644
index 000000000..458a86afe
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/impl/schema/package-info.java
@@ -0,0 +1,29 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * Provides an implementation of context schema handling that uses a schema helper plugin to manage schemas and to
+ * create, marshal, and unmarshal context items in various formats for APEX context. It also provides a default java
+ * schema handler plugin.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.impl.schema;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java
new file mode 100644
index 000000000..8e34ecb1b
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/ContextMonitor.java
@@ -0,0 +1,210 @@
+/*-
+ * ============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.context.monitoring;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to monitor context creates, deletes, gets, sets, locks and unlocks on context items in Apex
+ * context albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextMonitor {
+ // Logger for this class
+ private static final XLogger LOGGER = XLoggerFactory.getXLogger(ContextMonitor.class);
+
+ /**
+ * Monitor an initiation on a context item.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param value The value of the item
+ */
+ public void monitorInit(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final Object value) {
+ LOGGER.trace(monitor("INIT", null, albumKey, schemaKey, name, value));
+ }
+
+ /**
+ * Monitor an initiation on a context item.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param value The value of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorInit(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final Object value, final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("INIT", userArtifactStack, albumKey, schemaKey, name, value));
+ }
+
+ /**
+ * Monitor a deletion on a context item.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param value The value of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorDelete(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final Object value, final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("DEL", userArtifactStack, albumKey, schemaKey, name, value));
+ }
+
+ /**
+ * Monitor get on a context item.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param value The value of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorGet(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final Object value, final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("GET", userArtifactStack, albumKey, schemaKey, name, value));
+ }
+
+ /**
+ * Monitor set on a context item.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param value The value of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorSet(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final Object value, final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("SET", userArtifactStack, albumKey, schemaKey, name, value));
+ }
+
+ /**
+ * Monitor a read lock on a key.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorReadLock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("READLOCK", userArtifactStack, albumKey, schemaKey, name, null));
+ }
+
+ /**
+ * Monitor a write lock on a key.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorWriteLock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("WRITELOCK", userArtifactStack, albumKey, schemaKey, name, null));
+ }
+
+ /**
+ * Monitor a read unlock on a key.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorReadUnlock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("READUNLOCK", userArtifactStack, albumKey, schemaKey, name, null));
+ }
+
+ /**
+ * Monitor a write unlock on a key.
+ *
+ * @param albumKey The item album
+ * @param schemaKey The item schema
+ * @param name The name of the item
+ * @param userArtifactStack the keys of the artifacts using the context map at the moment
+ */
+ public void monitorWriteUnlock(final AxArtifactKey albumKey, final AxArtifactKey schemaKey, final String name,
+ final AxConcept[] userArtifactStack) {
+ LOGGER.trace(monitor("WRITEUNLOCK", userArtifactStack, albumKey, schemaKey, name, null));
+ }
+
+ /**
+ * Monitor the user artifact stack.
+ *
+ * @param preamble the preamble
+ * @param userArtifactStack The user stack to print
+ * @param albumKey the album key
+ * @param schemaKey the schema key
+ * @param name the name
+ * @param value the value
+ * @return the string
+ */
+ private String monitor(final String preamble, final AxConcept[] userArtifactStack, final AxArtifactKey albumKey,
+ final AxArtifactKey schemaKey, final String name, final Object value) {
+ final StringBuilder builder = new StringBuilder();
+
+ builder.append(preamble);
+ builder.append(",[");
+
+ if (userArtifactStack != null) {
+ boolean first = true;
+ for (final AxConcept stackKey : userArtifactStack) {
+ if (first) {
+ first = false;
+ } else {
+ builder.append(',');
+ }
+ if (stackKey instanceof AxArtifactKey) {
+ builder.append(((AxArtifactKey) stackKey).getID());
+ } else if (stackKey instanceof AxReferenceKey) {
+ builder.append(((AxReferenceKey) stackKey).getID());
+ } else {
+ builder.append(stackKey.toString());
+ }
+ }
+ }
+ builder.append("],");
+
+ builder.append(albumKey.getID());
+ builder.append(',');
+ builder.append(schemaKey.getID());
+ builder.append(',');
+ builder.append(name);
+
+ if (value != null) {
+ builder.append(',');
+ builder.append(value.toString());
+ }
+
+ return builder.toString();
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/package-info.java
new file mode 100644
index 000000000..2f8ac8281
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/monitoring/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=========================================================
+ */
+
+/**
+ * Monitors all creation, deletion, get, set, lock, and unlock operations on items in APEX context albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.monitoring;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java
new file mode 100644
index 000000000..8707ae36b
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/package-info.java
@@ -0,0 +1,29 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * Provides the context handling for APEX. It provides the infrastructure and generic implementation for context schemas
+ * and context albums. Schema handlers and context album handlers are implemented as plugins that implement interfaces
+ * defined in this package.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context;
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java
new file mode 100644
index 000000000..e50cc60b4
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/ContextParameters.java
@@ -0,0 +1,146 @@
+/*-
+ * ============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.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * Bean class to hold parameters for context handling in Apex. This class contains all the context parameters for schema
+ * handling, distribution, locking, and persistence of context albums.
+ * <p>
+ * The following parameters are defined:
+ * <ol>
+ * <li>flushPeriod: Context is flushed to any persistor plugin that is defined periodically, and the period for flushing
+ * is the flush period.
+ * <li>distributorParameters: The parameters (a {@link distributorParameters} instance) for the distributor plugin that
+ * is being used for context album distribution
+ * <li>schemaParameters: The parameters (a {@link SchemaParameters} instance) for the schema plugin that is being used
+ * for context album schemas
+ * <li>lockManagerParameters: The parameters (a {@link LockManagerParameters} instance) for the locking mechanism plugin
+ * that is being used for context album locking
+ * <li>persistorParameters: The parameters (a {@link PersistorParameters} instance) for the persistence plugin that is
+ * being used for context album persistence
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextParameters extends AbstractParameters {
+ // @formatter:off
+ // Plugin Parameters
+ private DistributorParameters distributorParameters = new DistributorParameters();
+ private SchemaParameters schemaParameters = new SchemaParameters();
+ private LockManagerParameters lockManagerParameters = new LockManagerParameters();
+ private PersistorParameters persistorParameters = new PersistorParameters();
+ // @formatter:on
+
+ /**
+ * Constructor to create a context parameters instance and register the instance with the parameter service.
+ */
+ public ContextParameters() {
+ super(ContextParameters.class.getCanonicalName());
+ ParameterService.registerParameters(ContextParameters.class, this);
+ }
+
+ /**
+ * Gets the distributor parameters.
+ *
+ * @return the distributor parameters
+ */
+ public DistributorParameters getDistributorParameters() {
+ return distributorParameters;
+ }
+
+ /**
+ * Sets the distributor parameters.
+ *
+ * @param distributorParameters the distributor parameters
+ */
+ public void setDistributorParameters(final DistributorParameters distributorParameters) {
+ this.distributorParameters = distributorParameters;
+ }
+
+ /**
+ * Gets the schema parameters.
+ *
+ * @return the schema parameters
+ */
+ public SchemaParameters getSchemaParameters() {
+ return schemaParameters;
+ }
+
+ /**
+ * Sets the schema parameters.
+ *
+ * @param schemaParameters the schema parameters
+ */
+ public void setSchemaParameters(final SchemaParameters schemaParameters) {
+ this.schemaParameters = schemaParameters;
+ }
+
+ /**
+ * Gets the lock manager parameters.
+ *
+ * @return the lock manager parameters
+ */
+ public LockManagerParameters getLockManagerParameters() {
+ return lockManagerParameters;
+ }
+
+ /**
+ * Sets the lock manager parameters.
+ *
+ * @param lockManagerParameters the lock manager parameters
+ */
+ public void setLockManagerParameters(final LockManagerParameters lockManagerParameters) {
+ this.lockManagerParameters = lockManagerParameters;
+ }
+
+ /**
+ * Gets the persistor parameters.
+ *
+ * @return the persistor parameters
+ */
+ public PersistorParameters getPersistorParameters() {
+ return persistorParameters;
+ }
+
+ /**
+ * Sets the persistor parameters.
+ *
+ * @param persistorParameters the persistor parameters
+ */
+ public void setPersistorParameters(final PersistorParameters persistorParameters) {
+ this.persistorParameters = persistorParameters;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+ */
+ @Override
+ public String toString() {
+ return "ContextParameters [distributorParameters=" + distributorParameters + ", schemaParameters="
+ + schemaParameters + ", lockManagerParameters=" + lockManagerParameters + ", persistorParameters="
+ + persistorParameters + "]";
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java
new file mode 100644
index 000000000..147e4eb35
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/DistributorParameters.java
@@ -0,0 +1,85 @@
+/*-
+ * ============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.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * An empty distributor parameter class that may be specialized by context distributor plugins that require plugin
+ * specific parameters. The class defines the default distributor plugin as the JVM local distributor.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class DistributorParameters extends AbstractParameters {
+ /** The default distributor makes context albums available to all threads in a single JVM. */
+ public static final String DEFAULT_DISTRIBUTOR_PLUGIN_CLASS =
+ "org.onap.policy.apex.context.impl.distribution.jvmlocal.JVMLocalDistributor";
+
+ // Plugin class names
+ private String pluginClass = DEFAULT_DISTRIBUTOR_PLUGIN_CLASS;
+
+ /**
+ * Constructor to create a distributor parameters instance and register the instance with the parameter service.
+ */
+ public DistributorParameters() {
+ super(DistributorParameters.class.getCanonicalName());
+ ParameterService.registerParameters(DistributorParameters.class, this);
+ }
+
+ /**
+ * Constructor to create a distributor parameters instance with the name of a sub class of this class and register
+ * the instance with the parameter service.
+ *
+ * @param parameterClassName the class name of a sub class of this class
+ */
+ public DistributorParameters(final String parameterClassName) {
+ super(parameterClassName);
+ }
+
+ /**
+ * Gets the plugin class.
+ *
+ * @return the plugin class
+ */
+ public String getPluginClass() {
+ return pluginClass;
+ }
+
+ /**
+ * Sets the plugin class.
+ *
+ * @param pluginClass the plugin class
+ */
+ public void setPluginClass(final String pluginClass) {
+ this.pluginClass = pluginClass;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+ */
+ @Override
+ public String toString() {
+ return "DistributorParameters [pluginClass=" + pluginClass + "]";
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java
new file mode 100644
index 000000000..93e422357
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/LockManagerParameters.java
@@ -0,0 +1,85 @@
+/*-
+ * ============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.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * An empty lock manager parameter class that may be specialized by context lock manager plugins that require plugin
+ * specific parameters. The class defines the default lock manager plugin as the JVM local lock manager.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class LockManagerParameters extends AbstractParameters {
+ /** The default lock manager can lock context album instance across all threads in a single JVM. */
+ public static final String DEFAULT_LOCK_MANAGER_PLUGIN_CLASS =
+ "org.onap.policy.apex.context.impl.locking.jvmlocal.JVMLocalLockManager";
+
+ // Plugin class names
+ private String pluginClass = DEFAULT_LOCK_MANAGER_PLUGIN_CLASS;
+
+ /**
+ * Constructor to create a lock manager parameters instance and register the instance with the parameter service.
+ */
+ public LockManagerParameters() {
+ super(LockManagerParameters.class.getCanonicalName());
+ ParameterService.registerParameters(LockManagerParameters.class, this);
+ }
+
+ /**
+ * Constructor to create a lock manager parameters instance with the name of a sub class of this class and register
+ * the instance with the parameter service.
+ *
+ * @param parameterClassName the class name of a sub class of this class
+ */
+ public LockManagerParameters(final String parameterClassName) {
+ super(parameterClassName);
+ }
+
+ /**
+ * Gets the plugin class.
+ *
+ * @return the plugin class
+ */
+ public String getPluginClass() {
+ return pluginClass;
+ }
+
+ /**
+ * Sets the plugin class.
+ *
+ * @param pluginClass the plugin class
+ */
+ public void setPluginClass(final String pluginClass) {
+ this.pluginClass = pluginClass;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+ */
+ @Override
+ public String toString() {
+ return "LockManagerParameters [pluginClass=" + pluginClass + "]";
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java
new file mode 100644
index 000000000..c9b0d85f8
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/PersistorParameters.java
@@ -0,0 +1,120 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * A persistor parameter class that may be specialized by context persistor plugins that require plugin specific
+ * parameters.
+ * <p>
+ * The following parameters are defined:
+ * <ol>
+ * <li>pluginClass: the persistor plugin as the JVM local dummy ephemeral persistor
+ * <li>flushPeriod: Context is flushed to any persistor plugin that is defined periodically, and the period for flushing
+ * is the flush period.
+ * </ol>
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class PersistorParameters extends AbstractParameters {
+ /** The default persistor is a dummy persistor that stubs the Persistor interface. */
+ public static final String DEFAULT_PERSISTOR_PLUGIN_CLASS =
+ "org.onap.policy.apex.context.impl.persistence.ephemeral.EphemeralPersistor";
+
+ /** Default periodic flushing interval, 5 minutes in milliseconds. */
+ public static final long DEFAULT_FLUSH_PERIOD = 300000;
+
+ // Plugin class names
+ private String pluginClass = DEFAULT_PERSISTOR_PLUGIN_CLASS;
+
+ // Parameters for flushing
+ private long flushPeriod = DEFAULT_FLUSH_PERIOD;
+
+ /**
+ * Constructor to create a persistor parameters instance and register the instance with the parameter service.
+ */
+ public PersistorParameters() {
+ super(PersistorParameters.class.getCanonicalName());
+ ParameterService.registerParameters(PersistorParameters.class, this);
+ }
+
+ /**
+ * Constructor to create a persistor parameters instance with the name of a sub class of this class and register the
+ * instance with the parameter service.
+ *
+ * @param parameterClassName the class name of a sub class of this class
+ */
+ public PersistorParameters(final String parameterClassName) {
+ super(parameterClassName);
+ }
+
+ /**
+ * Gets the plugin class.
+ *
+ * @return the plugin class
+ */
+ public String getPluginClass() {
+ return pluginClass;
+ }
+
+ /**
+ * Sets the plugin class.
+ *
+ * @param pluginClass the plugin class
+ */
+ public void setPluginClass(final String pluginClass) {
+ this.pluginClass = pluginClass;
+ }
+
+ /**
+ * Gets the flush period in milliseconds.
+ *
+ * @return the flush period
+ */
+ public long getFlushPeriod() {
+ return flushPeriod;
+ }
+
+ /**
+ * Sets the flush period in milliseconds.
+ *
+ * @param flushPeriod the flush period
+ */
+ public void setFlushPeriod(final long flushPeriod) {
+ if (flushPeriod <= 0) {
+ this.flushPeriod = DEFAULT_FLUSH_PERIOD;
+ } else {
+ this.flushPeriod = flushPeriod;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+ */
+ @Override
+ public String toString() {
+ return "PersistorParameters [pluginClass=" + pluginClass + ", flushPeriod=" + flushPeriod + "]";
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java
new file mode 100644
index 000000000..9ccd431a5
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaHelperParameters.java
@@ -0,0 +1,81 @@
+/*-
+ * ============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.context.parameters;
+
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * An empty schema helper parameter class that may be specialized by context schema helper plugins that require plugin
+ * specific parameters.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SchemaHelperParameters extends AbstractParameters {
+ // Schema helper plugin class for the schema
+ private String schemaHelperPluginClass;
+
+ /**
+ * Constructor to create a schema helper parameters instance and register the instance with the parameter service.
+ */
+ public SchemaHelperParameters() {
+ super(SchemaHelperParameters.class.getCanonicalName());
+ ParameterService.registerParameters(SchemaHelperParameters.class, this);
+ }
+
+ /**
+ * Constructor to create a schema helper parameters instance with the name of a sub class of this class and register
+ * the instance with the parameter service.
+ *
+ * @param parameterClassName the class name of a sub class of this class
+ */
+ public SchemaHelperParameters(final String parameterClassName) {
+ super(parameterClassName);
+ }
+
+ /**
+ * Gets the schema helper plugin class.
+ *
+ * @return the schema helper plugin class
+ */
+ public String getSchemaHelperPluginClass() {
+ return schemaHelperPluginClass;
+ }
+
+ /**
+ * Sets the schema helper plugin class.
+ *
+ * @param pluginClass the schema helper plugin class
+ */
+ public void setSchemaHelperPluginClass(final String pluginClass) {
+ schemaHelperPluginClass = pluginClass;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString()
+ */
+ @Override
+ public String toString() {
+ return "SchemaHelperParameters [schemaHelperPluginClass=" + schemaHelperPluginClass + "]";
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java
new file mode 100644
index 000000000..858a6a3f7
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/SchemaParameters.java
@@ -0,0 +1,87 @@
+/*-
+ * ============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.context.parameters;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters;
+import org.onap.policy.apex.model.basicmodel.service.AbstractParameters;
+import org.onap.policy.apex.model.basicmodel.service.ParameterService;
+
+/**
+ * Bean class holding schema parameters for schemas and their helpers. As more than one schema can be used in Apex
+ * simultaneously, this class is used to hold the schemas that are defined in a given Apex system and to get the schema
+ * helper plugin parameters {@link SchemaHelperParameters} for each schema.
+ * <p>
+ * The default {@code Java} schema is always defined and its parameters are held in a {@link JavaSchemaHelperParameters}
+ * instance.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class SchemaParameters extends AbstractParameters {
+ /** The Java schema flavour is always available for use. */
+ public static final String DEFAULT_SCHEMA_FLAVOUR = "Java";
+
+ // A map of parameters for executors of various logic types
+ private Map<String, SchemaHelperParameters> schemaHelperParameterMap;
+
+ /**
+ * Constructor to create a distributor parameters instance and register the instance with the parameter service.
+ */
+ public SchemaParameters() {
+ super(SchemaParameters.class.getCanonicalName());
+ ParameterService.registerParameters(SchemaParameters.class, this);
+
+ schemaHelperParameterMap = new TreeMap<>();
+
+ // The default schema helper
+ schemaHelperParameterMap.put(DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters());
+ }
+
+ /**
+ * Gets a map of the schemas and schema helper parameters that are defined.
+ *
+ * @return the schema helper parameter map
+ */
+ public Map<String, SchemaHelperParameters> getSchemaHelperParameterMap() {
+ return schemaHelperParameterMap;
+ }
+
+ /**
+ * Sets the map of the schemas and schema helper parameters.
+ *
+ * @param schemaHelperParameterMap the schema helper parameter map
+ */
+ public void setSchemaHelperParameterMap(final Map<String, SchemaHelperParameters> schemaHelperParameterMap) {
+ this.schemaHelperParameterMap = schemaHelperParameterMap;
+ }
+
+ /**
+ * Gets the schema helper parameters for a given context schema flavour.
+ *
+ * @param schemaFlavour the schema flavour for which to get the schema helper parameters
+ * @return the schema helper parameters for the given schema flavour
+ */
+ public SchemaHelperParameters getSchemaHelperParameters(final String schemaFlavour) {
+ return schemaHelperParameterMap.get(schemaFlavour);
+ }
+}
diff --git a/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java
new file mode 100644
index 000000000..52a42709c
--- /dev/null
+++ b/context/context-management/src/main/java/org/onap/policy/apex/context/parameters/package-info.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Holds the definitions of generic parameters for schema helpers, distributors, lock managers, and persistors in APEX.
+ * All the parameter definitions can be specialized to provide parameters to APEX plugins.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.context.parameters;