aboutsummaryrefslogtreecommitdiffstats
path: root/appc-dispatcher/appc-dispatcher-common
diff options
context:
space:
mode:
Diffstat (limited to 'appc-dispatcher/appc-dispatcher-common')
-rw-r--r--appc-dispatcher/appc-dispatcher-common/.gitignore2
-rw-r--r--appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml41
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java50
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java83
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java72
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java30
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java33
-rw-r--r--appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java43
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml36
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java72
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java95
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java72
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java93
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java83
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java97
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java53
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java73
-rw-r--r--appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java55
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml48
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java32
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java26
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java71
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java40
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java83
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java108
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java42
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java39
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java42
-rw-r--r--appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java72
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore2
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml27
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java34
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java69
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java33
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml107
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml33
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore2
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml64
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java130
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java43
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java51
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java47
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java34
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java71
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java32
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java263
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml41
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java167
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java36
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java93
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java80
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java27
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java132
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java227
-rw-r--r--appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml17
-rw-r--r--appc-dispatcher/appc-dispatcher-common/pom.xml27
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml37
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java35
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java27
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java30
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java26
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java26
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java26
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java119
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java38
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java30
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java49
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java45
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java40
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java87
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java45
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java100
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java30
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java40
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java225
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml27
-rw-r--r--appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml46
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml32
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java29
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java43
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java93
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java59
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java28
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java30
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java79
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java79
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java48
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java45
-rw-r--r--appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java98
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml52
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java34
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java78
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java147
-rw-r--r--appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml31
112 files changed, 5756 insertions, 0 deletions
diff --git a/appc-dispatcher/appc-dispatcher-common/.gitignore b/appc-dispatcher/appc-dispatcher-common/.gitignore
new file mode 100644
index 000000000..09e3bc9b2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml
new file mode 100644
index 000000000..8ab6095a6
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml
@@ -0,0 +1,41 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-data-access-lib</artifactId>
+ <packaging>jar</packaging>
+
+ <name>appc-data-access-lib</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java
new file mode 100644
index 000000000..4b38e6610
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/AppcJdbcConnectionFactory.java
@@ -0,0 +1,50 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.dao.util;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class AppcJdbcConnectionFactory implements JdbcConnectionFactory {
+
+ private String schema;
+
+ public void setSchema(String schema) {
+ this.schema = schema;
+ }
+
+ public Connection openDbConnection() {
+ try {
+ return DBUtils.getConnection(schema);
+ } catch(SQLException e) {
+ throw new JdbcRuntimeException(Messages.EXP_APPC_JDBC_CONNECT.format(schema), e);
+ }
+ }
+
+ public void closeDbConnection(Connection connection) {
+ try {
+ connection.close();
+ } catch(SQLException e) {
+ throw new JdbcRuntimeException(Messages.EXP_APPC_JDBC_DISCONNECT.format(schema), e);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java
new file mode 100644
index 000000000..294d948a0
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DBUtils.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.dao.util;
+
+import java.sql.*;
+
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+
+@Deprecated
+public class DBUtils {
+ private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+ static {
+ try {
+ String driver = JDBC_DRIVER;
+ Class.forName(driver);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static Connection getConnection(String schema) throws SQLException {
+ DriverManager.registerDriver(new com.mysql.jdbc.Driver());
+ String dbURL = configuration.getProperty(String.format("org.openecomp.appc.db.url.%s", schema), "");
+ String userName = configuration.getProperty(String.format("org.openecomp.appc.db.user.%s", schema), "");
+ String password = configuration.getProperty(String.format("org.openecomp.appc.db.pass.%s", schema), "");
+ return DriverManager.getConnection(dbURL, userName, password);
+ }
+
+ public static boolean clearResources(ResultSet resultSet, PreparedStatement ptmt, Connection connection) {
+ boolean clearFlag = false;
+ try {
+ if (resultSet != null)
+ resultSet.close();
+ if (ptmt != null)
+ ptmt.close();
+ if (connection != null)
+ connection.close();
+ clearFlag = true;
+ } catch (SQLException e) {
+
+ }
+ return clearFlag;
+
+ }
+
+ /*public static DbLibService getDBLibService(){
+ DbLibService dblibSvc = null;
+ BundleContext bctx = FrameworkUtil.getBundle(SvcLogicDblibStore.class).getBundleContext();
+ ServiceReference sref = bctx.getServiceReference("org.openecomp.sdnc.sli.resource.dblib.DBResourceManager");
+ if (sref == null) {
+// LOG.warn("Could not find service reference for DBLIB service (org.openecomp.sdnc.sli.resource.dblib.DBResourceManager)");
+ }
+ else {
+ dblibSvc = (DbLibService)bctx.getService(sref);
+ if (dblibSvc == null)
+ {
+// LOG.warn("Could not find service reference for DBLIB service (org.openecomp.sdnc.sli.resource.dblib.DBResourceManager)");
+ }
+ }
+ return dblibSvc;
+ }*/
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java
new file mode 100644
index 000000000..31db1e76e
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/DefaultJdbcConnectionFactory.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.dao.util;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public abstract class DefaultJdbcConnectionFactory implements JdbcConnectionFactory {
+
+ private static boolean driverRegistered = false;
+
+ private String jdbcURL;
+ private String jdbcUserName;
+ private String jdbcPassword;
+
+ public void setJdbcURL(String jdbcURL) {
+ this.jdbcURL = jdbcURL;
+ }
+
+ public void setJdbcUserName(String jdbcUserName) {
+ this.jdbcUserName = jdbcUserName;
+ }
+
+ public void setJdbcPassword(String jdbcPassword) {
+ this.jdbcPassword = jdbcPassword;
+ }
+
+
+ protected abstract void registedDriver() throws SQLException;
+
+ @Override
+ public Connection openDbConnection() {
+ try {
+ if(!driverRegistered) {
+ registedDriver();
+ driverRegistered = true;
+ }
+ return DriverManager.getConnection(jdbcURL, jdbcUserName, jdbcPassword);
+ } catch(SQLException e) {
+ throw new JdbcRuntimeException(Messages.EXP_JDBC_CONNECT.format(jdbcURL), e);
+ }
+ }
+
+ @Override
+ public void closeDbConnection(Connection connection) {
+ try {
+ connection.close();
+ } catch(SQLException e) {
+ throw new JdbcRuntimeException(Messages.EXP_JDBC_DISCONNECT.format(jdbcURL), e);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java
new file mode 100644
index 000000000..3bd38320b
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcConnectionFactory.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.dao.util;
+
+import java.sql.Connection;
+
+public interface JdbcConnectionFactory {
+
+ Connection openDbConnection();
+ void closeDbConnection(Connection connection);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java
new file mode 100644
index 000000000..7b0682906
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/JdbcRuntimeException.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.dao.util;
+
+public class JdbcRuntimeException extends RuntimeException {
+
+ public JdbcRuntimeException(String message) {
+ super(message);
+ }
+
+ public JdbcRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java
new file mode 100644
index 000000000..8c97188bd
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/src/main/java/org/openecomp/appc/dao/util/Messages.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.dao.util;
+
+public enum Messages {
+ EXP_JDBC_CONNECT("Error connecting to JDBC URL [%s]."),
+ EXP_JDBC_DISCONNECT("Error closing JDBC connection to URL [%s]."),
+ EXP_APPC_JDBC_CONNECT("Error connecting to JDBC using properties for schema [%s]"),
+ EXP_APPC_JDBC_DISCONNECT("Error closing JDBC connection for schema [%s].");
+
+ private String message;
+
+ Messages(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String format(Object... s) {
+ return String.format(message, s);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml
new file mode 100644
index 000000000..5722d18ea
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/pom.xml
@@ -0,0 +1,36 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>domain-model-lib</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>domain-model-lib</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Export-Package>org.openecomp.appc.domainmodel.lcm</Export-Package>
+ <Embed-Transitive>true</Embed-Transitive>
+
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java
new file mode 100644
index 000000000..dc01e8f20
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ActionIdentifiers.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+
+public class ActionIdentifiers {
+ private String serviceInstanceId;
+ private String vnfId;
+ private String vnfcName;
+ private String vServerId;
+
+ public String getServiceInstanceId() {
+ return serviceInstanceId;
+ }
+
+ public void setServiceInstanceId(String serviceInstanceId) {
+ this.serviceInstanceId = serviceInstanceId;
+ }
+
+ public String getVnfId() {
+ return vnfId;
+ }
+
+ public void setVnfId(String vnfId) {
+ this.vnfId = vnfId;
+ }
+
+ public String getVnfcName() {
+ return vnfcName;
+ }
+
+ public void setVnfcName(String vnfcName) {
+ this.vnfcName = vnfcName;
+ }
+
+ public String getVserverId() {
+ return vServerId;
+ }
+
+ public void setvServerId(String vServerId) {
+ this.vServerId = vServerId;
+ }
+
+ @Override
+ public String toString() {
+ return "ActionIdentifiers{" +
+ "serviceInstanceId='" + serviceInstanceId + '\'' +
+ ", vnfId='" + vnfId + '\'' +
+ ", vnfcName='" + vnfcName + '\'' +
+ ", vServerId='" + vServerId + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java
new file mode 100644
index 000000000..0819a58d5
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/CommonHeader.java
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+import java.util.Date;
+
+
+public class CommonHeader {
+
+ private Flags flags;
+ private Date timestamp;
+ private String apiVer;
+ private String originatorId;
+ private String requestId;
+ private String subRequestId;
+
+ public Flags getFlags() {
+ return flags;
+ }
+
+ public void setFlags(Flags flags) {
+ this.flags = flags;
+ }
+
+ public Date getTimeStamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(Date timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getApiVer() {
+ return apiVer;
+ }
+
+ public void setApiVer(String apiVer) {
+ this.apiVer = apiVer;
+ }
+
+ public String getOriginatorId() {
+ return originatorId;
+ }
+
+ public void setOriginatorId(String originatorId) {
+ this.originatorId = originatorId;
+ }
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ public void setRequestId(String requestId) {
+ this.requestId = requestId;
+ }
+
+ public String getSubRequestId() {
+ return subRequestId;
+ }
+
+ public void setSubRequestId(String subRequestId) {
+ this.subRequestId = subRequestId;
+ }
+
+ @Override
+ public String toString() {
+ return "CommonHeader{" +
+ "flags=" + flags +
+ ", timestamp=" + timestamp +
+ ", apiVer='" + apiVer + '\'' +
+ ", originatorId='" + originatorId + '\'' +
+ ", requestId='" + requestId + '\'' +
+ ", subRequestId='" + subRequestId + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java
new file mode 100644
index 000000000..4f4ddba35
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Flags.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+
+public class Flags {
+
+ private boolean force;
+ private int ttl;
+ private Mode mode;
+
+ public boolean isForce() {
+ return force;
+ }
+
+ public void setForce(boolean force) {
+ this.force = force;
+ }
+
+ public int getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(int ttl) {
+ this.ttl = ttl;
+ }
+
+ public Mode getMode() {
+ return mode;
+ }
+
+ public void setMode(Mode mode) {
+ this.mode = mode;
+ }
+
+ public void setMode(String mode) {
+ this.mode = Mode.valueOf(mode);
+ }
+
+ @Override
+ public String toString() {
+ return "Flags{" +
+ "force=" + force +
+ ", ttl=" + ttl +
+ ", mode=" + mode +
+ '}';
+ }
+
+ public enum Mode {
+ EXCLUSIVE,
+ NORMAL
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java
new file mode 100644
index 000000000..c37262498
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RequestContext.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class RequestContext {
+
+ private CommonHeader commonHeader;
+ private ActionIdentifiers actionIdentifiers;
+ private VNFOperation action;
+ private String payload;
+ private Map<String, String> additionalContext;
+
+ public CommonHeader getCommonHeader() {
+ return commonHeader;
+ }
+
+ public void setCommonHeader(CommonHeader commonHeader) {
+ this.commonHeader = commonHeader;
+ }
+
+ public ActionIdentifiers getActionIdentifiers() {
+ return actionIdentifiers;
+ }
+
+ public void setActionIdentifiers(ActionIdentifiers actionIdentifiers) {
+ this.actionIdentifiers = actionIdentifiers;
+ }
+
+ public VNFOperation getAction() {
+ return action;
+ }
+
+ public void setAction(VNFOperation action) {
+ this.action = action;
+ }
+
+ public String getPayload() {
+ return payload;
+ }
+
+ public void setPayload(String payload) {
+ this.payload = payload;
+ }
+
+ public Map<String, String> getAdditionalContext() {
+ return additionalContext;
+ }
+
+ public void setAdditionalContext(Map<String, String> additionalContext) {
+ this.additionalContext = additionalContext;
+ }
+
+ public void addKeyValueToAdditionalContext(String key, String value ){
+ if (this.additionalContext == null) {
+ this.additionalContext = new HashMap<>();
+ }
+ this.additionalContext.put(key, value);
+ }
+
+ @Override
+ public String toString() {
+ return "RequestContext{" +
+ "commonHeader=" + commonHeader +
+ ", actionIdentifiers=" + actionIdentifiers +
+ ", action=" + action +
+ ", payload='" + payload + '\'' +
+ ", additionalContext=" + additionalContext +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java
new file mode 100644
index 000000000..81fba28ee
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/ResponseContext.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class ResponseContext {
+ private CommonHeader commonHeader;
+ private Status status;
+ private String payload;
+ private Map<String, String> additionalContext;
+
+ public CommonHeader getCommonHeader() {
+ return commonHeader;
+ }
+
+ public void setCommonHeader(CommonHeader commonHeader) {
+ this.commonHeader = commonHeader;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+
+ public String getPayload() {
+ return payload;
+ }
+
+ public void setPayload(String payload) {
+ this.payload = payload;
+ }
+
+ public Map<String, String> getAdditionalContext() {
+ return additionalContext;
+ }
+
+ public void setAdditionalContext(Map<String, String> additionalContext) {
+ this.additionalContext = additionalContext;
+ }
+
+ public void addKeyValueToAdditionalContext(String key, String value ){
+ if (this.additionalContext == null) {
+ this.additionalContext = new HashMap<>();
+ }
+ this.additionalContext.put(key, value);
+ }
+
+ @Override
+ public String toString() {
+ return "ResponseContext{" +
+ "commonHeader=" + commonHeader +
+ ", status=" + status +
+ ", payload='" + payload + '\'' +
+ ", additionalContext=" + additionalContext +
+ '}';
+ }
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java
new file mode 100644
index 000000000..fd2bcffbf
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/RuntimeContext.java
@@ -0,0 +1,97 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+import java.util.Date;
+
+
+public class RuntimeContext {
+
+ private RequestContext requestContext;
+ private ResponseContext responseContext;
+ private VNFContext vnfContext;
+
+ //TODO move fields timeStart abd isLockAcquired to a better place
+ private Date timeStart;
+ private boolean isLockAcquired;
+ private String rpcName;
+
+ public String getRpcName() {
+ return rpcName;
+ }
+
+ public void setRpcName(String rpcName) {
+ this.rpcName = rpcName;
+ }
+
+ public Date getTimeStart() {
+ return timeStart;
+ }
+
+ public boolean isLockAcquired() {
+ return isLockAcquired;
+ }
+
+ public void setIsLockAcquired(boolean isLockAcquired) {
+ this.isLockAcquired = isLockAcquired;
+ }
+
+ public void setTimeStart(Date timeStart) {
+ this.timeStart = timeStart;
+ }
+
+ public RequestContext getRequestContext() {
+ return requestContext;
+ }
+
+ public void setRequestContext(RequestContext requestContext) {
+ this.requestContext = requestContext;
+ }
+
+ public ResponseContext getResponseContext() {
+ return responseContext;
+ }
+
+ public void setResponseContext(ResponseContext responseContext) {
+ this.responseContext = responseContext;
+ }
+
+ public VNFContext getVnfContext() {
+ return vnfContext;
+ }
+
+ public void setVnfContext(VNFContext vnfContext) {
+ this.vnfContext = vnfContext;
+ }
+
+ @Override
+ public String toString() {
+ return "RuntimeContext{" +
+ "requestContext=" + requestContext +
+ ", responseContext=" + responseContext +
+ ", vnfContext=" + vnfContext +
+ ", timeStart=" + timeStart +
+ ", isLockAcquired=" + isLockAcquired +
+ ", rpcName='" + rpcName + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java
new file mode 100644
index 000000000..a5fbefa9c
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/Status.java
@@ -0,0 +1,53 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+
+public class Status {
+
+ private int code;
+ private String message;
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String value) {
+ this.message = value;
+ }
+
+ @Override
+ public String toString() {
+ return "Status{" +
+ "code='" + code + '\'' +
+ ", message='" + message + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java
new file mode 100644
index 000000000..4e2570139
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFContext.java
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+
+public class VNFContext {
+ private String id;
+ private String type;
+ private String version;
+ private String status;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+
+ @Override
+ public String toString() {
+ return "VNFContext{" +
+ "id='" + id + '\'' +
+ ", type='" + type + '\'' +
+ ", version='" + version + '\'' +
+ ", status='" + status + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java
new file mode 100644
index 000000000..c61901eb3
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.domainmodel.lcm;
+
+public enum VNFOperation {
+
+ Configure, Test, HealthCheck, Start, Terminate, Restart, Rebuild, Stop, ModifyConfig, Backup, Snapshot,
+ SoftwareUpload, LiveUpgrade, Rollback, Sync, Audit, Test_lic, Migrate, Evacuate,
+ Lock(true), Unlock(true), CheckLock(true);
+
+ private boolean builtIn;
+
+ VNFOperation(boolean builtIn) {
+ this.builtIn = builtIn;
+ }
+
+ VNFOperation() {
+ this(false);
+ }
+
+ /**
+ * Operations handled directly by the RequestHandler without further call to DG are built-in operations.
+ */
+ public boolean isBuiltIn() {
+ return builtIn;
+ }
+
+ public static VNFOperation findByString(String operationName) {
+ for(VNFOperation operation: VNFOperation.values()) {
+ if(operation.name().equals(operationName)) {
+ return operation;
+ }
+ }
+ return null;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml
new file mode 100644
index 000000000..cfa75c0b2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml
@@ -0,0 +1,48 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>execution-queue-management-lib</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>execution-queue-management-lib</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Export-Package>org.openecomp.appc.executionqueue,org.openecomp.appc.executionqueue.impl</Export-Package>
+ <Import-Package>!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java
new file mode 100644
index 000000000..c93920083
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/ExecutionQueueService.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue;
+
+import java.util.concurrent.TimeUnit;
+
+import org.openecomp.appc.exceptions.APPCException;
+
+public interface ExecutionQueueService<M extends Runnable> {
+ void putMessage(M message) throws APPCException;
+ void putMessage(M message, long timeout, TimeUnit unit) throws APPCException;
+ void registerMessageExpirationListener(MessageExpirationListener listener);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java
new file mode 100644
index 000000000..cd5cbeab1
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/MessageExpirationListener.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue;
+
+public interface MessageExpirationListener<M> {
+ void onMessageExpiration(M message);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java
new file mode 100644
index 000000000..835e881aa
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/helper/Util.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue.helper;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+
+public class Util {
+
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ public static int DEFAULT_QUEUE_SIZE = 10;
+ public static int DEFAULT_THREADPOOL_SIZE = 10;
+
+ public static int getExecutionQueSize(){
+ String sizeStr = configuration.getProperty("appc.dispatcher.executionqueue.backlog.size", String.valueOf(DEFAULT_QUEUE_SIZE));
+ int size = DEFAULT_QUEUE_SIZE;
+ try{
+ size = Integer.parseInt(sizeStr);
+ }
+ catch (NumberFormatException e){
+
+ }
+ return size;
+ }
+
+ public static int getThreadPoolSize(){
+ String sizeStr = configuration.getProperty("appc.dispatcher.executionqueue.threadpool.size", String.valueOf(DEFAULT_THREADPOOL_SIZE));
+ int size = DEFAULT_THREADPOOL_SIZE;
+ try{
+ size = Integer.parseInt(sizeStr);
+ }
+ catch (NumberFormatException e){
+
+ }
+ return size;
+ }
+
+ public static ThreadFactory getThreadFactory(final boolean isDaemon){
+ return new ThreadFactory() {
+ final ThreadFactory factory = Executors.defaultThreadFactory();
+ public Thread newThread(Runnable r) {
+ Thread t = factory.newThread(r);
+ t.setDaemon(isDaemon);
+ return t;
+ }
+ };
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java
new file mode 100644
index 000000000..01e4358e9
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue.impl;
+
+import org.openecomp.appc.executionqueue.ExecutionQueueService;
+
+public class ExecutionQueueServiceFactory {
+
+ private static ExecutionQueueService executionQueueService =null;
+
+ public static ExecutionQueueService getExecutionQueueService(){
+ if(executionQueueService == null){
+ synchronized (ExecutionQueueServiceFactory.class){
+ if(executionQueueService == null)
+ executionQueueService = new ExecutionQueueServiceImpl();
+ }
+ }
+ return executionQueueService;
+ }
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java
new file mode 100644
index 000000000..c2be1b4ac
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceImpl.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue.impl;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executionqueue.ExecutionQueueService;
+import org.openecomp.appc.executionqueue.MessageExpirationListener;
+import org.openecomp.appc.executionqueue.impl.object.QueueMessage;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class ExecutionQueueServiceImpl<M extends Runnable> implements ExecutionQueueService<M> {
+
+ private static final EELFLogger logger =
+ EELFManager.getInstance().getLogger(ExecutionQueueServiceImpl.class);
+
+ ExecutionQueueServiceImpl(){
+
+ }
+
+ @Override
+ public void putMessage(M message) throws APPCException {
+ this.putMessage(message,-1,null);
+ }
+
+ @Override
+ public void putMessage(M message, long timeout, TimeUnit unit) throws APPCException{
+ QueueMessage queueMessage = null;
+
+ try {
+ Date expirationTime = calculateExpirationTime(timeout,unit);
+ queueMessage = new QueueMessage(message,expirationTime);
+ QueueManager queueManager = QueueManager.getInstance();
+ boolean enqueueTask = queueManager.enqueueTask(queueMessage);
+ if(!enqueueTask){
+ throw new APPCException("failed to put message in queue");
+ }
+ } catch (Exception e) {
+ logger.error("Error in putMessage method of ExecutionQueueServiceImpl" + e.getMessage());
+ throw new APPCException(e);
+ }
+ }
+
+ @Override
+ public void registerMessageExpirationListener(MessageExpirationListener listener) {
+ QueueManager.getInstance().setListener(listener);
+ }
+
+ private Date calculateExpirationTime(long timeToLive, TimeUnit unit) {
+ Date expirationTime = null;
+ if(timeToLive > 0){
+ long currentTime = System.currentTimeMillis();
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeInMillis(currentTime + unit.toMillis(timeToLive));
+ expirationTime = cal.getTime();
+ }
+ return expirationTime;
+ }
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java
new file mode 100644
index 000000000..2d4907fa1
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/QueueManager.java
@@ -0,0 +1,108 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.openecomp.appc.executionqueue.MessageExpirationListener;
+import org.openecomp.appc.executionqueue.helper.Util;
+import org.openecomp.appc.executionqueue.impl.object.QueueMessage;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class QueueManager {
+
+ private LinkedBlockingQueue<QueueMessage> queue;
+
+ private MessageExpirationListener listener;
+
+ private static int MAX_QUEUE_SIZE = Util.getExecutionQueSize();
+
+ private static int MAX_THREAD_SIZE = Util.getThreadPoolSize();
+
+ private ExecutorService messageExecutor;
+
+ private static final EELFLogger logger =
+ EELFManager.getInstance().getLogger(QueueManager.class);
+
+ private QueueManager(){
+ init();
+ }
+
+ private static class QueueManagerHolder {
+ private static final QueueManager INSTANCE = new QueueManager();
+ }
+
+ public static QueueManager getInstance() {
+ return QueueManagerHolder.INSTANCE;
+ }
+
+ private void init(){
+ queue = new LinkedBlockingQueue(MAX_QUEUE_SIZE);
+ messageExecutor = Executors.newFixedThreadPool(MAX_THREAD_SIZE,Util.getThreadFactory(true));
+
+ for(int i=0;i<MAX_THREAD_SIZE;i++){
+ messageExecutor.submit(new Runnable() {
+ @Override
+ public void run() {
+ while (true){
+ try{
+ QueueMessage queueMessage = queue.take();
+ if(messageExpired(queueMessage)){
+ logger.debug("Message expired "+ queueMessage.getMessage());
+ if(listener != null){
+ listener.onMessageExpiration(queueMessage.getMessage());
+ }
+ else{
+ logger.warn("Listener not available for expired message ");
+ }
+ }
+ else{
+ queueMessage.getMessage().run();
+ }
+ } catch (Exception e) {
+ logger.error("Error in startMessagePolling method of ExecutionQueueServiceImpl" + e.getMessage());
+ }
+ }
+ }
+ });
+ }
+ }
+
+ public void setListener(MessageExpirationListener listener) {
+ this.listener = listener;
+ }
+
+ public boolean enqueueTask(QueueMessage queueMessage) {
+ return queue.offer(queueMessage);
+ }
+
+ private boolean messageExpired(QueueMessage queueMessage) {
+ if(queueMessage.getExpirationTime() != null){
+ return queueMessage.getExpirationTime().getTime() < System.currentTimeMillis();
+ }
+ return false;
+ }
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java
new file mode 100644
index 000000000..bbf805871
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/object/QueueMessage.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue.impl.object;
+
+import java.util.Date;
+
+
+public class QueueMessage<M extends Runnable> {
+ M message;
+ Date expirationTime;
+ public QueueMessage(M message, Date expirationTime){
+ this.message = message;
+ this.expirationTime = expirationTime;
+ }
+
+ public M getMessage() {
+ return message;
+ }
+
+ public Date getExpirationTime() {
+ return expirationTime;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java
new file mode 100644
index 000000000..294ae61b1
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Listener.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue;
+
+import org.openecomp.appc.executionqueue.MessageExpirationListener;
+
+
+public class Listener implements MessageExpirationListener {
+
+ boolean listenerExecuted = false;
+
+ public boolean isListenerExecuted() {
+ return listenerExecuted;
+ }
+
+ @Override
+ public void onMessageExpiration(Object message) {
+ listenerExecuted = true;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java
new file mode 100644
index 000000000..61c847842
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/Message.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue;
+
+
+public class Message implements Runnable {
+
+ boolean runExecuted = false;
+
+ public boolean isRunExecuted() {
+ return runExecuted;
+ }
+
+ @Override
+ public void run() {
+ this.runExecuted = true;
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java
new file mode 100644
index 000000000..a8a20c10a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/test/java/org/openecomp/appc/executionqueue/TestExecutionQueueService.java
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.executionqueue;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executionqueue.ExecutionQueueService;
+import org.openecomp.appc.executionqueue.impl.ExecutionQueueServiceFactory;
+import org.powermock.api.mockito.PowerMockito;
+
+import java.util.concurrent.TimeUnit;
+
+
+public class TestExecutionQueueService {
+
+ @Test
+ public void testPositiveFlow(){
+ Message message = new Message();
+ ExecutionQueueService service = ExecutionQueueServiceFactory.getExecutionQueueService();
+ try {
+ service.putMessage(message);
+ waitFor(5000);
+ Assert.assertTrue(message.isRunExecuted());
+ } catch (APPCException e) {
+ Assert.fail(e.toString());
+ }
+ }
+
+// @Test
+ public void testTimeout(){
+ ExecutionQueueService service = ExecutionQueueServiceFactory.getExecutionQueueService();
+ Message message = new Message();
+ Listener listener = new Listener();
+ service.registerMessageExpirationListener(listener);
+ try {
+ service.putMessage(message,1, TimeUnit.MILLISECONDS);
+ waitFor(5000);
+ Assert.assertTrue(listener.isListenerExecuted());
+ } catch (APPCException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void waitFor(long milliSeconds){
+ try {
+ Thread.sleep(milliSeconds);
+ } catch (InterruptedException e) {
+ Assert.fail(e.toString());
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore
new file mode 100644
index 000000000..09e3bc9b2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml
new file mode 100644
index 000000000..c5560ab1f
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>lock-manager-lib</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>lock-manager-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>org.openecomp.appc.lockmanager.api</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java
new file mode 100644
index 000000000..c5a94f9e1
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockException.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.api;
+
+
+public class LockException extends Exception {
+
+ public LockException(String message) {
+ super(message);
+ }
+
+ public LockException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java
new file mode 100644
index 000000000..eebe5e24f
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockManager.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.api;
+
+/**
+ * Enables locking and unlocking of a resource by id.
+ * If the resource is locked, only lock owner can reacquire the lock or unlock the resource.
+ */
+public interface LockManager {
+
+ /**
+ * Lock resource without timeout. Lock never expires.
+ *
+ * @param resource resource id
+ * @param owner lock owner id
+ * @return true - if lock is acquired, false - if the resource was already locked by the owner
+ * @throws LockException thrown if resource is already locked by other owner
+ */
+ boolean acquireLock(String resource, String owner) throws LockException;
+
+ /**
+ * Lock resource with timeout. After the timeout resource becomes unlocked.
+ *
+ * @param resource resource id
+ * @param owner lock owner id
+ * @param timeout in milliseconds, after this timeout lock will expire and resource becomes unlocked,
+ * timeout == 0 means that the lock never expires - same as call acquireLock() without timeout parameter
+ * @return true - if lock is acquired, false - if the resource was already locked by the owner
+ * @throws LockException thrown if resource is already locked by other owner
+ */
+ boolean acquireLock(String resource, String owner, long timeout) throws LockException;
+
+ /**
+ * Unlock resource.
+ *
+ * @param resource resource id
+ * @param owner lock owner id
+ * @throws LockException thrown if resource is locked by other owner
+ */
+ void releaseLock(String resource, String owner) throws LockException;
+
+ /**
+ * check resource lock status.
+ *
+ * @param resource resource id
+ */
+
+ boolean isLocked(String resource);
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java
new file mode 100644
index 000000000..682cd6e27
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-api/src/main/java/org/openecomp/appc/lockmanager/api/LockRuntimeException.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.api;
+
+public class LockRuntimeException extends RuntimeException {
+
+ public LockRuntimeException(String message) {
+ super(message);
+ }
+
+ public LockRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml
new file mode 100644
index 000000000..560661dfb
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>lock-manager-lib</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>lock-manager-features</name>
+ <artifactId>lock-manager-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>lock-manager-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>lock-manager-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <filtering>true</filtering>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>filter</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ <phase>generate-resources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ <!--<plugin>
+ &lt;!&ndash; launches the feature test, which validates that your karaf feature
+ can be installed inside of a karaf container. It doesn't validate that your
+ functionality works correctly, just that you have all of the dependent bundles
+ defined correctly. &ndash;&gt;
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.16</version>
+ <configuration>
+ <systemPropertyVariables>
+ <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
+ <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
+ <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version>
+ </systemPropertyVariables>
+ <dependenciesToScan>
+ <dependency>org.opendaylight.yangtools:features-test</dependency>
+ </dependenciesToScan>
+ <classpathDependencyExcludes>
+ &lt;!&ndash; The dependencies which bring in AbstractDataBrokerTest class
+ brings in a second PaxExam container which results in the feature tests failing
+ with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous
+ TestContainer ..." This excludes the container we don't want to use. &ndash;&gt;
+ <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes>
+ </classpathDependencyExcludes>
+ </configuration>
+ </plugin>-->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/${features.file}</file>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <!-- Skipping ODL feature test -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skipTests>true</skipTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml
new file mode 100644
index 000000000..ed51ca775
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. 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.
+ ============LICENSE_END=========================================================
+ -->
+
+
+<features name="lock-manager-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
+
+ <feature name='lock-manager' description="lock-manager" version='${project.version}'>
+ <bundle start-level="80" start="true">mvn:org.openecomp.appc/lock-manager-api/${project.version}</bundle>
+ <bundle start-level="85" start="true">mvn:org.openecomp.appc/lock-manager-impl/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore
new file mode 100644
index 000000000..09e3bc9b2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml
new file mode 100644
index 000000000..8ca41399a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>lock-manager-lib</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>lock-manager-impl</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>lock-manager-api</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${mysql.connector.version}</version>
+ <type>jar</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-data-access-lib</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>${eelf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Export-Service>org.openecomp.appc.lockmanager.api.LockManager</Export-Service>
+ <Import-Package>org.openecomp.appc.lockmanager.api.*,*</Import-Package>
+ <Private-Package>org.openecomp.appc.lockmanager.impl.*</Private-Package>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!javax.mail.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package>
+ <Embed-Dependency>appc-common,appc-data-access-lib,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java
new file mode 100644
index 000000000..309e2790c
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImpl.java
@@ -0,0 +1,130 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.inmemory;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.openecomp.appc.lockmanager.api.LockException;
+import org.openecomp.appc.lockmanager.api.LockManager;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+
+public class LockManagerInMemoryImpl implements LockManager {
+
+ private static LockManagerInMemoryImpl instance = null;
+ private Map<String, LockValue> lockedVNFs;
+
+ private static final EELFLogger debugLogger = EELFManager.getInstance().getDebugLogger();
+
+ private LockManagerInMemoryImpl() {
+ lockedVNFs = new ConcurrentHashMap<>();
+ }
+
+ public static LockManager getLockManager() {
+ if(instance == null) {
+ instance = new LockManagerInMemoryImpl();
+ }
+ return instance;
+ }
+
+ @Override
+ public boolean acquireLock(String resource, String owner) throws LockException {
+ return acquireLock(resource, owner, 0);
+ }
+
+ @Override
+ public boolean acquireLock(String resource, String owner, long timeout) throws LockException {
+ debugLogger.debug("Try to acquire lock on resource " + resource + " with owner " + owner);
+ long now = System.currentTimeMillis();
+ LockValue lockValue = lockedVNFs.get(resource);
+ if (lockValue != null) {
+ if (lockIsMine(lockValue, owner, now) || hasExpired(lockValue, now)) {
+ setExpirationTime(resource, owner, timeout, now);
+ debugLogger.debug("Locked successfully resource " + resource + " with owner " + owner + " for " + timeout + " ms");
+ return hasExpired(lockValue, now);
+ }
+ else {
+ debugLogger.debug("Owner " + owner + " tried to lock resource " + resource + " but it is already locked by owner " + lockValue.getOwner());
+ throw new LockException("Owner " + owner + " tried to lock resource " + resource + " but it is already locked by owner " + lockValue.getOwner());
+ }
+ }
+ else {
+ setExpirationTime(resource, owner, timeout, now);
+ debugLogger.debug("Locked successfully resource " + resource + " with owner " + owner + " for " + timeout + " ms");
+ return true;
+ }
+ }
+
+ @Override
+ public void releaseLock(String resource, String owner) throws LockException {
+ debugLogger.debug("Try to release lock on resource " + resource + " with owner " + owner);
+ long now = System.currentTimeMillis();
+ LockValue lockValue = lockedVNFs.get(resource);
+ if (lockValue != null) {
+ if (!hasExpired(lockValue, now)) {
+ if (isOwner(lockValue, owner)) {
+ debugLogger.debug("Unlocked successfully resource " + resource + " with owner " + owner);
+ lockedVNFs.remove(resource);
+ }
+ else {
+ debugLogger.debug("Unlock failed. Tried to release lock on resource " + resource + " from owner " + owner + " but it is held by a different owner");
+ throw new LockException("Unlock failed. Tried to release lock on resource " + resource + " from owner " + owner + " but it is held by a different owner");
+ }
+ }
+ else {
+ lockedVNFs.remove(resource);
+ debugLogger.debug("Unlock failed. lock on resource " + resource + " has expired");
+ throw new LockException("Unlock failed. lock on resource " + resource + " has expired");
+ }
+
+ }
+ else {
+ debugLogger.debug("Tried to release lock on resource " + resource + " from owner " + owner + " but there is not lock on this resource");
+ throw new LockException("Tried to release lock on resource " + resource + " from owner " + owner + " but there is not lock on this resource");
+ }
+ }
+
+ @Override
+ public boolean isLocked(String resource) {
+ return lockedVNFs.get(resource)!=null?true:false;
+ }
+
+ private boolean lockIsMine(LockValue lockValue, String owner, long now) {
+ return isOwner(lockValue, owner) && !hasExpired(lockValue, now);
+ }
+
+ private boolean isOwner(LockValue lockValue, String owner) {
+ return lockValue.getOwner() != null && lockValue.getOwner().equals(owner);
+ }
+
+ private boolean hasExpired(LockValue lockValue, long now) {
+ return (lockValue.getExpirationTime() != 0 && now > lockValue.getExpirationTime());
+ }
+
+ private void setExpirationTime(String resource, String owner, long timeout, long now) {
+ long expirationTime = timeout == 0 ? 0 : now + timeout;
+ LockValue lockValue = new LockValue(owner, expirationTime);
+ lockedVNFs.put(resource, lockValue);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java
new file mode 100644
index 000000000..abdd494d9
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/inmemory/LockValue.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.inmemory;
+
+
+public class LockValue {
+
+ private String owner;
+ private long expirationTime;
+
+ LockValue(String owner, long expirationTime) {
+ this.owner = owner;
+ this.expirationTime = expirationTime;
+ }
+
+ String getOwner() {
+ return owner;
+ }
+
+ long getExpirationTime() {
+ return expirationTime;
+ }
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java
new file mode 100644
index 000000000..97a5cc339
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/JdbcLockManager.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql;
+
+import java.sql.Connection;
+
+import org.openecomp.appc.dao.util.JdbcConnectionFactory;
+import org.openecomp.appc.lockmanager.api.LockManager;
+
+public abstract class JdbcLockManager implements LockManager {
+
+ private static final String DEF_TABLE_LOCK_MANAGEMENT = "LOCK_MANAGEMENT";
+
+ private JdbcConnectionFactory connectionFactory;
+ protected String tableName = DEF_TABLE_LOCK_MANAGEMENT;
+
+ public void setConnectionFactory(JdbcConnectionFactory connectionFactory) {
+ this.connectionFactory = connectionFactory;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ protected Connection openDbConnection() {
+ return connectionFactory.openDbConnection();
+ }
+
+ protected void closeDbConnection(Connection connection) {
+ connectionFactory.closeDbConnection(connection);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java
new file mode 100644
index 000000000..0399726b5
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql;
+
+public enum Messages {
+
+ ERR_NULL_LOCK_OWNER("Cannot acquire lock for resource [%s]: lock owner must be specified"),
+ ERR_LOCK_LOCKED_BY_OTHER("Cannot lock resource [%s] for [%s]: already locked by [%s]"),
+ ERR_UNLOCK_NOT_LOCKED("Error unlocking resource [%s]: resource is not locked"),
+ ERR_UNLOCK_LOCKED_BY_OTHER("Error unlocking resource [%s] by [%s]: resource is locked by [%s]"),
+ EXP_LOCK("Error locking resource [%s]."),
+ EXP_UNLOCK("Error unlocking resource [%s]."),
+ ;
+
+ private String message;
+
+ Messages(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String format(Object... s) {
+ return String.format(message, s);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java
new file mode 100644
index 000000000..4ccd0c453
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/MySqlConnectionFactory.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql;
+
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import org.openecomp.appc.dao.util.DefaultJdbcConnectionFactory;
+
+public class MySqlConnectionFactory extends DefaultJdbcConnectionFactory {
+
+ protected void registedDriver() throws SQLException {
+ DriverManager.registerDriver(new com.mysql.jdbc.Driver());
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java
new file mode 100644
index 000000000..d66804488
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/LockRecord.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql.optimistic;
+
+class LockRecord {
+
+ private String resource;
+ private String owner;
+ private long updated;
+ private long timeout;
+ private long ver;
+
+ LockRecord(String resource) {
+ this.resource = resource;
+ }
+
+ public String getResource() {
+ return resource;
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ this.owner = owner;
+ }
+
+ public long getUpdated() {
+ return updated;
+ }
+
+ public void setUpdated(long updated) {
+ this.updated = updated;
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ public long getVer() {
+ return ver;
+ }
+
+ public void setVer(long ver) {
+ this.ver = ver;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java
new file mode 100644
index 000000000..e80133620
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManager.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql.optimistic;
+
+import java.sql.SQLException;
+
+public class MySqlLockManager extends SqlLockManager {
+
+ @Override
+ protected boolean isDuplicatePkError(SQLException e) {
+ return (e.getErrorCode() == 1062);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java
new file mode 100644
index 000000000..52c75d2b2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java
@@ -0,0 +1,263 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql.optimistic;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.openecomp.appc.lockmanager.api.LockException;
+import org.openecomp.appc.lockmanager.api.LockRuntimeException;
+import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager;
+import org.openecomp.appc.lockmanager.impl.sql.Messages;
+
+abstract class SqlLockManager extends JdbcLockManager {
+
+ private static final String SQL_LOAD_LOCK_RECORD = "SELECT * FROM %s WHERE RESOURCE_ID=?";
+ private static final String SQL_INSERT_LOCK_RECORD = "INSERT INTO %s (RESOURCE_ID, OWNER_ID, UPDATED, TIMEOUT, VER) VALUES (?, ?, ?, ?, ?)";
+ private static final String SQL_UPDATE_LOCK_RECORD = "UPDATE %s SET OWNER_ID=?, UPDATED=?, TIMEOUT=?, VER=? WHERE RESOURCE_ID=? AND VER=?";
+// private static final String SQL_DELETE_LOCK_RECORD = "DELETE FROM %s WHERE RESOURCE_ID=? AND VER=?";
+ private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()";
+
+ private String sqlLoadLockRecord;
+ private String sqlInsertLockRecord;
+ private String sqlUpdateLockRecord;
+// private String sqlDeleteLockRecord;
+
+ @Override
+ public boolean acquireLock(String resource, String owner) throws LockException {
+ return acquireLock(resource, owner, 0);
+ }
+
+ @Override
+ public boolean acquireLock(String resource, String owner, long timeout) throws LockException {
+ if(owner == null) {
+ throw new LockRuntimeException(Messages.ERR_NULL_LOCK_OWNER.format(resource));
+ }
+ boolean res = false;
+ Connection connection = openDbConnection();
+ try {
+ res = lockResource(connection, resource, owner, timeout);
+ } finally {
+ closeDbConnection(connection);
+ }
+ return res;
+ }
+
+ @Override
+ public void releaseLock(String resource, String owner) throws LockException {
+ Connection connection = openDbConnection();
+ try {
+ unlockResource(connection, resource, owner);
+ } finally {
+ closeDbConnection(connection);
+ }
+ }
+
+ @Override
+ public boolean isLocked(String resource) {
+ Connection connection=openDbConnection();
+ try {
+ LockRecord lockRecord=loadLockRecord(connection,resource);
+ if(lockRecord==null){
+ return false;
+ }else{
+ if(lockRecord.getOwner()==null){
+ return false;
+ }else if(isLockExpired(lockRecord, connection)){
+ return false;
+ }else{
+ return true;
+ }
+ }
+ } catch (SQLException e) {
+ throw new LockRuntimeException(Messages.EXP_LOCK.format(resource));
+ }finally {
+ closeDbConnection(connection);
+ }
+ }
+
+ private boolean lockResource(Connection connection, String resource, String owner, long timeout) throws LockException {
+ try {
+ boolean res = false;
+ LockRecord lockRecord = loadLockRecord(connection, resource);
+ if(lockRecord != null) {
+ // lock record already exists
+ String currentOwner = lockRecord.getOwner();
+ if(currentOwner != null) {
+ if(isLockExpired(lockRecord, connection)) {
+ currentOwner = null;
+ } else if(!owner.equals(currentOwner)) {
+ throw new LockException(Messages.ERR_LOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner));
+ }
+ }
+ // set new owner on the resource lock record
+ if(!updateLockRecord(connection, resource, owner, timeout, lockRecord.getVer())) {
+ // try again - maybe same owner updated the record
+ lockResource(connection, resource, owner, timeout);
+ }
+ if(currentOwner == null) {
+ // no one locked the resource before
+ res = true;
+ }
+ } else {
+ // resource record does not exist in lock table => create new record
+ try {
+ addLockRecord(connection, resource, owner, timeout);
+ res = true;
+ } catch(SQLException e) {
+ if(isDuplicatePkError(e)) {
+ // try again - maybe same owner inserted the record
+ lockResource(connection, resource, owner, timeout);
+ } else {
+ throw e;
+ }
+ }
+ }
+ return res;
+ } catch(SQLException e) {
+ throw new LockRuntimeException(Messages.EXP_LOCK.format(resource), e);
+ }
+ }
+
+ protected boolean isDuplicatePkError(SQLException e) {
+ return e.getSQLState().startsWith("23");
+ }
+
+ private void unlockResource(Connection connection, String resource, String owner) throws LockException {
+ try {
+ LockRecord lockRecord = loadLockRecord(connection, resource);
+ if(lockRecord != null) {
+ // check if expired
+ if(isLockExpired(lockRecord, connection)) {
+ // lock is expired => no lock
+ lockRecord = null;
+ }
+ }
+ if((lockRecord == null) || (lockRecord.getOwner() == null)) {
+ // resource is not locked
+ throw new LockException(Messages.ERR_UNLOCK_NOT_LOCKED.format(resource));
+ }
+ String currentOwner = lockRecord.getOwner();
+ if(!owner.equals(currentOwner)) {
+ throw new LockException(Messages.ERR_UNLOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner));
+ }
+ if (!updateLockRecord(connection, resource, null, 0, lockRecord.getVer())) {
+ unlockResource(connection, resource, owner);
+ }
+ // TODO delete record from table on lock release?
+// deleteLockRecord(connection, resource, lockRecord.getVer());
+ } catch(SQLException e) {
+ throw new LockRuntimeException(Messages.EXP_UNLOCK.format(resource), e);
+ }
+ }
+
+ protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException {
+ LockRecord res = null;
+ if(sqlLoadLockRecord == null) {
+ sqlLoadLockRecord = String.format(SQL_LOAD_LOCK_RECORD, tableName);
+ }
+ try(PreparedStatement statement = connection.prepareStatement(sqlLoadLockRecord)) {
+ statement.setString(1, resource);
+ try(ResultSet resultSet = statement.executeQuery()) {
+ if(resultSet.next()) {
+ res = new LockRecord(resource);
+ res.setOwner(resultSet.getString(2));
+ res.setUpdated(resultSet.getLong(3));
+ res.setTimeout(resultSet.getLong(4));
+ res.setVer(resultSet.getLong(5));
+ }
+ }
+ }
+ return res;
+ }
+
+ protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException {
+ if(sqlInsertLockRecord == null) {
+ sqlInsertLockRecord = String.format(SQL_INSERT_LOCK_RECORD, tableName);
+ }
+ try(PreparedStatement statement = connection.prepareStatement(sqlInsertLockRecord)) {
+ statement.setString(1, resource);
+ statement.setString(2, owner);
+ statement.setLong(3, getCurrentTime(connection));
+ statement.setLong(4, timeout);
+ statement.setLong(5, 1);
+ statement.executeUpdate();
+ }
+ }
+
+ protected boolean updateLockRecord(Connection connection, String resource, String owner, long timeout, long ver) throws SQLException {
+ if(sqlUpdateLockRecord == null) {
+ sqlUpdateLockRecord = String.format(SQL_UPDATE_LOCK_RECORD, tableName);
+ }
+ try(PreparedStatement statement = connection.prepareStatement(sqlUpdateLockRecord)) {
+ long newVer = (ver >= Long.MAX_VALUE) ? 1 : (ver + 1);
+ statement.setString(1, owner);
+ statement.setLong(2, getCurrentTime(connection));
+ statement.setLong(3, timeout);
+ statement.setLong(4, newVer);
+ statement.setString(5, resource);
+ statement.setLong(6, ver);
+ return (statement.executeUpdate() != 0);
+ }
+ }
+
+// protected void deleteLockRecord(Connection connection, String resource, long ver) throws SQLException {
+// if(sqlDeleteLockRecord == null) {
+// sqlDeleteLockRecord = String.format(SQL_DELETE_LOCK_RECORD, tableName);
+// }
+// try(PreparedStatement statement = connection.prepareStatement(sqlDeleteLockRecord)) {
+// statement.setString(1, resource);
+// statement.setLong(2, ver);
+// statement.executeUpdate();
+// }
+// }
+
+ private boolean isLockExpired(LockRecord lockRecord, Connection connection) throws SQLException {
+ long timeout = lockRecord.getTimeout();
+ if(timeout == 0) {
+ return false;
+ }
+ long updated = lockRecord.getUpdated();
+ long now = getCurrentTime(connection);
+ long expiration = updated + timeout;
+ return (now > expiration);
+ }
+
+ private long getCurrentTime(Connection connection) throws SQLException {
+ long res = -1;
+ if(connection != null) {
+ try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) {
+ try(ResultSet resultSet = statement.executeQuery()) {
+ if(resultSet.next()) {
+ res = resultSet.getTimestamp(1).getTime();
+ }
+ }
+ }
+ }
+ if(res == -1) {
+ res = System.currentTimeMillis();
+ }
+ return res;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..6ec23eeb0
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. 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.
+ ============LICENSE_END=========================================================
+ -->
+
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+ <!--<bean id="lockManagerInMemoryBean" class="org.openecomp.appc.lockmanager.impl.inmemory.LockManagerInMemoryImpl" factory-method="getLockManager" scope="singleton"/>-->
+ <!--<service id="lockManagerInMemoryService" interface="org.openecomp.appc.lockmanager.api.LockManager" ref="lockManagerInMemoryBean"/>-->
+
+ <service id="lockManagerMySqlOptimisticService" interface="org.openecomp.appc.lockmanager.api.LockManager">
+ <bean class="org.openecomp.appc.lockmanager.impl.sql.optimistic.MySqlLockManager">
+ <property name="connectionFactory">
+ <bean class="org.openecomp.appc.dao.util.AppcJdbcConnectionFactory">
+ <property name="schema" value="sdnctl"/>
+ </bean>
+ </property>
+ <property name="tableName" value="VNF_LOCK_MANAGEMENT"/>
+ </bean>
+ </service>
+</blueprint>
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java
new file mode 100644
index 000000000..47e27f79d
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/api/LockManagerBaseTests.java
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.api;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.appc.lockmanager.api.LockException;
+import org.openecomp.appc.lockmanager.api.LockManager;
+
+public abstract class LockManagerBaseTests {
+
+ protected enum Resource {Resource1, Resource2};
+ protected enum Owner {A, B};
+
+ protected LockManager lockManager;
+
+ @Before
+ public void beforeTest() {
+ lockManager = createLockManager();
+ }
+
+ protected abstract LockManager createLockManager();
+
+ @Test
+ public void testAcquireLock() throws LockException {
+ boolean lockRes = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ try {
+ Assert.assertTrue(lockRes);
+ } finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+ @Test
+ public void testAcquireLock_AlreadyLockedBySameOwner() throws LockException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ try {
+ Assert.assertTrue(lockRes1);
+ boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ Assert.assertFalse(lockRes2);
+ } finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+ @Test(expected = LockException.class)
+ public void testAcquireLock_AlreadyLockedByOtherOwner() throws LockException {
+ String owner2 = "B";
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ try {
+ Assert.assertTrue(lockRes1);
+ boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), owner2);
+ Assert.assertFalse(lockRes2);
+ } finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+ @Test
+ public void testAcquireLock_LockDifferentResources() throws LockException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ try {
+ Assert.assertTrue(lockRes1);
+ boolean lockRes2 = lockManager.acquireLock(Resource.Resource2.name(), Owner.B.name());
+ try {
+ Assert.assertTrue(lockRes2);
+ } finally {
+ lockManager.releaseLock(Resource.Resource2.name(), Owner.B.name());
+ }
+ } finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+ @Test(expected = LockException.class)
+ public void testReleaseLock_NotLockedResource() throws LockException {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+
+ @Test(expected = LockException.class)
+ public void testReleaseLock_LockedByOtherOwnerResource() throws LockException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ try {
+ Assert.assertTrue(lockRes1);
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.B.name());
+ } finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+ @Test(expected = LockException.class)
+ public void testAcquireLock_LockExpired() throws LockException, InterruptedException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50);
+ Assert.assertTrue(lockRes1);
+ Thread.sleep(1000);
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+
+ @Test
+ public void testAcquireLock_OtherLockExpired() throws LockException, InterruptedException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50);
+ Assert.assertTrue(lockRes1);
+ Thread.sleep(1000);
+ boolean lockRes2 = lockManager.acquireLock(Resource.Resource1.name(), Owner.B.name());
+ try {
+ Assert.assertTrue(lockRes2);
+ }finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.B.name());
+ }
+ }
+
+ @Test
+ public void testIsLocked_WhenLocked() throws LockException, InterruptedException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50);
+ try {
+ Assert.assertTrue(lockManager.isLocked(Resource.Resource1.name()));
+ }finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+
+ @Test(expected = LockException.class)
+ public void testIsLocked_LockExpired() throws LockException, InterruptedException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50);
+ Assert.assertTrue(lockRes1);
+ Assert.assertTrue(lockManager.isLocked(Resource.Resource1.name()));
+ Thread.sleep(1000);
+ try {
+ Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name()));
+ }finally {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ }
+
+ @Test
+ public void testIsLocked_LockReleased() throws LockException, InterruptedException {
+ boolean lockRes1 = lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name(), 50);
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name()));
+ }
+
+ @Test
+ public void testIsLocked_NoLock() throws LockException, InterruptedException {
+ Assert.assertFalse(lockManager.isLocked(Resource.Resource1.name()));
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java
new file mode 100644
index 000000000..99faec23d
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/inmemory/LockManagerInMemoryImplTest.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.inmemory;
+
+import org.openecomp.appc.lockmanager.api.LockManager;
+import org.openecomp.appc.lockmanager.api.LockManagerBaseTests;
+import org.openecomp.appc.lockmanager.impl.inmemory.LockManagerInMemoryImpl;
+
+
+public class LockManagerInMemoryImplTest extends LockManagerBaseTests {
+
+ @Override
+ protected LockManager createLockManager() {
+ return LockManagerInMemoryImpl.getLockManager();
+ }
+
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java
new file mode 100644
index 000000000..da5607819
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/MySqlLockManagerBaseTests.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql;
+
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.openecomp.appc.dao.util.DefaultJdbcConnectionFactory;
+import org.openecomp.appc.lockmanager.api.LockManager;
+import org.openecomp.appc.lockmanager.api.LockManagerBaseTests;
+import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager;
+import org.openecomp.appc.lockmanager.impl.sql.MySqlConnectionFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+public abstract class MySqlLockManagerBaseTests extends LockManagerBaseTests {
+
+ private static final boolean USE_REAL_DB = Boolean.getBoolean("lockmanager.tests.useRealDb");
+ private static final String TABLE_LOCK_MANAGEMENT = "TEST_LOCK_MANAGEMENT";
+ private static final String JDBC_URL = System.getProperty("lockmanager.tests.jdbcUrl", "jdbc:mysql://192.168.1.2/test");
+ private static final String JDBC_USERNAME = System.getProperty("lockmanager.tests.jdbcUsername", "test");
+ private static final String JDBC_PASSWORD = System.getProperty("lockmanager.tests.jdbcPassword", "123456");
+
+ protected static final int CONCURRENT_TEST_WAIT_TIME = 10; // secs
+
+ @Rule
+ public TestName testName = new TestName();
+
+ @Override
+ protected LockManager createLockManager() {
+ JdbcLockManager jdbcLockManager = createJdbcLockManager(USE_REAL_DB);
+ DefaultJdbcConnectionFactory connectionFactory = new MySqlConnectionFactory();
+ connectionFactory.setJdbcURL(JDBC_URL);
+ connectionFactory.setJdbcUserName(JDBC_USERNAME);
+ connectionFactory.setJdbcPassword(JDBC_PASSWORD);
+ jdbcLockManager.setConnectionFactory(connectionFactory);
+ jdbcLockManager.setTableName(TABLE_LOCK_MANAGEMENT);
+ System.out.println("=> Running LockManager test [" + jdbcLockManager.getClass().getName() + "." + testName.getMethodName() + "]" + (USE_REAL_DB ? ". JDBC URL is [" + JDBC_URL + "]" : ""));
+ clearTestLocks(jdbcLockManager);
+ return jdbcLockManager;
+ }
+
+ protected abstract JdbcLockManager createJdbcLockManager(boolean useRealDb);
+
+ protected boolean setSynchronizer(Synchronizer synchronizer) {
+ if(!(lockManager instanceof SynchronizerReceiver)) {
+ System.err.println("Skipping concurrency test [" + testName.getMethodName() + "] for LockManager of type " + lockManager.getClass());
+ return false;
+ }
+ ((SynchronizerReceiver)lockManager).setSynchronizer(synchronizer);
+ return true;
+ }
+
+ private static final String SQL_DELETE_LOCK_RECORD = String.format("DELETE FROM %s WHERE RESOURCE_ID=?", TABLE_LOCK_MANAGEMENT);
+ private void clearTestLocks(JdbcLockManager jdbcLockManager) {
+ Connection connection = jdbcLockManager.openDbConnection();
+ if(connection == null) {
+ return;
+ }
+ try {
+ for(Resource resource: Resource.values()) {
+ try(PreparedStatement statement = connection.prepareStatement(SQL_DELETE_LOCK_RECORD)) {
+ statement.setString(1, resource.name());
+ statement.executeUpdate();
+ }
+ }
+ } catch(SQLException e) {
+ throw new RuntimeException("Cannot clear test resources in table", e);
+ } finally {
+ jdbcLockManager.closeDbConnection(connection);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java
new file mode 100644
index 000000000..8d1f0bbfd
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/Synchronizer.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql;
+
+public class Synchronizer {
+
+ private int participantNo;
+ private int participantCount;
+
+ public Synchronizer(int participantNo) {
+ this.participantNo = participantNo;
+ }
+
+ public int getParticipantCount() {
+ return participantCount;
+ }
+
+ public void postLoadLockRecord(String resource, String owner) {
+ synchronized(this) {
+ waitForAllParticipants(this, participantNo, ++participantCount);
+ }
+ }
+
+ public void preAddLockRecord(String resource, String owner) {
+ }
+
+ public void postAddLockRecord(String resource, String owner) {
+ }
+
+ public void preUpdateLockRecord(String resource, String owner) {
+ }
+
+ public void postUpdateLockRecord(String resource, String owner) {
+ }
+
+ public void releaseWait() {
+ synchronized(this) {
+ this.notifyAll();
+ }
+ }
+
+ protected void waitOn(Object obj, long timeout) {
+ try {
+ obj.wait(timeout);
+ } catch(InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected void waitOn(Object obj) {
+ waitOn(obj, 0);
+ }
+
+ protected void waitForAllParticipants(Object waitObj, int totalParticipantsNo, int currentParticipantsNo) {
+ if(totalParticipantsNo > currentParticipantsNo) {
+ waitOn(waitObj);
+ } else {
+ waitObj.notifyAll();
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java
new file mode 100644
index 000000000..945fed10b
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/SynchronizerReceiver.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql;
+
+public interface SynchronizerReceiver {
+
+ void setSynchronizer(Synchronizer synchronizer);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java
new file mode 100644
index 000000000..3e6a236ba
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/MySqlLockManagerMock.java
@@ -0,0 +1,132 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql.optimistic;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.openecomp.appc.lockmanager.impl.sql.Synchronizer;
+import org.openecomp.appc.lockmanager.impl.sql.SynchronizerReceiver;
+import org.openecomp.appc.lockmanager.impl.sql.optimistic.LockRecord;
+import org.openecomp.appc.lockmanager.impl.sql.optimistic.MySqlLockManager;
+
+class MySqlLockManagerMock extends MySqlLockManager implements SynchronizerReceiver {
+
+ private final ConcurrentMap<String, LockRecord> locks = new ConcurrentHashMap<>();
+ private boolean useReal;
+ private Synchronizer synchronizer;
+
+ MySqlLockManagerMock(boolean useReal) {
+ this.useReal = useReal;
+ }
+
+ @Override
+ public void setSynchronizer(Synchronizer synchronizer) {
+ this.synchronizer = synchronizer;
+ }
+
+ @Override
+ protected Connection openDbConnection() {
+ if(useReal) {
+ return super.openDbConnection();
+ }
+ return null;
+ }
+
+ @Override
+ protected void closeDbConnection(Connection connection) {
+ if(useReal) {
+ super.closeDbConnection(connection);
+ }
+ }
+
+ @Override
+ protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException {
+ LockRecord res;
+ if(useReal) {
+ res = super.loadLockRecord(connection, resource);
+ } else {
+ res = locks.get(resource);
+ }
+ if(synchronizer != null) {
+ synchronizer.postLoadLockRecord(resource, (res == null) ? null : res.getOwner());
+ }
+ return res;
+ }
+
+ @Override
+ protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException {
+ if(synchronizer != null) {
+ synchronizer.preAddLockRecord(resource, owner);
+ }
+ try {
+ if(useReal) {
+ super.addLockRecord(connection, resource, owner, timeout);
+ return;
+ }
+ LockRecord lockRecord = new LockRecord(resource);
+ lockRecord.setOwner(owner);
+ lockRecord.setUpdated(System.currentTimeMillis());
+ lockRecord.setTimeout(timeout);
+ lockRecord.setVer(1);
+ LockRecord prevLockRecord = locks.putIfAbsent(resource, lockRecord);
+ if(prevLockRecord != null) {
+ // simulate unique constraint violation
+ throw new SQLException("Duplicate PK exception", "23000", 1062);
+ }
+ } finally {
+ if(synchronizer != null) {
+ synchronizer.postAddLockRecord(resource, owner);
+ }
+ }
+ }
+
+ @Override
+ protected boolean updateLockRecord(Connection connection, String resource, String owner, long timeout, long ver) throws SQLException {
+ if(synchronizer != null) {
+ synchronizer.preUpdateLockRecord(resource, owner);
+ }
+ try {
+ if(useReal) {
+ return super.updateLockRecord(connection, resource, owner, timeout, ver);
+ }
+ LockRecord lockRecord = loadLockRecord(connection, resource);
+ synchronized(lockRecord) {
+ // should be atomic operation
+ if(ver != lockRecord.getVer()) {
+ return false;
+ }
+ lockRecord.setOwner(owner);
+ lockRecord.setUpdated(System.currentTimeMillis());
+ lockRecord.setTimeout(timeout);
+ lockRecord.setVer(ver + 1);
+ }
+ return true;
+ } finally {
+ if(synchronizer != null) {
+ synchronizer.postUpdateLockRecord(resource, owner);
+ }
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java
new file mode 100644
index 000000000..6106dd84b
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/TestMySqlLockManager.java
@@ -0,0 +1,227 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.lockmanager.impl.sql.optimistic;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.appc.lockmanager.api.LockException;
+import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager;
+import org.openecomp.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests;
+import org.openecomp.appc.lockmanager.impl.sql.Synchronizer;
+
+import java.util.concurrent.*;
+
+public class TestMySqlLockManager extends MySqlLockManagerBaseTests {
+
+ @Override
+ protected JdbcLockManager createJdbcLockManager(boolean useReal) {
+ return new MySqlLockManagerMock(useReal);
+ }
+
+ @Test
+ public void testConcurrentLockDifferentOwners() throws LockException, InterruptedException, ExecutionException, TimeoutException {
+
+ final int participantsNo = 2;
+ Synchronizer synchronizer = new Synchronizer(participantsNo) {
+
+ private boolean wait = true;
+
+ @Override
+ public void preAddLockRecord(String resource, String owner) {
+ if(Owner.A.name().equals(owner)) {
+ synchronized(this) {
+ if(wait) {
+ waitOn(this);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void postAddLockRecord(String resource, String owner) {
+ if(!Owner.A.name().equals(owner)) {
+ synchronized(this) {
+ notifyAll();
+ wait = false;
+ }
+ }
+ }
+
+ @Override
+ public void preUpdateLockRecord(String resource, String owner) {
+ preAddLockRecord(resource, owner);
+ }
+
+ @Override
+ public void postUpdateLockRecord(String resource, String owner) {
+ postAddLockRecord(resource, owner);
+ }
+ };
+ if(!setSynchronizer(synchronizer)) {
+ return;
+ }
+ ExecutorService executor = Executors.newFixedThreadPool(participantsNo);
+ // acquireLock by owner A should fail as it will wait for acquireLock by owner B
+ Future<Boolean> future1 = executor.submit(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ try {
+ lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ return false;
+ } catch(LockException e) {
+ // this call should fail as Synchronizer delays its lock to make sure the second call locks the resource first
+ Assert.assertEquals("Cannot lock resource [" + Resource.Resource1.name() + "] for [" + Owner.A.name() + "]: already locked by [" + Owner.B.name() + "]", e.getMessage());
+ return true;
+ }
+ }
+ });
+ try {
+ // acquireLock by owner B should success
+ Future<Boolean> future2 = executor.submit(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ // this call should success as Synchronizer delays the above lock to make sure this call success to lock the resource
+ return lockManager.acquireLock(Resource.Resource1.name(), Owner.B.name());
+ }
+ });
+ try {
+ Assert.assertTrue(future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS));
+ Assert.assertTrue(future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS));
+ } finally {
+ future2.cancel(true);
+ }
+ } finally {
+ future1.cancel(true);
+ }
+ }
+
+ @Test
+ public void testConcurrentLockSameOwner() throws LockException, InterruptedException, ExecutionException, TimeoutException {
+ final int participantsNo = 2;
+ Synchronizer synchronizer = new Synchronizer(participantsNo) {
+
+ private boolean wait = true;
+
+ @Override
+ public void preAddLockRecord(String resource, String owner) {
+ synchronized(this) {
+ if(wait) {
+ wait = false;
+ waitOn(this);
+ }
+ }
+ }
+
+ @Override
+ public void postAddLockRecord(String resource, String owner) {
+ synchronized(this) {
+ notifyAll();
+ }
+ }
+ };
+ if(!setSynchronizer(synchronizer)) {
+ return;
+ }
+ ExecutorService executor = Executors.newFixedThreadPool(participantsNo);
+ // one acquireLock should return true and the other should return false
+ Callable<Boolean> callable = new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ }
+ };
+ Future<Boolean> future1 = executor.submit(callable);
+ try {
+ Future<Boolean> future2 = executor.submit(callable);
+ try {
+ boolean future1Res = future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS);
+ boolean future2Res = future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS);
+ // one of the lock requests should return true, the other one false as lock is requested simultaneously from 2 threads by same owner
+ Assert.assertNotEquals(future1Res, future2Res);
+ } finally {
+ future2.cancel(true);
+ }
+ } finally {
+ future1.cancel(true);
+ }
+ }
+
+ @Test
+ public void testConcurrentUnlockSameOwner() throws LockException, InterruptedException, ExecutionException, TimeoutException {
+ lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
+ final int participantsNo = 2;
+ Synchronizer synchronizer = new Synchronizer(participantsNo) {
+
+ private boolean wait = true;
+
+ @Override
+ public void preUpdateLockRecord(String resource, String owner) {
+ synchronized(this) {
+ // make sure second call updates the LockRecord first
+ if(wait) {
+ wait = false;
+ waitOn(this);
+ }
+ }
+ }
+
+ @Override
+ public void postUpdateLockRecord(String resource, String owner) {
+ synchronized(this) {
+ notifyAll();
+ }
+ }
+ };
+ if(!setSynchronizer(synchronizer)) {
+ return;
+ }
+ ExecutorService executor = Executors.newFixedThreadPool(participantsNo);
+ Callable<Boolean> callable = new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ try {
+ lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
+ // one of the unlock calls should success
+ return true;
+ } catch(LockException e) {
+ // one of the unlock calls should throw the LockException as the resource should already be unlocked by other call
+ Assert.assertEquals("Error unlocking resource [" + Resource.Resource1.name() + "]: resource is not locked", e.getMessage());
+ return false;
+ }
+ }
+ };
+ Future<Boolean> future1 = executor.submit(callable);
+ try {
+ Future<Boolean> future2 = executor.submit(callable);
+ try {
+ boolean future1Res = future1.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS);
+ boolean future2Res = future2.get(CONCURRENT_TEST_WAIT_TIME, TimeUnit.SECONDS);
+ // one of the unlock calls should return true, the other one false as unlock is requested simultaneously from 2 threads by same owner
+ Assert.assertNotEquals(future1Res, future2Res);
+ } finally {
+ future2.cancel(true);
+ }
+ } finally {
+ future1.cancel(true);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml
new file mode 100644
index 000000000..56440c4f0
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>lock-manager-lib</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>lock-manager-api</module>
+ <module>lock-manager-impl</module>
+ <module>lock-manager-features</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-dispatcher-common/pom.xml b/appc-dispatcher/appc-dispatcher-common/pom.xml
new file mode 100644
index 000000000..4054ff79e
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC Dispatcher Common</name>
+ <description>APPC Dispatcher Common</description>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-data-access-lib</module>
+ <module>execution-queue-management-lib</module>
+ <module>state-machine-lib</module>
+ <module>ranking-framework-lib</module>
+ <module>lock-manager-lib</module>
+ <module>domain-model-lib</module>
+ <module>transaction-recorder</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml
new file mode 100644
index 000000000..03562065d
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/pom.xml
@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-ranking-framework-lib</artifactId>
+ <packaging>bundle</packaging>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Export-Package>org.openecomp.appc.rankingframework</Export-Package>
+ <Private-Package>org.openecomp.appc.rankingframework.impl</Private-Package>
+ <Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Import-Package>!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.apache.log,*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java
new file mode 100644
index 000000000..75480b300
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/AbstractRankedAttributesResolverFactory.java
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+import org.openecomp.appc.rankingframework.impl.DefaultRankedAttributesTreeFactory;
+
+public abstract class AbstractRankedAttributesResolverFactory implements RankedAttributesResolverFactory {
+
+ private static class ReferenceHolder {
+ private static final RankedAttributesResolverFactory INSTANCE = new DefaultRankedAttributesTreeFactory();
+ }
+
+ public static RankedAttributesResolverFactory getInstance() {
+ return ReferenceHolder.INSTANCE;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java
new file mode 100644
index 000000000..77fa8930d
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationEntry.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+public interface ConfigurationEntry<R> {
+ Object getAttributeValue(String name);
+ R getResult();
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java
new file mode 100644
index 000000000..2e862d9fc
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/ConfigurationSet.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+import java.util.Collection;
+
+public interface ConfigurationSet<R> {
+ Collection<String> getRankedAttributeNames();
+
+ Iterable<ConfigurationEntry<R>> getEntries();
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java
new file mode 100644
index 000000000..a8d9b71ec
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesContext.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+public interface RankedAttributesContext {
+ Object getAttributeValue(String name);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java
new file mode 100644
index 000000000..1948ccc1f
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolver.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+public interface RankedAttributesResolver<R> {
+ R resolve(RankedAttributesContext context);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java
new file mode 100644
index 000000000..7267c046c
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/RankedAttributesResolverFactory.java
@@ -0,0 +1,26 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+public interface RankedAttributesResolverFactory {
+ <R> RankedAttributesResolver<R> create(ConfigurationSet<R> config);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java
new file mode 100644
index 000000000..1365ae834
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/BacktraceStrategy.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.openecomp.appc.rankingframework.RankedAttributesContext;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+class BacktraceStrategy implements Strategy {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(BacktraceStrategy.class);
+
+ @Override
+ public <R> R resolve(CompositeNode<R> rootNode, List<String> rankedNames, RankedAttributesContext context) {
+
+ if (logger.isDebugEnabled()) {
+ StringBuilder buff = new StringBuilder(128);
+ for (String name : rankedNames) {
+ buff.append("/{").append(name).append(" = ").append(Utils.value(context.getAttributeValue(name))).append('}');
+ }
+ logger.debug(String.format("Trying to resolve path: %s", buff));
+ }
+
+ Set<String> visited = new HashSet<>();
+
+ CompositeNode<R> parentNode = rootNode;
+ int depth = 0;
+ boolean stop = false;
+ R result = null;
+
+ String attribute = null;
+ Object value = null;
+
+ do {
+ if (value == null) {
+ attribute = rankedNames.get(depth);
+ value = Utils.value(context.getAttributeValue(attribute));
+ }
+
+ Node<R> childNode = parentNode.children().get(value);
+
+ if (childNode != null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Found matching node '%s' - checking it out", childNode));
+ }
+
+ if (!visited.add(childNode.id())) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("The matching node '%s' was checked before - ignoring it", childNode));
+ }
+ childNode = null;
+ }
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Node '%s/{%s = %s}' not found - falling back", parentNode, attribute, value != null ? value : "NULL"));
+ }
+ }
+
+ if (childNode != null) {
+ switch (childNode.type()) {
+ case COMPOSITE:
+ depth++;
+ value = null;
+ parentNode = (CompositeNode<R>) childNode;
+ break;
+ case LEAF:
+ if (logger.isDebugEnabled()) {
+ logger.debug( String.format("Result node has been resolved succesfully - '%s'", childNode));
+ }
+ result = ((LeafNode<R>) childNode).result();
+ stop = true;
+ break;
+ default:
+ throw new IllegalStateException(childNode.type().name());
+ }
+ } else {
+ if (!value.equals(Constants.DEFAULT_MATCH)) {
+ logger.debug("Exact match didn't work, trying the default option, if any");
+ value = Constants.DEFAULT_MATCH;
+ } else if (depth > 0) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Exact match didn't work and no default option available beneath '%s' - moving out", parentNode));
+ }
+ depth--;
+ value = null;
+ parentNode = parentNode.parent();
+ } else {
+ logger.debug("Didn't success to resolve the path - stopping without result");
+ stop = true;
+ }
+ }
+ } while (!stop);
+
+ return result;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java
new file mode 100644
index 000000000..0b5e633f3
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/CompositeNode.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.Map;
+
+class CompositeNode<R> extends NodeBase<R> {
+
+ private final Map<Object, Node<R>> children;
+
+ CompositeNode(String name, Object value, CompositeNode<R> parent, Map<Object, Node<R>> children) {
+ super(name, value, parent, Type.COMPOSITE);
+ this.children = children;
+ }
+
+ Map<Object, Node<R>> children() {
+ return children;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java
new file mode 100644
index 000000000..4111131e2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Constants.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+class Constants {
+
+ private Constants() {
+ }
+
+ static final String DEFAULT_MATCH = "*";
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java
new file mode 100644
index 000000000..d7c48dae6
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/DefaultRankedAttributesTreeFactory.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.openecomp.appc.rankingframework.ConfigurationSet;
+import org.openecomp.appc.rankingframework.RankedAttributesResolver;
+import org.openecomp.appc.rankingframework.RankedAttributesResolverFactory;
+
+public final class DefaultRankedAttributesTreeFactory implements RankedAttributesResolverFactory {
+
+ private final Strategy DEFAULT_STRATEGY = new BacktraceStrategy();
+
+ @Override
+ public <R> RankedAttributesResolver<R> create(ConfigurationSet<R> config) {
+
+ CompositeNode<R> root = RankedAttributesTreeBuilder.build(config);
+ RankedAttributesResolver<R> tree = new RankedAttributesTree<R>(root, toList(config.getRankedAttributeNames()),
+ DEFAULT_STRATEGY);
+ return tree;
+ }
+
+ private static List<String> toList(Collection<String> col) {
+ return Collections.unmodifiableList(new ArrayList<>(col));
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java
new file mode 100644
index 000000000..1b1dffdc8
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/LeafNode.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+class LeafNode<R> extends NodeBase<R> {
+
+ private final R result;
+
+ LeafNode(String name, Object value, CompositeNode<R> parent, R result) {
+ super(name, value, parent, Type.LEAF);
+ this.result = result;
+ }
+
+ R result() {
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buff = new StringBuffer(128);
+ buff.append(super.toString());
+ buff.append(" --> ");
+ buff.append(result.toString());
+ return buff.toString();
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java
new file mode 100644
index 000000000..c33e4d875
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Node.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+interface Node<R> {
+ enum Type {
+ LEAF, COMPOSITE
+ }
+
+ String id();
+
+ String name();
+
+ Object value();
+
+ CompositeNode<R> parent();
+
+ Type type();
+
+ boolean isDefaultMatch();
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java
new file mode 100644
index 000000000..747d9cfd2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/NodeBase.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.UUID;
+
+abstract class NodeBase<R> implements Node<R> {
+
+ private final String name;
+ private final Object value;
+ private final Type type;
+ private final CompositeNode<R> parent;
+ private final String id = UUID.randomUUID().toString();
+
+ NodeBase(String name, Object value, CompositeNode<R> parent, Type type) {
+ this.name = name;
+ this.value = value;
+ this.parent = parent;
+ this.type = type;
+ }
+
+ @Override
+ public String id() {
+ return id;
+ }
+
+ @Override
+ public Type type() {
+ return type;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+
+ @Override
+ public Object value() {
+ return value;
+ }
+
+ @Override
+ public CompositeNode<R> parent() {
+ return parent;
+ }
+
+ @Override
+ public boolean isDefaultMatch() {
+ return value.equals(Constants.DEFAULT_MATCH);
+ }
+
+ @Override
+ public String toString() {
+ if (!name.equals("ROOT")) {
+ StringBuffer buff = new StringBuffer(128);
+ if (parent != null) {
+ buff.append(parent.toString());
+ }
+ buff.append("/{");
+ buff.append(name).append(" = ").append(value);
+ buff.append("}");
+
+ return buff.toString();
+ } else {
+ return "";
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java
new file mode 100644
index 000000000..305af85a6
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTree.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.List;
+
+import org.openecomp.appc.rankingframework.RankedAttributesContext;
+import org.openecomp.appc.rankingframework.RankedAttributesResolver;
+
+class RankedAttributesTree<R> implements RankedAttributesResolver<R> {
+
+ private final CompositeNode<R> root;
+ private final Strategy strategy;
+ private final List<String> rankedNames;
+
+ RankedAttributesTree(CompositeNode<R> root, List<String> rankedNames, Strategy strategy) {
+ this.root = root;
+ this.rankedNames = rankedNames;
+ this.strategy = strategy;
+ }
+
+ @Override
+ public R resolve(RankedAttributesContext context) {
+ return strategy.resolve(root, rankedNames, context);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java
new file mode 100644
index 000000000..16aee5607
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/RankedAttributesTreeBuilder.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.HashMap;
+
+import org.openecomp.appc.rankingframework.ConfigurationEntry;
+import org.openecomp.appc.rankingframework.ConfigurationSet;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+class RankedAttributesTreeBuilder {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(RankedAttributesTreeBuilder.class);
+
+ private RankedAttributesTreeBuilder() {
+ }
+
+ static <R> CompositeNode<R> build(ConfigurationSet<R> config) {
+
+ Object[] names = config.getRankedAttributeNames().toArray();
+
+ CompositeNode<R> root = new CompositeNode<>("ROOT", Constants.DEFAULT_MATCH, null,
+ new HashMap<Object, Node<R>>());
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Building decision tree for ranked attributes: %s", config.getRankedAttributeNames()));
+ }
+
+ for (ConfigurationEntry<R> entry : config.getEntries()) {
+ process(entry, names, root);
+ }
+
+ return root;
+ }
+
+ private static <R> void process(ConfigurationEntry<R> entry, Object[] names, CompositeNode<R> root) {
+ CompositeNode<R> parentNode = null;
+ for (int i = 0; i < names.length; i++) {
+
+ if (i == 0) {
+ parentNode = root;
+ }
+
+ final String name = (String) names[i];
+
+ final Object value = value(entry, name);
+
+ if (i < names.length - 1) {
+ CompositeNode<R> currentNode = (CompositeNode<R>) parentNode.children().get(value);
+ if (currentNode == null) {
+ currentNode = new CompositeNode<>(name, value, parentNode, new HashMap<Object, Node<R>>());
+ parentNode.children().put(value, currentNode);
+ }
+ parentNode = currentNode;
+ } else {
+ LeafNode<R> currentNode = (LeafNode<R>) parentNode.children().get(value);
+ if (currentNode == null) {
+ currentNode = new LeafNode<R>(name, value, parentNode, entry.getResult());
+ parentNode.children().put(value, currentNode);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Branch has been created: %s", currentNode));
+ }
+ } else {
+ logger.error(
+ String.format("Duplicated configuration entry has been detected for attribute '%s' with value '%s' - the node '%s'exists already",
+ name,
+ value,
+ currentNode));
+ throw new IllegalArgumentException("Duplicated configuration entry: " + currentNode);
+ }
+ }
+ }
+ }
+
+ private static <R> Object value(ConfigurationEntry<R> entry, String name) {
+ Object value = entry.getAttributeValue(name);
+ return Utils.value(value);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java
new file mode 100644
index 000000000..121f1fb2d
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Strategy.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+import java.util.List;
+
+import org.openecomp.appc.rankingframework.RankedAttributesContext;
+
+interface Strategy {
+ <R> R resolve(CompositeNode<R> root, List<String> rankedNames, RankedAttributesContext context);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java
new file mode 100644
index 000000000..88ca6d5f5
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/main/java/org/openecomp/appc/rankingframework/impl/Utils.java
@@ -0,0 +1,40 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework.impl;
+
+class Utils {
+
+ private Utils() {
+ }
+
+ static <R> Object value(Object value) {
+ if (value == null || (value instanceof String && isEmpty((String) value))) {
+ value = Constants.DEFAULT_MATCH;
+ }
+
+ return value;
+ }
+
+ private static boolean isEmpty(String str) {
+ return str == null || str.length() == 0;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java
new file mode 100644
index 000000000..75301dc37
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/java/org/openecomp/appc/rankingframework/TestRankingFramework.java
@@ -0,0 +1,225 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.rankingframework;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.appc.rankingframework.AbstractRankedAttributesResolverFactory;
+import org.openecomp.appc.rankingframework.ConfigurationEntry;
+import org.openecomp.appc.rankingframework.ConfigurationSet;
+import org.openecomp.appc.rankingframework.RankedAttributesContext;
+import org.openecomp.appc.rankingframework.RankedAttributesResolver;
+
+public class TestRankingFramework {
+
+ private static final String COUNTRY = "COUNTRY";
+ private static final String STATE = "STATE";
+ private static final String CITY = "CITY";
+
+ private static final List<String> NAMES = Arrays.asList(COUNTRY, STATE, CITY);
+
+ private static final String PACIFIC = "Pacific";
+ private static final String ATLANTIC = "Atlantic";
+ private static final String ARCTIC = "Arctic";
+ private static final String NA = "N/A";
+
+ private static ConfigurationEntry<String> entry(String [] attributes, String result) {
+ if (attributes == null || attributes.length != NAMES.size()) {
+ throw new IllegalArgumentException();
+ }
+
+ Map<String, String> map = new HashMap<>(attributes.length);
+ for (int i = 0; i < attributes.length; i++) {
+ map.put(NAMES.get(i), attributes[i]);
+ }
+
+ return new ConfigurationEntryImpl(map, result);
+ }
+
+ private static ConfigurationSet<String> config(ConfigurationEntry<String> ... entries) {
+ return new ConfigurationSetImpl(Arrays.asList(entries), NAMES);
+ }
+
+ private static RankedAttributesContext context(String ... attributes) {
+ if (attributes == null || attributes.length != NAMES.size()) {
+ throw new IllegalArgumentException();
+ }
+
+ Map<String, String> map = new HashMap<>(attributes.length);
+ for (int i = 0; i < attributes.length; i++) {
+ map.put(NAMES.get(i), attributes[i]);
+ }
+
+ return new Context(map);
+ }
+
+ private static class ConfigurationSetImpl implements ConfigurationSet<String> {
+
+ private final Collection<ConfigurationEntry<String>> entries;
+ private final Collection<String> names;
+
+ ConfigurationSetImpl(Collection<ConfigurationEntry<String>> entries, Collection<String> names) {
+ this.entries = entries;
+ this.names = names;
+ }
+
+ @Override
+ public Iterable<ConfigurationEntry<String>> getEntries() {
+ return entries;
+ }
+
+ @Override
+ public Collection<String> getRankedAttributeNames() {
+ return names;
+ }
+ }
+
+ private static class ConfigurationEntryImpl implements ConfigurationEntry<String> {
+
+ private final Map<String, String> attributes;
+ private final String result;
+
+ ConfigurationEntryImpl(Map<String, String> attributes, String result) {
+ this.attributes = attributes;
+ this.result = result;
+ }
+
+ @Override
+ public Object getAttributeValue(String name) {
+ return attributes.get(name);
+ }
+
+ @Override
+ public String getResult() {
+ return result;
+ }
+ }
+
+ private static class Context implements RankedAttributesContext {
+
+ private final Map<String, String> map;
+
+ Context(Map<String, String> map) {
+ this.map = map;
+ }
+
+ @Override
+ public Object getAttributeValue(String name) {
+ return map.get(name);
+ }
+ }
+
+ private static ConfigurationSet<String> testData() {
+ @SuppressWarnings("unchecked")
+ ConfigurationSet<String> config = config(
+ entry(new String [] {"US", "CA", "SFO"}, PACIFIC),
+ entry(new String [] {"US", "CA", "LA"}, PACIFIC),
+ entry(new String [] {"US", "FL", "MIAMI"}, ATLANTIC),
+ entry(new String [] {"US", "AK", "Barrow"}, ARCTIC),
+ entry(new String [] {"US", "AK", "*"}, PACIFIC),
+ entry(new String [] {"US", "*", "Houston"}, ATLANTIC),
+ entry(new String [] {"US", "*", "*"}, NA)
+ );
+
+ return config;
+ }
+
+ private static RankedAttributesResolver<String> resolver(ConfigurationSet<String> config) {
+ return AbstractRankedAttributesResolverFactory.getInstance().create(config);
+ }
+
+ @Test
+ public void testExactMatch() {
+
+ ConfigurationSet<String> config = testData();
+
+ RankedAttributesResolver<String> resolver = resolver(config) ;
+
+ RankedAttributesContext context = context("US", "CA", "SFO");
+
+ String result = resolver.resolve(context);
+
+ Assert.assertEquals(PACIFIC, result);
+ }
+
+ @Test
+ public void testDefaultMatchPartial() {
+
+ ConfigurationSet<String> config = testData();
+
+ RankedAttributesResolver<String> resolver = resolver(config) ;
+
+ RankedAttributesContext context = context("US", "AK", "Anchorage");
+
+ String result = resolver.resolve(context);
+
+ Assert.assertEquals(PACIFIC, result);
+ }
+
+ @Test
+ public void testDefaultMatchFull() {
+
+ ConfigurationSet<String> config = testData();
+
+ RankedAttributesResolver<String> resolver = resolver(config) ;
+
+ RankedAttributesContext context = context("US", "IL", "Chicago");
+
+ String result = resolver.resolve(context);
+
+ Assert.assertEquals(NA, result);
+ }
+
+ @Test
+ public void testDefaultMatchInTheMiddle() {
+
+ ConfigurationSet<String> config = testData();
+
+ RankedAttributesResolver<String> resolver = resolver(config) ;
+
+ RankedAttributesContext context = context("US", "TX", "Houston");
+
+ String result = resolver.resolve(context);
+
+ Assert.assertEquals(ATLANTIC, result);
+ }
+
+ @Test
+ public void testBacktrace() {
+
+ ConfigurationSet<String> config = testData();
+
+ RankedAttributesResolver<String> resolver = resolver(config) ;
+
+ RankedAttributesContext context = context("US", "CA", "SJC");
+
+ String result = resolver.resolve(context);
+
+ Assert.assertEquals(NA, result);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml
new file mode 100644
index 000000000..2ac88adbc
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/com/att/eelf/logback.xml
@@ -0,0 +1,27 @@
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="false">
+
+<!--
+ Dummy file to suppress default EELF configuration
+ -->
+</configuration>
diff --git a/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml
new file mode 100644
index 000000000..c93e4e4a9
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/ranking-framework-lib/src/test/resources/logback.xml
@@ -0,0 +1,46 @@
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<configuration scan="true" scanPeriod="3 seconds" debug="false">
+
+ <property name="logDirectory" value="target" />
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern> %.-5level %-36.36logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${logDirectory}/debug.log</file>
+ <encoder>
+ <pattern> %.-5level %-36.36logger - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="org.openecomp.appc" level="DEBUG" additivity="false">
+ <appender-ref ref="FILE" />
+ </logger>
+
+ <root level="WARN">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml
new file mode 100644
index 000000000..10f74c6da
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/pom.xml
@@ -0,0 +1,32 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>state-machine-lib</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>state-machine-lib</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Export-Package>org.openecomp.appc.statemachine.*</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java
new file mode 100644
index 000000000..daa8a1ed3
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/StateMachine.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine;
+
+import org.openecomp.appc.statemachine.objects.*;
+
+
+public interface StateMachine {
+ StateMachineResponse handleEvent(State currentState, Event event) throws InvalidInputException;
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java
new file mode 100644
index 000000000..d8a135be4
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineFactory.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.openecomp.appc.statemachine.StateMachine;
+import org.openecomp.appc.statemachine.objects.Event;
+import org.openecomp.appc.statemachine.objects.State;
+import org.openecomp.appc.statemachine.objects.StateMachineMetadata;
+
+
+public class StateMachineFactory {
+
+ private StateMachineFactory(){
+
+ }
+
+ public static StateMachine getStateMachine(StateMachineMetadata metadata){
+ StateMachine machine = new StateMachineImpl(metadata);
+ return machine;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java
new file mode 100644
index 000000000..f4f6612f8
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/impl/StateMachineImpl.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.openecomp.appc.statemachine.StateMachine;
+import org.openecomp.appc.statemachine.objects.*;
+
+
+public class StateMachineImpl implements StateMachine {
+
+ private final Set<State> states;
+
+ private final Set<Event> events;
+
+ StateMachineImpl(StateMachineMetadata metadata){
+ this.states = new HashSet<State>();
+ this.states.addAll(metadata.getStates());
+ this.events = new HashSet<Event>();
+ this.events.addAll(metadata.getEvents());
+ }
+
+ public StateMachineResponse handleEvent(State inputState, Event event) throws InvalidInputException{
+
+ if(!validateInputs(inputState,event)){
+ throw new InvalidInputException("VNF State or incoming event is invalid. State = " +inputState + " event = " + event );
+ }
+
+ StateMachineResponse response = new StateMachineResponse();
+ State currentState = null,nextState = null;
+ for(State stateInSet:states){
+ if(stateInSet.equals(inputState)){
+ currentState = stateInSet;
+ break;
+ }
+ }
+ for(Transition transition : currentState.getTransitions()){
+ if(event.equals(transition.getEvent())){
+ nextState = transition.getNextState();
+ }
+ }
+ if(nextState == null){
+ response.setResponse(Response.NO_TRANSITION_DEFINED);
+ }
+ else if(inputState.equals(nextState)){
+ response.setResponse(Response.NO_STATE_CHANGE);
+ }
+ else{
+ response.setResponse(Response.VALID_TRANSITION);
+ }
+ response.setNextState(nextState);
+ return response;
+ }
+
+ private boolean validateInputs(State state,Event event){
+ if(state ==null || event == null){
+ return false;
+ }
+ if(!(this.states.contains(state) && this.events.contains(event))){
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "StateMachineImpl{" +
+ "states=" + states +
+ ", events=" + events +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java
new file mode 100644
index 000000000..377cd8138
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Event.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+public class Event{
+
+ private String eventName;
+
+ private Event(){
+
+ }
+ @Override
+ public int hashCode(){
+ return this.eventName.hashCode();
+ }
+ @Override
+ public boolean equals(Object obj){
+ if(obj == null){
+ return false;
+ }
+ if(!(obj instanceof Event)){
+ return false;
+ }
+ Event event = (Event)obj;
+ return this.eventName.equals(event.getEventName());
+ }
+
+ public Event(String eventName){
+ this();
+ this.eventName = eventName;
+ }
+
+ public String getEventName() {
+ return eventName;
+ }
+ @Override
+ public String toString(){
+ return this.eventName;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java
new file mode 100644
index 000000000..db6b6d3ce
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/InvalidInputException.java
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+public class InvalidInputException extends Exception{
+ public InvalidInputException(String message){
+ super(message);
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java
new file mode 100644
index 000000000..8f24c46a0
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Response.java
@@ -0,0 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+
+public enum Response {
+ NO_TRANSITION_DEFINED,NO_STATE_CHANGE,VALID_TRANSITION;
+ public String toString(){
+ return this.name();
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java
new file mode 100644
index 000000000..18daef02e
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/State.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+
+public class State{
+ private String stateName;
+ private List<Transition> transitions;
+
+ private State(){
+
+ }
+
+ public State(String state){
+ this();
+ this.stateName = state;
+ this.transitions = new ArrayList<Transition>();
+ }
+
+ @Override
+ public int hashCode(){
+ return this.stateName.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj){
+ if(obj == null){
+ return false;
+ }
+ if(!(obj instanceof State)){
+ return false;
+ }
+ State state = (State)obj;
+ return this.stateName.equals(state.getStateName());
+ }
+
+
+ public String getStateName(){
+ return stateName;
+ }
+
+ void addTransition(Transition transition){
+ this.transitions.add(transition);
+ }
+
+ public List<Transition> getTransitions() {
+ return transitions;
+ }
+
+ @Override
+ public String toString(){
+ return this.stateName;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java
new file mode 100644
index 000000000..6625fef19
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineMetadata.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+public class StateMachineMetadata {
+
+ Set<State> states;
+ Set<Event> events;
+
+ private StateMachineMetadata(StateMachineMetadataBuilder builder){
+ states = builder.states;
+ events = builder.events;
+ }
+
+ public Set<State> getStates() {
+ return states;
+ }
+
+ public Set<Event> getEvents() {
+ return events;
+ }
+
+ public static class StateMachineMetadataBuilder{
+
+ private Set<State> states;
+ private Set<Event> events;
+
+ public StateMachineMetadataBuilder(){
+ states = new HashSet<State>();
+ events = new HashSet<Event>();
+ }
+
+ public StateMachineMetadataBuilder addState(State state){
+ this.states.add(state);
+ return this;
+ }
+
+ public StateMachineMetadataBuilder addEvent(Event event){
+ this.events.add(event);
+ return this;
+ }
+
+ public StateMachineMetadataBuilder addTransition(State currentState,Event event,State nextState){
+ Transition transition = new Transition(event,nextState);
+ currentState.addTransition(transition);
+ return this;
+ }
+
+ public StateMachineMetadata build(){
+ StateMachineMetadata machine = new StateMachineMetadata(this);
+ return machine;
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java
new file mode 100644
index 000000000..ce75693fc
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/StateMachineResponse.java
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+
+public class StateMachineResponse {
+ State nextState;
+ Response response;
+
+ public StateMachineResponse(){
+
+ }
+
+ public State getNextState() {
+ return nextState;
+ }
+
+ public Response getResponse() {
+ return response;
+ }
+
+ public void setNextState(State nextState) {
+ this.nextState = nextState;
+ }
+
+ public void setResponse(Response response) {
+ this.response = response;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java
new file mode 100644
index 000000000..4a268f931
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/main/java/org/openecomp/appc/statemachine/objects/Transition.java
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine.objects;
+
+
+public class Transition {
+ private Event event;
+ private State nextState;
+
+ private Transition(){
+
+ }
+ public Transition(Event event,State nextState){
+ this();
+ this.event = event;
+ this.nextState = nextState;
+ }
+
+ public Event getEvent() {
+ return event;
+ }
+
+ public State getNextState() {
+ return nextState;
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java
new file mode 100644
index 000000000..735e8e13c
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/state-machine-lib/src/test/java/org/openecomp/appc/statemachine/TestStateMachine.java
@@ -0,0 +1,98 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.statemachine;
+
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.appc.statemachine.impl.StateMachineFactory;
+import org.openecomp.appc.statemachine.objects.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+
+public class TestStateMachine {
+
+ @Test
+ public void handleEvent() throws InvalidInputException {
+
+// MetadataReader metadataReader = new MetadataReader();
+// StateMachineMetadata metadata = metadataReader.readMetadata(null);
+//
+// StateMachine machine = StateMachineFactory.getStateMachine(metadata);
+//
+// /*
+// Testing Positive Scenario passing the valid events and validating the StateMachineResponse
+// */
+// for(State state:metadata.getStates()){
+//
+// for(Transition transition:state.getTransitions()){
+// Event event = transition.getEvent();
+// State nextState = transition.getNextState();
+//
+// StateMachineResponse response = machine.handleEvent(state,event);
+// Assert.assertEquals(response.getNextState(),nextState);
+// Assert.assertEquals(response.getResponse(),Response.VALID_TRANSITION);
+// }
+// }
+//
+// /*
+// Testing Negative Scenarios, 1. Passing the valid Events for which Transition is not defined in
+// Metadata and validating the StateMachineResponse 2. Passing the invalid events which are not
+// registered as events in the StateMachineMetadata and validating StateMachineResponse
+// */
+// for(State state:metadata.getStates()){
+//
+// for(Transition transition:state.getTransitions()){
+// List<Event> negativeEvents = getNegativeEvents(state,metadata.getEvents());
+//
+// for(Event negativeEvent:negativeEvents){
+// StateMachineResponse response = machine.handleEvent(state,negativeEvent);
+// Assert.assertEquals(response.getNextState(),null);
+// Assert.assertEquals(response.getResponse(),Response.NO_TRANSITION_DEFINED);
+//
+// boolean flag =false;
+// try{
+// response = machine.handleEvent(state,new Event("PUT"));
+// }
+// catch(InvalidInputException e){
+// flag = true;
+// }
+// Assert.assertTrue(flag);
+//
+// }
+// }
+// }
+ }
+
+// private List<Event> getNegativeEvents(State state,Set<Event> events) {
+// List<Event> negativeEventList = new ArrayList<>();
+// negativeEventList.addAll(events);
+//
+// for(Transition transition: state.getTransitions()){
+// negativeEventList.remove(transition.getEvent());
+// }
+// return negativeEventList;
+// }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="java" version="1.8"/>
+</faceted-project>
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml
new file mode 100644
index 000000000..af399eae2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>appc-dispatcher-common</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>transaction-recorder</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>transaction-recorder</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-data-access-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Bundle-Version>${project.version}</Bundle-Version>
+ <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Export-Service>org.openecomp.appc.transactionrecorder.TransactionRecorder</Export-Service>
+ <Import-Package>!javax.*,!groovy.lang,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package>
+ <Export-Package>org.openecomp.appc.transactionrecorder,org.openecomp.appc.transactionrecorder.objects</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java
new file mode 100644
index 000000000..27fdc05b0
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/TransactionRecorder.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.transactionrecorder;
+
+
+import org.openecomp.appc.transactionrecorder.objects.TransactionRecord;
+
+
+public interface TransactionRecorder {
+ /**
+ * Stores transaction record to appc database by calling APPC Dao layer.
+ * @param record Transaction record data.
+ */
+ void store(TransactionRecord record);
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java
new file mode 100644
index 000000000..74040d3e4
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/impl/TransactionRecorderImpl.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.transactionrecorder.impl;
+
+import org.openecomp.appc.dao.util.DBUtils;
+import org.openecomp.appc.transactionrecorder.TransactionRecorder;
+import org.openecomp.appc.transactionrecorder.objects.TransactionRecord;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+
+
+public class TransactionRecorderImpl implements TransactionRecorder {
+
+ private static String APPCCTL_SCHEMA = "appcctl";
+
+ private static final Logger logger = LoggerFactory.getLogger(TransactionRecorderImpl.class);
+
+ /**
+ * Stores transaction record to appc database by calling APPC Dao layer.
+ * @param record Transaction record data.
+ */
+ @Override
+ public void store(TransactionRecord record) {
+ Connection connection = null;
+ PreparedStatement stmt = null;
+ String queryString = "INSERT INTO transactions VALUES (?,?,?,?,?,?,?,?,?,?)";
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Transaction Data started Inserting Successfully into DB");
+ }
+ connection = DBUtils.getConnection(APPCCTL_SCHEMA);
+ stmt = connection.prepareStatement(queryString);
+ stmt.setTimestamp(1, new java.sql.Timestamp(record.getTimeStamp().getTime()));
+ stmt.setString(2, record.getRequestID());
+ stmt.setTimestamp(3, new java.sql.Timestamp(record.getStartTime().getTime()));
+ stmt.setTimestamp(4, new java.sql.Timestamp(record.getEndTime().getTime()));
+ stmt.setString(5, record.getTargetID());
+ stmt.setString(6, record.getTargetType());
+ stmt.setString(7, record.getSubComponent());
+ stmt.setString(8, record.getOperation());
+ stmt.setString(9, record.getResultCode());
+ stmt.setString(10, record.getDescription());
+ stmt.execute();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Transaction Data Inserted Successfully into DB");
+ }
+ } catch (SQLException e) {
+ logger.error("Error Accessing Database " + e);
+ throw new RuntimeException(e);
+ } finally {
+ DBUtils.clearResources(null, stmt, connection);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java
new file mode 100644
index 000000000..4807aed0a
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/java/org/openecomp/appc/transactionrecorder/objects/TransactionRecord.java
@@ -0,0 +1,147 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.transactionrecorder.objects;
+
+import java.util.Date;
+
+
+public class TransactionRecord {
+
+ /*
+- Timestamp = RequestHandlerInput.RequestHeader.timeStamp
+- Request ID = RequestHandlerInput.RequestHeader.requestID
+- Start time = from flow
+- End time = from flow
+- VF_ID = RequestHandlerInput.targetID
+- VF_type = genericVnf.getVnfType()
+- Sub-component (optional) e.g. VFC_ID/VM UUID - ???? empty
+- Operation e.g. Start, Configure etc. = CommandContext.Command
+- Result - Success/Error code + description,as published to the initiator RequestHandlerResponse.ACCEPTED/RequestHandlerResponse.REJECTED + String (description)
+ */
+
+ private Date timeStamp;
+ private String requestID;
+ private Date startTime;
+ private Date endTime;
+ private String targetID;
+ private String targetType;
+ private String subComponent;
+ private String operation;
+ private String resultCode;
+ private String description;
+
+ public Date getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(Date timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public String getRequestID() {
+ return requestID;
+ }
+
+ public void setRequestID(String requestID) {
+ this.requestID = requestID;
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ this.startTime = startTime;
+ }
+
+ public Date getEndTime() {
+ return endTime;
+ }
+
+ public void setEndTime(Date endTime) {
+ this.endTime = endTime;
+ }
+
+ public String getTargetID() {
+ return targetID;
+ }
+
+ public void setTargetID(String targetID) {
+ this.targetID = targetID;
+ }
+
+ public String getTargetType() {
+ return targetType;
+ }
+
+ public void setTargetType(String targetType) {
+ this.targetType = targetType;
+ }
+
+ public String getSubComponent() {
+ return subComponent;
+ }
+
+ public void setSubComponent(String subComponent) {
+ this.subComponent = subComponent;
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public void setOperation(String operation) {
+ this.operation = operation;
+ }
+
+ public String getResultCode() {
+ return resultCode;
+ }
+
+ public void setResultCode(String resultCode) {
+ this.resultCode = resultCode;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ @Override
+ public String toString() {
+ return "TransactionRecord{" +
+ "timeStamp=" + timeStamp +
+ ", requestID='" + requestID + '\'' +
+ ", startTime=" + startTime +
+ ", endTime=" + endTime +
+ ", targetID='" + targetID + '\'' +
+ ", targetType='" + targetType + '\'' +
+ ", subComponent='" + subComponent + '\'' +
+ ", operation='" + operation + '\'' +
+ ", resultCode='" + resultCode + '\'' +
+ ", description='" + description + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..2d2ef7a23
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-common/transaction-recorder/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ openECOMP : APP-C
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. 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.
+ ============LICENSE_END=========================================================
+ -->
+
+<!--
+ Starter Blueprint Camel Definition appc-aai-adapter-blueprint
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+ <bean id="transactionRecorderBean" class="org.openecomp.appc.transactionrecorder.impl.TransactionRecorderImpl" scope="singleton" ></bean>
+ <service id="transactionRecorderService" interface="org.openecomp.appc.transactionrecorder.TransactionRecorder" ref="transactionRecorderBean"/>
+</blueprint>