aboutsummaryrefslogtreecommitdiffstats
path: root/appc-dispatcher
diff options
context:
space:
mode:
authorPatrick Brady <pb071s@att.com>2017-02-15 23:11:26 -0800
committerPatrick Brady <pb071s@att.com>2017-02-15 23:13:06 -0800
commit1c192d2dd68724e292b6a30f463085a262e1e813 (patch)
treed0e2b3a396e169863cd0efaa835c8675e9d5aaac /appc-dispatcher
parentc69ba05c7508aa7d7f675189a45c8c87569369ef (diff)
Moving all files to root directory
Change-Id: Ica5535fd6ec85f350fe1640b42137b49f83f10f0 Signed-off-by: Patrick Brady <pb071s@att.com>
Diffstat (limited to 'appc-dispatcher')
-rw-r--r--appc-dispatcher/.gitignore2
-rw-r--r--appc-dispatcher/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-command-executor/.gitignore1
-rw-r--r--appc-dispatcher/appc-command-executor/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/.gitignore1
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml60
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java41
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.java29
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.java49
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java54
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.java38
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java112
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java57
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java123
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore1
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml105
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java153
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java126
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java65
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.java72
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.java45
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java261
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java81
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java89
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.java32
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.java33
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml51
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties48
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java312
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java157
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties102
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore3
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-features/pom.xml107
-rw-r--r--appc-dispatcher/appc-command-executor/appc-command-executor-features/src/main/resources/features.xml35
-rw-r--r--appc-dispatcher/appc-command-executor/pom.xml22
-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
-rw-r--r--appc-dispatcher/appc-dispatcher-features/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-features/pom.xml60
-rw-r--r--appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml37
-rw-r--r--appc-dispatcher/appc-dispatcher-installer/.gitignore1
-rw-r--r--appc-dispatcher/appc-dispatcher-installer/pom.xml223
-rw-r--r--appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml59
-rw-r--r--appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml47
-rw-r--r--appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh54
-rw-r--r--appc-dispatcher/appc-license-manager/.gitignore1
-rw-r--r--appc-dispatcher/appc-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/.gitignore1
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml47
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java109
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java54
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java58
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.java45
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.java45
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore1
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml71
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java177
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java100
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml33
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties49
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java22
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java57
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java22
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java56
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java61
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore3
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-features/pom.xml107
-rw-r--r--appc-dispatcher/appc-license-manager/appc-license-manager-features/src/main/resources/features.xml34
-rw-r--r--appc-dispatcher/appc-license-manager/pom.xml22
-rw-r--r--appc-dispatcher/appc-lifecycle-management/.gitignore1
-rw-r--r--appc-dispatcher/appc-lifecycle-management/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.gitignore1
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/pom.xml36
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.java30
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.java33
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.java34
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.java34
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.java29
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore1
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml82
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java337
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java94
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml34
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties48
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java155
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore1
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml108
-rw-r--r--appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml35
-rw-r--r--appc-dispatcher/appc-lifecycle-management/pom.xml22
-rw-r--r--appc-dispatcher/appc-request-handler/.gitignore1
-rw-r--r--appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore1
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml59
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java28
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java77
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java58
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java48
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore1
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml121
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java33
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java40
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java127
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java341
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java35
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java29
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java29
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java29
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java29
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java34
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java79
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java37
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java114
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java839
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java382
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java48
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java44
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java28
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java227
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java30
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java90
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml60
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties53
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java360
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java583
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java626
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java110
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties107
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore1
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml107
-rw-r--r--appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml36
-rw-r--r--appc-dispatcher/appc-request-handler/pom.xml22
-rw-r--r--appc-dispatcher/appc-workflow-management/.gitignore1
-rw-r--r--appc-dispatcher/appc-workflow-management/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.gitignore1
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/pom.xml48
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.java47
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java94
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java67
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.java47
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore1
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml76
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java67
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java343
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.java59
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java139
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java128
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml35
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties52
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java186
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties100
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore1
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-features/pom.xml107
-rw-r--r--appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml34
-rw-r--r--appc-dispatcher/appc-workflow-management/pom.xml22
-rw-r--r--appc-dispatcher/pom.xml78
275 files changed, 17895 insertions, 0 deletions
diff --git a/appc-dispatcher/.gitignore b/appc-dispatcher/.gitignore
new file mode 100644
index 000000000..09e3bc9b2
--- /dev/null
+++ b/appc-dispatcher/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/appc-dispatcher/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/.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-command-executor/.gitignore b/appc-dispatcher/appc-command-executor/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-command-executor/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-command-executor/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/.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-command-executor/appc-command-executor-api/.gitignore b/appc-dispatcher/appc-command-executor/appc-command-executor-api/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-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-command-executor/appc-command-executor-api/pom.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml
new file mode 100644
index 000000000..645f0b630
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml
@@ -0,0 +1,60 @@
+<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-command-executor</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-command-executor-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-command-executor-api</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>execution-queue-management-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>domain-model-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--<dependency>-->
+ <!--<groupId>org.apache.commons</groupId>-->
+ <!--<artifactId>commons-lang3</artifactId>-->
+ <!--<version>3.4</version>-->
+ <!--<scope>provided</scope>-->
+ <!--<type>bundle</type>-->
+ <!--</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.executor,org.openecomp.appc.executor.objects,org.openecomp.appc.executor.conv,org.openecomp.appc.executor.helper</Export-Package>
+ <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,javax.json;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <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.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java
new file mode 100644
index 000000000..ac5223b93
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/CommandExecutor.java
@@ -0,0 +1,41 @@
+/*-
+ * ============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.executor;
+
+
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+
+
+
+public interface CommandExecutor {
+ /**
+ * Execute given command
+ * Create command request and enqueue it for execution.
+ * @param commandHeaderInput Contains CommandHeader, command , target Id , payload and conf ID (optional)
+ * @throws APPCException in case of error.
+ */
+ void executeCommand(CommandExecutorInput commandHeaderInput) throws APPCException;
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.java
new file mode 100644
index 000000000..3727cdb40
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/UnstableVNFException.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.executor;
+
+
+public class UnstableVNFException extends Exception{
+ public UnstableVNFException(String message){
+ super(message);
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.java
new file mode 100644
index 000000000..a9991e43e
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/conv/Converter.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.executor.conv;
+
+import java.io.IOException;
+
+import org.openecomp.appc.executor.objects.Params;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+public class Converter {
+
+ public static Params convJsonStringToParams(String inObj) throws IOException {
+ Params outObj = null;
+ if(inObj != null) {
+ outObj = new ObjectMapper().readValue(inObj, Params.class);
+ }
+ return outObj;
+ }
+
+ public static String convParamsToJsonString(Params inObj) throws JsonProcessingException {
+ String outObj = null;
+ if(inObj != null) {
+ outObj = new ObjectMapper().writeValueAsString(inObj);
+ }
+ return outObj;
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java
new file mode 100644
index 000000000..4cb5f1b99
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandExecutorInput.java
@@ -0,0 +1,54 @@
+/*-
+ * ============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.executor.objects;
+
+import org.openecomp.appc.domainmodel.lcm.RuntimeContext;
+
+public class CommandExecutorInput {
+ private RuntimeContext runtimeContext ;
+ private int ttl;
+
+
+ public RuntimeContext getRuntimeContext() {
+ return runtimeContext;
+ }
+
+ public void setRuntimeContext(RuntimeContext runtimeContext) {
+ this.runtimeContext = runtimeContext;
+ }
+
+ public int getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(int ttl) {
+ this.ttl = ttl;
+ }
+
+ @Override
+ public String toString() {
+ return "CommandExecutorInput{" +
+ "runtimeContext=" + runtimeContext +
+ ", ttl=" + ttl +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.java
new file mode 100644
index 000000000..c973fcde1
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/CommandResponse.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.executor.objects;
+
+import org.openecomp.appc.domainmodel.lcm.RuntimeContext;
+
+
+public class CommandResponse {
+
+ private RuntimeContext runtimeContext;
+
+ public RuntimeContext getRuntimeContext() {
+ return runtimeContext;
+ }
+
+ public void setRuntimeContext(RuntimeContext runtimeContext) {
+ this.runtimeContext = runtimeContext;
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java
new file mode 100644
index 000000000..4e3a40e75
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java
@@ -0,0 +1,112 @@
+/*-
+ * ============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.executor.objects;
+
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.appc.util.MessageFormatter;
+
+import java.util.Map;
+
+public enum LCMCommandStatus {
+
+ ACCEPTED(100,"ACCEPTED - request accepted"),
+
+ //ERROR(2xx) – request can’t be handled due to some technical error
+ UNEXPECTED_ERROR(200,"UNEXPECTED ERROR - ${errorMsg}"),
+
+ //REJECT(3xx) – request has been rejected due to some business reason (e.g. no such service-instance-id, command is not supported, etc)
+ REJECTED(300,"REJECTED - ${errorMsg}"),
+ INVALID_INPUT_PARAMETER(301,"INVALID INPUT PARAMETER - ${errorMsg}"),// TODO 77777777 to support "${paramName} with invalid value ${paramValue}"
+ MISSING_MANDATORY_PARAMETER(302,"MISSING MANDATORY PARAMETER - Parameter/s ${paramName} is/are missing" ),
+ REQUEST_PARSING_FAILED(303,"REQUEST PARSING FAILED - ${errorMsg}"),
+ NO_TRANSITION_DEFINE(304,"ACTION IS NOT ALLOWED - Action ${actionName} is not allowed for VNF in state ${currentState}"),
+ ACTION_NOT_SUPPORTED(305,"ACTION NOT SUPPORTED - ${actionName} action is not supported" ),
+ VNF_NOT_FOUND(306,"VNF NOT FOUND - VNF with ID ${vnfId} was not found" ),
+ DG_WORKFLOW_NOT_FOUND(307,"DG WORKFLOW NOT FOUND - No DG workflow found for the combination of ${dgModule} module ${dgName} name and ${dgVersion} version"),//TODO need to support it
+ WORKFLOW_NOT_FOUND(308,"WORKFLOW NOT FOUND - No workflow found for VNF type ${vnfTypeVersion} and ${actionName} action"),
+ UNSTABLE_VNF(309,"UNSTABLE VNF - VNF ${vnfId} is not stable to accept the command"),
+ LOCKING_FAILURE(310,"LOCKING FAILURE - ${errorMsg}" ),
+ EXPIRED_REQUEST(311,"EXPIRED REQUEST"),
+ DUPLICATE_REQUEST(312,"DUPLICATE REQUEST"),
+
+ SUCCESS(400,"SUCCESS - request has been processed successfully"),
+
+
+ // FAILURE(5xx) – request processing results with failure. The FAILURE response is always transmitted asynchronously, via DMaaP.
+ DG_FAILURE(401,"DG FAILURE - ${errorMsg}"),
+ NO_TRANSITION_DEFINE_FAILURE(402,"NO TRANSITION DEFINE - No Transition Defined for ${actionName} action and ${currentState} state"),
+ UPDATE_AAI_FAILURE(403,"UPDATE_AAI_FAILURE - failed to update AAI. ${errorMsg}"),
+ EXPIRED_REQUEST_FAILURE(404,"EXPIRED REQUEST FAILURE - failed after accepted because TTL expired"),
+ UNEXPECTED_FAILURE(405,"UNEXPECTED FAILURE - ${errorMsg}"),
+ UNSTABLE_VNF_FAILURE(406,"UNSTABLE VNF FAILURE - VNF ${vnfId} is not stable to accept the command"),
+
+ ;
+
+
+ public static final String errorDgMessageParamName = "errorDgMessage";
+
+ private int responseCode;
+ private String responseMessage;
+
+
+
+
+ LCMCommandStatus(int responseCode, String responseMessage) {
+ this.responseCode = responseCode;
+ this.responseMessage = responseMessage;
+ }
+
+ public String getResponseMessage() {
+ return responseMessage;
+ }
+
+ public int getResponseCode() {
+ return responseCode;
+ }
+
+
+ /**
+ *
+ * @return messageTemplate
+ */
+
+
+ public String getFormattedMessage(Params params){
+ Map<String,Object> paramsMap = params != null ? params.getParams() : null;
+ return MessageFormatter.format(getResponseMessage(),paramsMap);
+
+ }
+
+ public String getFormattedMessageWithCode(Params params){
+ return getResponseCode()+"-" + getFormattedMessage(params);
+ }
+
+ @Override
+ public String toString() {
+ return "LCMCommandStatus{" +
+ "responseCode=" + responseCode +
+ ", responseMessage='" + responseMessage + '\'' +
+ '}';
+ }
+}
+
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java
new file mode 100644
index 000000000..8db4f6576
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/Params.java
@@ -0,0 +1,57 @@
+/*-
+ * ============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.executor.objects;
+
+import java.lang.Object;
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class Params {
+ public static final String paramDgNameSpace = "dg.status.message.param.";
+ public static final String errorDgMessageParamName = "errorDgMessage";
+ private Map<String, java.lang.Object> params;
+
+ public Params() {
+ }
+
+ public Map<String, java.lang.Object> getParams() {
+ return params;
+ }
+
+ public void setParams(Map<String, java.lang.Object> params) {
+ this.params = params;
+ }
+
+ public Params addParam(String paramName, java.lang.Object paramValue) {
+ params = params == null ? new HashMap<String, Object>() : params;
+ params.put(paramName, paramValue);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "Params{" +
+ "params=" + params +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java
new file mode 100644
index 000000000..0e33ca4c2
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/UniqueRequestIdentifier.java
@@ -0,0 +1,123 @@
+/*-
+ * ============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.executor.objects;
+
+
+import org.apache.commons.lang3.StringUtils;
+
+
+public class UniqueRequestIdentifier {
+ private static final String IDENTIFIER_DELIMITER = "@";
+
+ private String originatorID;
+ private String requestID;
+ private String subRequestID;
+
+ private UniqueRequestIdentifier(){
+
+ }
+ public UniqueRequestIdentifier(String originatorID,
+ String requestID,
+ String subRequestID) {
+ this();
+ this.originatorID = originatorID;
+ this.requestID = requestID;
+ this.subRequestID = subRequestID;
+ }
+
+ public String toIdentifierString(){
+ StringBuilder stringBuilder = new StringBuilder();
+ if(originatorID != null){
+ stringBuilder.append(originatorID);
+ }
+ stringBuilder.append(IDENTIFIER_DELIMITER);
+
+ if(requestID != null){
+ stringBuilder.append(requestID);
+ }
+ stringBuilder.append(IDENTIFIER_DELIMITER);
+
+ if(subRequestID != null){
+ stringBuilder.append(subRequestID);
+ }
+ return stringBuilder.toString();
+ }
+
+ public static UniqueRequestIdentifier getUniqueRequestIdentifier(String identifierString){
+ String[] splitIdentifier = identifierString.split(IDENTIFIER_DELIMITER);
+ if(splitIdentifier == null || splitIdentifier.length <2){
+ throw new IllegalArgumentException("input identifierString is not valid "+identifierString);
+ }
+ String originatorID = splitIdentifier[0];
+ String requestID = StringUtils.isEmpty(splitIdentifier[1])? null :splitIdentifier[1];
+ String subRequestID = splitIdentifier.length>=3 ? splitIdentifier[2] : null;
+ return new UniqueRequestIdentifier(originatorID,requestID,subRequestID);
+ }
+ public String toString(){
+ return "originatorID = " + originatorID +
+ " , requestID = " + requestID +
+ " , subRequestID = " + subRequestID;
+ }
+ @Override
+ public boolean equals(Object obj){
+ if(obj ==null){
+ return false;
+ }
+ if(!(obj instanceof UniqueRequestIdentifier)){
+ return false;
+ }
+ UniqueRequestIdentifier identifier = (UniqueRequestIdentifier)obj;
+ if(this.originatorID == null){
+ if(identifier.originatorID !=null)
+ return false;
+ }
+ else if(!this.originatorID.equals(identifier.originatorID))
+ return false;
+
+ if(this.requestID == null){
+ if(identifier.requestID !=null)
+ return false;
+ }
+ else if(!this.requestID.equals(identifier.requestID))
+ return false;
+
+ if(this.subRequestID == null){
+ if(identifier.subRequestID !=null)
+ return false;
+ }
+ else if(!this.subRequestID.equals(identifier.subRequestID))
+ return false;
+
+ return true;
+ }
+ @Override
+ public int hashCode(){
+ final int prime = 31;
+ int result = 1;
+ result = result * prime + (this.originatorID == null ? 0 :this.originatorID.hashCode());
+ result = result * prime + (this.requestID == null ? 0 :this.requestID.hashCode());
+ result = result * prime + (this.subRequestID == null ? 0 :this.subRequestID.hashCode());
+ return result;
+ }
+
+
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore b/appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/.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-command-executor/appc-command-executor-core/pom.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml
new file mode 100644
index 000000000..942bf7dd0
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml
@@ -0,0 +1,105 @@
+<?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">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-command-executor-core</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-command-executor-core Bundle</name>
+ <description>appc-command-executor-core OSGi bundle project.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>execution-queue-management-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-data-access-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dmaap-adapter-bundle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.adaptors</groupId>
+ <artifactId>aai-service-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>domain-model-lib</artifactId>
+ <version>${project.version}</version>
+ </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-Service>org.openecomp.appc.executor.CommandExecutor</Export-Service>
+ <Import-Package>org.openecomp.appc.executionqueue.*,org.openecomp.appc.executor,org.openecomp.appc.executor.objects,!groovy.lang,!javax.jms,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!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-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java
new file mode 100644
index 000000000..60a951722
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java
@@ -0,0 +1,153 @@
+/*-
+ * ============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.executor.impl;
+
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executionqueue.ExecutionQueueService;
+import org.openecomp.appc.executionqueue.impl.ExecutionQueueServiceFactory;
+import org.openecomp.appc.executor.CommandExecutor;
+import org.openecomp.appc.executor.impl.objects.CommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMCommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMReadOnlyCommandRequest;
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+
+public class CommandExecutorImpl implements CommandExecutor {
+
+ private CommandTaskFactory executionTaskFactory ;
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(CommandExecutorImpl.class);
+
+ private ExecutionQueueService executionQueueService;
+ private ExpiredMessageHandler expiredMessageHandler;
+
+ public CommandExecutorImpl(){
+
+ }
+
+ public void setExecutionQueueService(ExecutionQueueService executionQueueService) {
+ this.executionQueueService = executionQueueService;
+ }
+
+ public void setExpiredMessageHandler(ExpiredMessageHandler expiredMessageHandler) {
+ this.expiredMessageHandler = expiredMessageHandler;
+ }
+
+ public void initialize() {
+ logger.info("initialization started of CommandExecutorImpl");
+ executionQueueService = ExecutionQueueServiceFactory.getExecutionQueueService();
+ executionQueueService.registerMessageExpirationListener(expiredMessageHandler);
+ }
+
+ public void setExecutionTaskFactory(CommandTaskFactory executionTaskFactory) {
+ this.executionTaskFactory = executionTaskFactory;
+ }
+
+ /**
+ * Execute given command
+ * Create command request and enqueue it for execution.
+ * @param commandExecutorInput Contains CommandHeader, command , target Id , payload and conf ID (optional)
+ * @throws APPCException in case of error.
+ */
+ @Override
+ public void executeCommand (CommandExecutorInput commandExecutorInput) throws APPCException{
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to executeCommand with CommandExecutorInput = "+ ObjectUtils.toString(commandExecutorInput));
+ }
+ CommandRequest request = getCommandRequest(commandExecutorInput);
+ enqueRequest(request);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from executeCommand");
+ }
+ }
+
+ private CommandRequest getCommandRequest(CommandExecutorInput commandExecutorInput){
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to getCommandRequest with CommandExecutorInput = "+ ObjectUtils.toString(commandExecutorInput));
+ }
+ CommandRequest commandRequest;
+
+ switch(commandExecutorInput.getRuntimeContext().getRequestContext().getAction()){
+ case Sync:
+ commandRequest = new LCMReadOnlyCommandRequest(commandExecutorInput);
+ break;
+ case Audit:
+ commandRequest = new LCMReadOnlyCommandRequest(commandExecutorInput);
+ break;
+ default:
+ commandRequest = new LCMCommandRequest(commandExecutorInput);
+ break;
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from getCommandRequest with (CommandRequest = "+ ObjectUtils.toString(commandRequest)+")");
+ }
+ return commandRequest;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void enqueRequest(CommandRequest request) throws APPCException{
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to enqueRequest with CommandRequest = "+ ObjectUtils.toString(request));
+ }
+ try {
+ CommandTask commandTask = getMessageExecutor(request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getAction().name());
+ commandTask.setCommandRequest(request);
+ long remainingTTL = getRemainingTTL(request);
+ executionQueueService.putMessage(commandTask,remainingTTL, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ logger.error("Exception: "+e.getMessage());
+ throw new APPCException(e);
+ }
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from enqueRequest");
+ }
+ }
+
+ private long getRemainingTTL(CommandRequest request) {
+ Date requestTimestamp = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader().getTimeStamp();
+ int ttl = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader().getFlags().getTtl();
+ return ttl*1000 + requestTimestamp.getTime() - System.currentTimeMillis();
+ }
+
+ private CommandTask getMessageExecutor(String action){
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to getMessageExecutor with command = "+ action);
+ }
+ CommandTask executionTask = executionTaskFactory.getExecutionTask(action);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from getMessageExecutor");
+ }
+ return executionTask;
+ }
+
+
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java
new file mode 100644
index 000000000..6418002c2
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java
@@ -0,0 +1,126 @@
+/*-
+ * ============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.executor.impl;
+
+import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY;
+import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID;
+import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN;
+import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+import java.net.InetAddress;
+
+import org.openecomp.appc.domainmodel.lcm.RuntimeContext;
+import org.openecomp.appc.domainmodel.lcm.Status;
+import org.openecomp.appc.executor.impl.objects.CommandRequest;
+import org.openecomp.appc.executor.objects.CommandResponse;
+import org.openecomp.appc.executor.objects.LCMCommandStatus;
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.logging.LoggingConstants;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workflow.objects.WorkflowResponse;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.slf4j.MDC;
+
+/**
+ * This abstract class is base class for all Command tasks. All command task must inherit this class.
+ */
+
+public abstract class CommandTask<M> implements Runnable {
+
+ protected RequestHandler requestHandler;
+ protected WorkFlowManager workflowManager;
+
+ private CommandRequest commandRequest;
+
+ public CommandRequest getCommandRequest() {
+ return commandRequest;
+ }
+
+ public void setCommandRequest(CommandRequest commandRequest) {
+ this.commandRequest = commandRequest;
+ }
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(CommandTask.class);
+
+ public void setWorkflowManager(WorkFlowManager workflowManager) {
+ this.workflowManager = workflowManager;
+ }
+
+ public void setRequestHandler(RequestHandler requestHandler) {
+ this.requestHandler = requestHandler;
+ }
+
+ CommandTask(){
+ }
+
+ public void onRequestCompletion(CommandRequest request, CommandResponse response , boolean isAAIUpdated) {
+ logger.debug("Entry: onRequestCompletion()");
+ requestHandler.onRequestExecutionEnd(request.getCommandExecutorInput().getRuntimeContext(), isAAIUpdated);
+ }
+
+ public abstract void onRequestCompletion(CommandRequest request, CommandResponse response);
+
+ protected CommandResponse buildCommandResponse(CommandRequest request, WorkflowResponse response) {
+
+ CommandResponse commandResponse = new CommandResponse();
+ commandResponse.setRuntimeContext(request.getCommandExecutorInput().getRuntimeContext());
+ return commandResponse;
+ }
+
+
+ public void execute() {
+ final RuntimeContext runtimeContext = commandRequest.getCommandExecutorInput().getRuntimeContext();
+ MDC.put(MDC_KEY_REQUEST_ID, runtimeContext.getRequestContext().getCommonHeader().getRequestId());
+ if (runtimeContext.getRequestContext().getActionIdentifiers().getServiceInstanceId() != null)
+ MDC.put(MDC_SERVICE_INSTANCE_ID, runtimeContext.getRequestContext().getActionIdentifiers().getServiceInstanceId());
+ MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, runtimeContext.getRequestContext().getCommonHeader().getOriginatorId());
+ MDC.put(MDC_SERVICE_NAME, runtimeContext.getRequestContext().getAction().name());
+ try {
+ MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getLocalHostName() again please. It's wrong!
+ MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+ }catch(Exception e){
+ logger.debug(e.getMessage());
+ }
+ MDC.put(MDC_INSTANCE_UUID, ""); //TODO make instanse_UUID generation once during APPC-instanse deploying
+
+ WorkflowRequest workflowRequest = new WorkflowRequest();
+ workflowRequest.setRequestContext(runtimeContext.getRequestContext());
+ workflowRequest.setResponseContext(runtimeContext.getResponseContext());
+ workflowRequest.setVnfContext(runtimeContext.getVnfContext());
+
+ WorkflowResponse response = workflowManager.executeWorkflow(workflowRequest);
+
+ CommandResponse commandResponse = buildCommandResponse(commandRequest, response);
+ this.onRequestCompletion(commandRequest,commandResponse);
+ }
+
+ public static void fillStatus(Status status, LCMCommandStatus lcmCommandStatus, Params params) {
+ status.setCode(lcmCommandStatus.getResponseCode());
+ status.setMessage(lcmCommandStatus.getFormattedMessage(params));
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java
new file mode 100644
index 000000000..610f0bca3
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java
@@ -0,0 +1,65 @@
+/*-
+ * ============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.executor.impl;
+
+
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.workflow.WorkFlowManager;
+
+
+
+
+public class CommandTaskFactory {
+
+// private LCMCommandTask lcmCommandTask;
+// private LCMReadonlyCommandTask LCMReadonlyCommandTask;
+
+ private RequestHandler requestHandler;
+ private WorkFlowManager workflowManager;
+ private LifecycleManager lifecyclemanager;
+
+
+ public void setWorkflowManager(WorkFlowManager workflowManager) {
+ this.workflowManager = workflowManager;
+ }
+
+ public void setRequestHandler(RequestHandler requestHandler) {
+ this.requestHandler = requestHandler;
+ }
+
+ public void setLifecyclemanager(LifecycleManager lifecyclemanager) {
+ this.lifecyclemanager = lifecyclemanager;
+ }
+
+
+ public synchronized CommandTask getExecutionTask(String action){
+ if (VNFOperation.Sync.toString().equals(action) || VNFOperation.Audit.toString().equals(action)){
+ return new LCMReadonlyCommandTask(requestHandler,workflowManager);
+ }else {
+ return new LCMCommandTask(requestHandler,workflowManager,
+ lifecyclemanager);
+ }
+ }
+
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.java
new file mode 100644
index 000000000..6ecf76c3a
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommonMethods.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.executor.impl;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+
+
+class CommonMethods {
+
+ private static final HashMap m = new HashMap();
+
+ static {
+ m.put(34, "&quot;"); // < - less-than
+ m.put(60, "&lt;"); // < - less-than
+ m.put(62, "&gt;"); // > - greater-than
+ m.put(38, "&amp;"); // & - Ampersand
+ }
+
+ static String escapeHtml(String source) {
+ try {
+ StringWriter writer = new StringWriter((int) (source.length() * 1.5));
+ escape(writer, source);
+ return writer.toString();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ return null;
+ }
+ }
+
+ private static void escape(Writer writer, String str) throws IOException {
+ int len = str.length();
+ for (int i = 0; i < len; i++) {
+ char c = str.charAt(i);
+ int ascii = (int) c;
+ String entityName = (String) m.get(ascii);
+ if (entityName == null) {
+ if (c > 0x7F) {
+ writer.write("&#");
+ writer.write(Integer.toString(c, 10));
+ writer.write(';');
+ } else {
+ writer.write(c);
+ }
+ } else {
+ writer.write(entityName);
+ }
+ }
+ }
+
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.java
new file mode 100644
index 000000000..fc79c461f
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/ExpiredMessageHandler.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.executor.impl;
+
+import org.openecomp.appc.executionqueue.MessageExpirationListener;
+import org.openecomp.appc.executor.impl.objects.CommandRequest;
+import org.openecomp.appc.requesthandler.RequestHandler;
+
+
+public class ExpiredMessageHandler<M> implements MessageExpirationListener<M>{
+ private RequestHandler requestHandler;
+
+ public ExpiredMessageHandler(){
+
+ }
+
+ public void setRequestHandler(RequestHandler requestHandler) {
+ this.requestHandler = requestHandler;
+ }
+
+ @Override
+ public void onMessageExpiration(M message) {
+ CommandRequest commandRequest = (CommandRequest)message;
+ requestHandler.onRequestTTLEnd(commandRequest.getCommandExecutorInput().getRuntimeContext(), true);
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java
new file mode 100644
index 000000000..6e64a546b
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java
@@ -0,0 +1,261 @@
+/*-
+ * ============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.executor.impl;
+
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.appc.domainmodel.lcm.CommonHeader;
+import org.openecomp.appc.domainmodel.lcm.Status;
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.executor.impl.objects.CommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMCommandRequest;
+import org.openecomp.appc.executor.objects.CommandResponse;
+import org.openecomp.appc.executor.objects.LCMCommandStatus;
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.executor.objects.UniqueRequestIdentifier;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.lifecyclemanager.objects.VNFOperationOutcome;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowResponse;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.openecomp.sdnc.sli.aai.AAIService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class LCMCommandTask extends CommandTask<LCMCommandRequest> {
+
+ private AAIService aaiService;
+ private LifecycleManager lifecyclemanager;
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(LCMCommandTask.class);
+
+ public LCMCommandTask(RequestHandler requestHandler, WorkFlowManager workflowManager,
+ LifecycleManager lifecyclemanager){
+ setRequestHandler(requestHandler);
+ setWorkflowManager(workflowManager);
+ setLifecyclemanager(lifecyclemanager);
+ getAAIservice();
+ }
+
+ public void setLifecyclemanager(LifecycleManager lifecyclemanager) {
+ this.lifecyclemanager = lifecyclemanager;
+ }
+
+
+ private void getAAIservice() {
+ BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext();
+ // Get AAIadapter reference
+ ServiceReference sref = bctx.getServiceReference(AAIService.class.getName());
+ if (sref != null) {
+ logger.info("AAIService from bundlecontext");
+ aaiService = (AAIService) bctx.getService(sref);
+
+ } else {
+ logger.info("AAIService error from bundlecontext");
+ logger.warn("Cannot find service reference for org.openecomp.sdnc.sli.aai.AAIService");
+
+ }
+ }
+
+
+ @Override
+ public void onRequestCompletion(CommandRequest request, CommandResponse response) {
+
+ boolean isAAIUpdated = false;
+ try {
+
+ final int statusCode = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus().getCode();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Workflow Execution Status = "+ statusCode);
+ }
+
+ boolean isSuccess = statusCode == 100 || statusCode == 400;
+
+ if (isSuccess && VNFOperation.Terminate == request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getAction()) {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx = getVnfdata(request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId(), "vnf", ctx);
+ isAAIUpdated = aaiService.deleteGenericVnfData(request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId(), ctx.getAttribute("vnf.resource-version"));
+ }
+ else{
+ isAAIUpdated = updateAAI(request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId() , false, isSuccess);
+ }
+ logger.debug("isAAIUpdated = " + isAAIUpdated);
+ }
+ catch(Exception e1) {
+ logger.error("Exception = " + e1);
+ throw new RuntimeException(e1);
+ }
+ finally {
+ super.onRequestCompletion(request, response , isAAIUpdated);
+ }
+ }
+
+ @Override
+ public void run() {
+ LCMCommandRequest request = (LCMCommandRequest)getCommandRequest();
+ boolean isAAIUpdated;
+ final String vnfId = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId();
+ final String vnfType = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getType();
+ try {
+ final CommonHeader commonHeader = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader();
+ final boolean forceFlag = commonHeader.getFlags().isForce();
+ UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(commonHeader.getOriginatorId(),
+ commonHeader.getRequestId(), commonHeader.getSubRequestId());
+ String requestIdentifierString = requestIdentifier.toIdentifierString();
+ requestHandler.onRequestExecutionStart(vnfId,false, requestIdentifierString, forceFlag);
+
+ final String currentStatus = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getStatus();
+ final VNFOperation action = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getAction();
+
+ final String nextState = lifecyclemanager.getNextState(vnfType, currentStatus, action.name());
+
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx=getVnfdata(vnfId, "onRequestExecutionStart", ctx);
+ isAAIUpdated= postVnfdata(vnfId, nextState,"onRequestExecutionStart",ctx);
+ } catch (NoTransitionDefinedException e) {
+ logger.error("Error getting Next State for AAI Update: " + e.getMessage(), e);
+ Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus();
+ Params params = new Params().addParam("actionName",e.event).addParam("currentState",e.currentState);
+ fillStatus(status, LCMCommandStatus.NO_TRANSITION_DEFINE_FAILURE, params);
+ isAAIUpdated = false;
+ } catch (UnstableVNFException e) {
+ logger.error(e.getMessage(), e);
+ Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus();
+ Params params = new Params().addParam("vnfId",vnfId);
+ fillStatus(status, LCMCommandStatus.UNSTABLE_VNF_FAILURE, params);
+ isAAIUpdated = false;
+ }catch (Exception e) {
+ logger.error("Error before Request Execution starts.", e);
+ Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus();
+ String errorMsg = StringUtils.isEmpty(e.getMessage()) ? e.toString() : e.getMessage();
+ Params params = new Params().addParam("errorMsg",errorMsg);
+ fillStatus(status, LCMCommandStatus.UNEXPECTED_FAILURE, params);
+ isAAIUpdated = false;
+ }
+
+ if (isAAIUpdated){
+ super.execute();
+ }else{
+ String errorMsg = "Error updating A& AI before Workflow execution";
+ logger.error(errorMsg);
+ WorkflowResponse response = new WorkflowResponse();
+ response.setResponseContext(request.getCommandExecutorInput().getRuntimeContext().getResponseContext());
+ CommandResponse commandResponse = super.buildCommandResponse(request, response);
+ this.onRequestCompletion(request,commandResponse);
+ }
+ }
+
+
+
+ private boolean updateAAI(String vnf_id , boolean isTTLEnd , boolean executionStatus)
+ {
+ String orchestrationStatus = null;
+ String nextState;
+ boolean callbackResponse;
+ VNFOperationOutcome outcome;
+ SvcLogicContext ctx = new SvcLogicContext();
+ try {
+ ctx=getVnfdata(vnf_id, "onRequestExecutionEnd",ctx);
+ orchestrationStatus=ctx.getAttribute("onRequestExecutionEnd.orchestration-status");
+
+ if(isTTLEnd){
+ outcome = VNFOperationOutcome.FAILURE;
+ }
+ else if(executionStatus){
+ outcome = VNFOperationOutcome.SUCCESS;
+ }
+ else{
+ outcome = VNFOperationOutcome.FAILURE;
+ }
+ nextState = lifecyclemanager.getNextState(null,orchestrationStatus, outcome.toString()) ;
+ callbackResponse= postVnfdata(vnf_id, nextState,"onRequestExecutionEnd",ctx);
+ logger.debug("AAI posting status: " + callbackResponse);
+
+ } catch (NoTransitionDefinedException e) {
+ logger.debug("Transition not defined for State = " + orchestrationStatus);
+ callbackResponse =false;
+ } catch (LifecycleException e) {
+ logger.debug("State or command not registered with State Machine. State = " + orchestrationStatus);
+ callbackResponse =false;
+ }
+ return callbackResponse;
+ }
+
+
+ private SvcLogicContext getVnfdata(String vnf_id, String prefix,SvcLogicContext ctx) {
+ String key="vnf-id = '"+ vnf_id+"'";
+ logger.debug("inside getVnfdata=== "+key);
+ try {
+ SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key,prefix, null, ctx);
+ if(SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)){
+ logger.warn("VNF " + vnf_id + " not found while updating A&AI");
+ throw new RuntimeException("VNF not found for vnf_id = "+ vnf_id);
+ }
+ else if(SvcLogicResource.QueryStatus.FAILURE.equals(response)){
+ throw new RuntimeException("Error Querying AAI with vnfID = " +vnf_id);
+ }
+ logger.info("AAIResponse: " + response.toString());
+ } catch (SvcLogicException e) {
+ logger.error("Error in getVnfdata "+ e);
+ throw new RuntimeException(e);
+ }
+ return ctx;
+ }
+
+ private boolean postVnfdata(String vnf_id, String status,String prefix,SvcLogicContext ctx) {
+ String key="vnf-id = '"+ vnf_id+"'";
+ logger.debug("inside postVnfdata=== "+key);
+ Map<String, String> data = new HashMap<>();
+ data.put("orchestration-status", status);
+ try {
+ SvcLogicResource.QueryStatus response = aaiService.update("generic-vnf", key, data, prefix, ctx);
+ if(SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)){
+ logger.warn("VNF " + vnf_id + " not found while updating A&AI");
+ return false;
+ }
+ logger.info("AAIResponse: " + response.toString());
+ if(response.toString().equals("SUCCESS"))
+ {
+ return true;
+ }
+ } catch (SvcLogicException e) {
+ logger.error("Error in postVnfdata "+ e);
+ throw new RuntimeException(e);
+ }
+ return false;
+ }
+
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java
new file mode 100644
index 000000000..137a2e4b5
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMReadonlyCommandTask.java
@@ -0,0 +1,81 @@
+/*-
+ * ============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.executor.impl;
+
+
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.appc.domainmodel.lcm.CommonHeader;
+import org.openecomp.appc.domainmodel.lcm.Status;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.executor.impl.objects.CommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMCommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMReadOnlyCommandRequest;
+import org.openecomp.appc.executor.objects.CommandResponse;
+import org.openecomp.appc.executor.objects.LCMCommandStatus;
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.executor.objects.UniqueRequestIdentifier;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+public class LCMReadonlyCommandTask extends CommandTask<LCMReadOnlyCommandRequest> {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(LCMReadonlyCommandTask.class);
+
+ public LCMReadonlyCommandTask(RequestHandler requestHandler, WorkFlowManager workflowManager){
+
+ setRequestHandler(requestHandler);
+ setWorkflowManager(workflowManager);
+ }
+
+
+ @Override
+ public void onRequestCompletion(CommandRequest request, CommandResponse response) {
+ super.onRequestCompletion(request, response, true);
+ }
+
+ @Override
+ public void run() {
+ LCMReadOnlyCommandRequest request = (LCMReadOnlyCommandRequest)getCommandRequest();
+ final CommonHeader commonHeader = request.getCommandExecutorInput().getRuntimeContext().getRequestContext().getCommonHeader();
+ final boolean forceFlag = commonHeader.getFlags().isForce();
+ UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(commonHeader.getOriginatorId(), commonHeader.getRequestId(), commonHeader.getSubRequestId());
+ String requestIdentifierString = requestIdentifier.toIdentifierString();
+ final String vnfId = request.getCommandExecutorInput().getRuntimeContext().getVnfContext().getId();
+ try {
+ requestHandler.onRequestExecutionStart(vnfId,true, requestIdentifierString, forceFlag);
+ super.execute();
+ } catch (UnstableVNFException e) {
+ logger.error(e.getMessage(), e);
+ Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus();
+ Params params = new Params().addParam("vnfId",vnfId);
+ fillStatus(status, LCMCommandStatus.UNSTABLE_VNF_FAILURE, params);
+ }catch (Exception e) {
+ logger.error("Error during runing LCMReadonlyCommandTask.", e);
+ Status status = request.getCommandExecutorInput().getRuntimeContext().getResponseContext().getStatus();
+ String errorMsg = StringUtils.isEmpty(e.getMessage()) ? e.toString() : e.getMessage();
+ Params params = new Params().addParam("errorMsg",errorMsg);
+ fillStatus(status, LCMCommandStatus.UNEXPECTED_FAILURE, params);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java
new file mode 100644
index 000000000..a1384c7bb
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/CommandRequest.java
@@ -0,0 +1,89 @@
+/*-
+ * ============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.executor.impl.objects;
+
+import java.util.Date;
+
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+
+@SuppressWarnings("unused")
+public class CommandRequest {
+
+
+ private CommandExecutorInput commandExecutorInput;
+ private Date commandInTimeStamp;
+
+ public CommandRequest(CommandExecutorInput commandExecutorInput) {
+ this.commandExecutorInput = commandExecutorInput;
+ }
+
+
+ public CommandExecutorInput getCommandExecutorInput() {
+ return commandExecutorInput;
+ }
+
+ public void setCommandExecutorInput(CommandExecutorInput commandExecutorInput) {
+ this.commandExecutorInput = commandExecutorInput;
+ }
+
+ public Date getCommandInTimeStamp() {
+ return commandInTimeStamp;
+ }
+
+ public void setCommandInTimeStamp(Date commandInTimeStamp) {
+ this.commandInTimeStamp = commandInTimeStamp;
+ }
+
+ // @Override
+ // public boolean isTTLExpired() {
+ // Calendar tempTimeStamp = addTTLToRequestTime();
+ // long currentTime = System.currentTimeMillis();
+ // long tempTimeStampWithTTL = tempTimeStamp.getTimeInMillis() ;
+ // return currentTime > tempTimeStampWithTTL;
+ // }
+ //
+ // @Override
+ // public int getRemainingTTL(TimeUnit timeunit) {
+ // long tempTimeStampWithTTL = addTTLToRequestTime().getTimeInMillis() ;
+ // long currentTime = System.currentTimeMillis();
+ // long remainingTTL = tempTimeStampWithTTL - currentTime;
+ // return (int)(tempTimeStampWithTTL - currentTime);
+ // }
+ // private Calendar addTTLToRequestTime()
+ // {
+ // Date timeInRequest = this.getCommandInTimeStamp();
+ // int ttlValue = this.getCommandContext().getTtl();
+ // Calendar tempTimeStamp = Calendar.getInstance();
+ // tempTimeStamp.setTime(timeInRequest);
+ // tempTimeStamp.add(Calendar.SECOND, ttlValue);
+ // return tempTimeStamp;
+ // }
+
+
+ @Override
+ public String toString() {
+ return "CommandRequest{" +
+ "commandExecutorInput=" + commandExecutorInput +
+ ", commandInTimeStamp=" + commandInTimeStamp +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.java
new file mode 100644
index 000000000..45111d6c1
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMCommandRequest.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.executor.impl.objects;
+
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+
+
+public class LCMCommandRequest extends CommandRequest {
+
+ public LCMCommandRequest(CommandExecutorInput commandExecutorInput) {
+ super(commandExecutorInput);
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.java
new file mode 100644
index 000000000..4d76973e2
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/objects/LCMReadOnlyCommandRequest.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.executor.impl.objects;
+
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+
+
+
+public class LCMReadOnlyCommandRequest extends CommandRequest {
+
+ public LCMReadOnlyCommandRequest(CommandExecutorInput commandExecutorInput) {
+ super(commandExecutorInput);
+ }
+}
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..4c5589885
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,51 @@
+<?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-command-executor-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="commandExecutorBean" class="org.openecomp.appc.executor.impl.CommandExecutorImpl"
+ scope="singleton" init-method="initialize">
+ <property name="executionTaskFactory" ref="CommandExecutionTaskFactory"/>
+ <property name="expiredMessageHandler" ref="expiredMessageHandlerBean"/>
+ </bean>
+
+ <bean id="CommandExecutionTaskFactory" class="org.openecomp.appc.executor.impl.CommandTaskFactory" scope="singleton" >
+ <property name="requestHandler" ref="RequestHandlerRef" />
+ <property name="workflowManager" ref="WorkFlowManagerRef" />
+ <property name="lifecyclemanager" ref="LifecyclemanagerRef" />
+ </bean>
+
+ <bean id="expiredMessageHandlerBean" class="org.openecomp.appc.executor.impl.ExpiredMessageHandler"
+ scope="singleton">
+ <property name="requestHandler" ref="RequestHandlerRef" />
+ </bean>
+
+ <reference id="WorkFlowManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.workflow.WorkFlowManager" />
+ <reference id="RequestHandlerRef" availability="optional" activation="eager" interface="org.openecomp.appc.requesthandler.RequestHandler" />
+ <reference id="LifecyclemanagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" />
+
+ <service id="commandExecutorService" interface="org.openecomp.appc.executor.CommandExecutor" ref="commandExecutorBean"/>
+</blueprint>
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..2e5f26a0f
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties
@@ -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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-MAIN
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=2
+dmaap.threads.poolsize.max=2
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java
new file mode 100644
index 000000000..0504c3998
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutionTask.java
@@ -0,0 +1,312 @@
+/*-
+ * ============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.executor;
+/**
+ *
+ */
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.executor.impl.CommandTask;
+import org.openecomp.appc.executor.impl.CommandTaskFactory;
+import org.openecomp.appc.executor.impl.LCMCommandTask;
+import org.openecomp.appc.executor.impl.LCMReadonlyCommandTask;
+import org.openecomp.appc.executor.impl.objects.CommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMCommandRequest;
+import org.openecomp.appc.executor.impl.objects.LCMReadOnlyCommandRequest;
+import org.openecomp.appc.executor.objects.*;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workflow.objects.WorkflowResponse;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.openecomp.sdnc.sli.aai.AAIService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Matchers.*;
+
+
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest( {FrameworkUtil.class, CommandTask.class, LCMCommandTask.class})
+public class TestCommandExecutionTask {
+
+ private static final String TTL_FLAG= "TTL";
+ private static final String API_VERSION= "2.0.0";
+ private static final String ORIGINATOR_ID= "1";
+ private LCMCommandTask executionTask;
+ private LCMReadonlyCommandTask LCMReadonlyCommandTask;
+ private CommandTaskFactory factory ;
+
+ private RequestHandler requestHandler;
+ private WorkFlowManager workflowManager;
+ private AAIService aaiService;
+ private LifecycleManager lifecyclemanager;
+
+ private final BundleContext bundleContext=Mockito.mock(BundleContext.class);
+ private final Bundle bundleService=Mockito.mock(Bundle.class);
+ private final ServiceReference sref=Mockito.mock(ServiceReference.class);
+
+ @Before
+ public void init() throws SvcLogicException {
+
+ // ***
+ AAIService aaiService = Mockito.mock(AAIService.class);;
+ PowerMockito.mockStatic(FrameworkUtil.class);
+ PowerMockito.when(FrameworkUtil.getBundle(AAIService.class)).thenReturn(bundleService);
+ PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext);
+ PowerMockito.when(bundleContext.getServiceReference(AAIService.class.getName())).thenReturn(sref);
+ PowerMockito.when(bundleContext.getService(sref)).thenReturn(aaiService);
+ PowerMockito.when(aaiService.query(anyString(),anyBoolean(),anyString(),anyString(),anyString(),anyString(),(SvcLogicContext)anyObject())).thenAnswer(new Answer<SvcLogicResource.QueryStatus>() {
+ @Override
+ public SvcLogicResource.QueryStatus answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ SvcLogicContext ctx =(SvcLogicContext)args[6];
+ String prefix = (String)args[4];
+ String key = (String)args[3];
+ if(key.contains("'28'")){
+ return SvcLogicResource.QueryStatus.FAILURE ;
+ }else if ( key.contains("'8'")) {
+ return SvcLogicResource.QueryStatus.NOT_FOUND ;
+ }else {
+ ctx.setAttribute(prefix + ".vnf-type", "FIREWALL");
+ ctx.setAttribute(prefix + ".orchestration-status", "INSTANTIATED");
+ }
+ return SvcLogicResource.QueryStatus.SUCCESS ;
+ }
+ });
+ PowerMockito.when(aaiService.update(anyString(),anyString(),(Map)anyObject(),anyString(),(SvcLogicContext)anyObject())).thenReturn(SvcLogicResource.QueryStatus.SUCCESS);
+
+ requestHandler = Mockito.mock(RequestHandler.class);
+ workflowManager = Mockito.mock(WorkFlowManager.class);
+ lifecyclemanager = Mockito.mock(LifecycleManager.class );
+
+ executionTask = new LCMCommandTask(requestHandler,workflowManager,lifecyclemanager);
+ LCMReadonlyCommandTask = new LCMReadonlyCommandTask(requestHandler,workflowManager);
+ factory = new CommandTaskFactory();
+ factory.setLifecyclemanager(lifecyclemanager);
+ factory.setWorkflowManager(workflowManager);
+ factory.setRequestHandler(requestHandler);
+ Mockito.when(workflowManager.executeWorkflow((WorkflowRequest)anyObject())).thenReturn(getWorkflowResponse () );
+ }
+
+
+ @Test
+ public void testFactory(){
+ CommandTask task;
+ task = factory.getExecutionTask("Configure");
+ assertEquals(LCMCommandTask.class,task.getClass() );
+ task = factory.getExecutionTask("Sync");
+ assertEquals(LCMReadonlyCommandTask.class,task.getClass() );
+
+ }
+
+
+
+ @Test
+ public void testOnRequestCompletion(){
+ Mockito.doNothing().when(requestHandler).onRequestTTLEnd((RuntimeContext) anyObject(),anyBoolean());
+ LCMCommandRequest request = getLCMCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"), VNFOperation.Configure, "1", "1.0");
+ CommandResponse response = getCommandResponse(VNFOperation.Configure, true, "11", "","1");
+ executionTask.onRequestCompletion(request, response);
+ }
+
+ @Test
+ public void testRunGetConfig(){
+ LCMReadOnlyCommandRequest request = getConfigCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"),VNFOperation.Sync, "1", "1.0");
+ LCMReadonlyCommandTask.setCommandRequest(request);
+ LCMReadonlyCommandTask.run();
+ }
+
+ @Test
+ public void testRun(){
+ LCMCommandRequest request = getLCMCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"),VNFOperation.Sync, "1", "1.0");
+ executionTask.setCommandRequest(request);
+ executionTask.run();
+ }
+
+ @Test
+ public void testRunNegative(){
+ LCMCommandRequest request = getLCMCommandRequest("FIREWALL",30,new Date(), "11" ,setTTLInFlags("30"),VNFOperation.Sync, "1", "1.0");
+ executionTask.setCommandRequest(request);
+ executionTask.run();
+ }
+
+
+ CommandResponse getCommandResponse(VNFOperation action , boolean success, String responseId, String payload, String vnfId){
+ CommandResponse commandResponse = new CommandResponse();
+ RuntimeContext runtimeContext = new RuntimeContext();
+ commandResponse.setRuntimeContext(runtimeContext);
+ ResponseContext responseContext = new ResponseContext();
+ runtimeContext.setResponseContext(responseContext);
+ RequestContext requestContext = new RequestContext();
+ runtimeContext.setRequestContext(requestContext);
+ CommonHeader commonHeader = new CommonHeader();
+ requestContext.setCommonHeader(commonHeader);
+ responseContext.setCommonHeader(commonHeader);
+ Flags flags = new Flags();
+ commonHeader.setFlags(flags);
+ ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
+ requestContext.setActionIdentifiers(actionIdentifiers);
+ VNFContext vnfContext = new VNFContext();
+ runtimeContext.setVnfContext(vnfContext);
+ requestContext.setAction(action);
+ runtimeContext.setRpcName(action.name().toLowerCase());
+ commonHeader.setApiVer(API_VERSION);
+ Status status = new Status();
+ status.setCode(100);
+ responseContext.setStatus(status);
+ commonHeader.setRequestId(responseId);
+ responseContext.setPayload(payload);
+ commonHeader.setTimestamp(new Date());
+ vnfContext.setId(vnfId);
+ return commandResponse;
+ }
+
+
+
+ @Test
+ public void testPositiveFlow_configure() {
+
+ Date timeStamp = new Date();
+ String requestId = "1";
+
+ CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput("FIREWALL",30, "1.0", timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "", VNFOperation.Configure, "33", "");
+ CommandRequest request = new CommandRequest(commandExecutorInput);
+ }
+
+
+ private Map<String,Object> setTTLInFlags( String value){
+ Map<String,Object> flags = new HashMap<String,Object>();
+ if( value != null || !("".equalsIgnoreCase(value))){
+ flags.put(TTL_FLAG, value);
+ }
+ return flags;
+ }
+
+
+ private LCMReadOnlyCommandRequest getConfigCommandRequest(String vnfType , Integer ttl , Date timeStamp, String requestId,
+ Map<String,Object> flags, VNFOperation command , String vnfId, String vnfVersion ){
+
+ CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput(vnfType, ttl, vnfVersion, timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "", command, vnfId, "");
+ LCMReadOnlyCommandRequest request = new LCMReadOnlyCommandRequest(commandExecutorInput);
+
+ return request;
+ }
+
+ private LCMCommandRequest getLCMCommandRequest(String vnfType , Integer ttl ,Date timeStamp, String requestId,
+ Map<String,Object> flags, VNFOperation command , String vnfId, String vnfVersion ){
+
+ CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput(vnfType, ttl, vnfVersion, timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "", command, vnfId, "");
+ LCMCommandRequest request = new LCMCommandRequest(commandExecutorInput);
+
+ return request;
+ }
+
+ public WorkflowResponse getWorkflowResponse (){
+ WorkflowResponse wfResponse = new WorkflowResponse();
+ ResponseContext responseContext = createResponseContextWithSuObjects();
+ wfResponse.setResponseContext(responseContext);
+ responseContext.setPayload("");
+ wfResponse.getResponseContext().getStatus().setCode(100);
+ return wfResponse;
+ }
+
+ private CommandExecutorInput pouplateCommandExecutorInput(String vnfType, int ttl, String vnfVersion, Date timeStamp, String apiVersion, String requestId, String originatorID, String subRequestID, VNFOperation action, String vnfId , String payload){
+ CommandExecutorInput commandExecutorInput = createCommandExecutorInputWithSubObjects();
+ RuntimeContext runtimeContext = commandExecutorInput.getRuntimeContext();
+ RequestContext requestContext = runtimeContext.getRequestContext();
+ ResponseContext responseContext = createResponseContextWithSuObjects();
+ runtimeContext.setResponseContext(responseContext);
+
+ requestContext.getCommonHeader().getFlags().setTtl(ttl);
+ requestContext.getCommonHeader().setApiVer(apiVersion);
+ requestContext.getCommonHeader().setTimestamp(timeStamp);
+ requestContext.getCommonHeader().setRequestId(requestId);
+ requestContext.getCommonHeader().setSubRequestId(subRequestID);
+ requestContext.getCommonHeader().setOriginatorId(originatorID);
+ requestContext.setAction(action);
+ requestContext.setPayload(payload);
+ requestContext.getActionIdentifiers().setVnfId(vnfId);
+ VNFContext vnfContext = runtimeContext.getVnfContext();
+ vnfContext.setType(vnfType);
+ vnfContext.setId(vnfId);
+ vnfContext.setVersion(vnfVersion);
+ return commandExecutorInput;
+ }
+
+ private CommandExecutorInput createCommandExecutorInputWithSubObjects() {
+ CommandExecutorInput commandExecutorInput = new CommandExecutorInput();
+ RuntimeContext runtimeContext = createRuntimeContextWithSubObjects();
+ commandExecutorInput.setRuntimeContext(runtimeContext);
+ return commandExecutorInput;
+ }
+
+ private RuntimeContext createRuntimeContextWithSubObjects() {
+ RuntimeContext runtimeContext = new RuntimeContext();
+ RequestContext requestContext = new RequestContext();
+ runtimeContext.setRequestContext(requestContext);
+ CommonHeader commonHeader = new CommonHeader();
+ requestContext.setCommonHeader(commonHeader);
+ Flags flags = new Flags();
+ commonHeader.setFlags(flags);
+ ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
+ requestContext.setActionIdentifiers(actionIdentifiers);
+ VNFContext vnfContext = new VNFContext();
+ runtimeContext.setVnfContext(vnfContext);
+ return runtimeContext;
+
+ }
+
+ private ResponseContext createResponseContextWithSuObjects(){
+ ResponseContext responseContext = new ResponseContext();
+ CommonHeader commonHeader = new CommonHeader();
+ Flags flags = new Flags();
+ Status status = new Status();
+ responseContext.setCommonHeader(commonHeader);
+ responseContext.setStatus(status);
+ commonHeader.setFlags(flags);
+ return responseContext;
+ }
+
+}
+
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java
new file mode 100644
index 000000000..473e14e88
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/java/org/openecomp/appc/executor/TestCommandExecutor.java
@@ -0,0 +1,157 @@
+/*-
+ * ============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.executor;
+/**
+ *
+ */
+
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executionqueue.ExecutionQueueService;
+import org.openecomp.appc.executor.impl.CommandExecutorImpl;
+import org.openecomp.appc.executor.impl.CommandTaskFactory;
+import org.openecomp.appc.executor.impl.LCMCommandTask;
+import org.openecomp.appc.executor.impl.LCMReadonlyCommandTask;
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.workflow.WorkFlowManager;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import static junit.framework.Assert.assertTrue;
+
+
+@SuppressWarnings("deprecation")
+public class TestCommandExecutor {
+
+ private static final String TTL_FLAG= "TTL";
+ private static final String API_VERSION= "2.0.0";
+ private static final String ORIGINATOR_ID= "1";
+
+ CommandExecutorImpl commandExecutor;
+
+ CommandTaskFactory executionTaskFactory;
+
+ private RequestHandler requestHandler;
+ private WorkFlowManager workflowManager;
+ private LifecycleManager lifecyclemanager;
+
+ private ExecutionQueueService executionQueueService;
+
+ @Before
+ public void init()throws Exception {
+ requestHandler= Mockito.mock(RequestHandler.class);
+ lifecyclemanager= Mockito.mock(LifecycleManager.class);
+ workflowManager= Mockito.mock(WorkFlowManager.class);
+
+ executionQueueService = Mockito.mock(ExecutionQueueService.class);
+
+ commandExecutor = new CommandExecutorImpl();
+ executionTaskFactory = Mockito.mock(CommandTaskFactory.class);
+ commandExecutor.setExecutionTaskFactory(executionTaskFactory);
+ commandExecutor.setExecutionQueueService(executionQueueService);
+ LCMCommandTask lcmCommandTask = Mockito.mock(LCMCommandTask.class);
+ LCMReadonlyCommandTask LCMReadonlyCommandTask = Mockito.mock(LCMReadonlyCommandTask.class);
+ Mockito.when(executionTaskFactory.getExecutionTask("Configure")).thenReturn(lcmCommandTask);
+ Mockito.when(executionTaskFactory.getExecutionTask("Sync")).thenReturn(LCMReadonlyCommandTask);
+// Mockito.when(executionQueueService.putMessage((Runnable) Mockito.anyObject(),Mockito.anyLong(),(TimeUnit)Mockito.anyObject())).thenReturn(true);
+
+ }
+
+
+ @Test
+ public void testPositiveFlow_LCM(){
+ //Map <String,Object> flags = setTTLInFlags("30");
+ Date timeStamp = new Date();
+ String requestId = "1";
+ CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput("FIREWALL", 30, "1.0", timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "2", VNFOperation.Configure, "15", "") ;
+ try {
+ commandExecutor.executeCommand(commandExecutorInput);
+ } catch (APPCException e) {
+ Assert.fail(e.toString());
+ }
+
+ }
+
+ @Test
+ public void testPositiveFlow_GetConfig(){
+ Date timeStamp = new Date();
+ String requestId = "1";
+
+ CommandExecutorInput commandExecutorInput = pouplateCommandExecutorInput("FIREWALL", 30, "1.0", timeStamp, API_VERSION, requestId, ORIGINATOR_ID, "2", VNFOperation.Sync,"15","") ;
+ try {
+ commandExecutor.executeCommand(commandExecutorInput);
+ } catch (APPCException e) {
+ Assert.fail(e.toString());
+ }
+
+ }
+
+
+ private CommandExecutorInput pouplateCommandExecutorInput(String vnfType, int ttl, String vnfVersion, Date timeStamp, String apiVersion, String requestId, String originatorID, String subRequestID, VNFOperation action, String vnfId , String payload){
+ CommandExecutorInput commandExecutorInput = createCommandExecutorInputWithSubObjects();
+ RuntimeContext runtimeContext = commandExecutorInput.getRuntimeContext();
+ RequestContext requestContext = runtimeContext.getRequestContext();
+ requestContext.getCommonHeader().getFlags().setTtl(ttl);
+ requestContext.getCommonHeader().setApiVer(apiVersion);
+ requestContext.getCommonHeader().setTimestamp(timeStamp);
+ requestContext.getCommonHeader().setRequestId(requestId);
+ requestContext.getCommonHeader().setSubRequestId(subRequestID);
+ requestContext.getCommonHeader().setOriginatorId(originatorID);
+ requestContext.setAction(action);
+ requestContext.setPayload(payload);
+ requestContext.getActionIdentifiers().setVnfId(vnfId);
+ VNFContext vnfContext = runtimeContext.getVnfContext();
+ vnfContext.setType(vnfType);
+ vnfContext.setId(vnfId);
+ vnfContext.setVersion(vnfVersion);
+ return commandExecutorInput;
+ }
+
+ private CommandExecutorInput createCommandExecutorInputWithSubObjects() {
+ CommandExecutorInput commandExecutorInput = new CommandExecutorInput();
+ RuntimeContext runtimeContext = new RuntimeContext();
+ commandExecutorInput.setRuntimeContext(runtimeContext);
+ RequestContext requestContext = new RequestContext();
+ runtimeContext.setRequestContext(requestContext);
+ CommonHeader commonHeader = new CommonHeader();
+ requestContext.setCommonHeader(commonHeader);
+ Flags flags = new Flags();
+ commonHeader.setFlags(flags);
+ ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
+ requestContext.setActionIdentifiers(actionIdentifiers);
+ VNFContext vnfContext = new VNFContext();
+ runtimeContext.setVnfContext(vnfContext);
+ return commandExecutorInput;
+ }
+
+
+
+}
+
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..74552a9d7
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties
@@ -0,0 +1,102 @@
+###
+# ============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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options
+#org.openecomp.appc.bootstrap.file=executor-test.properties
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+
+#
+# Certificate keystore and truststore
+#
+#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE>
+#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin
+#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE>
+#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin
+org.openecomp.sdnc.sli.aai.host.certificate.ignore=true
+org.openecomp.sdnc.sli.aai.certificate.trust.all=true
+
+
+#
+# Configuration file for A&AI Adapter
+#
+
+# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT
+org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443
+
+org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query
+
+# service instance
+org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances
+org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance
+
+# complex
+org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes
+org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id}
+
+# vservers
+org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers
+org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}
+
+# generic-vnf
+org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/
+org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id}
+
+#
+# Formatting
+#
+org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s
+org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type
+org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id
+org.openecomp.sdnc.sli.aai.param.service.type=service-type
+
+org.openecomp.appc.logging.path=${user.home},etc,../etc,.
+org.openecomp.appc.logging.file=logback.xml
+
+org.openecomp.appc.db.url.%s", schema), "");
+org.openecomp.appc.db.user.%s", schema), "");
+org.openecomp.appc.db.pass.%s", schema), "");
+
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-TEST
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=2
+dmaap.threads.poolsize.max=2
+
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore b/appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore
new file mode 100644
index 000000000..2992ae832
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-features/.gitignore
@@ -0,0 +1,3 @@
+/target/
+/bin/
+/.settings/
diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-features/pom.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-features/pom.xml
new file mode 100644
index 000000000..420c25ca4
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-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>appc-command-executor</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>appc-command-executor-features</name>
+ <artifactId>appc-command-executor-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor-core</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> -->
+ <!-- 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. -->
+<!-- <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> -->
+ <!-- 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. -->
+<!-- <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-command-executor/appc-command-executor-features/src/main/resources/features.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-features/src/main/resources/features.xml
new file mode 100644
index 000000000..48846fc73
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/appc-command-executor-features/src/main/resources/features.xml
@@ -0,0 +1,35 @@
+<?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="appc-command-executor-${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='appc-command-executor' description="application executor" version='${project.version}'>
+ <bundle>mvn:org.openecomp.appc/execution-queue-management-lib/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-command-executor-api/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-command-executor-core/${project.version}</bundle>
+ <!--<bundle>mvn:org.apache.commons/commons-lang3/3.4</bundle>-->
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-command-executor/pom.xml b/appc-dispatcher/appc-command-executor/pom.xml
new file mode 100644
index 000000000..d028d1899
--- /dev/null
+++ b/appc-dispatcher/appc-command-executor/pom.xml
@@ -0,0 +1,22 @@
+<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-command-executor</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC Command Executor</name>
+ <description>APPC Command Executor</description>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-command-executor-api</module>
+ <module>appc-command-executor-core</module>
+ <module>appc-command-executor-features</module>
+ </modules>
+
+</project> \ No newline at end of file
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>
diff --git a/appc-dispatcher/appc-dispatcher-features/.gitignore b/appc-dispatcher/appc-dispatcher-features/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-features/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-features/pom.xml b/appc-dispatcher/appc-dispatcher-features/pom.xml
new file mode 100644
index 000000000..b26d324d2
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-features/pom.xml
@@ -0,0 +1,60 @@
+<?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</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>appc-dispatcher-features</name>
+ <artifactId>appc-dispatcher-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <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>
+ <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>
+
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml b/appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml
new file mode 100644
index 000000000..3d0859340
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-features/src/main/resources/features.xml
@@ -0,0 +1,37 @@
+<?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="appc-dispatcher-${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='appc-dispatcher' description="appc-dispatcher" version='${project.version}'>
+ <feature version='${project.version}'>appc-request-handler</feature>
+ <feature version='${project.version}'>appc-command-executor</feature>
+ <feature version='${project.version}'>appc-lifecycle-management</feature>
+ <feature version='${project.version}'>appc-license-manager</feature>
+ <feature version='${project.version}'>appc-workflow-management</feature>
+ <feature version='${project.version}'>lock-manager</feature>
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-dispatcher-installer/.gitignore b/appc-dispatcher/appc-dispatcher-installer/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-installer/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-dispatcher-installer/pom.xml b/appc-dispatcher/appc-dispatcher-installer/pom.xml
new file mode 100644
index 000000000..27a4061ce
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-installer/pom.xml
@@ -0,0 +1,223 @@
+<?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</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+
+ <artifactId>appc-dispatcher-installer</artifactId>
+ <name>APPC Dispatcher - Karaf Installer</name>
+ <packaging>pom</packaging>
+
+ <properties>
+ <application.name>appc-dispatcher</application.name>
+ <features.boot>appc-dispatcher</features.boot>
+ <features.boot.licenseManager>appc-license-manager</features.boot.licenseManager>
+ <!--<features.repositories>mvn:org.openecomp.appc/appc-dispatcher-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-request-handler-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-command-executor-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-lifecycle-management-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-license-manager-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-workflow-management-features/${project.version}/xml/features,mvn:org.openecomp.appc/lock-manager-features/${project.version}/xml/features</features.repositories>-->
+
+ <!-- SEPARATING FEATURE INSTALLS -->
+ <features.repo.dispatcher>mvn:org.openecomp.appc/appc-dispatcher-features/${project.version}/xml/features</features.repo.dispatcher>
+ <features.repo.requestHandler>mvn:org.openecomp.appc/appc-request-handler-features/${project.version}/xml/features</features.repo.requestHandler>
+ <features.repo.commandExecutor>mvn:org.openecomp.appc/appc-command-executor-features/${project.version}/xml/features</features.repo.commandExecutor>
+ <features.repo.lifecycleManagement>mvn:org.openecomp.appc/appc-lifecycle-management-features/${project.version}/xml/features</features.repo.lifecycleManagement>
+ <features.repo.licenseManager>mvn:org.openecomp.appc/appc-license-manager-features/${project.version}/xml/features</features.repo.licenseManager>
+ <features.repo.workflowManagement>mvn:org.openecomp.appc/appc-workflow-management-features/${project.version}/xml/features</features.repo.workflowManagement>
+ <features.repo.lockManager>mvn:org.openecomp.appc/lock-manager-features/${project.version}/xml/features</features.repo.lockManager>
+
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dispatcher-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+<!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+<!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+<!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+<!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+<!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-license-manager-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>lock-manager-features</artifactId>
+ <version>${project.version}</version>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <!-- <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions> -->
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>maven-repo-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>false</attach>
+ <finalName>stage/${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ <execution>
+ <id>installer-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>true</attach>
+ <finalName>${application.name}-${project.version}</finalName>
+ <descriptors>
+ <descriptor>src/assembly/assemble_installer_zip.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <transitive>false</transitive>
+ <outputDirectory>${project.build.directory}/assembly/system</outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <useRepositoryLayout>true</useRepositoryLayout>
+ <addParentPoms>false</addParentPoms>
+ <copyPom>false</copyPom>
+ <excludeGroupIds>org.opendaylight</excludeGroupIds>
+ <scope>provided</scope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-version</id>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <!-- here the phase you need -->
+ <phase>validate</phase>
+ <configuration>
+ <outputDirectory>${basedir}/target/stage</outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources/scripts</directory>
+ <includes>
+ <include>install-feature.sh</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml b/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 000000000..8948a3302
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_installer_zip.xml
@@ -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=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>controller</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>755</fileMode>
+ <includes>
+ <include>*.sh</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>644</fileMode>
+ <excludes>
+ <exclude>*.sh</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+
+</assembly>
diff --git a/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml b/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 000000000..a18efd00b
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -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=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>controller</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+</assembly>
diff --git a/appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh b/appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 000000000..c73d14abd
--- /dev/null
+++ b/appc-dispatcher/appc-dispatcher-installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,54 @@
+###
+# ============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=========================================================
+###
+
+#!/bin/bash
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"}
+INSTALLERDIR=$(dirname $0)
+
+REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip
+
+if [ -f ${REPOZIP} ]
+then
+ unzip -n -d ${ODL_HOME} ${REPOZIP}
+else
+ echo "ERROR : repo zip ($REPOZIP) not found"
+ exit 1
+fi
+
+# ${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories}
+
+# INSTALLING ODL FEATURES SEPARATELY-->
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.dispatcher}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.requestHandler}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.commandExecutor}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.lifecycleManagement}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.licenseManager}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.workflowManagement}
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repo.lockManager}
+
+# INSTALLING appc-license-manager first since it's a dependency on other features
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot.licenseManager}
+
+${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot}
+
diff --git a/appc-dispatcher/appc-license-manager/.gitignore b/appc-dispatcher/appc-license-manager/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-license-manager/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/.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-license-manager/appc-license-manager-api/.gitignore b/appc-dispatcher/appc-license-manager/appc-license-manager-api/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-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-license-manager/appc-license-manager-api/pom.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml
new file mode 100644
index 000000000..5bf4457a6
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml
@@ -0,0 +1,47 @@
+<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-license-manager</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-license-manager-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-license-manager-api</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>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</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.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects</Export-Package>
+ <Embed-Dependency>!dblib-provider,appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <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.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java
new file mode 100644
index 000000000..81ce0e713
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java
@@ -0,0 +1,109 @@
+/*-
+ * ============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.licmgr;
+
+public class Constants {
+
+ private Constants(){}
+
+ public static final String CONFIGURE_PATH = "/restconf/config/opendaylight-inventory:nodes/node/";
+ public static final String CONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules";
+ public static final String CHECK_CONNECTION_PATH = "/restconf/operational/opendaylight-inventory:nodes/node/";
+ public static final String DISCONNECT_PATH = "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules/module/odl-sal-netconf-connector-cfg:sal-netconf-connector/";
+
+ public static final String CONTROLLER_IP = "127.0.0.1";
+ public static final int CONTROLLER_PORT = 8181;
+ public static final String PROTOCOL = "http";
+
+ public static final String VF_LICENSE = "VF_LICENSE";
+
+ // tables and fields
+ public static final String NETCONF_SCHEMA = "sdnctl";
+ public static final String SDNCTL_SCHEMA = "sdnctl";
+ public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION";
+ public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES";
+ public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG";
+ public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT";
+ public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME";
+ public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME";
+ public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD";
+ public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER";
+ public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE";
+ public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID";
+ public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID";
+ public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE";
+ public static final String LOG_FIELD_NAME = "LOG";
+ public static final String ASDC_ARTIFACTS_TABLE_NAME = "ASDC_ARTIFACTS";
+
+ // input fields names
+ public static final String PAYLOAD = "payload";
+
+ // constants fo DG
+ public static final String VNF_TYPE_FIELD_NAME = "org.openecomp.appc.vftype";
+ public static final String VNF_VERSION_FIELD_NAME = "org.openecomp.appc.vfversion";
+ public static final String VNF_RESOURCE_VERSION_FIELD_NAME = "org.openecomp.appc.resource-version";
+ public static final String TARGET_VNF_TYPE = "target-vnf-type";
+ public static final String FILE_CONTENT_FIELD_NAME = "file-content";
+ public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details";
+ public static final String CONFIGURATION_FILE_FIELD_NAME = "configuration-file-name";
+ public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address";
+ public static final String UPGRADE_VERSION = "upgrade-version";
+ public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error";
+ public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message";
+ public static final String RESOURCEKEY = "resourceKey";
+ public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid";
+ public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion";
+ public static final String MODEL_ENTITLMENT_POOL_UUID_NAME = "model.entitlement.pool.uuid";
+ public static final String MODEL_LICENSE_KEY_UUID_NAME = "model.license.key.uuid";
+ public static final String ENTITLMENT_POOL_UUID_NAME = "entitlement.pool.uuid";
+ public static final String LICENSE_KEY_UUID_NAME = "license.key.uuid";
+ public static final String IS_ACQUIRE_LICENSE_REQUIRE ="is.acquire-license.require";
+ public static final String IS_RELEASE_LICENSE_REQUIRE ="is.release-license.require";
+
+ public static final String AAI_ENTITLMENT_POOL_UUID_NAME = "aai.input.data.entitlement-assignment-group-uuid";
+ public static final String AAI_LICENSE_KEY_UUID_NAME = "aai.input.data.license-assignment-group-uuid";
+ public static final String AAI_LICENSE_KEY_VALUE = "aai.input.data.license-key";
+ public static final String IS_AAI_ENTITLEMENT_UPDATE_REQUIRE = "is.aai-entitlement-update.require";
+ public static final String IS_AAI_LICENSE_UPDATE_REQUIRE = "is.aai-license-update.require";
+ public static final String IS_ACQUIRE_ENTITLEMENT_REQUIRE ="is.acquire-entitlement.require";
+ public static final String IS_RELEASE_ENTITLEMENT_REQUIRE ="is.release-entitlement.require";
+
+ public enum ASDC_ARTIFACTS_FIELDS {
+ SERVICE_UUID,
+ DISTRIBUTION_ID,
+ SERVICE_NAME,
+ SERVICE_DESCRIPTION,
+ RESOURCE_UUID,
+ RESOURCE_INSTANCE_NAME,
+ RESOURCE_NAME,
+ RESOURCE_VERSION,
+ RESOURCE_TYPE,
+ ARTIFACT_UUID,
+ ARTIFACT_TYPE,
+ ARTIFACT_VERSION,
+ ARTIFACT_DESCRIPTION,
+ INTERNAL_VERSION,
+ CREATION_DATE,
+ ARTIFACT_NAME,
+ ARTIFACT_CONTENT
+ }
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java
new file mode 100644
index 000000000..34936f859
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseDataAccessService.java
@@ -0,0 +1,54 @@
+/*-
+ * ============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.licmgr;
+
+import java.util.Map;
+
+import org.openecomp.appc.licmgr.exception.DataAccessException;
+import org.openecomp.sdnc.sli.resource.dblib.DbLibService;
+
+
+@SuppressWarnings("JavaDoc")
+public interface LicenseDataAccessService {
+
+ /**
+ *
+ * @param schema
+ */
+ void setSchema(String schema);
+
+ /**
+ *
+ * @param vnfType resource name
+ * @param vnfVersion resource version
+ * @return map contains requested fields as Strings
+ * @throws RuntimeException
+ */
+ Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException;
+
+ /**
+ *
+ * @param parameters parameters to store in artifacts table
+ * @throws RuntimeException
+ */
+ void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException;
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java
new file mode 100644
index 000000000..40c7d8bb6
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.licmgr;
+
+import java.util.Map;
+
+import org.openecomp.appc.licmgr.exception.DataAccessException;
+import org.openecomp.appc.licmgr.objects.LicenseModel;
+
+
+public interface LicenseManager {
+
+ /**
+ *
+ * @param vnfType
+ * @param vnfVersion
+ * @return pojo object represented license model
+ * @throws DataAccessException
+ */
+ LicenseModel retrieveLicenseModel(String vnfType, String vnfVersion) throws DataAccessException;
+
+ /**
+ *
+ * @param vnfType resource name
+ * @param vnfVersion resource version
+ * @return map contains requested fields as Strings
+ * @throws RuntimeException
+ */
+ Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws
+ DataAccessException;
+
+ /**
+ *
+ * @param parameters parameters to store in artifacts table
+ * @throws RuntimeException
+ */
+ void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException;
+
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.java
new file mode 100644
index 000000000..a7e3a084a
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/exception/DataAccessException.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.licmgr.exception;
+
+
+
+public class DataAccessException extends RuntimeException {
+
+ private static final long serialVersionUID = -155423437162622414L;
+
+ public DataAccessException(){
+ }
+
+ public DataAccessException(String message){
+ super(message);
+ }
+
+ public DataAccessException(Throwable cause){
+ super(cause);
+ }
+
+ public DataAccessException(String message , Throwable cause){
+ super(message , cause);
+ }
+
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.java
new file mode 100644
index 000000000..c3c886d77
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/objects/LicenseModel.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.licmgr.objects;
+
+public class LicenseModel {
+
+ private String entitlementPoolUuid;
+
+ private String licenseKeyGroupUuid;
+
+ public String getEntitlementPoolUuid() {
+ return entitlementPoolUuid;
+ }
+
+ public void setEntitlementPoolUuid(String entitlementPoolUuid) {
+ this.entitlementPoolUuid = entitlementPoolUuid;
+ }
+
+ public String getLicenseKeyGroupUuid() {
+ return licenseKeyGroupUuid;
+ }
+
+ public void setLicenseKeyGroupUuid(String licenseKeyGroupUuid) {
+ this.licenseKeyGroupUuid = licenseKeyGroupUuid;
+ }
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore b/appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/.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-license-manager/appc-license-manager-core/pom.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml
new file mode 100644
index 000000000..1b209f1e0
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml
@@ -0,0 +1,71 @@
+<?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-license-manager</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-license-manager-core</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>APPC License Manager Bundle</name>
+ <description>appc-license-manager-core OSGi bundle project.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-license-manager-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>javax.mail</artifactId>
+ <version>1.5.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-common</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.sdnc.core</groupId>
+ <artifactId>dblib-provider</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>!dblib-provider,appc-common,eelf-core,logback-core,logback-classic,javax.mail;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Export-Service>org.openecomp.appc.licmgr.LicenseManager</Export-Service>
+ <Import-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects,javax.mail.internet,!javax.mail,!groovy.lang,!javax.jms,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!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-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java
new file mode 100644
index 000000000..2aff1ffb9
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java
@@ -0,0 +1,177 @@
+/*-
+ * ============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.licmgr.impl;
+
+import org.openecomp.appc.licmgr.Constants;
+import org.openecomp.appc.licmgr.LicenseDataAccessService;
+import org.openecomp.appc.licmgr.exception.DataAccessException;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.openecomp.sdnc.sli.resource.dblib.DbLibService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+import javax.sql.rowset.CachedRowSet;
+
+import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@SuppressWarnings("JavaDoc")
+class LicenseDataAccessServiceImpl implements LicenseDataAccessService {
+
+ private static EELFLogger logger = EELFManager.getInstance().getLogger(LicenseDataAccessServiceImpl.class);
+
+ public void setSchema(String schema) {
+ this.schema = schema;
+ }
+
+ private String schema;
+
+ private DbLibService dbLibService;
+
+ private void checkDbLibService() throws DataAccessException {
+ if (null != dbLibService) {return;}
+
+ //get dblib service and send it to DAService
+ BundleContext bctx = FrameworkUtil.getBundle(LicenseManagerImpl.class).getBundleContext();
+ ServiceReference sref = bctx.getServiceReference(DbLibService.class.getName());
+ dbLibService = (DbLibService)bctx.getService(sref);
+
+ }
+
+ /**
+ * empty constructor
+ */
+ public LicenseDataAccessServiceImpl(){}
+
+ @Override
+ public Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws
+ DataAccessException {
+
+ checkDbLibService();
+
+ Map<String,String> result = new HashMap<>();
+ if (null == fields || 0 == fields.length) fields = new String[]{ASDC_ARTIFACTS_FIELDS.ARTIFACT_CONTENT.name()};
+
+ String queryString = buildQueryStatement();
+
+ ArrayList<String> argList = new ArrayList<>();
+ argList.add(vnfType);
+ argList.add(vnfVersion);
+ argList.add(Constants.VF_LICENSE);
+
+ try {
+
+ final CachedRowSet data = dbLibService.getData(queryString, argList, Constants.NETCONF_SCHEMA);
+
+ if (data.first()) {
+ for (String field : fields) {
+ result.put(field, data.getString(field));
+ }
+ } else {
+ String msg = "Missing license model for VNF_TYPE: " + vnfType + " and VNF_VERSION: " + vnfVersion + " in table " + Constants.ASDC_ARTIFACTS_TABLE_NAME;
+ logger.info(msg);
+ }
+ } catch (SQLException e) {
+ logger.error("Error Accessing Database " + e);
+ throw new DataAccessException(e);
+ }
+
+ return result;
+ }
+
+ private String buildQueryStatement() {
+ return "select * " + "from " + Constants.ASDC_ARTIFACTS_TABLE_NAME + " " +
+ "where " + ASDC_ARTIFACTS_FIELDS.RESOURCE_NAME.name() + " = ?" +
+ " AND " + ASDC_ARTIFACTS_FIELDS.RESOURCE_VERSION.name() + " = ?" +
+ " AND " + ASDC_ARTIFACTS_FIELDS.ARTIFACT_TYPE.name() + " = ?";
+ }
+
+ /**
+ * Implementation of storeArtifactPayload()
+ * @see LicenseDataAccessService
+ */
+ @Override
+ public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException {
+
+ checkDbLibService();
+
+ if(parameters == null || parameters.isEmpty()) {
+ throw new RuntimeException("No parameters for insert are provided");
+ }
+
+ String insertStr = "INSERT INTO " + Constants.ASDC_ARTIFACTS_TABLE_NAME + "(";
+ String valuesStr = "VALUES(";
+ String insertStatementStr;
+
+ ArrayList<String> params = new ArrayList<>();
+ boolean firstTime = true;
+ for(Map.Entry<String, String> entry : parameters.entrySet()) {
+ if(!firstTime) {
+ insertStr += ",";
+ valuesStr += ",";
+ }
+ else {
+ firstTime = false;
+ }
+ insertStr += entry.getKey();
+ valuesStr += "?";
+
+ params.add(entry.getValue());
+ }
+
+ insertStr += ")";
+ valuesStr += ")";
+ insertStatementStr = insertStr + " " + valuesStr;
+
+ executeStoreArtifactPayload(insertStatementStr, params);
+ }
+
+ /**
+ * Exexutes insert statement for artifact payload
+ * @param insertStatementStr
+ * @param params
+ * @throws RuntimeException
+ */
+ private void executeStoreArtifactPayload(String insertStatementStr, ArrayList<String> params) throws RuntimeException {
+
+ try {
+ logger.info("used schema=" + this.schema);
+ logger.info("insert statement=" + insertStatementStr);
+
+ dbLibService.writeData(insertStatementStr, params, this.schema);
+
+ logger.info("finished to execute insert");
+
+ } catch (SQLException e) {
+ logger.error("Storing Artifact payload failed - " + insertStatementStr);
+ throw new RuntimeException("Storing Artifact payload failed - " + insertStatementStr);
+ }
+ }
+
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java
new file mode 100644
index 000000000..815bb02ab
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.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.licmgr.impl;
+
+import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS.ARTIFACT_CONTENT;
+
+import java.util.Map;
+
+import org.openecomp.appc.licmgr.Constants;
+import org.openecomp.appc.licmgr.LicenseDataAccessService;
+import org.openecomp.appc.licmgr.LicenseManager;
+import org.openecomp.appc.licmgr.exception.DataAccessException;
+import org.openecomp.appc.licmgr.objects.LicenseModel;
+
+
+@SuppressWarnings("all")
+public class LicenseManagerImpl implements LicenseManager {
+
+ private LicenseDataAccessService DAService;
+
+ public void setDAService(LicenseDataAccessService daSrv){
+ DAService = daSrv;
+ }
+
+ public LicenseManagerImpl() {
+ DAService = new LicenseDataAccessServiceImpl();
+ DAService.setSchema(Constants.SDNCTL_SCHEMA);
+ }
+
+ @Override
+ public LicenseModel retrieveLicenseModel(String vnfType, String vnfVersion) throws DataAccessException {
+
+ LicenseModel licenseModel;
+ try {
+ Map<String,String> resultMap = DAService.retrieveLicenseModelData(vnfType, vnfVersion);
+ if (resultMap.isEmpty()) {
+ throw new DataAccessException(String.format("License model not found for vnfType='%s' and vnfVersion='%s'", vnfType, vnfVersion));
+ }
+ String licenseModelXML = resultMap.get(ARTIFACT_CONTENT.name());
+ licenseModel = convert(licenseModelXML); // JAXBUtil.<VfLicenseModel>toObject(licenseModelXML, VfLicenseModel.class);
+ } catch (DataAccessException le) {
+ throw le;
+ } catch (Exception e) {
+ throw new DataAccessException(e);
+ }
+ return licenseModel;
+ }
+
+ @Override
+ public Map<String, String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException {
+
+ Map<String,String> resultMap = DAService.retrieveLicenseModelData(vnfType, vnfVersion, fields);
+ return resultMap;
+ }
+
+ @Override
+ public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException {
+
+ DAService.storeArtifactPayload(parameters);
+ }
+
+ private static LicenseModel convert(String xml) {
+
+ LicenseModel licenseModel = new LicenseModel();
+
+ int posEntitlementStart = xml.indexOf("<entitlement-pool-uuid>");
+ int posEntitlementEnd = xml.indexOf("</entitlement-pool-uuid>", posEntitlementStart);
+ if (-1 != posEntitlementStart) {
+ licenseModel.setEntitlementPoolUuid(xml.substring(posEntitlementStart + "<entitlement-pool-uuid>".length(), posEntitlementEnd));
+ }
+
+ int posLicenseStart = xml.indexOf("<license-key-group-uuid>");
+ int posLicenseEnd = xml.indexOf("</license-key-group-uuid>", posEntitlementStart);
+ if (-1 != posLicenseStart) {
+ licenseModel.setLicenseKeyGroupUuid(xml.substring(posLicenseStart + "<license-key-group-uuid>".length(), posLicenseEnd));
+ }
+
+ return licenseModel;
+ }
+
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..c8efb8390
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.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=========================================================
+ -->
+
+<!--
+ Starter Blueprint Camel Definition appc-command-executor-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="licenseServiceBean" class="org.openecomp.appc.licmgr.impl.LicenseManagerImpl" scope="singleton" activation="lazy"/>
+ <service id="licenseService" interface="org.openecomp.appc.licmgr.LicenseManager" ref="licenseServiceBean"/>
+
+</blueprint>
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..9d9e1d787
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties
@@ -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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-LIC-MGR-MAIN
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=2
+dmaap.threads.poolsize.max=2
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java
new file mode 100644
index 000000000..41bc7cadf
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerImplTest.java
@@ -0,0 +1,22 @@
+/*-
+ * ============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.licmgr;
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java
new file mode 100644
index 000000000..ca7c1f2e9
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerMock.java
@@ -0,0 +1,57 @@
+/*-
+ * ============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.licmgr;
+
+import java.util.Map;
+
+import org.openecomp.appc.licmgr.LicenseManager;
+import org.openecomp.appc.licmgr.exception.DataAccessException;
+import org.openecomp.appc.licmgr.objects.LicenseModel;
+
+
+public class LicenseManagerMock implements LicenseManager {
+
+ LicenseModel licenseModel;
+ @Override
+ public LicenseModel retrieveLicenseModel(String vnfType, String vnfVersion) throws DataAccessException {
+ if (vnfType == "VSCP" && vnfVersion == "123"){
+ return licenseModel;
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override public Map<String, String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields)
+ throws DataAccessException {
+ return null;
+ }
+
+ @Override public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException {
+
+ }
+
+ public void storeLicenseModel(LicenseModel licenseModel){
+ this.licenseModel = licenseModel;
+
+ }
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java
new file mode 100644
index 000000000..41bc7cadf
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseManagerPluginImplTest.java
@@ -0,0 +1,22 @@
+/*-
+ * ============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.licmgr;
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java
new file mode 100644
index 000000000..e496da7b5
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java
@@ -0,0 +1,56 @@
+/*-
+ * ============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.licmgr;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openecomp.appc.licmgr.LicenseDataAccessService;
+import org.openecomp.appc.licmgr.exception.DataAccessException;
+import org.openecomp.sdnc.sli.resource.dblib.DbLibService;
+
+class LicenseServiceMock implements LicenseDataAccessService {
+
+ private String configFile;
+ private HashMap<String, String> backupConf;
+
+ @Override
+ public void setSchema(String schema) {
+ }
+
+ void setConfigFile(String configFile) {
+ this.configFile = configFile;
+ }
+
+ public HashMap<String, String> getBackupConf() {
+ return backupConf;
+ }
+
+ @Override
+ public Map<String, String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException {
+ return null;
+ }
+
+ @Override
+ public void storeArtifactPayload(Map<String, String> parameters) throws DataAccessException {
+ }
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java
new file mode 100644
index 000000000..26482a1dc
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/TestVfLicenseModelConvert.java
@@ -0,0 +1,61 @@
+/*-
+ * ============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.licmgr;
+
+/*
+import org.openecomp.appc.licmgr.objects.VfLicenseModel;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+*/
+
+public class TestVfLicenseModelConvert {
+/*
+ public static void main(String args[]) {
+
+ try {
+
+ //create JAXB context
+ JAXBContext context = JAXBContext.newInstance(VfLicenseModel.class);
+
+ //Create Unmarshaller using JAXB context
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+
+ Path xmlPath = Paths.get("src/test/resources/xml/vf-license-model.xml");
+ InputStream xmlInputStream = Files.newInputStream(xmlPath);
+
+ VfLicenseModel licenseModel = (VfLicenseModel) unmarshaller.unmarshal(xmlInputStream);
+
+ String vnfId = licenseModel.getVnfId();
+ String vendorName = licenseModel.getVendorName();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+*/
+}
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore b/appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore
new file mode 100644
index 000000000..2992ae832
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-features/.gitignore
@@ -0,0 +1,3 @@
+/target/
+/bin/
+/.settings/
diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-features/pom.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-features/pom.xml
new file mode 100644
index 000000000..3adbcf5e2
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-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>appc-license-manager</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>appc-license-manager-features</name>
+ <artifactId>appc-license-manager-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-license-manager-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-license-manager-core</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> -->
+ <!-- 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. -->
+<!-- <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> -->
+ <!-- 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. -->
+<!-- <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-license-manager/appc-license-manager-features/src/main/resources/features.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-features/src/main/resources/features.xml
new file mode 100644
index 000000000..34635b839
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/appc-license-manager-features/src/main/resources/features.xml
@@ -0,0 +1,34 @@
+<?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="appc-license-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='appc-license-manager' description="application license manager" version='${project.version}'>
+ <bundle>mvn:com.sun.mail/javax.mail/1.5.0</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-license-manager-api/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-license-manager-core/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-license-manager/pom.xml b/appc-dispatcher/appc-license-manager/pom.xml
new file mode 100644
index 000000000..f590f42b5
--- /dev/null
+++ b/appc-dispatcher/appc-license-manager/pom.xml
@@ -0,0 +1,22 @@
+<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-license-manager</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC License Manager</name>
+ <description>APPC License Manager</description>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-license-manager-api</module>
+ <module>appc-license-manager-core</module>
+ <module>appc-license-manager-features</module>
+ </modules>
+
+</project>
diff --git a/appc-dispatcher/appc-lifecycle-management/.gitignore b/appc-dispatcher/appc-lifecycle-management/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-lifecycle-management/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-lifecycle-management/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/.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-lifecycle-management/appc-lifecycle-management-api/.gitignore b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-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-lifecycle-management/appc-lifecycle-management-api/pom.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/pom.xml
new file mode 100644
index 000000000..67e52a2a6
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/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-lifecycle-management</artifactId>
+ <version>1.0.0</version>
+ </parent>
+
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-api</artifactId>
+ <version>1.0.0</version>
+ <packaging>bundle</packaging>
+
+ <name>appc-lifecycle-management-api</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.lifecyclemanager.*</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.java
new file mode 100644
index 000000000..795e340e0
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/LifecycleManager.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.lifecyclemanager;
+
+
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+
+public interface LifecycleManager {
+ String getNextState(String vnfType, String currentState, String event) throws NoTransitionDefinedException,LifecycleException;
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.java
new file mode 100644
index 000000000..70aefee26
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LCMResponse.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.lifecyclemanager.objects;
+
+public enum LCMResponse {
+ INVALID_INPUT_PARAMETERS,
+ NO_STATE_CHANGE,
+ NO_TRANSITION_DEFINED,
+ VALID_TRANSITION;
+
+ public String toString(){
+ return this.name();
+ }
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.java
new file mode 100644
index 000000000..d729ca161
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/LifecycleException.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.lifecyclemanager.objects;
+
+
+public class LifecycleException extends Exception {
+ public final String currentState;
+ public final String event;
+ public LifecycleException(Exception e,String currentState,String event){
+ super(e);
+ this.currentState = currentState;
+ this.event = event;
+
+ }
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.java
new file mode 100644
index 000000000..688be531d
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/NoTransitionDefinedException.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.lifecyclemanager.objects;
+
+
+public class NoTransitionDefinedException extends Exception {
+ public final String currentState;
+ public final String event;
+ public NoTransitionDefinedException(String message,String currentState,String event){
+ super(message);
+ this.currentState = currentState;
+ this.event = event;
+
+ }
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.java
new file mode 100644
index 000000000..9ad1cc701
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-api/src/main/java/org/openecomp/appc/lifecyclemanager/objects/VNFOperationOutcome.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.lifecyclemanager.objects;
+
+public enum VNFOperationOutcome {
+ SUCCESS,FAILURE,EXPIRE;
+ public String toString(){
+ return this.name();
+ }
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/.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-lifecycle-management/appc-lifecycle-management-core/pom.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml
new file mode 100644
index 000000000..b8535cb62
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml
@@ -0,0 +1,82 @@
+<?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">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-core</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-lifecycle-management-core Bundle</name>
+ <description>appc-lifecycle-management-core OSGi bundle project.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>state-machine-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ <version>${eelf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>domain-model-lib</artifactId>
+ <version>${project.version}</version>
+ </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-Service>org.openecomp.appc.lifecyclemanager.LifecycleManager</Export-Service>
+ <Import-Package>org.openecomp.appc.lifecyclemanager.*,!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-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java
new file mode 100644
index 000000000..516bb7e4b
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java
@@ -0,0 +1,337 @@
+/*-
+ * ============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.lifecyclemanager.helper;
+
+
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+import org.openecomp.appc.lifecyclemanager.objects.VNFOperationOutcome;
+import org.openecomp.appc.statemachine.objects.Event;
+import org.openecomp.appc.statemachine.objects.State;
+import org.openecomp.appc.statemachine.objects.StateMachineMetadata;
+
+
+public class MetadataReader {
+
+ private enum VNFStates {
+ Not_Instantiated, Instantiated, Configuring, Configured, Testing, Tested, Rebuilding, Restarting, Error, Running, Unknown, Terminating, Stopping, Stopped,
+ Backing_Up, Snapshotting, Software_Uploading, Upgrading, Rollbacking, Licensing, Migrating, Evacuating;
+ }
+
+ @SuppressWarnings("unused")
+ public StateMachineMetadata readMetadata(String vnfType){
+ State NOT_INSTANTIATED = new State(VNFStates.Not_Instantiated.toString());
+ State INSTANTIATED = new State(VNFStates.Instantiated.toString());
+ State CONFIGURING = new State(VNFStates.Configuring.toString());
+ State CONFIGURED = new State(VNFStates.Configured.toString());
+ State TESTING = new State(VNFStates.Testing.toString());
+ State TESTED = new State(VNFStates.Tested.toString());
+ State REBUILDING = new State(VNFStates.Rebuilding.toString());
+ State RESTARTING = new State(VNFStates.Restarting.toString());
+ State ERROR = new State(VNFStates.Error.toString());
+ State RUNNING = new State(VNFStates.Running.toString());
+ State UNKNOWN = new State(VNFStates.Unknown.toString());
+ State TERMINATING = new State(VNFStates.Terminating.toString());
+ State STOPPING = new State(VNFStates.Stopping.toString());
+ State STOPPED = new State(VNFStates.Stopped.toString());
+
+// State PRE_UPGRADE_TESTING = new State(VNFStates.Pre_Upgrade_Testing.toString());
+ State BACKING_UP = new State(VNFStates.Backing_Up.toString());
+ State SNAPSHOTTING = new State(VNFStates.Snapshotting.toString());
+ State SOFTWARE_UPLOADING = new State(VNFStates.Software_Uploading.toString());
+ State UPGRADING = new State(VNFStates.Upgrading.toString());
+ State ROLLBACKING = new State(VNFStates.Rollbacking.toString());
+
+ State MIGRATING = new State(VNFStates.Migrating.toString());
+ State EVACUATING = new State(VNFStates.Evacuating.toString());
+
+ Event CONFIGURE = new Event(VNFOperation.Configure.toString());
+ Event HEALTHCHECK = new Event(VNFOperation.HealthCheck.toString());
+ Event TEST = new Event(VNFOperation.Test.toString());
+ Event START = new Event(VNFOperation.Start.toString());
+ Event TERMINATE = new Event(VNFOperation.Terminate.toString());
+ Event RESTART = new Event(VNFOperation.Restart.toString());
+ Event REBUILD = new Event(VNFOperation.Rebuild.toString());
+ Event STOP = new Event(VNFOperation.Stop.toString());
+ Event MODIFY_CONFIG = new Event(VNFOperation.ModifyConfig.toString());
+ Event BACKUP = new Event(VNFOperation.Backup.toString());
+ Event SNAPSHOT = new Event(VNFOperation.Snapshot.toString());
+ Event SOFTWARE_UPLOAD = new Event(VNFOperation.SoftwareUpload.toString());
+ Event LIVE_UPGRADE = new Event(VNFOperation.LiveUpgrade.toString());
+ Event ROLLBACK = new Event(VNFOperation.Rollback.toString());
+ Event SYNC = new Event(VNFOperation.Sync.toString());
+ Event AUDIT = new Event(VNFOperation.Audit.toString());
+ Event MIGRATE = new Event(VNFOperation.Migrate.toString());
+ Event EVACUATE = new Event(VNFOperation.Evacuate.toString());
+
+ Event LOCK = new Event(VNFOperation.Lock.toString());
+ Event UNLOCK = new Event(VNFOperation.Unlock.toString());
+ Event CHECKLOCK = new Event(VNFOperation.CheckLock.toString());
+
+ Event SUCCESS = new Event(VNFOperationOutcome.SUCCESS.toString());
+ Event FAILURE = new Event(VNFOperationOutcome.FAILURE.toString());
+
+
+ StateMachineMetadata.StateMachineMetadataBuilder builder = new StateMachineMetadata.StateMachineMetadataBuilder();
+
+ builder = builder.addState(NOT_INSTANTIATED);
+ builder = builder.addState(INSTANTIATED);
+ builder = builder.addState(CONFIGURING);
+ builder = builder.addState(CONFIGURED);
+ builder = builder.addState(TESTING);
+ builder = builder.addState(TESTED);
+ builder = builder.addState(REBUILDING);
+ builder = builder.addState(RESTARTING);
+ builder = builder.addState(ERROR);
+ builder = builder.addState(RUNNING);
+ builder = builder.addState(UNKNOWN);
+ builder = builder.addState(TERMINATING);
+ builder = builder.addState(STOPPING);
+ builder = builder.addState(STOPPED);
+// builder = builder.addState(PRE_UPGRADE_TESTING);
+ builder = builder.addState(BACKING_UP);
+ builder = builder.addState(SNAPSHOTTING);
+ builder = builder.addState(SOFTWARE_UPLOADING);
+ builder = builder.addState(UPGRADING);
+ builder = builder.addState(ROLLBACKING);
+ builder = builder.addState(MIGRATING);
+ builder = builder.addState(EVACUATING);
+
+ builder = builder.addEvent(CONFIGURE);
+ builder = builder.addEvent(TEST);
+ builder = builder.addEvent(START);
+ builder = builder.addEvent(TERMINATE);
+ builder = builder.addEvent(RESTART);
+ builder = builder.addEvent(REBUILD);
+ builder = builder.addEvent(SUCCESS);
+ builder = builder.addEvent(FAILURE);
+ builder = builder.addEvent(STOP);
+ builder = builder.addEvent(MODIFY_CONFIG);
+ builder = builder.addEvent(HEALTHCHECK);
+ builder = builder.addEvent(BACKUP);
+ builder = builder.addEvent(SNAPSHOT);
+ builder = builder.addEvent(SOFTWARE_UPLOAD);
+ builder = builder.addEvent(LIVE_UPGRADE);
+ builder = builder.addEvent(ROLLBACK);
+ builder = builder.addEvent(SYNC);
+ builder = builder.addEvent(AUDIT);
+ builder = builder.addEvent(MIGRATE);
+ builder = builder.addEvent(EVACUATE);
+ builder = builder.addEvent(LOCK);
+ builder = builder.addEvent(UNLOCK);
+ builder = builder.addEvent(CHECKLOCK);
+
+ builder = builder.addTransition(INSTANTIATED,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(INSTANTIATED,TEST,TESTING);
+ builder = builder.addTransition(INSTANTIATED,START,RESTARTING);
+ builder = builder.addTransition(INSTANTIATED,TERMINATE,TERMINATING);
+ builder = builder.addTransition(INSTANTIATED,RESTART,RESTARTING);
+ builder = builder.addTransition(INSTANTIATED,REBUILD,REBUILDING);
+ builder = builder.addTransition(INSTANTIATED,STOP,STOPPING);
+ builder = builder.addTransition(INSTANTIATED,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(INSTANTIATED,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(INSTANTIATED,BACKUP,BACKING_UP);
+ builder = builder.addTransition(INSTANTIATED,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(INSTANTIATED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(INSTANTIATED,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(INSTANTIATED,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(INSTANTIATED,MIGRATE,MIGRATING);
+ builder = builder.addTransition(INSTANTIATED,EVACUATE,EVACUATING);
+ builder = builder.addTransition(INSTANTIATED,LOCK,INSTANTIATED);
+ builder = builder.addTransition(INSTANTIATED,UNLOCK,INSTANTIATED);
+ builder = builder.addTransition(INSTANTIATED,CHECKLOCK,INSTANTIATED);
+
+ builder = builder.addTransition(CONFIGURED,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(CONFIGURED,TEST,TESTING);
+ builder = builder.addTransition(CONFIGURED,START,RESTARTING);
+ builder = builder.addTransition(CONFIGURED,TERMINATE,TERMINATING);
+ builder = builder.addTransition(CONFIGURED,RESTART,RESTARTING);
+ builder = builder.addTransition(CONFIGURED,REBUILD,REBUILDING);
+ builder = builder.addTransition(CONFIGURED,STOP,STOPPING);
+ builder = builder.addTransition(CONFIGURED,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(CONFIGURED,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(CONFIGURED,BACKUP,BACKING_UP);
+ builder = builder.addTransition(CONFIGURED,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(CONFIGURED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(CONFIGURED,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(CONFIGURED,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(CONFIGURED,SYNC,CONFIGURED);
+ builder = builder.addTransition(CONFIGURED,AUDIT,CONFIGURED);
+ builder = builder.addTransition(CONFIGURED,MIGRATE,MIGRATING);
+ builder = builder.addTransition(CONFIGURED,EVACUATE,EVACUATING);
+ builder = builder.addTransition(CONFIGURED,LOCK,CONFIGURED);
+ builder = builder.addTransition(CONFIGURED,UNLOCK,CONFIGURED);
+ builder = builder.addTransition(CONFIGURED,CHECKLOCK,CONFIGURED);
+
+ builder = builder.addTransition(TESTED,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(TESTED,TEST,TESTING);
+ builder = builder.addTransition(TESTED,START,RESTARTING);
+ builder = builder.addTransition(TESTED,TERMINATE,TERMINATING);
+ builder = builder.addTransition(TESTED,RESTART,RESTARTING);
+ builder = builder.addTransition(TESTED,REBUILD,REBUILDING);
+ builder = builder.addTransition(TESTED,STOP,STOPPING);
+ builder = builder.addTransition(TESTED,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(TESTED,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(TESTED,BACKUP,BACKING_UP);
+ builder = builder.addTransition(TESTED,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(TESTED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(TESTED,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(TESTED,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(TESTED,SYNC,TESTED);
+ builder = builder.addTransition(TESTED,AUDIT,TESTED);
+ builder = builder.addTransition(TESTED,MIGRATE,MIGRATING);
+ builder = builder.addTransition(TESTED,EVACUATE,EVACUATING);
+ builder = builder.addTransition(TESTED,LOCK,TESTED);
+ builder = builder.addTransition(TESTED,UNLOCK,TESTED);
+ builder = builder.addTransition(TESTED,CHECKLOCK,TESTED);
+
+ builder = builder.addTransition(RUNNING,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(RUNNING,TEST,TESTING);
+ builder = builder.addTransition(RUNNING,START,RESTARTING);
+ builder = builder.addTransition(RUNNING,TERMINATE,TERMINATING);
+ builder = builder.addTransition(RUNNING,RESTART,RESTARTING);
+ builder = builder.addTransition(RUNNING,REBUILD,REBUILDING);
+ builder = builder.addTransition(RUNNING,STOP,STOPPING);
+ builder = builder.addTransition(RUNNING,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(RUNNING,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(RUNNING,BACKUP,BACKING_UP);
+ builder = builder.addTransition(RUNNING,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(RUNNING,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(RUNNING,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(RUNNING,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(RUNNING,SYNC,RUNNING);
+ builder = builder.addTransition(RUNNING,AUDIT,RUNNING);
+ builder = builder.addTransition(RUNNING,MIGRATE,MIGRATING);
+ builder = builder.addTransition(RUNNING,EVACUATE,EVACUATING);
+ builder = builder.addTransition(RUNNING,LOCK,RUNNING);
+ builder = builder.addTransition(RUNNING,UNLOCK,RUNNING);
+ builder = builder.addTransition(RUNNING,CHECKLOCK,RUNNING);
+
+ builder = builder.addTransition(ERROR,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(ERROR,TEST,TESTING);
+ builder = builder.addTransition(ERROR,START,RESTARTING);
+ builder = builder.addTransition(ERROR,TERMINATE,TERMINATING);
+ builder = builder.addTransition(ERROR,RESTART,RESTARTING);
+ builder = builder.addTransition(ERROR,REBUILD,REBUILDING);
+ builder = builder.addTransition(ERROR,STOP,STOPPING);
+ builder = builder.addTransition(ERROR,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(ERROR,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(ERROR,BACKUP,BACKING_UP);
+ builder = builder.addTransition(ERROR,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(ERROR,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(ERROR,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(ERROR,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(ERROR,SYNC,ERROR);
+ builder = builder.addTransition(ERROR,AUDIT,ERROR);
+ builder = builder.addTransition(ERROR,MIGRATE,MIGRATING);
+ builder = builder.addTransition(ERROR,EVACUATE,EVACUATING);
+ builder = builder.addTransition(ERROR,LOCK,ERROR);
+ builder = builder.addTransition(ERROR,UNLOCK,ERROR);
+ builder = builder.addTransition(ERROR,CHECKLOCK,ERROR);
+
+ builder = builder.addTransition(UNKNOWN,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(UNKNOWN,TEST,TESTING);
+ builder = builder.addTransition(UNKNOWN,START,RESTARTING);
+ builder = builder.addTransition(UNKNOWN,TERMINATE,TERMINATING);
+ builder = builder.addTransition(UNKNOWN,RESTART,RESTARTING);
+ builder = builder.addTransition(UNKNOWN,REBUILD,REBUILDING);
+ builder = builder.addTransition(UNKNOWN,STOP,STOPPING);
+ builder = builder.addTransition(UNKNOWN,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(UNKNOWN,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(UNKNOWN,BACKUP,BACKING_UP);
+ builder = builder.addTransition(UNKNOWN,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(UNKNOWN,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(UNKNOWN,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(UNKNOWN,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(UNKNOWN,SYNC,UNKNOWN);
+ builder = builder.addTransition(UNKNOWN,AUDIT,UNKNOWN);
+ builder = builder.addTransition(UNKNOWN,MIGRATE,MIGRATING);
+ builder = builder.addTransition(UNKNOWN,EVACUATE,EVACUATING);
+ builder = builder.addTransition(UNKNOWN,LOCK,UNKNOWN);
+ builder = builder.addTransition(UNKNOWN,UNLOCK,UNKNOWN);
+ builder = builder.addTransition(UNKNOWN,CHECKLOCK,UNKNOWN);
+
+ builder = builder.addTransition(STOPPED,CONFIGURE,CONFIGURING);
+ builder = builder.addTransition(STOPPED,TEST,TESTING);
+ builder = builder.addTransition(STOPPED,START,RESTARTING);
+ builder = builder.addTransition(STOPPED,TERMINATE,TERMINATING);
+ builder = builder.addTransition(STOPPED,RESTART,RESTARTING);
+ builder = builder.addTransition(STOPPED,REBUILD,REBUILDING);
+ builder = builder.addTransition(STOPPED,MODIFY_CONFIG,CONFIGURING);
+ builder = builder.addTransition(STOPPED,HEALTHCHECK,TESTING);
+ builder = builder.addTransition(STOPPED,BACKUP,BACKING_UP);
+ builder = builder.addTransition(STOPPED,SNAPSHOT,SNAPSHOTTING);
+ builder = builder.addTransition(STOPPED,SOFTWARE_UPLOAD,SOFTWARE_UPLOADING);
+ builder = builder.addTransition(STOPPED,LIVE_UPGRADE,UPGRADING);
+ builder = builder.addTransition(STOPPED,ROLLBACK,ROLLBACKING);
+ builder = builder.addTransition(STOPPED,MIGRATE,MIGRATING);
+ builder = builder.addTransition(STOPPED,EVACUATE,EVACUATING);
+ builder = builder.addTransition(STOPPED,LOCK,STOPPED);
+ builder = builder.addTransition(STOPPED,UNLOCK,STOPPED);
+ builder = builder.addTransition(STOPPED,CHECKLOCK,STOPPED);
+
+ builder = builder.addTransition(CONFIGURING,SUCCESS,CONFIGURED);
+ builder = builder.addTransition(CONFIGURING,FAILURE,ERROR);
+
+ builder = builder.addTransition(TESTING,SUCCESS,TESTED);
+ builder = builder.addTransition(TESTING,FAILURE,ERROR);
+
+ builder = builder.addTransition(RESTARTING,SUCCESS,RUNNING);
+ builder = builder.addTransition(RESTARTING,FAILURE,ERROR);
+
+ builder = builder.addTransition(TERMINATING,SUCCESS,NOT_INSTANTIATED);
+ builder = builder.addTransition(TERMINATING,FAILURE,ERROR);
+
+ builder = builder.addTransition(REBUILDING,SUCCESS,RUNNING);
+ builder = builder.addTransition(REBUILDING,FAILURE,ERROR);
+
+ builder = builder.addTransition(STOPPING,SUCCESS,STOPPED);
+ builder = builder.addTransition(STOPPING,FAILURE,ERROR);
+
+// builder = builder.addTransition(PRE_UPGRADE_TESTING,SUCCESS,TESTED);
+// builder = builder.addTransition(PRE_UPGRADE_TESTING,FAILURE,ERROR);
+
+ builder = builder.addTransition(BACKING_UP,SUCCESS,RUNNING);
+ builder = builder.addTransition(BACKING_UP,FAILURE,ERROR);
+
+ builder = builder.addTransition(SNAPSHOTTING,SUCCESS,RUNNING);
+ builder = builder.addTransition(SNAPSHOTTING,FAILURE,ERROR);
+
+ builder = builder.addTransition(SOFTWARE_UPLOADING,SUCCESS,RUNNING);
+ builder = builder.addTransition(SOFTWARE_UPLOADING,FAILURE,ERROR);
+
+ builder = builder.addTransition(UPGRADING,SUCCESS,RUNNING);
+ builder = builder.addTransition(UPGRADING,FAILURE,ERROR);
+
+ builder = builder.addTransition(ROLLBACKING,SUCCESS,RUNNING);
+ builder = builder.addTransition(ROLLBACKING,FAILURE,ERROR);
+
+ builder = builder.addTransition(MIGRATING,SUCCESS,RUNNING);
+ builder = builder.addTransition(MIGRATING,FAILURE,ERROR);
+
+ builder = builder.addTransition(EVACUATING,SUCCESS,RUNNING);
+ builder = builder.addTransition(EVACUATING,FAILURE,ERROR);
+
+ return builder.build();
+
+ }
+
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java
new file mode 100644
index 000000000..ffaab140a
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/impl/LifecycleManagerImpl.java
@@ -0,0 +1,94 @@
+/*-
+ * ============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.lifecyclemanager.impl;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.openecomp.appc.i18n.Msg;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.lifecyclemanager.helper.MetadataReader;
+import org.openecomp.appc.lifecyclemanager.objects.*;
+import org.openecomp.appc.statemachine.*;
+import org.openecomp.appc.statemachine.impl.StateMachineFactory;
+import org.openecomp.appc.statemachine.objects.*;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+
+
+public class LifecycleManagerImpl implements LifecycleManager{
+
+ private MetadataReader metadataReader;
+ private static Map<String,StateMachine> stateMachineMap = new ConcurrentHashMap<String,StateMachine>();
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(LifecycleManagerImpl.class);
+ private static EELFLogger errorLogger = EELFManager.getInstance().getErrorLogger();
+ public LifecycleManagerImpl(){
+ this.metadataReader = new MetadataReader();
+ }
+
+ @Override
+ public String getNextState(String vnfType, String currentState, String event) throws NoTransitionDefinedException,LifecycleException{
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to getNextState with vnfType = "+ vnfType + ", currentState = " + currentState + ", event = " + event);
+ }
+
+ State nextState = null;
+ StateMachine machine = null;
+ StateMachineResponse response;
+ try {
+ machine = this.getStateMachine(vnfType);
+ response = machine.handleEvent(new State(currentState),new Event(event));
+ if(Response.NO_TRANSITION_DEFINED.equals(response.getResponse())){
+ errorLogger.error(EELFResourceManager.format(Msg.VF_ILLEGAL_COMMAND, vnfType,event,currentState));
+ throw new NoTransitionDefinedException("No Transition Defined for currentState = " + currentState + ", event = " + event,currentState,event);
+ }
+ nextState = response.getNextState();
+ } catch (InvalidInputException e) {
+ logger.error(e.getMessage());
+ throw new LifecycleException(e,currentState,event);
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from getNextState with (nextState = "+nextState.getStateName()!=null?nextState.getStateName():"null"+")");
+ }
+ return nextState.getStateName();
+ }
+
+ private StateMachine getStateMachine(String vnfType){
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to getNextState with vnfType = "+ vnfType);
+ }
+ if(vnfType == null){
+ vnfType = "DEFAULT";
+ }
+ StateMachine machine = stateMachineMap.get(vnfType);
+ if(machine == null){
+ StateMachineMetadata metadata = metadataReader.readMetadata(vnfType);
+ machine = StateMachineFactory.getStateMachine(metadata);
+ stateMachineMap.put(vnfType,machine);
+ }
+
+ logger.trace("Exiting getStateMachine with (StateMachine = "+stateMachineMap.get(vnfType)!=null?stateMachineMap.get(vnfType).toString():"null"+")");
+ return stateMachineMap.get(vnfType);
+ }
+
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..a7d0b83ea
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,34 @@
+<?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="lifecycleManagerBean" class="org.openecomp.appc.lifecyclemanager.impl.LifecycleManagerImpl" scope="singleton" >
+</bean>
+
+ <service id="lcmService" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" ref="lifecycleManagerBean"/>
+
+</blueprint>
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..63711c27f
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties
@@ -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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-LC-MGMT-MAIN
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=1
+dmaap.threads.poolsize.max=2
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java
new file mode 100644
index 000000000..4c14e90bd
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java
@@ -0,0 +1,155 @@
+/*-
+ * ============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;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.lifecyclemanager.helper.MetadataReader;
+import org.openecomp.appc.lifecyclemanager.impl.LifecycleManagerImpl;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.statemachine.objects.*;
+
+import java.util.*;
+
+
+public class TestLifecycleManager {
+
+ private static final State[] VALID_LOCK_STATES = new State[] {
+ new State("Instantiated"),
+ new State("Configured"),
+ new State("Tested"),
+ new State("Running"),
+ new State("Error"),
+ new State("Unknown"),
+ new State("Stopped"),
+ };
+
+ @Test
+ public void handleEvent() throws InvalidInputException, LifecycleException, NoTransitionDefinedException {
+
+ MetadataReader metadataReader = new MetadataReader();
+ StateMachineMetadata metadata = metadataReader.readMetadata(null);
+
+ LifecycleManagerImpl lifecycleManager = new LifecycleManagerImpl();
+
+ /*
+ 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 nextStateFromMetadata = transition.getNextState();
+
+ String expectedNextState = lifecycleManager.getNextState(null,state.toString(),event.toString());
+ Assert.assertEquals(expectedNextState,nextStateFromMetadata.toString());
+ }
+ }
+
+ /*
+ 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){
+ boolean flag =false;
+ try{
+ String response = lifecycleManager.getNextState(null,state.toString(),negativeEvent.toString());
+
+ }
+ catch (NoTransitionDefinedException e){
+ flag =true;
+ }
+ Assert.assertEquals(flag,true);
+
+ flag =false;
+ try{
+ String response = lifecycleManager.getNextState(null,state.toString(),"PUT");
+ }
+ catch(LifecycleException 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;
+ }
+
+ @Test
+ public void testLockStates() throws LifecycleException, NoTransitionDefinedException {
+ MetadataReader metadataReader = new MetadataReader();
+ StateMachineMetadata metadata = metadataReader.readMetadata(null);
+ LifecycleManager lifecycleManager = new LifecycleManagerImpl();
+ for(State state: metadata.getStates()) {
+ if(isValidState(state, VALID_LOCK_STATES)) {
+ assertSameNextState(lifecycleManager, state, VNFOperation.Lock);
+ assertSameNextState(lifecycleManager, state, VNFOperation.Unlock);
+ assertSameNextState(lifecycleManager, state, VNFOperation.CheckLock);
+ } else {
+ assertNoNextState(lifecycleManager, state, VNFOperation.Lock);
+ assertNoNextState(lifecycleManager, state, VNFOperation.Unlock);
+ assertNoNextState(lifecycleManager, state, VNFOperation.CheckLock);
+ }
+ }
+ }
+
+ private boolean isValidState(State state, State[] validStates) {
+ for(State validState: validStates) {
+ if(validState.equals(state)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void assertSameNextState(LifecycleManager lifecycleManager, State state, VNFOperation operation) throws LifecycleException, NoTransitionDefinedException {
+ Assert.assertEquals(state.getStateName(), lifecycleManager.getNextState("no-matter", state.getStateName(), operation.toString()));
+ }
+
+ private void assertNoNextState(LifecycleManager lifecycleManager, State state, VNFOperation operation) throws LifecycleException {
+ try {
+ lifecycleManager.getNextState("no-matter", state.getStateName(), operation.toString());
+ Assert.fail("lifecycleManager.getNextState() should fail for state [" + state + "], operation [" + operation + "]");
+ } catch(NoTransitionDefinedException e) {
+ // this exception is excepted
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml
new file mode 100644
index 000000000..00886e75f
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/pom.xml
@@ -0,0 +1,108 @@
+<?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-lifecycle-management</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>appc-lifecycle-management-features</name>
+ <artifactId>appc-lifecycle-management-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-core</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-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml
new file mode 100644
index 000000000..b74afa93f
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-features/src/main/resources/features.xml
@@ -0,0 +1,35 @@
+<?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="appc-lifecycle-management-${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='appc-lifecycle-management' description="application executor" version='${project.version}'>
+ <bundle dependency="true">mvn:org.openecomp.appc/domain-model-lib/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/state-machine-lib/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-lifecycle-management-api/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-lifecycle-management-core/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-lifecycle-management/pom.xml b/appc-dispatcher/appc-lifecycle-management/pom.xml
new file mode 100644
index 000000000..7d75c0fd4
--- /dev/null
+++ b/appc-dispatcher/appc-lifecycle-management/pom.xml
@@ -0,0 +1,22 @@
+<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-lifecycle-management</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC Lifecycle Management</name>
+ <description>APPC Lifecycle Management</description>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-lifecycle-management-api</module>
+ <module>appc-lifecycle-management-core</module>
+ <module>appc-lifecycle-management-features</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-request-handler/.gitignore b/appc-dispatcher/appc-request-handler/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/.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-request-handler/appc-request-handler-api/.gitignore b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-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-request-handler/appc-request-handler-api/pom.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml
new file mode 100644
index 000000000..b24c10797
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml
@@ -0,0 +1,59 @@
+<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-request-handler</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-request-handler-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-request-handler-api</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+<!-- <version>${jackson.version}</version> -->
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-data-access-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </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.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder,org.openecomp.appc.message</Export-Package>
+ <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Import-Package>com.fasterxml.jackson.annotation,org.apache.commons.lang3,!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!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-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java
new file mode 100644
index 000000000..c397f09cd
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.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.message;
+
+
+public class RequestHandlerMessages {
+ public final static String VNF_WORKING_STATE_UPDATED = "VNF WorkingState for vnfId ${vnfId} was updated to ${workingState} at attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}";
+ public final static String VNF_WORKING_STATE_WAS_NOT_UPDATED = "VNF WorkingState for vnfId ${vnfId} was not updated to ${workingState} attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}";
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java
new file mode 100644
index 000000000..d0d54c9db
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java
@@ -0,0 +1,77 @@
+/*-
+ * ============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.requesthandler;
+
+import org.openecomp.appc.domainmodel.lcm.RuntimeContext;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerInput;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput;
+
+/**
+ * This class provides application logic for the Request/Response Handler Component.
+ *
+ */
+public interface RequestHandler {
+ /**
+ * It receives requests from the north-bound REST API (Communication) Layer and
+ * performs following validations.
+ * 1. VNF exists in A&AI for the given targetID (VnfID)
+ * 2. For the current VNF Orchestration Status, the command can be executed
+ * 3. For the given VNF type and Operation, there exists work-flow definition in the APPC database
+ * If any of the validation fails, it returns appropriate response
+ *
+ * @param input RequestHandlerInput object which contains request header and other request parameters like command , target Id , payload etc.
+ * @return response for request as enum with Return code and message.
+ */
+ RequestHandlerOutput handleRequest(RequestHandlerInput input);
+
+ /**
+ * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI.
+ * @param vnf_id vnf id or target Id on which updates required
+ * @param requestIdentifierString - string contains id uniquely represents the request
+ * @param forceFlag
+ * @return true in case AAI updates are successful. false for any error or exception.
+ */
+ void onRequestExecutionStart(String vnf_id, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException;
+
+ /**
+ * This method perform following operations required after execution of workflow.
+ * It posts asynchronous response to message bus (DMaaP).
+ * Unlock VNF Id
+ * Removes request from request registry.
+ * Generate audit logs.
+ * Adds transaction record to database id if transaction logging is enabled.
+ * @param runtimeContext RuntimeContext object which contains all parameters from request, response and few parameters from AA&I
+ * @param isAAIUpdated boolean flag which indicate AAI upodate status after request completion.
+ */
+ void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated);
+
+ /**
+ * This method perform following operations required if TTL ends when request still waiting in execution queue .
+ * It posts asynchronous response to message bus (DMaaP).
+ * Unlock VNF Id
+ * Removes request from request registry.
+ * @param runtimeContext RuntimeContext object which contains all parameters from request, response and few parameters from AA&I;
+ * @param updateAAI boolean flag which indicate AAI upodate status after request completion.
+ */
+ void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI);
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java
new file mode 100644
index 000000000..70d9b84e8
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.requesthandler.objects;
+
+import org.openecomp.appc.domainmodel.lcm.RequestContext;
+
+public class RequestHandlerInput {
+
+
+ private RequestContext requestContext;
+ private String rpcName;
+
+ public String getRpcName() {
+ return rpcName;
+ }
+
+ public void setRpcName(String rpcName) {
+ this.rpcName = rpcName;
+ }
+
+ public RequestContext getRequestContext() {
+ return requestContext;
+ }
+
+ public RequestHandlerInput(){
+ }
+
+
+ public void setRequestContext(RequestContext requestContext) {
+ this.requestContext = requestContext;
+ }
+
+ @Override
+ public String toString() {
+ return "RequestHandlerInput{" +
+ "requestContext=" + requestContext +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java
new file mode 100644
index 000000000..051c02708
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.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.requesthandler.objects;
+
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+
+public class RequestHandlerOutput {
+
+ private ResponseContext responseContext;
+
+ public RequestHandlerOutput(){
+
+ }
+
+ public ResponseContext getResponseContext() {
+ return responseContext;
+ }
+
+ public void setResponseContext(ResponseContext responseContext) {
+ this.responseContext = responseContext;
+ }
+
+ @Override
+ public String toString() {
+ return "RequestHandlerOutput{" +
+ "responseContext=" + responseContext +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.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-request-handler/appc-request-handler-core/pom.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml
new file mode 100644
index 000000000..d2f469bbc
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml
@@ -0,0 +1,121 @@
+<?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">
+
+ <!-- Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with this
+ work for additional information regarding copyright ownership. The ASF licenses
+ this file to You 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. -->
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-request-handler-core</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-request-handler-core Bundle</name>
+ <description>appc-request-handler-core OSGi bundle project.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-metric-bundle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-dmaap-adapter-bundle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-command-executor-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>execution-queue-management-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-lifecycle-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-data-access-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>lock-manager-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.openecomp.sdnc.adaptors</groupId>
+ <artifactId>aai-service-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>domain-model-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-provider-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>transaction-recorder</artifactId>
+ <version>${project.version}</version>
+ </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-provider-model,appc-dmaap-adapter-bundle,appc-metric-bundle,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.requesthandler.RequestHandler</Export-Service>
+ <Import-Package>org.openecomp.appc.lockmanager.api.*,org.openecomp.appc.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder,org.openecomp.appc.transactionrecorder.objects,!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>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java
new file mode 100644
index 000000000..e516f4991
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.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.common.constant;
+
+import java.util.concurrent.TimeUnit;
+
+public class Constants {
+
+ public static final int DEFAULT_TTL = 30;
+ public static final String SUCCESS_MSG="SUCCESS";
+ public static final String FAILURE_MSG="FAILURE";
+ public static final String DEFAULT_LOGGING_FLAG="true";
+ public static final long DEFAULT_IDLE_TIMEOUT = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java
new file mode 100644
index 000000000..e24237fcb
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.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.messageadapter;
+
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+
+public interface MessageAdapter {
+ /**
+ * Initialize dmaapProducer client to post messages using configuration properties
+ */
+ void init();
+
+ /**
+ * Posts message to DMaaP. As DMaaP accepts only json messages this method first convert dmaapMessage to json format and post it to DMaaP.
+ * @param asyncResponse response data that based on it a message will be send to DMaaP (the format of the message that will be sent to DMaaP based on the action and its YANG domainmodel).
+ * @return True if message is postes successfully else False
+ */
+ boolean post(VNFOperation operation, String rpcName, ResponseContext asyncResponse);
+
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java
new file mode 100644
index 000000000..9f74ad438
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java
@@ -0,0 +1,127 @@
+/*-
+ * ============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.messageadapter.impl;
+
+import java.util.HashSet;
+import java.util.Properties;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.openecomp.appc.adapter.dmaap.Producer;
+import org.openecomp.appc.adapter.dmaap.DmaapProducer;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+import org.openecomp.appc.messageadapter.MessageAdapter;
+import org.openecomp.appc.requesthandler.conv.Converter;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public class MessageAdapterDmaapImpl implements MessageAdapter{
+
+ private Producer dmaapProducer;
+ private String partition ;
+ private Configuration configuration;
+ private HashSet<String> pool;
+ private String writeTopic;
+ private String apiKey;
+ private String apiSecret;
+
+ private Integer READ_TIMEOUT;
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapterDmaapImpl.class);
+
+ /**
+ * Initialize dmaapProducer client to post messages using configuration properties
+ */
+ @Override
+ public void init(){
+ this.dmaapProducer = getDmaapProducer();
+ }
+ private Producer getDmaapProducer() {
+ configuration = ConfigurationFactory.getConfiguration();
+ Properties properties=configuration.getProperties();
+ updateProperties(properties);
+ Producer producer=new DmaapProducer(pool,writeTopic);
+ producer.updateCredentials(apiKey, apiSecret);
+ return producer;
+ }
+
+
+ private void updateProperties(Properties props) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to updateProperties with Properties = "+ ObjectUtils.toString(props));
+ }
+ pool = new HashSet<>();
+ if (props != null) {
+ // readTopic = props.getProperty("dmaap.topic.read");
+ writeTopic = props.getProperty("dmaap.topic.write");
+ apiKey = props.getProperty("dmaap.client.key");
+ apiSecret = props.getProperty("dmaap.client.secret");
+ /* clientName = props.getProperty("dmaap.client.name", "APP-C");
+ clientId = props.getProperty("dmaap.client.name.id", "0");
+ filter_json = props.getProperty("dmaap.topic.read.filter");
+ */
+ // READ_TIMEOUT = Integer.valueOf(props.getProperty("dmaap.topic.read.timeout", String.valueOf(READ_TIMEOUT)));
+ String hostnames = props.getProperty("dmaap.poolMembers");
+ if (hostnames != null && !hostnames.isEmpty()) {
+ for (String name : hostnames.split(",")) {
+ pool.add(name);
+ }
+ }
+ }
+ }
+
+ /**
+ * Posts message to DMaaP. As DMaaP accepts only json messages this method first convert dmaapMessage to json format and post it to DMaaP.
+ * @param asyncResponse response data that based on it a message will be send to DMaaP (the format of the message that will be sent to DMaaP based on the action and its YANG domainmodel).
+ * @return True if message is postes successfully else False
+ */
+ @Override
+ public boolean post(VNFOperation operation, String rpcName, ResponseContext asyncResponse){
+ boolean success;
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(asyncResponse));
+ }
+
+ String jsonMessage;
+ try {
+ jsonMessage = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(operation, rpcName, asyncResponse);
+ if (logger.isDebugEnabled()) {
+ logger.debug("DMaaP Response = " + jsonMessage);
+ }
+ success = dmaapProducer.post(this.partition, jsonMessage);
+ } catch (JsonProcessingException e1) {
+ logger.error("Error generating Jason from DMaaP message "+ e1.getMessage());
+ success= false;
+ }catch (Exception e){
+ logger.error("Error sending message to DMaaP "+e.getMessage());
+ success= false;
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from post with (success = "+ ObjectUtils.toString(success)+")");
+ }
+ return success;
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java
new file mode 100644
index 000000000..50c18d661
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java
@@ -0,0 +1,341 @@
+/*-
+ * ============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.requesthandler.conv;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Payload;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutputBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ZULU;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeader;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeaderBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.FlagsBuilder;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.Status;
+import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.StatusBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+import org.openecomp.appc.domainmodel.lcm.VNFOperation;
+import org.openecomp.appc.requesthandler.impl.DmaapOutgoingMessage;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+
+public class Converter {
+ public static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
+ public static final String MODE_FLAG = "MODE";
+ public static final String FORCE_FLAG = "FORCE";
+ public static final String TTL_FLAG = "TTL";
+ public final static String DMaaP_ROOT_VALUE = "output";
+ private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT);
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(Converter.class);
+ static {
+ isoFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
+
+ public static Builder<?> convAsyncResponseToBuilder(VNFOperation vnfOperation, String rpcName, ResponseContext response) {
+ Builder<?> outObj = null;
+ if(response == null){
+ throw new IllegalArgumentException("empty asyncResponse");
+ }
+ if(vnfOperation == null){
+ throw new IllegalArgumentException("empty asyncResponse.action");
+ }
+ Action action = Action.valueOf(vnfOperation.name());
+ CommonHeader commonHeader = convAsyncResponseTorev160108CommonHeader(response);
+ Status status = convAsyncResponseTorev160108Status(response);
+// Payload payload = convAsyncResponseTorev160108Payload(inObj);
+ switch (action){
+ case Rollback:
+ outObj = new RollbackOutputBuilder();
+ ((RollbackOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((RollbackOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Snapshot:
+ outObj = new SnapshotOutputBuilder();
+ ((SnapshotOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((SnapshotOutputBuilder)outObj).setStatus(status);
+ try {
+ ((SnapshotOutputBuilder) outObj).setSnapshotId(response.getAdditionalContext().get("output.snapshot-id"));
+ } catch (NullPointerException ignored) {
+ // in case of negative response, snapshotID does not populated, so just ignore NPL
+ }
+ return outObj;
+ case Audit:
+ outObj = new AuditOutputBuilder();
+ ((AuditOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((AuditOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case HealthCheck:
+ outObj = new HealthCheckOutputBuilder();
+ ((HealthCheckOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((HealthCheckOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case LiveUpgrade:
+ outObj = new LiveUpgradeOutputBuilder();
+ ((LiveUpgradeOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((LiveUpgradeOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Lock:
+ outObj = new LockOutputBuilder();
+ ((LockOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((LockOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case ModifyConfig:
+ outObj = new ModifyConfigOutputBuilder();
+ ((ModifyConfigOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((ModifyConfigOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case SoftwareUpload:
+ outObj = new SoftwareUploadOutputBuilder();
+ ((SoftwareUploadOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((SoftwareUploadOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Stop:
+ outObj = new StopOutputBuilder();
+ ((StopOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((StopOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Sync:
+ outObj = new SyncOutputBuilder();
+ ((SyncOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((SyncOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Terminate:
+ outObj = new TerminateOutputBuilder();
+ ((TerminateOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((TerminateOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Test:
+ outObj = new TestOutputBuilder();
+ ((TestOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((TestOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ case Unlock:
+ outObj = new UnlockOutputBuilder();
+ ((UnlockOutputBuilder)outObj).setCommonHeader(commonHeader);
+ ((UnlockOutputBuilder)outObj).setStatus(status);
+ return outObj;
+ default:
+ throw new IllegalArgumentException(action+" action is not supported");
+ }
+ }
+
+ public static Payload convAsyncResponseTorev160108Payload(ResponseContext inObj) throws ParseException {
+ Payload payload = null;
+ if(inObj.getPayload() != null) {
+ payload = new Payload(inObj.getPayload());
+ }
+ return payload;
+ }
+
+ public static String convPayloadObjectToJsonString(Object inObj) throws ParseException {
+ String payloadAsString = null;
+ if(inObj != null) {
+
+ if(inObj instanceof String){
+ payloadAsString = (String)inObj;
+ }else {
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ payloadAsString = objectMapper.writeValueAsString(inObj);
+// payloadAsString = objectMapper.writeValueAsString(payloadAsString);
+ } catch (JsonProcessingException e) {
+ String errMsg = "Error serialize payload json to string";
+ throw new ParseException(errMsg + "-" + e.toString(), 0);
+ }
+ }
+ }
+ return payloadAsString;
+ }
+
+ public static Status convAsyncResponseTorev160108Status(ResponseContext inObj) {
+ StatusBuilder statusBuilder = new StatusBuilder();
+ statusBuilder.setCode(inObj.getStatus().getCode());
+ statusBuilder.setMessage(inObj.getStatus().getMessage());
+ return statusBuilder.build();
+ }
+
+ public static CommonHeader convAsyncResponseTorev160108CommonHeader(ResponseContext inObj) {
+ CommonHeader outObj = null;
+ if(inObj == null){
+ throw new IllegalArgumentException("empty asyncResponse");
+ }
+
+ CommonHeaderBuilder commonHeaderBuilder = new CommonHeaderBuilder();
+ org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags commonHeaderFlags = null;
+ if(inObj.getCommonHeader().getFlags() != null){
+ commonHeaderFlags = Converter.convFlagsMapTorev160108Flags(inObj.getCommonHeader().getFlags());
+ commonHeaderBuilder.setFlags(commonHeaderFlags);
+ }
+
+
+ commonHeaderBuilder.setApiVer(inObj.getCommonHeader().getApiVer());
+ commonHeaderBuilder.setRequestId(inObj.getCommonHeader().getRequestId());
+ if(inObj.getCommonHeader().getSubRequestId() != null){
+ commonHeaderBuilder.setSubRequestId(inObj.getCommonHeader().getSubRequestId());
+ }
+
+ if(inObj.getCommonHeader().getOriginatorId() != null){
+ commonHeaderBuilder.setOriginatorId(inObj.getCommonHeader().getOriginatorId());
+ }
+
+ if(inObj.getCommonHeader().getTimeStamp() != null){
+ String zuluTimestampStr = Converter.convDateToZuluString(inObj.getCommonHeader().getTimeStamp());
+ ZULU zuluTimestamp = new ZULU(zuluTimestampStr);
+ commonHeaderBuilder.setTimestamp(zuluTimestamp);
+ }
+ outObj = commonHeaderBuilder.build();
+ return outObj;
+
+ }
+
+ public static String convDateToZuluString(Date timeStamp) {
+ return isoFormatter.format(timeStamp);
+ }
+
+ public static org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags
+ convFlagsMapTorev160108Flags(org.openecomp.appc.domainmodel.lcm.Flags flags) {
+ Flags rev160108flags = null;
+ boolean anyFlag = false;
+ FlagsBuilder flagsBuilder = new FlagsBuilder();
+ /*
+ * TODO: The below flags are related to APP-C request and should not be sent back - uncomment when response flags are introduced.
+ */
+ /*
+ if(flags.containsKey(FORCE_FLAG)){
+ org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Force force =
+ org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Force.valueOf(flags.get(FORCE_FLAG).toString());
+ flagsBuilder.setForce(force);
+ anyFlag = true;
+ }
+ if(flags.containsKey(MODE_FLAG)){
+ org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Mode mode =
+ org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Mode.valueOf(flags.get(MODE_FLAG).toString());
+ flagsBuilder.setMode(mode);
+ anyFlag = true;
+ }
+ if(flags.containsKey(TTL_FLAG)){
+ flagsBuilder.setTtl(Integer.valueOf(flags.get(TTL_FLAG).toString()));
+ anyFlag = true;
+ }
+ if(anyFlag){
+ rev160108flags = flagsBuilder.build();
+ }
+ */
+
+ rev160108flags = flagsBuilder.build();
+ return rev160108flags;
+ }
+
+ public static String convAsyncResponseToJsonStringBody(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException {
+ Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse);
+ Object message = builder.build();
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.addMixInAnnotations(message.getClass(), MixInFlagsMessage.class);
+ objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class);
+ objectMapper.addMixInAnnotations(Flags.class, MixIn.class);
+ objectMapper.addMixInAnnotations(Status.class, MixIn.class);
+ objectMapper.addMixInAnnotations(Payload.class, MixIn.class);
+ objectMapper.addMixInAnnotations(ZULU.class, MixIn.class);
+
+// .configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY,true)
+ ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true)
+ .writer(SerializationFeature.WRAP_ROOT_VALUE).withRootName(DMaaP_ROOT_VALUE).withoutFeatures(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS);
+ return writer.writeValueAsString(message);
+ }
+
+ public static String convAsyncResponseToDmaapOutgoingMessageJsonString(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException {
+ DmaapOutgoingMessage dmaapOutgoingMessage = convAsyncResponseToDmaapOutgoingMessage(vnfOperation, rpcName, asyncResponse);
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.addMixInAnnotations(dmaapOutgoingMessage.getBody().getOutput().getClass(), MixInFlagsMessage.class);
+ objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class);
+ objectMapper.addMixInAnnotations(Flags.class, MixIn.class);
+ objectMapper.addMixInAnnotations(Status.class, MixIn.class);
+ objectMapper.addMixInAnnotations(Payload.class, MixIn.class);
+ objectMapper.addMixInAnnotations(ZULU.class, MixIn.class);
+
+// .configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY,true)
+ ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true).writer();
+ return writer.writeValueAsString(dmaapOutgoingMessage);
+ }
+
+ public static DmaapOutgoingMessage convAsyncResponseToDmaapOutgoingMessage(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException {
+ DmaapOutgoingMessage outObj = new DmaapOutgoingMessage();
+ outObj.setRpcName(rpcName);
+ Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse);
+ Object messageBody = builder.build();
+ DmaapOutgoingMessage.Body body = new DmaapOutgoingMessage.Body(messageBody);
+ outObj.setBody(body);
+ return outObj;
+ }
+
+ abstract class MixIn {
+ @JsonIgnore
+ abstract Class<? extends DataContainer> getImplementedInterface(); // to be removed during serialization
+
+ @JsonValue
+ abstract java.lang.String getValue();
+ }
+ abstract class MixInCommonHeader extends MixIn {
+ @JsonProperty("api-ver")
+ abstract java.lang.String getApiVer();
+ @JsonProperty("originator-id")
+ abstract java.lang.String getOriginatorId();
+ @JsonProperty("request-id")
+ abstract java.lang.String getRequestId();
+ @JsonProperty("sub-request-id")
+ abstract java.lang.String getSubRequestId();
+
+ }
+ abstract class MixInFlagsMessage extends MixIn {
+ @JsonProperty("common-header")
+ abstract CommonHeader getCommonHeader();
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java
new file mode 100644
index 000000000..c41f42ed6
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.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.requesthandler.exceptions;
+
+
+public class DGWorkflowNotFoundException extends Exception {
+ public final String workflowModule;
+ public final String workflowName;
+ public final String workflowVersion;
+ public DGWorkflowNotFoundException(String message,String workflowModule,String workflowName,String workflowVersion){
+ super(message);
+ this.workflowModule = workflowModule;
+ this.workflowName = workflowName;
+ this.workflowVersion = workflowVersion;
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java
new file mode 100644
index 000000000..a9c1c0000
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.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.requesthandler.exceptions;
+
+
+public class DuplicateRequestException extends Exception {
+ public DuplicateRequestException(String message){
+ super(message);
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java
new file mode 100644
index 000000000..a70b6f14a
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.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.requesthandler.exceptions;
+
+
+public class InvalidInputException extends Exception {
+ public InvalidInputException(String message){
+ super(message);
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java
new file mode 100644
index 000000000..44b0869a9
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.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.requesthandler.exceptions;
+
+
+public class RequestExpiredException extends Exception {
+ public RequestExpiredException(String message){
+ super(message);
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java
new file mode 100644
index 000000000..16a9e5e6e
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.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.requesthandler.exceptions;
+
+
+public class VNFNotFoundException extends Exception {
+ public VNFNotFoundException(String message){
+ super(message);
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java
new file mode 100644
index 000000000..97dabe869
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.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.requesthandler.exceptions;
+
+
+public class WorkflowNotFoundException extends Exception {
+ public final String vnfTypeVersion;
+ public final String command;
+ public WorkflowNotFoundException(String message,String vnfTypeVersion,String command){
+ super(message);
+ this.vnfTypeVersion = vnfTypeVersion;
+ this.command = command;
+ }
+
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java
new file mode 100644
index 000000000..874626c78
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.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.requesthandler.helper;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.openecomp.appc.executor.objects.UniqueRequestIdentifier;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ *
+ * This class serves as Request Registry, which holds the
+ * request unique parameters (originatorId,requestId,subRequestId)
+ * in memory.
+ */
+public class RequestRegistry {
+
+ static Set<UniqueRequestIdentifier> set = Collections.newSetFromMap(new ConcurrentHashMap<UniqueRequestIdentifier, Boolean>());
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestRegistry.class);
+ public RequestRegistry(){
+
+ }
+
+ /**
+ * This method accepts unique request parameters and adds it to Request Registry
+ * if Registry already contains same parameters it returns false,
+ * else returns true.
+ * @param requestIdentifier
+ * @return
+ */
+ public boolean registerRequest(UniqueRequestIdentifier requestIdentifier){
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to registerRequest with UniqueRequestIdentifier = "+ ObjectUtils.toString(requestIdentifier));
+ }
+ boolean output = set.add(requestIdentifier);
+ logger.debug(" Output = " + output);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from registerRequest with (output = "+ ObjectUtils.toString(output)+")");
+ }
+ return output;
+ }
+
+ /**
+ * This method accepts unique request parameters and removes request
+ * from the Request Registry
+ * @param requestIdentifier
+ */
+ public void removeRequest(UniqueRequestIdentifier requestIdentifier){
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to removeRequest with UniqueRequestIdentifier = "+ ObjectUtils.toString(requestIdentifier));
+ }
+ set.remove(requestIdentifier);
+ }
+
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java
new file mode 100644
index 000000000..4f2986d74
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java
@@ -0,0 +1,37 @@
+/*-
+ * ============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.requesthandler.helper;
+
+import org.openecomp.appc.domainmodel.lcm.RuntimeContext;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.requesthandler.exceptions.DGWorkflowNotFoundException;
+import org.openecomp.appc.requesthandler.exceptions.DuplicateRequestException;
+import org.openecomp.appc.requesthandler.exceptions.InvalidInputException;
+import org.openecomp.appc.requesthandler.exceptions.RequestExpiredException;
+import org.openecomp.appc.requesthandler.exceptions.VNFNotFoundException;
+import org.openecomp.appc.requesthandler.exceptions.WorkflowNotFoundException;
+
+public interface RequestValidator {
+ public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException;
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java
new file mode 100644
index 000000000..4546726e9
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java
@@ -0,0 +1,114 @@
+/*-
+ * ============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.requesthandler.impl;
+
+
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+/**
+ * This class represents a message being sent out to DMaaP by APPC as async response.
+ * note the structure of this class must be adapted to the sync message sent to DMaaP represened in org.openecomp.appc.listener.LCM.domainmodel.DmaapOutgoingMessage
+ *
+ */
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DmaapOutgoingMessage {
+
+ private final static String defaultCambriaPartition = "MSO";
+ @JsonProperty("cambria.partition")
+ private String cambriaPartition = defaultCambriaPartition;
+
+ @JsonProperty("rpc-name")
+ private String rpcName;
+
+ @JsonProperty("body")
+ private Body body;
+
+ public DmaapOutgoingMessage() {
+ }
+
+ public String getCambriaPartition() {
+ return cambriaPartition;
+ }
+
+ public void setCambriaPartition(String cambriaPartition) {
+ this.cambriaPartition = cambriaPartition;
+ }
+
+ public String getRpcName() {
+ return rpcName;
+ }
+
+ public void setRpcName(String rpcName) {
+ this.rpcName = rpcName;
+ }
+
+ public Body getBody() {
+ return body;
+ }
+
+ public void setBody(Body body) {
+ this.body = body;
+ }
+
+ @Override
+ public String toString() {
+ return "DmaapOutgoingMessage{" +
+ "cambriaPartition='" + cambriaPartition + '\'' +
+ ", rpcName='" + rpcName + '\'' +
+ ", body=" + body +
+ '}';
+ }
+
+ @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class Body {
+ public Body() {
+ }
+
+ public Body(Object output) {
+ this.output = output;
+ }
+
+ @JsonProperty("output")
+ private Object output;
+
+ public Object getOutput() {
+ return output;
+ }
+
+ public void setOutput(Object body) {
+ this.output = body;
+ }
+
+ @Override
+ public String toString() {
+ return "Body{" +
+ "output=" + output +
+ '}';
+ }
+ }
+}
+
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java
new file mode 100644
index 000000000..d1303605d
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java
@@ -0,0 +1,839 @@
+/*-
+ * ============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.requesthandler.impl;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.openecomp.appc.common.constant.Constants;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.executor.CommandExecutor;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+import org.openecomp.appc.executor.objects.LCMCommandStatus;
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.executor.objects.UniqueRequestIdentifier;
+import org.openecomp.appc.i18n.Msg;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.lockmanager.api.LockException;
+import org.openecomp.appc.lockmanager.api.LockManager;
+import org.openecomp.appc.logging.LoggingConstants;
+import org.openecomp.appc.logging.LoggingUtils;
+import org.openecomp.appc.messageadapter.MessageAdapter;
+import org.openecomp.appc.messageadapter.impl.MessageAdapterDmaapImpl;
+import org.openecomp.appc.metricservice.MetricRegistry;
+import org.openecomp.appc.metricservice.MetricService;
+import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric;
+import org.openecomp.appc.metricservice.metric.Metric;
+import org.openecomp.appc.metricservice.metric.MetricType;
+import org.openecomp.appc.metricservice.policy.PublishingPolicy;
+import org.openecomp.appc.metricservice.publisher.LogPublisher;
+import org.openecomp.appc.requesthandler.RequestHandler;
+import org.openecomp.appc.requesthandler.exceptions.*;
+import org.openecomp.appc.requesthandler.helper.RequestRegistry;
+import org.openecomp.appc.requesthandler.helper.RequestValidator;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerInput;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput;
+import org.openecomp.appc.transactionrecorder.TransactionRecorder;
+import org.openecomp.appc.transactionrecorder.objects.TransactionRecord;
+import org.openecomp.appc.workingstatemanager.WorkingStateManager;
+import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicResource.QueryStatus;
+import org.openecomp.sdnc.sli.aai.AAIService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.MDC;
+
+import static com.att.eelf.configuration.Configuration.*;
+
+import java.net.InetAddress;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This class provides application logic for the Request/Response Handler Component.
+ *
+ */
+public class RequestHandlerImpl implements RequestHandler {
+
+ /**
+ * APP-C VNF lock idle timeout in milliseconds. Applied only when locking VNF using northbound API "lock"
+ */
+ private static final String PROP_IDLE_TIMEOUT = "org.openecomp.appc.lock.idleTimeout";
+
+ private CommandExecutor commandExecutor;
+
+ private TransactionRecorder transactionRecorder;
+ private MessageAdapter messageAdapter;
+ private RequestValidator requestValidator;
+ private static MetricRegistry metricRegistry;
+ private boolean isMetricEnabled = false;
+ private RequestRegistry requestRegistry;
+ private LockManager lockManager;
+ private WorkingStateManager workingStateManager;
+ private AAIService aaiService;
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestHandlerImpl.class);
+
+ public void setAaiService(AAIService aaiService) {
+ this.aaiService = aaiService;
+ }
+
+ public void setTransactionRecorder(TransactionRecorder transactionRecorder) {
+ this.transactionRecorder = transactionRecorder;
+ }
+
+ public void setLockManager(LockManager lockManager) {
+ this.lockManager = lockManager;
+ }
+
+ public void setRequestValidator(RequestValidator requestValidator) {
+ this.requestValidator = requestValidator;
+ }
+
+ public void setMessageAdapter(MessageAdapter messageAdapter) {
+ this.messageAdapter = messageAdapter;
+ }
+
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ public void setWorkingStateManager(WorkingStateManager workingStateManager) {
+ this.workingStateManager = workingStateManager;
+ }
+
+ public RequestHandlerImpl() {
+ requestRegistry = new RequestRegistry();
+ messageAdapter = new MessageAdapterDmaapImpl();
+ messageAdapter.init();
+ Properties properties = configuration.getProperties();
+ if (properties != null && properties.getProperty("metric.enabled") != null) {
+ isMetricEnabled = Boolean.valueOf(properties.getProperty("metric.enabled"));
+ }
+ if (isMetricEnabled) {
+ initMetric();
+ }
+ }
+
+ public void setCommandExecutor(CommandExecutor commandExecutor) {
+ this.commandExecutor = commandExecutor;
+ }
+
+
+ /**
+ * It receives requests from the north-bound REST API (Communication) Layer and
+ * performs following validations.
+ * 1. VNF exists in A&AI for the given targetID (VnfID)
+ * 2. For the current VNF Orchestration Status, the command can be executed
+ * 3. For the given VNF type and Operation, there exists work-flow definition in the APPC database
+ * If any of the validation fails, it returns appropriate response
+ *
+ * @param input RequestHandlerInput object which contains request header and other request parameters like command , target Id , payload etc.
+ * @return response for request as enum with Return code and message.
+ */
+ @Override
+ public RequestHandlerOutput handleRequest(RequestHandlerInput input) {
+ if (logger.isTraceEnabled())
+ logger.trace("Entering to handleRequest with RequestHandlerInput = " + ObjectUtils.toString(input) + ")");
+ Params params = null;
+ String vnfId = null, vnfType = null, errorMessage = null;
+ Date startTime = new Date(System.currentTimeMillis());
+ RequestHandlerOutput output = null;
+ setInitialLogProperties(input.getRequestContext());
+
+ RuntimeContext runtimeContext = new RuntimeContext();
+ runtimeContext.setRequestContext(input.getRequestContext());
+ runtimeContext.setTimeStart(startTime);
+ runtimeContext.setRpcName(input.getRpcName());
+
+ final ResponseContext responseContext = new ResponseContext();
+ responseContext.setStatus(new Status());
+ responseContext.setAdditionalContext(new HashMap<String, String>(4));
+ responseContext.setCommonHeader(input.getRequestContext().getCommonHeader());
+ runtimeContext.setResponseContext(responseContext);
+ runtimeContext.getResponseContext().setStatus(new Status());
+
+ vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId();
+
+ try {
+
+ requestValidator.validateRequest(runtimeContext);
+
+ handleRequest(runtimeContext);
+
+ final int statusCode = runtimeContext.getResponseContext().getStatus().getCode();
+ if (statusCode % 100 == 2 || statusCode % 100 == 3) {
+ createTransactionRecord(runtimeContext);
+ }
+ output = new RequestHandlerOutput();
+ output.setResponseContext(runtimeContext.getResponseContext());
+
+ } catch (VNFNotFoundException e) {
+ errorMessage = e.getMessage();
+ String logMessage = EELFResourceManager.format(Msg.APPC_NO_RESOURCE_FOUND, vnfId);
+ storeErrorMessageToLog(runtimeContext, LoggingConstants.TargetNames.AAI, "", logMessage);
+ params = new Params().addParam("vnfId", vnfId);
+ output = buildRequestHandlerOutput(LCMCommandStatus.VNF_NOT_FOUND, params);
+ } catch (NoTransitionDefinedException e) {
+ errorMessage = e.getMessage();
+ String logMessage = EELFResourceManager.format(Msg.VF_UNDEFINED_STATE, input.getRequestContext().getCommonHeader().getOriginatorId(), input.getRequestContext().getAction().name());
+ params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("currentState", e.currentState);
+ output = buildRequestHandlerOutput(LCMCommandStatus.NO_TRANSITION_DEFINE, params);
+ storeErrorMessageToLog(runtimeContext,
+ LoggingConstants.TargetNames.APPC,
+ LoggingConstants.TargetNames.STATE_MACHINE,
+ logMessage);
+ } catch (LifecycleException e) {
+ errorMessage = e.getMessage();
+ params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("currentState", e.currentState);
+ output = buildRequestHandlerOutput(LCMCommandStatus.ACTION_NOT_SUPPORTED, params);
+ } catch (UnstableVNFException e) {
+ errorMessage = e.getMessage();
+ params = new Params().addParam("vnfId", vnfId);
+ output = buildRequestHandlerOutput(LCMCommandStatus.UNSTABLE_VNF, params);
+ } catch (WorkflowNotFoundException e) {
+ errorMessage = e.getMessage();
+ String vnfTypeVersion = e.vnfTypeVersion;
+ params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("vnfTypeVersion", vnfTypeVersion);
+ output = buildRequestHandlerOutput(LCMCommandStatus.WORKFLOW_NOT_FOUND, params);
+ } catch (DGWorkflowNotFoundException e) {
+ errorMessage = e.getMessage();
+ String logMessage = EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfType, input.getRequestContext().getAction().name());
+ storeErrorMessageToLog(runtimeContext,
+ LoggingConstants.TargetNames.APPC,
+ LoggingConstants.TargetNames.WORKFLOW_MANAGER,
+ logMessage);
+ params = new Params().addParam("actionName", input.getRequestContext().getAction().name())
+ .addParam("dgModule", e.workflowModule).addParam("dgName", e.workflowName).addParam("dgVersion", e.workflowVersion);
+ output = buildRequestHandlerOutput(LCMCommandStatus.DG_WORKFLOW_NOT_FOUND, params);
+ } catch (RequestExpiredException e) {
+ errorMessage = e.getMessage();
+ params = new Params().addParam("actionName", input.getRequestContext().getAction().name());
+ output = buildRequestHandlerOutput(LCMCommandStatus.EXPIRED_REQUEST, params);
+ } catch (InvalidInputException e) {
+ errorMessage = e.getMessage() != null ? e.getMessage() : e.toString();
+ params = new Params().addParam("errorMsg", errorMessage);
+ output = buildRequestHandlerOutput(LCMCommandStatus.INVALID_INPUT_PARAMETER, params);
+ } catch (DuplicateRequestException e) {
+ errorMessage = e.getMessage();
+ output = buildRequestHandlerOutput(LCMCommandStatus.DUPLICATE_REQUEST, null);
+ } catch (Exception e) {
+ storeErrorMessageToLog(runtimeContext, "", "", "Exception = " + e.getMessage());
+ errorMessage = e.getMessage() != null ? e.getMessage() : e.toString();
+ params = new Params().addParam("errorMsg", errorMessage);
+ output = buildRequestHandlerOutput(LCMCommandStatus.UNEXPECTED_ERROR, params);
+ } finally {
+ try {
+ if (logger.isDebugEnabled() && errorMessage != null)
+ logger.debug("error occurred in handleRequest " + errorMessage);
+ logger.debug("output.getResponse().getResponseCode().equals(LCMCommandStatus.ACCEPTED.getResponseCode(): " + (output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode()));
+ logger.debug("output.getResponse().getResponseCode().equals(LCMCommandStatus.SUCCESS.getResponseCode(): " + (output.getResponseContext().getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode()));
+
+ runtimeContext.setResponseContext(output.getResponseContext());
+ if ((null == output) || !(output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode())) {
+ if (isMetricEnabled) {
+ ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementRejectedRequest();
+ }
+ removeRequestFromRegistry(input.getRequestContext().getCommonHeader());
+ }
+ } finally {
+ storeAuditLogRecord(runtimeContext);
+ storeMetricLogRecord(runtimeContext);
+ clearRequestLogProperties();
+ }
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from handleRequest with (RequestHandlerOutput = " + ObjectUtils.toString(output.getResponseContext()) + ")");
+ }
+ return output;
+ }
+
+ private void storeErrorMessageToLog(RuntimeContext runtimeContext, String targetEntity, String targetServiceName, String additionalMessage) {
+ LoggingUtils.logErrorMessage(runtimeContext.getResponseContext().getStatus() != null ?
+ String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()) : "",
+ runtimeContext.getResponseContext().getStatus() != null ?
+ String.valueOf(runtimeContext.getResponseContext().getStatus().getMessage()) : "",
+ targetEntity,
+ targetServiceName,
+ additionalMessage,
+ this.getClass().getCanonicalName());
+ }
+
+ private void createTransactionRecord(RuntimeContext runtimeContext) {
+ TransactionRecord transactionRecord = new TransactionRecord();
+ transactionRecord.setTimeStamp(runtimeContext.getResponseContext().getCommonHeader().getTimeStamp());
+ transactionRecord.setRequestID(runtimeContext.getResponseContext().getCommonHeader().getRequestId());
+ transactionRecord.setStartTime(runtimeContext.getTimeStart());
+ transactionRecord.setEndTime(new Date(System.currentTimeMillis()));
+ transactionRecord.setTargetID(runtimeContext.getVnfContext().getId());
+ transactionRecord.setTargetType(runtimeContext.getVnfContext().getType());
+ transactionRecord.setOperation(runtimeContext.getRequestContext().getAction().name());
+ transactionRecord.setResultCode(String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()));
+ transactionRecord.setDescription(runtimeContext.getResponseContext().getStatus().getMessage());
+ transactionRecorder.store(transactionRecord);
+ }
+
+ private void handleRequest(RuntimeContext runtimeContext) {
+
+ switch (runtimeContext.getRequestContext().getAction()) {
+ case Lock:
+ try {
+ lockWithTimeout(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId());
+ fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null);
+ } catch (LockException e) {
+ Params params = new Params().addParam("errorMsg", e.getMessage());
+ fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params);
+ storeErrorMessageToLog(runtimeContext,
+ LoggingConstants.TargetNames.APPC,
+ LoggingConstants.TargetNames.LOCK_MANAGER,
+ EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId()));
+ }
+
+ break;
+
+ case Unlock:
+ try {
+ releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId());
+ fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null);
+ } catch (LockException e) {
+ //TODO add proper error code and message
+ // logger.error(EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId()));
+ Params params = new Params().addParam("errorMsg", e.getMessage());
+ fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params);
+ }
+ break;
+
+ case CheckLock:
+ boolean isLocked = lockManager.isLocked(runtimeContext.getVnfContext().getId());
+ fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null);
+ runtimeContext.getResponseContext().addKeyValueToAdditionalContext("locked", String.valueOf(isLocked).toUpperCase());
+ break;
+ default:
+ try {
+ boolean lockAcquired = acquireVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId(), 0);
+ runtimeContext.setIsLockAcquired(lockAcquired);
+ callWfOperation(runtimeContext);
+ } catch (LockException e) {
+ Params params = new Params().addParam("errorMsg", e.getMessage());
+ fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params);
+ } finally {
+ if (runtimeContext.isLockAcquired()) {
+ final int statusCode = runtimeContext.getResponseContext().getStatus().getCode();
+ if (statusCode % 100 == 2 || statusCode % 100 == 3) {
+ try {
+ releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId());
+ //TODO add logger call
+ } catch (LockException e) {
+ //ignore
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ private void callWfOperation(RuntimeContext runtimeContext) {
+ int remainingTTL = calculateRemainingTTL(runtimeContext.getRequestContext().getCommonHeader());
+ if (remainingTTL > 0) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Calling command Executor with remaining TTL value: " + remainingTTL);
+ }
+
+ RuntimeContext clonedContext = cloneContext(runtimeContext);
+
+ CommandExecutorInput commandExecutorInput = new CommandExecutorInput();
+ commandExecutorInput.setRuntimeContext(clonedContext);
+ commandExecutorInput.setTtl(remainingTTL);
+
+ try {
+ commandExecutor.executeCommand(commandExecutorInput);
+ if(logger.isTraceEnabled()) {
+ logger.trace("Command was added to queue successfully for vnfID = " + ObjectUtils.toString(runtimeContext.getRequestContext().getActionIdentifiers().getVnfId()));
+ }
+ fillStatus(runtimeContext, LCMCommandStatus.ACCEPTED, null);
+ if (isMetricEnabled) {
+ ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementAcceptedRequest();
+ }
+ } catch (APPCException e) {
+ String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString();
+ Params params = new Params().addParam("errorMsg", errorMessage);
+ fillStatus(runtimeContext, LCMCommandStatus.UNEXPECTED_ERROR, params);
+ }
+
+ } else {
+ fillStatus(runtimeContext, LCMCommandStatus.EXPIRED_REQUEST, null);
+ storeErrorMessageToLog(runtimeContext,
+ LoggingConstants.TargetNames.APPC,
+ LoggingConstants.TargetNames.REQUEST_HANDLER,
+ EELFResourceManager.format(Msg.APPC_EXPIRED_REQUEST,
+ runtimeContext.getRequestContext().getCommonHeader().getOriginatorId(),
+ runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(),
+ String.valueOf(runtimeContext.getRequestContext().getCommonHeader().getFlags().getTtl())));
+ }
+ }
+
+ private void fillStatus(RuntimeContext runtimeContext, LCMCommandStatus lcmCommandStatus, Params params) {
+ runtimeContext.getResponseContext().getStatus().setCode(lcmCommandStatus.getResponseCode());
+ runtimeContext.getResponseContext().getStatus().setMessage(lcmCommandStatus.getFormattedMessage(params));
+ }
+
+ /*
+ * Workaround to clone context in order to prevent sharing of ResponseContext by two threads (one to set Accepted
+ * status code and other - depending on DG status). Other properties should not be a problem
+ */
+ private RuntimeContext cloneContext(RuntimeContext runtimeContext) {
+ RuntimeContext other = new RuntimeContext();
+ other.setRequestContext(runtimeContext.getRequestContext());
+ other.setResponseContext(new ResponseContext());
+ other.getResponseContext().setStatus(new Status());
+ other.getResponseContext().setCommonHeader(runtimeContext.getRequestContext().getCommonHeader());
+ other.setVnfContext(runtimeContext.getVnfContext());
+ other.setRpcName(runtimeContext.getRpcName());
+ other.setTimeStart(runtimeContext.getTimeStart());
+ other.setIsLockAcquired(runtimeContext.isLockAcquired());
+ return other;
+ }
+
+
+ private void clearRequestLogProperties() {
+ try {
+ MDC.remove(MDC_KEY_REQUEST_ID);
+ MDC.remove(MDC_SERVICE_INSTANCE_ID);
+ MDC.remove(MDC_SERVICE_NAME);
+ MDC.remove(LoggingConstants.MDCKeys.PARTNER_NAME);
+ MDC.remove(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY);
+ } catch (Exception e) {
+
+ }
+ }
+
+ private void removeRequestFromRegistry(CommonHeader commonHeader) {
+ if (logger.isTraceEnabled())
+ logger.trace("Entering to removeRequestFromRegistry with RequestHeader = " + ObjectUtils.toString(commonHeader));
+ requestRegistry.removeRequest(
+ new UniqueRequestIdentifier(commonHeader.getOriginatorId(),
+ commonHeader.getRequestId(),
+ commonHeader.getSubRequestId()));
+ }
+
+ private boolean acquireVNFLock(String vnfID, String requestId, long timeout) throws LockException {
+ if (logger.isTraceEnabled())
+ logger.trace("Entering to acquireVNFLock with vnfID = " + vnfID);
+ boolean lockAcquired = lockManager.acquireLock(vnfID, requestId, timeout);
+ if (lockAcquired) {
+ logger.info("Lock acquired for vnfID = " + vnfID);
+ } else {
+ logger.info("vnfID = " + vnfID + " was already locked");
+ }
+ return lockAcquired;
+ }
+
+ private void lockWithTimeout(String vnfId, String requestId) throws LockException {
+ long timeout = configuration.getLongProperty(PROP_IDLE_TIMEOUT, Constants.DEFAULT_IDLE_TIMEOUT);
+ acquireVNFLock(vnfId, requestId, timeout);
+ }
+
+ private void resetLock(String vnfId, String requestId, boolean lockAcquired, boolean resetLockTimeout) {
+ if (lockAcquired) {
+ try {
+ releaseVNFLock(vnfId, requestId);
+ } catch (LockException e) {
+ logger.error("Unlock VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e);
+
+
+ }
+ } else if (resetLockTimeout) {
+ try {
+ // reset timeout to previous value
+ lockWithTimeout(vnfId, requestId);
+ } catch (LockException e) {
+ logger.error("Reset lock idle timeout for VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e);
+ }
+ }
+ }
+
+ private void releaseVNFLock(String vnfId, String transactionId) throws LockException {
+ lockManager.releaseLock(vnfId, transactionId);
+ logger.info("Lock released for vnfID = " + vnfId);
+ }
+
+ private void setInitialLogProperties(RequestContext requestContext) {
+
+ try {
+ MDC.put(MDC_KEY_REQUEST_ID, requestContext.getCommonHeader().getRequestId());
+ if (requestContext.getActionIdentifiers().getServiceInstanceId() != null) {
+ MDC.put(MDC_SERVICE_INSTANCE_ID, requestContext.getActionIdentifiers().getServiceInstanceId());
+ }
+ MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, requestContext.getCommonHeader().getOriginatorId());
+ MDC.put(MDC_INSTANCE_UUID, ""); // value should be created in the future
+ try {
+ MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getHostName() again please. It's wrong!
+ MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress());
+ MDC.put(LoggingConstants.MDCKeys.SERVER_NAME, InetAddress.getLocalHost().getHostName());
+ MDC.put(MDC_SERVICE_NAME, requestContext.getAction().name());
+ MDC.put(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY, requestContext.getActionIdentifiers().getVnfId());
+
+ } catch (Exception e) {
+ logger.debug(e.getMessage());
+ }
+ } catch (RuntimeException e) {
+ //ignore
+ }
+ }
+
+
+ private int calculateRemainingTTL(CommonHeader commonHeader) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to calculateRemainingTTL with RequestHeader = " + ObjectUtils.toString(commonHeader));
+ }
+ long usedTimeInMillis = (System.currentTimeMillis() - commonHeader.getTimeStamp().getTime());
+ logger.debug("usedTimeInMillis = " + usedTimeInMillis);
+ int usedTimeInSeconds = Math.round(usedTimeInMillis / 1000);
+ logger.debug("usedTimeInSeconds = " + usedTimeInSeconds);
+ Integer inputTTL = this.getInputTTL(commonHeader);
+ logger.debug("inputTTL = " + inputTTL);
+ Integer remainingTTL = inputTTL - usedTimeInSeconds;
+ logger.debug("Remaining TTL = " + remainingTTL);
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from calculateRemainingTTL with (remainingTTL = " + ObjectUtils.toString(remainingTTL) + ")");
+ return remainingTTL;
+ }
+
+ private Integer getInputTTL(CommonHeader header) {
+ if (logger.isTraceEnabled())
+ logger.trace("Entering in getInputTTL with RequestHeader = " + ObjectUtils.toString(header));
+ if (!isValidTTL(String.valueOf(header.getFlags().getTtl()))) {
+ String defaultTTLStr = configuration.getProperty("org.openecomp.appc.workflow.default.ttl", String.valueOf(Constants.DEFAULT_TTL));
+ Integer defaultTTL = Integer.parseInt(defaultTTLStr);
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from getInputTTL with (defaultTTL = " + ObjectUtils.toString(defaultTTL) + ")");
+ return defaultTTL;
+ }
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from getInputTTL with (inputTTL = " + ObjectUtils.toString(header.getFlags().getTtl()) + ")");
+
+ return header.getFlags().getTtl();
+ }
+
+ private boolean isValidTTL(String ttl) {
+ if (ttl == null || ttl.length() == 0) {
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from getInputTTL with (result = false)");
+ return false;
+ }
+ try {
+ Integer i = Integer.parseInt(ttl);
+ return (i > 0);
+ } catch (NumberFormatException e) {
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from getInputTTL with (result = false)");
+ return false;
+ }
+ }
+
+ private Boolean isLoggingEnabled() {
+ String defaultFlagStr = configuration.getProperty("org.openecomp.appc.localTransactionRecorder.enable", String.valueOf(Constants.DEFAULT_LOGGING_FLAG));
+ Boolean defaultFlag = Boolean.parseBoolean(defaultFlagStr);
+ return defaultFlag;
+ }
+
+ private static RequestHandlerOutput buildRequestHandlerOutput(LCMCommandStatus response, Params params) {
+ RequestHandlerOutput output = new RequestHandlerOutput();
+ ResponseContext responseContext = new ResponseContext();
+ org.openecomp.appc.domainmodel.lcm.Status status = new org.openecomp.appc.domainmodel.lcm.Status();
+ status.setCode(response.getResponseCode());
+ status.setMessage(response.getFormattedMessage(params));
+ responseContext.setStatus(status);
+ output.setResponseContext(responseContext);
+ return output;
+ }
+
+ /**
+ * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI.
+ *
+ * @return true in case AAI updates are successful. false for any error or exception.
+ */
+ @Override
+ public void onRequestExecutionStart(String vnfId, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to onRequestExecutionStart with vnfId = " + vnfId + "and requestIdentifierString = " + requestIdentifierString);
+ }
+ try {
+ boolean updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, requestIdentifierString, forceFlag);
+ if (!updated) {
+ throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId);
+ }
+ } catch (Exception e) {
+ logger.error("Error updating working state for vnf " + vnfId + e);
+ throw new RuntimeException(e);
+ }
+
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from onRequestExecutionStart ");
+ }
+
+ /**
+ * This method perform following operations required after execution of workflow.
+ * It posts asynchronous response to message bus (DMaaP).
+ * Unlock VNF Id
+ * Removes request from request registry.
+ * Generate audit logs.
+ * Adds transaction record to database id if transaction logging is enabled.
+ *
+ * @param isAAIUpdated boolean flag which indicate AAI upodate status after request completion.
+ */
+ @Override
+ public void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to onRequestExecutionEnd with runtimeContext = " + ObjectUtils.toString(runtimeContext));
+ }
+
+ postMessageToDMaaP(runtimeContext.getRequestContext().getAction(), runtimeContext.getRpcName(), runtimeContext.getResponseContext());
+ requestRegistry.removeRequest(
+ new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(),
+ runtimeContext.getResponseContext().getCommonHeader().getRequestId(),
+ runtimeContext.getResponseContext().getCommonHeader().getSubRequestId()));
+ resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true);
+ Status status = runtimeContext.getResponseContext().getStatus();
+
+ VNFWorkingState workingState;
+ if (status.getCode() == LCMCommandStatus.SUCCESS.getResponseCode() || isReadOnlyAction(runtimeContext.getRequestContext().getAction())) {
+ workingState = VNFWorkingState.STABLE;
+ } else {
+ workingState = VNFWorkingState.UNKNOWN;
+ }
+
+ UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(),
+ runtimeContext.getResponseContext().getCommonHeader().getRequestId(),
+ runtimeContext.getResponseContext().getCommonHeader().getSubRequestId());
+
+ String requestIdentifierString = requestIdentifier.toIdentifierString();
+ workingStateManager.setWorkingState(runtimeContext.getVnfContext().getId(), workingState, requestIdentifierString, false);
+
+
+ storeAuditLogRecord(runtimeContext);
+
+ if (isLoggingEnabled()) {
+ createTransactionRecord(runtimeContext);
+ }
+ }
+
+ private void storeAuditLogRecord(RuntimeContext runtimeContext) {
+ LoggingUtils.logAuditMessage(runtimeContext.getTimeStart(),
+ new Date(System.currentTimeMillis()),
+ String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()),
+ runtimeContext.getResponseContext().getStatus().getMessage(),
+ this.getClass().getCanonicalName());
+ }
+
+ private void storeMetricLogRecord(RuntimeContext runtimeContext) {
+ LoggingUtils.logMetricsMessage(runtimeContext.getTimeStart(),
+ new Date(System.currentTimeMillis()),
+ LoggingConstants.TargetNames.APPC,
+ runtimeContext.getRequestContext().getAction().name(),
+ runtimeContext.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode() ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR,
+ String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()),
+ runtimeContext.getResponseContext().getStatus().getMessage(),
+ this.getClass().getCanonicalName());
+ }
+
+ private boolean isReadOnlyAction(VNFOperation action) {
+ return VNFOperation.Sync == action
+ || VNFOperation.Audit == action;
+ }
+
+
+ //returns null if asyncResponse was not modified otherwise reutrns the updated asyncResponse
+ private void postMessageToDMaaP(VNFOperation operation, String rpcName, ResponseContext responseContext/*, boolean isTTLEnd, boolean aaiUpdateSuccess*/) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to postMessageToDMaaP with AsyncResponse = " + ObjectUtils.toString(responseContext));
+ }
+ /*boolean updated = updateAsyncResponseStatus(responseContext, isTTLEnd, aaiUpdateSuccess);
+ */
+ boolean callbackResponse = messageAdapter.post(operation, rpcName, responseContext);
+ if (!callbackResponse) {
+ logger.error("DMaaP posting status: " + callbackResponse, "dmaapMessage: " + responseContext);
+ }
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from postMessageToDMaaP with (callbackResponse = " + ObjectUtils.toString(callbackResponse) + ")");
+ }
+
+ //returns true if asyncResponse was modified
+ /* private boolean updateAsyncResponseStatus(ResponseContext asyncResponse, boolean isTTLEnd, boolean aaiUpdateSuccess) {
+ boolean updated = false;
+ if (logger.isTraceEnabled())
+ logger.trace("Entering to updateAsyncResponseStatus with AsyncResponse = "+ObjectUtils.toString(asyncResponse)+ ", isTTLEnd = "+ ObjectUtils.toString(isTTLEnd)+ ", aaiUpdateSuccess = "+ ObjectUtils.toString(aaiUpdateSuccess));
+ if(!aaiUpdateSuccess){
+ if (asyncResponse.getStatus().getCode() == 0 || asyncResponse.getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode()) {
+ asyncResponse.getStatus().setCode(LCMCommandStatus.UPDATE_AAI_FAILURE.getResponseCode());
+ asyncResponse.getStatus().setMessage(LCMCommandStatus.UPDATE_AAI_FAILURE.getResponseMessage());
+ updated = true;
+ }
+ }else if(isTTLEnd){
+ asyncResponse.getStatus().setCode(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseCode());
+ asyncResponse.getStatus().setMessage(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseMessage());
+ updated = true;
+ }
+ if (logger.isTraceEnabled())
+ logger.trace("Exiting from updateAsyncResponseStatus with (asyncResponse = "+ ObjectUtils.toString(asyncResponse)+")");
+ return updated;
+ }*/
+
+
+ /**
+ * This method perform following operations required if TTL ends when request still waiting in execution queue .
+ * It posts asynchronous response to message bus (DMaaP).
+ * Unlock VNF Id
+ * Removes request from request registry.
+ *
+ * @param runtimeContext AsyncResponse object which contains VNF Id , timestamp , apiVersion, responseId, executionSuccess, payload, isExpired, action, startTime, vnfType, originatorId, subResponseId;
+ * @param updateAAI boolean flag which indicate AAI upodate status after request completion.
+ */
+ @Override
+ public void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to onRequestTTLEnd with " +
+ "AsyncResponse = " + ObjectUtils.toString(runtimeContext) +
+ ", updateAAI = " + ObjectUtils.toString(updateAAI));
+ }
+ logger.error(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseMessage());
+ fillStatus(runtimeContext, LCMCommandStatus.EXPIRED_REQUEST_FAILURE, null);
+ postMessageToDMaaP(runtimeContext.getRequestContext().getAction(), runtimeContext.getRpcName(), runtimeContext.getResponseContext());
+ resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true);
+ requestRegistry.removeRequest(
+ new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(),
+ runtimeContext.getResponseContext().getCommonHeader().getRequestId(),
+ runtimeContext.getResponseContext().getCommonHeader().getSubRequestId()));
+ }
+
+ private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException {
+ String key = "vnf-id = '" + vnf_id + "'";
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to getVnfdata with " +
+ "vnfId = " + vnf_id +
+ ", prefix = " + prefix +
+ ", SvcLogicContex = " + ObjectUtils.toString(ctx));
+ }
+ try {
+ QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null, ctx);
+ if (QueryStatus.NOT_FOUND.equals(response)) {
+ throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id);
+ } else if (QueryStatus.FAILURE.equals(response)) {
+ throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id);
+ }
+ logger.info("AAIResponse: " + response.toString());
+ } catch (SvcLogicException e) {
+ logger.error("Error in getVnfdata " + e);
+ throw new RuntimeException(e);
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from getVnfdata with (SvcLogicContext = " + ObjectUtils.toString(ctx) + ")");
+ }
+ return ctx;
+ }
+
+ private boolean postVnfdata(String vnf_id, String status, String prefix, SvcLogicContext ctx) throws VNFNotFoundException {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to postVnfdata with " +
+ "vnfId = " + vnf_id +
+ ", status = " + status +
+ ", prefix = " + prefix +
+ ", SvcLogicContext = " + ObjectUtils.toString(ctx));
+ }
+ String key = "vnf-id = '" + vnf_id + "'";
+ Map<String, String> data = new HashMap<>();
+ data.put("orchestration-status", status);
+ try {
+ QueryStatus response = aaiService.update("generic-vnf", key, data, prefix, ctx);
+ if (QueryStatus.NOT_FOUND.equals(response)) {
+ throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id);
+ }
+ logger.info("AAIResponse: " + response.toString());
+ if (response.toString().equals("SUCCESS")) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from postVnfdata with (Result = " + ObjectUtils.toString(true) + ")");
+ }
+ return true;
+ }
+
+ } catch (SvcLogicException e) {
+ logger.error("Error in postVnfdata " + e);
+ throw new RuntimeException(e);
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from postVnfdata with (Result = " + ObjectUtils.toString(false) + ")");
+ }
+ return false;
+ }
+
+ private void initMetric() {
+ if (logger.isDebugEnabled())
+ logger.debug("Metric getting initialized");
+ MetricService metricService = getMetricservice();
+ metricRegistry = metricService.createRegistry("APPC");
+ DispatchingFuntionMetric dispatchingFuntionMetric = metricRegistry.metricBuilderFactory().
+ dispatchingFunctionCounterBuilder().
+ withName("DISPATCH_FUNCTION").withType(MetricType.COUNTER).
+ withAcceptRequestValue(0)
+ .withRejectRequestValue(0)
+ .build();
+ if (metricRegistry.register(dispatchingFuntionMetric)) {
+ Metric[] metrics = new Metric[]{dispatchingFuntionMetric};
+ LogPublisher logPublisher = new LogPublisher(metricRegistry, metrics);
+ LogPublisher[] logPublishers = new LogPublisher[1];
+ logPublishers[0] = logPublisher;
+ PublishingPolicy manuallyScheduledPublishingPolicy = metricRegistry.policyBuilderFactory().
+ scheduledPolicyBuilder().withPublishers(logPublishers).
+ withMetrics(metrics).
+ build();
+ if (logger.isDebugEnabled())
+ logger.debug("Policy getting initialized");
+ manuallyScheduledPublishingPolicy.init();
+ if (logger.isDebugEnabled())
+ logger.debug("Metric initialized");
+ }
+ }
+
+
+ private MetricService getMetricservice() {
+ BundleContext bctx = FrameworkUtil.getBundle(MetricService.class).getBundleContext();
+ ServiceReference sref = bctx.getServiceReference(MetricService.class.getName());
+ if (sref != null) {
+ logger.info("Metric Service from bundlecontext");
+ return (MetricService) bctx.getService(sref);
+ } else {
+ logger.info("Metric Service error from bundlecontext");
+ logger.warn("Cannot find service reference for org.openecomp.appc.metricservice.MetricService");
+ return null;
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java
new file mode 100644
index 000000000..0871a8f97
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java
@@ -0,0 +1,382 @@
+/*-
+ * ============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.requesthandler.impl;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.openecomp.appc.common.constant.Constants;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.executor.objects.UniqueRequestIdentifier;
+import org.openecomp.appc.i18n.Msg;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.logging.LoggingConstants;
+import org.openecomp.appc.logging.LoggingUtils;
+import org.openecomp.appc.requesthandler.exceptions.*;
+import org.openecomp.appc.requesthandler.helper.RequestRegistry;
+import org.openecomp.appc.requesthandler.helper.RequestValidator;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowExistsOutput;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workingstatemanager.WorkingStateManager;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.openecomp.sdnc.sli.aai.AAIService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+
+import java.util.Calendar;
+import java.util.Date;
+
+
+public class RequestValidatorImpl implements RequestValidator {
+
+ private AAIService aaiService;
+
+ private LifecycleManager lifecyclemanager;
+
+ private WorkFlowManager workflowManager;
+
+ private WorkingStateManager workingStateManager;
+
+ private final RequestRegistry requestRegistry = new RequestRegistry();
+
+ private final Configuration configuration = ConfigurationFactory.getConfiguration();
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(RequestValidatorImpl.class);
+ private final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+ public void setLifecyclemanager(LifecycleManager lifecyclemanager) {
+ this.lifecyclemanager = lifecyclemanager;
+ }
+
+ public void setWorkflowManager(WorkFlowManager workflowManager) {
+ this.workflowManager = workflowManager;
+ }
+
+ public void setWorkingStateManager(WorkingStateManager workingStateManager) {
+ this.workingStateManager = workingStateManager;
+ }
+
+ public RequestValidatorImpl() {
+ }
+
+ @Override
+ public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ if (logger.isTraceEnabled()){
+ logger.trace("Entering to validateRequest with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext));
+ }
+ getAAIservice();
+ validateInput(runtimeContext.getRequestContext());
+ checkVNFWorkingState(runtimeContext);
+ String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId();
+ VNFContext vnfContext = queryAAI(vnfId);
+ runtimeContext.setVnfContext(vnfContext);
+
+ queryLCM(runtimeContext.getVnfContext().getStatus(), runtimeContext.getRequestContext().getAction());
+ VNFOperation operation = runtimeContext.getRequestContext().getAction();
+ if(!operation.isBuiltIn()) {
+ // for built-in operations skip WF presence check
+ queryWFM(vnfContext, runtimeContext.getRequestContext());
+ }
+ }
+
+ private boolean isValidTTL(String ttl) {
+ if (logger.isTraceEnabled()){
+ logger.trace("Entering to isValidTTL where ttl = "+ ObjectUtils.toString(ttl));
+ }
+ if (ttl == null || ttl.length() == 0) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from isValidTT with (result = "+ ObjectUtils.toString(false)+")");
+ }
+ return false;
+ }
+ try {
+ Integer i = Integer.parseInt(ttl);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from isValidTTL with (result = "+ ObjectUtils.toString(i > 0)+")");
+ }
+ return (i > 0);
+ } catch (NumberFormatException e) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from isValidTTL with (result = "+ ObjectUtils.toString(false)+")");
+ }
+ return false;
+ }
+ }
+
+ private void validateInput(RequestContext requestContext) throws RequestExpiredException, InvalidInputException, DuplicateRequestException {
+ if (logger.isTraceEnabled()){
+ logger.trace("Entering to validateInput with RequestHandlerInput = "+ ObjectUtils.toString(requestContext));
+ }
+ if (requestContext.getActionIdentifiers().getVnfId() == null || requestContext.getAction() == null
+ || requestContext.getActionIdentifiers().getVnfId().length() == 0 || requestContext.getAction().name().length() == 0 ||
+ null == requestContext.getCommonHeader().getApiVer()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("vnfID = " + requestContext.getActionIdentifiers().getVnfId() + ", action = " + requestContext.getAction().name());
+ }
+
+ LoggingUtils.logErrorMessage(
+ LoggingConstants.TargetNames.REQUEST_VALIDATOR,
+ EELFResourceManager.format(Msg.APPC_INVALID_INPUT),
+ this.getClass().getCanonicalName());
+
+ throw new InvalidInputException("vnfID or command is null");
+ }
+ CommonHeader commonHeader = requestContext.getCommonHeader();
+
+ checkForDuplicateRequest(commonHeader);
+
+ Calendar inputTimeStamp = DateToCalendar(commonHeader.getTimeStamp());
+ Calendar currentTime = Calendar.getInstance();
+
+ // If input timestamp is of future, we reject the request
+ if (inputTimeStamp.getTime().getTime() > currentTime.getTime().getTime()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Input Timestamp is of future = " + inputTimeStamp.getTime());
+ }
+ throw new InvalidInputException("Input Timestamp is of future = " + inputTimeStamp.getTime());
+ }
+ Integer ttl = readTTL(commonHeader);
+ logger.debug("TTL value set to (seconds) : " + ttl);
+ inputTimeStamp.add(Calendar.SECOND, ttl);
+ if (currentTime.getTime().getTime() >= inputTimeStamp.getTime().getTime()) {
+
+ LoggingUtils.logErrorMessage(
+ LoggingConstants.TargetNames.REQUEST_VALIDATOR,
+ "TTL Expired: Current time - " + currentTime.getTime().getTime() + " Request time: " + inputTimeStamp.getTime().getTime() + " with TTL value: " + ttl,
+ this.getClass().getCanonicalName());
+
+ throw new RequestExpiredException("TTL Expired");
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Validation of the request is successful");
+ }
+ }
+
+
+ private static Calendar DateToCalendar(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ return cal;
+ }
+
+ // TODO: Get reference once via Blueprint and get rid of this method
+ private void getAAIservice() {
+ BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext();
+ // Get AAIadapter reference
+ ServiceReference sref = bctx.getServiceReference(AAIService.class.getName());
+ if (sref != null) {
+ logger.info("AAIService from bundlecontext");
+ aaiService = (AAIService) bctx.getService(sref);
+
+ } else {
+ logger.info("AAIService error from bundlecontext");
+ logger.warn("Cannot find service reference for org.openecomp.sdnc.sli.aai.AAIService");
+
+ }
+ }
+
+ private VNFContext queryAAI(String vnfId) throws VNFNotFoundException {
+ SvcLogicContext ctx = new SvcLogicContext();
+ ctx = getVnfdata(vnfId, "vnf", ctx);
+
+ VNFContext vnfContext = new VNFContext();
+ populateVnfContext(vnfContext, ctx);
+
+ return vnfContext;
+ }
+
+ private String queryLCM(String orchestrationStatus, VNFOperation action) throws LifecycleException, NoTransitionDefinedException {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to queryLCM with Orchestration Status = "+ ObjectUtils.toString(orchestrationStatus)+
+ ", command = "+ ObjectUtils.toString(action));
+ }
+
+ String nextState = lifecyclemanager.getNextState(null, orchestrationStatus, action.name());
+ if (logger.isDebugEnabled()) {
+ logger.trace("Exiting from queryLCM with (LCMResponse = "+ ObjectUtils.toString(nextState)+")");
+ }
+ return nextState;
+ }
+
+ private void queryWFM(VNFContext vnfContext, RequestContext requestContext) throws WorkflowNotFoundException,DGWorkflowNotFoundException {
+
+ checkWorkflowExists(vnfContext, requestContext);
+ }
+
+ private void checkWorkflowExists(VNFContext vnfContext, RequestContext requestContext) throws WorkflowNotFoundException,DGWorkflowNotFoundException {
+
+ WorkflowExistsOutput workflowExistsOutput = workflowManager.workflowExists(getWorkflowQueryParams(vnfContext, requestContext));
+ if (!workflowExistsOutput.isMappingExist()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("WorkflowManager : Workflow not found for vnfType = " + vnfContext.getType() + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name());
+ }
+
+ LoggingUtils.logErrorMessage(
+ LoggingConstants.TargetNames.WORKFLOW_MANAGER,
+ EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()),
+ this.getClass().getCanonicalName());
+
+
+ throw new WorkflowNotFoundException("Workflow not found for vnfType = " + vnfContext.getType() + ", command = " + requestContext.getAction().name(),vnfContext.getType(),requestContext.getAction().name());
+ }
+ if (!workflowExistsOutput.isDgExist()) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("WorkflowManager : DG Workflow not found for vnfType = " + vnfContext.getType() + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name()+" "+workflowExistsOutput);
+ }
+
+
+ LoggingUtils.logErrorMessage(
+ LoggingConstants.TargetNames.WORKFLOW_MANAGER,
+ EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()),
+ this.getClass().getCanonicalName());
+
+
+ throw new DGWorkflowNotFoundException("Workflow not found for vnfType = " + vnfContext.getType() + ", command = " + requestContext.getAction().name(),
+ workflowExistsOutput.getWorkflowModule(),workflowExistsOutput.getWorkflowName(),workflowExistsOutput.getWorkflowVersion());
+ }
+ }
+
+ private void populateVnfContext(VNFContext vnfContext, SvcLogicContext ctx) {
+ vnfContext.setType(ctx.getAttribute("vnf.vnf-type"));
+ vnfContext.setStatus(ctx.getAttribute("vnf.orchestration-status"));
+ vnfContext.setId(ctx.getAttribute("vnf.vnf-id"));
+ // TODO: Uncomment once A&AI supports VNF version
+ //vnfContext.setVersion(ctx.getAttribute("vnf.vnf-version"));
+ }
+
+ private WorkflowRequest getWorkflowQueryParams(VNFContext vnfContext, RequestContext requestContext) {
+
+ WorkflowRequest workflowRequest = new WorkflowRequest();
+ workflowRequest.setVnfContext(vnfContext);
+ workflowRequest.setRequestContext(requestContext);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from etWorkflowQueryParams with (WorkflowRequest = "+ ObjectUtils.toString(workflowRequest)+")");
+ }
+ return workflowRequest;
+ }
+
+
+ private void checkForDuplicateRequest(CommonHeader header) throws DuplicateRequestException {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to checkForDuplicateRequest with RequestHeader = "+ ObjectUtils.toString(header));
+ }
+
+ UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(header.getOriginatorId(), header.getRequestId(), header.getSubRequestId());
+ boolean requestAccepted = requestRegistry.registerRequest(requestIdentifier);
+ if (!requestAccepted) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Duplicate Request with " + requestIdentifier);
+ }
+ throw new DuplicateRequestException("Duplicate Request with " + requestIdentifier);
+ }
+ }
+
+ private void checkVNFWorkingState(RuntimeContext runtimeContext) throws UnstableVNFException {
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to checkVNFWorkingState with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext.getRequestContext()));
+ }
+ boolean forceFlag = runtimeContext.getRequestContext().getCommonHeader().getFlags() != null ? runtimeContext.getRequestContext().getCommonHeader().getFlags().isForce() : false;
+ String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("forceFlag = " + forceFlag);
+ }
+ boolean isVNFStable = workingStateManager.isVNFStable(vnfId);
+ if (!isVNFStable && !forceFlag) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("VNF is not stable for VNF ID = " + vnfId);
+ }
+ throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId);
+ }
+
+ }
+
+
+ private Integer readTTL(CommonHeader header) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to readTTL with RequestHandlerInput = "+ ObjectUtils.toString(header));
+ }
+ if (header.getFlags()== null || !isValidTTL(String.valueOf(header.getFlags().getTtl()))) {
+ String defaultTTLStr = configuration.getProperty("org.openecomp.appc.workflow.default.ttl", String.valueOf(Constants.DEFAULT_TTL));
+ Integer defaultTTL = Integer.parseInt(defaultTTLStr);
+ return defaultTTL;
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from readTTL with (TTL = "+ ObjectUtils.toString(header.getFlags().getTtl())+")");
+ }
+ return header.getFlags().getTtl();
+ }
+
+
+ private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to getVnfdata with vnfid = "+ ObjectUtils.toString(vnf_id) + ", prefix = "+ ObjectUtils.toString(prefix)+ ", SvcLogicContext"+ ObjectUtils.toString(ctx));
+ }
+
+ String key = "vnf-id = '" + vnf_id + "'";
+ logger.debug("inside getVnfdata=== " + key);
+ try {
+ Date beginTimestamp = new Date();
+ SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null, ctx);
+ Date endTimestamp = new Date();
+ String status = SvcLogicResource.QueryStatus.SUCCESS.equals(response) ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR;
+ LoggingUtils.logMetricsMessage(
+ beginTimestamp,
+ endTimestamp,
+ LoggingConstants.TargetNames.AAI,
+ LoggingConstants.TargetServiceNames.AAIServiceNames.QUERY,
+ status,
+ "",
+ response.name(),
+ this.getClass().getCanonicalName());
+ if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) {
+ throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id);
+ } else if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) {
+ throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id);
+ }
+ logger.info("AAIResponse: " + response.toString());
+ } catch (SvcLogicException e) {
+
+ LoggingUtils.logErrorMessage(
+ LoggingConstants.TargetServiceNames.AAIServiceNames.GET_VNF_DATA,
+ "Error in getVnfdata" + e,
+ this.getClass().getCanonicalName());
+
+ throw new RuntimeException(e);
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from getVnfdata with (SvcLogicContext = "+ ObjectUtils.toString(ctx)+")");
+ }
+ return ctx;
+ }
+
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java
new file mode 100644
index 000000000..8755ad3f5
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.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.workingstatemanager;
+
+import org.openecomp.appc.requesthandler.exceptions.VNFNotFoundException;
+import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
+
+
+public interface WorkingStateManager {
+
+ /**
+ * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found exception.
+ * @param vnfId vnf Id to be verified for stable state
+ * @return True if vnf Exists and state is STABLE else False.
+ */
+ public boolean isVNFStable(String vnfId);
+
+ /**
+ * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or
+ * if the registered ownerId is equal to the given ownerId or if the forceFlag is true.
+ * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store.
+ * @param vnfId vnf Id to be updated
+ * @param workingState new working state
+ * @param ownerId
+ * @param forceFlag - force to update also on case given onwerId is different then the registered one
+ */
+ public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag);
+
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java
new file mode 100644
index 000000000..07d97739a
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java
@@ -0,0 +1,44 @@
+/*-
+ * ============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.workingstatemanager.impl;
+
+import java.sql.Connection;
+
+import org.openecomp.appc.dao.util.JdbcConnectionFactory;
+import org.openecomp.appc.workingstatemanager.WorkingStateManager;
+
+public abstract class JdbcWorkingStateManager implements WorkingStateManager {
+
+ private JdbcConnectionFactory connectionFactory;
+
+ public void setConnectionFactory(JdbcConnectionFactory connectionFactory) {
+ this.connectionFactory = connectionFactory;
+ }
+
+ protected Connection openDbConnection() {
+ return connectionFactory.openDbConnection();
+ }
+
+ protected void closeDbConnection(Connection connection) {
+ connectionFactory.closeDbConnection(connection);
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java
new file mode 100644
index 000000000..1de81606e
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.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.workingstatemanager.impl;
+
+
+public class RequestHandlerMessages {
+ public final static String VNF_WORKING_STATE_UPDATED = "VNF WorkingState for vnfId ${vnfId} was updated to ${workingState} at attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}";
+ public final static String VNF_WORKING_STATE_WAS_NOT_UPDATED = "VNF WorkingState for vnfId ${vnfId} was not updated to ${workingState} attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}";
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java
new file mode 100644
index 000000000..732a41304
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.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.workingstatemanager.impl;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.executor.objects.Params;
+import org.openecomp.appc.message.RequestHandlerMessages;
+import org.openecomp.appc.util.MessageFormatter;
+import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
+import org.openecomp.appc.workingstatemanager.objects.VnfWorkingStateDto;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.apache.commons.lang3.StringUtils;
+
+
+public class WorkingStateManagerImpl extends JdbcWorkingStateManager {
+
+ private static final String SQL_RETRIEVE_VNF_STATE_MANAGEMENT = "SELECT VNF_ID,STATE,OWNER_ID,UPDATED,VER FROM VNF_STATE_MANAGEMENT WHERE VNF_ID=?";
+ private static final String SQL_INSERT_VNF_STATE_MANAGEMENT = "INSERT IGNORE INTO VNF_STATE_MANAGEMENT (VNF_ID,STATE,OWNER_ID,UPDATED,VER) VALUES (?, ?, ?, ?, ?)";
+ private static final String SQL_UPDATE_VNF_STATE_MANAGEMENT = "UPDATE VNF_STATE_MANAGEMENT SET OWNER_ID=?, UPDATED=?, STATE=?, VER=? WHERE VNF_ID=? AND VER=?";
+ private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()";
+ private static int maxAttempts = ConfigurationFactory.getConfiguration().getIntegerProperty("org.openecomp.appc.workingstatemanager.maxAttempts",20);
+
+ private static Map<String,VNFWorkingState> workingStateMap = new ConcurrentHashMap<>();
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkingStateManagerImpl.class);
+
+
+ /**
+ * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found exception.
+ * @param vnfId vnf Id to be verified for stable state
+ * @return True if vnf Exists and state is STABLE else False.
+ */
+ @Override
+ public boolean isVNFStable(String vnfId){
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to isVNFStable with vnfId = "+ vnfId);
+ }
+ Connection connection = null;
+ boolean vnfStable = false;
+ try {
+ connection = openDbConnection();
+ VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId);
+ vnfStable = isVNFStable(vnfWorkingStateDto);
+ } catch (SQLException e) {
+ String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage();
+ throw new RuntimeException(errMsg);
+ } finally {
+ if(connection != null) {
+ closeDbConnection(connection);
+ }
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from isVNFStable for vnfId = "+ vnfId+" with Result = "+vnfStable);
+ }
+ return vnfStable;
+ }
+
+ /**
+ * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or
+ * if the registered ownerId is equal to the given ownerId or if the forceFlag is true.
+ * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store.
+ * @param vnfId vnf Id to be updated
+ * @param workingState new working state
+ * @param ownerId
+ * @param forceFlag - force to update also on case given onwerId is different then the registered one
+ */
+ @Override
+ public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag){
+ boolean updated = false;
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to setWorkingState with vnfId = "+ ObjectUtils.toString(vnfId)+ ", VNFWorkingState = " + workingState.name() + ", ownerId = "+ownerId+", forceFlag = "+forceFlag);
+ }
+ Connection connection = null;
+ try {
+ connection = openDbConnection();
+ updated = setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag, maxAttempts);
+ } catch (SQLException e) {
+ String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage();
+ throw new RuntimeException(errMsg);
+ } finally {
+ if(connection != null) {
+ closeDbConnection(connection);
+ }
+ }
+
+ logger.trace("setWorkingState exit with output updated = "+updated);
+ return updated;
+ }
+
+ public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag, int maxAttempts) throws SQLException {
+ return setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,1,maxAttempts);
+ }
+ public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag,int attempt, int maxAttempts) throws SQLException {
+ boolean updated = false;
+ VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId);
+ Long currentVersion = vnfWorkingStateDto != null ? vnfWorkingStateDto.getVer() : null;
+ if(forceFlag || isVNFStable(vnfWorkingStateDto) || vnfWorkingStateDto.getOwnerId().equals(ownerId)){
+ updated = storeWorkingStateIfSameVersion(connection, vnfId, workingState, ownerId, currentVersion);
+
+ Params params = new Params().addParam("vnfId", vnfId).addParam("workingState",workingState.name())
+ .addParam("attempt",attempt).addParam("maxAttempts",maxAttempts).addParam("ownerId",ownerId).addParam("forceFlag",forceFlag);
+ String logMessage;
+ if(updated) {
+ logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_UPDATED, params.getParams());
+ }else {
+ logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_WAS_NOT_UPDATED, params.getParams());
+ }
+ logger.debug(logMessage);
+ if(!updated && attempt<maxAttempts){
+ setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,++attempt,maxAttempts);
+ }
+
+ }
+ return updated;
+ }
+
+
+ public boolean storeWorkingStateIfSameVersion(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, Long currentVersion) throws SQLException {
+ boolean stored = false;
+ if (currentVersion != null) {
+ stored = updateStateIfSameVersion(connection, vnfId, ownerId, workingState.name(), currentVersion);
+ } else {
+ stored = addVnfWorkingStateIfNotExists(connection, vnfId, ownerId, workingState.name());
+ }
+
+ return stored;
+ }
+
+ private boolean isVNFStable(VnfWorkingStateDto vnfWorkingStateDto) {
+ if( vnfWorkingStateDto == null || vnfWorkingStateDto.getState() ==VNFWorkingState.STABLE){
+ return true;
+ }
+ return false;
+ }
+
+ public boolean updateStateIfSameVersion(Connection connection, String vnfId, String ownerId, String state, long currentVer) throws SQLException {
+ try(PreparedStatement statement = connection.prepareStatement(SQL_UPDATE_VNF_STATE_MANAGEMENT)) {
+ long newVer = (currentVer >= Long.MAX_VALUE) ? 1 : (currentVer + 1);
+ statement.setString(1, ownerId);
+ statement.setLong(2, getCurrentTime(connection));
+ statement.setString(3, state);
+ statement.setLong(4, newVer);
+ statement.setString(5, vnfId);
+ statement.setLong(6, currentVer);
+ return (statement.executeUpdate() != 0);
+ }
+ }
+
+ protected VnfWorkingStateDto retrieveVnfWorkingState(Connection connection, String vnfId) throws SQLException {
+ VnfWorkingStateDto res = null;
+
+ try(PreparedStatement statement = connection.prepareStatement(SQL_RETRIEVE_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER
+ statement.setString(1, vnfId);
+ try(ResultSet resultSet = statement.executeQuery()) {
+ if(resultSet.next()) {
+ res = new VnfWorkingStateDto(vnfId);
+ String stateString = resultSet.getString(2);
+ VNFWorkingState vnfWorkingState = VNFWorkingState.valueOf(stateString);
+ res.setState(vnfWorkingState);
+ res.setOwnerId(resultSet.getString(3));
+ res.setUpdated(resultSet.getLong(4));
+ res.setVer(resultSet.getLong(5));
+ }
+ }
+ }
+ return res;
+ }
+
+ 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;
+ }
+
+ protected boolean addVnfWorkingStateIfNotExists(Connection connection, String vnfId, String ownerId, String state) throws SQLException {
+ boolean added = false;
+ try(PreparedStatement statement = connection.prepareStatement(SQL_INSERT_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER
+ statement.setString(1, vnfId);
+ statement.setString(2, state);
+ statement.setString(3, ownerId);
+ statement.setLong(4, getCurrentTime(connection));
+ statement.setLong(5, 1L);
+ int rowCount = statement.executeUpdate();
+ added = rowCount != 0 ? true : false;
+ }
+ return added;
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java
new file mode 100644
index 000000000..ad6973712
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.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.workingstatemanager.objects;
+
+
+public enum VNFWorkingState {
+ STABLE,UNSTABLE,UNKNOWN;
+ public String toString(){
+ return this.name();
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java
new file mode 100644
index 000000000..ed840f480
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java
@@ -0,0 +1,90 @@
+/*-
+ * ============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.workingstatemanager.objects;
+
+
+public class VnfWorkingStateDto {
+ private String vnfId;
+ private VNFWorkingState state;
+ private String ownerId;
+ private long updated;
+ private long ver;
+
+ public VnfWorkingStateDto() {
+ }
+
+ public VnfWorkingStateDto(String vnfId) {
+ this.vnfId = vnfId;
+ }
+
+ public String getVnfId() {
+ return vnfId;
+ }
+
+ public void setVnfId(String vnfId) {
+ this.vnfId = vnfId;
+ }
+
+ public VNFWorkingState getState() {
+ return state;
+ }
+
+ public void setState(VNFWorkingState state) {
+ this.state = state;
+ }
+
+ public String getOwnerId() {
+ return ownerId;
+ }
+
+ public void setOwnerId(String ownerId) {
+ this.ownerId = ownerId;
+ }
+
+ public long getUpdated() {
+ return updated;
+ }
+
+ public void setUpdated(long updated) {
+ this.updated = updated;
+ }
+
+ public long getVer() {
+ return ver;
+ }
+
+ public void setVer(long ver) {
+ this.ver = ver;
+ }
+
+
+ @Override
+ public String toString() {
+ return "VnfWorkingStateDto{" +
+ "vnfId='" + vnfId + '\'' +
+ ", state=" + state +
+ ", ownerId='" + ownerId + '\'' +
+ ", updated=" + updated +
+ ", ver=" + ver +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..785b6cb04
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,60 @@
+<?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="requestHandlerBean" class="org.openecomp.appc.requesthandler.impl.RequestHandlerImpl" scope="singleton" >
+ <property name="commandExecutor" ref="commandExecutorRef" />
+ <property name="requestValidator" ref="requestValidatorBean" />
+ <property name="lockManager" ref="lockManagerRef" />
+ <property name="workingStateManager" ref="workingStateManagerBean"/>
+ <property name="transactionRecorder" ref="transactionRecorderRef" />
+ <property name="aaiService" ref="aaiServiceRef" />
+ </bean>
+
+ <bean id="requestValidatorBean" class="org.openecomp.appc.requesthandler.impl.RequestValidatorImpl" scope="singleton" >
+ <property name="lifecyclemanager" ref="lifecyclemanagerRef" />
+ <property name="workflowManager" ref="workflowManagerRef" />
+ <property name="workingStateManager" ref="workingStateManagerBean" />
+ </bean>
+
+ <service id="requestHandlerService" interface="org.openecomp.appc.requesthandler.RequestHandler" ref="requestHandlerBean"/>
+ <reference id="lifecyclemanagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" />
+ <reference id="workflowManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.workflow.WorkFlowManager" />
+ <reference id="commandExecutorRef" availability="optional" activation="eager" interface="org.openecomp.appc.executor.CommandExecutor" />
+ <reference id="lockManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lockmanager.api.LockManager" />
+ <reference id="transactionRecorderRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.transactionrecorder.TransactionRecorder" />
+ <reference xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" ext:proxy-method="classes" id="aaiServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.aai.AAIService" />
+
+ <bean id="workingStateManagerBean" class="org.openecomp.appc.workingstatemanager.impl.WorkingStateManagerImpl" scope="singleton" >
+ <property name="connectionFactory">
+ <bean class="org.openecomp.appc.dao.util.AppcJdbcConnectionFactory">
+ <property name="schema" value="sdnctl"/>
+ </bean>
+ </property>
+ </bean>
+
+</blueprint>
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..2e2763f9a
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties
@@ -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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-REQ-HDLR-MAIN
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=1
+dmaap.threads.poolsize.max=2
+
+org.openecomp.appc.db.url.sdnctl=jdbc:mysql://127.0.0.1:3306/test
+org.openecomp.appc.db.user.sdnctl=test
+org.openecomp.appc.db.pass.sdnctl=123456
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
+org.openecomp.appc.workingstatemanager.maxAttempts=20
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java
new file mode 100644
index 000000000..46875a269
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java
@@ -0,0 +1,360 @@
+/*-
+ * ============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.requesthandler;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.junit.Assert;
+import org.junit.Test;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.executor.objects.LCMCommandStatus;
+import org.openecomp.appc.requesthandler.conv.Converter;
+
+import javax.ws.rs.container.AsyncResponse;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.HashMap;
+
+
+public class TestConverter {
+ private String expectedJsonBodyStr ="{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}}";
+ private String expectedDmaapOutgoingMessageJsonStringTest ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"test\"}";
+ private String expectedDmaapOutgoingMessageJsonStringRollback ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"rollback\"}";
+ private String expectedDmaapOutgoingMessageJsonStringSnapshot ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"snapshot\"}";
+ private String expectedDmaapOutgoingMessageJsonStringAudit ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"audit\"}";
+ private String expectedDmaapOutgoingMessageJsonStringHealthCheck ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"health-check\"}";
+ private String expectedDmaapOutgoingMessageJsonStringLiveUpgrade ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"live-upgrade\"}";
+ private String expectedDmaapOutgoingMessageJsonStringLock ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"lock\"}";
+ private String expectedDmaapOutgoingMessageJsonStringModifyConfig ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"modify-config\"}";
+ private String expectedDmaapOutgoingMessageJsonStringSoftwareUpload ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"software-upload\"}";
+ private String expectedDmaapOutgoingMessageJsonStringStop ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"stop\"}";
+ private String expectedDmaapOutgoingMessageJsonStringSync ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"sync\"}";
+ private String expectedDmaapOutgoingMessageJsonStringTerminate ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"terminate\"}";
+ private String expectedDmaapOutgoingMessageJsonStringUnlock ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"unlock\"}";
+
+ @Test
+ public void convDateToZuluStringTest(){
+ String dateToZuluString = Converter.convDateToZuluString(new Date(0L));
+ Assert.assertEquals("1970-01-01T00:00:00.000Z", dateToZuluString);
+ }
+
+ @Test
+ public void convAsyncResponseToBuilderTestTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Test;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringTestTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Test;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringTest,jsonStr);
+ }
+
+ @Test
+ public void convPayloadObjectToJsonStringTest() throws JsonProcessingException, ParseException {
+ String jsonString = Converter.convPayloadObjectToJsonString("any valid JSON string value");
+ Assert.assertEquals("any valid JSON string value", jsonString);
+
+ HashMap<String, String> hashMap = new HashMap<>();
+ hashMap.put("key","value");
+ jsonString = Converter.convPayloadObjectToJsonString(hashMap);
+ Assert.assertEquals("{\"key\":\"value\"}", jsonString);
+ }
+
+ @Test
+ public void convAsyncResponseToBuilderRollbackTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Rollback;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringRollbackTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Rollback;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringRollback,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToBuilderSnapshotTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Snapshot;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringSnapshotTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Snapshot;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSnapshot,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderAuditTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Audit;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringAuditTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Audit;
+ String rpcName = action.name().toLowerCase();
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringAudit,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderHealthCheckTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.HealthCheck;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringHealthCheckTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.HealthCheck;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringHealthCheck,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderLiveUpgradeTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.LiveUpgrade;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringLiveUpgradeTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.LiveUpgrade;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringLiveUpgrade,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderLockTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Lock;
+ String rpcName = convertActionNameToUrl(action.name());
+
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringLockTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Lock;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringLock,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderModifyConfigTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.ModifyConfig;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringModifyConfigTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.ModifyConfig;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringModifyConfig,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderSoftwareUploadTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.SoftwareUpload;
+ String rpcName = convertActionNameToUrl(action.name());
+
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringSoftwareUploadTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.SoftwareUpload;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSoftwareUpload,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderStopTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Stop;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringStopTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Stop;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringStop,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderSync() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Sync;
+ String rpcName = convertActionNameToUrl(action.name());
+
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringSync() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Sync;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSync,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderTerminateTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Sync;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringTerminateTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Terminate;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringTerminate,jsonStr);
+ }
+ @Test
+ public void convAsyncResponseToBuilderUnlockTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Unlock;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringUnlockTest() throws JsonProcessingException {
+ ResponseContext asyncResponse = buildAsyncResponse();
+ VNFOperation action = VNFOperation.Unlock;
+ String rpcName = convertActionNameToUrl(action.name());
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringUnlock,jsonStr);
+ }
+ /*@Test
+ public void convAsyncResponseToBuilderTest() throws JsonProcessingException {
+ AsyncResponse asyncResponse = buildAsyncResponse();
+ String jsonStr = Converter.convAsyncResponseToJsonStringBody(asyncResponse);
+ Assert.assertEquals(expectedJsonBodyStr,jsonStr);
+ }
+
+ @Test
+ public void convAsyncResponseToDmaapOutgoingMessageJsonStringTest() throws JsonProcessingException {
+ AsyncResponse asyncResponse = buildAsyncResponse();
+ String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(asyncResponse);
+ System.out.println("jsonStr = " + jsonStr);
+ Assert.assertEquals(expectedDmaapOutgoingMessageJsonString,jsonStr);
+ }*/
+
+
+ private ResponseContext buildAsyncResponse() {
+ ResponseContext asyncResponse = createResponseContextWithSubObjects();
+ asyncResponse.getStatus().setCode(LCMCommandStatus.SUCCESS.getResponseCode());
+ asyncResponse.getStatus().setMessage(LCMCommandStatus.SUCCESS.getResponseMessage());
+ asyncResponse.getCommonHeader().setOriginatorId("oid");
+ asyncResponse.getCommonHeader().setApiVer("2.0.0");
+ asyncResponse.getCommonHeader().setRequestId("reqid");
+ asyncResponse.getCommonHeader().setTimestamp(new Date(1000L));
+ asyncResponse.setPayload("any valid JSON string value. Json escape characters need to be added to make it a valid json string value");
+ return asyncResponse;
+ }
+
+ private ResponseContext createResponseContextWithSubObjects() {
+
+ ResponseContext responseContext = new ResponseContext();
+ CommonHeader commonHeader = new CommonHeader();
+ Flags flags = new Flags();
+ Status status = new Status();
+ responseContext.setCommonHeader(commonHeader);
+ responseContext.setStatus(status);
+ commonHeader.setFlags(flags);
+ return responseContext;
+ }
+
+ private String convertActionNameToUrl(String action) {
+ String regex = "([a-z])([A-Z]+)";
+ String replacement = "$1-$2";
+ return action.replaceAll(regex, replacement)
+ .toLowerCase();
+ }
+
+
+}
+
+
+
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java
new file mode 100644
index 000000000..e4c1e92d3
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java
@@ -0,0 +1,583 @@
+/*-
+ * ============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.requesthandler;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.executor.CommandExecutor;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.executor.objects.CommandExecutorInput;
+import org.openecomp.appc.executor.objects.LCMCommandStatus;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.lockmanager.api.LockException;
+import org.openecomp.appc.lockmanager.api.LockManager;
+import org.openecomp.appc.messageadapter.MessageAdapter;
+import org.openecomp.appc.requesthandler.exceptions.*;
+import org.openecomp.appc.requesthandler.impl.RequestHandlerImpl;
+import org.openecomp.appc.requesthandler.impl.RequestValidatorImpl;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerInput;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput;
+import org.openecomp.appc.transactionrecorder.TransactionRecorder;
+import org.openecomp.appc.transactionrecorder.objects.TransactionRecord;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowExistsOutput;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workingstatemanager.WorkingStateManager;
+import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.osgi.framework.FrameworkUtil;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class})
+public class TestRequestHandler {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class);
+
+ private RequestHandlerImpl requestHandler;
+ private RequestValidatorImpl requestValidator;
+ private WorkFlowManager workflowManager;
+ private WorkingStateManager workingStateManager ;
+ private LockManager lockManager;
+
+ @Before
+ public void init() throws Exception {
+
+ requestHandler = new RequestHandlerImpl();
+ LifecycleManager lifecyclemanager= mock(LifecycleManager.class);
+ workflowManager= mock(WorkFlowManager.class);
+ CommandExecutor commandExecutor= mock(CommandExecutor.class);
+ MessageAdapter messageAdapter = mock(MessageAdapter.class);
+ workingStateManager = mock(WorkingStateManager.class);
+ lockManager = mock(LockManager.class);
+ TransactionRecorder transactionRecorder= mock(TransactionRecorder.class);
+
+ requestHandler.setWorkingStateManager(workingStateManager);
+ requestHandler.setMessageAdapter(messageAdapter);
+ requestValidator = mock(RequestValidatorImpl.class);
+ requestValidator.setLifecyclemanager(lifecyclemanager);
+ requestValidator.setWorkingStateManager(workingStateManager);
+ requestValidator.setWorkflowManager(workflowManager);
+ requestValidator.setLifecyclemanager(lifecyclemanager);
+ requestHandler.setCommandExecutor(commandExecutor);
+ requestHandler.setRequestValidator(requestValidator);
+ requestHandler.setLockManager(lockManager);
+ requestHandler.setTransactionRecorder(transactionRecorder);
+
+ doNothing().when(transactionRecorder).store((TransactionRecord) anyObject());
+// Mockito.when(commandExecutor.executeCommand((CommandExecutorInput)anyObject())).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true);
+ for(Integer i=130; i<=140 ; i++)
+ {
+ Mockito.when(workingStateManager.isVNFStable(i.toString())).thenReturn(true);
+ }
+ Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("40")).thenReturn(true).thenReturn(false);
+ Mockito.when(workingStateManager.isVNFStable("38")).thenReturn(true).thenReturn(false);
+ Mockito.when(workingStateManager.isVNFStable("201")).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("202")).thenReturn(true).thenReturn(false);
+ Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true).thenReturn(false);
+ Mockito.when(workingStateManager.isVNFStable("302")).thenReturn(true).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("303")).thenReturn(true).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("310")).thenReturn(true).thenReturn(true);
+ }
+
+ private void threadSleep(){
+ try {
+ Thread.sleep(5);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void testNegativeFlowWithRequestingUsedVnfId() throws Exception {
+ logger.debug("=====================testNegativeFlowWithRequestingUsedVnfId=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input1 = this.getRequestHandlerInput("131", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ mockRuntimeContextAndVnfContext(input1);
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte());
+ RequestHandlerOutput output1 = requestHandler.handleRequest(input1);
+ threadSleep ();
+ Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(), output1.getResponseContext().getStatus().getCode());
+ logger.debug("testNegativeFlowWithRequestingUsedVnfId");
+ logger.debug("=====================testNegativeFlowWithRequestingUsedVnfId=============================");
+ }
+
+ @Test
+ public void testInvalidVNFExceptionRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure, 0,false,originatorID, requestID, subRequestID,new Date());
+ PowerMockito.doThrow(new VNFNotFoundException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.VNF_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void testLifecycleException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ PowerMockito.doThrow(new LifecycleException(new Exception(),"Configured","test event")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.ACTION_NOT_SUPPORTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+
+ @Test
+ public void testRequestExpiredException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ PowerMockito.doThrow(new RequestExpiredException("")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.EXPIRED_REQUEST.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void testWorkflowNotFoundException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ PowerMockito.doThrow(new WorkflowNotFoundException("Unable to find the DG","VNF-2.0.0.0", "Test")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.WORKFLOW_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode());}
+
+ @Test
+ public void testDGWorkflowNotFoundException() throws Exception {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest) anyObject())).thenReturn(new WorkflowExistsOutput(true, true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure, 0, false, originatorID, requestID, subRequestID, new Date());
+ PowerMockito.doThrow(new DGWorkflowNotFoundException("Unable to find the DG", "VNF-2.0.0.0", "temp", "Test")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.DG_WORKFLOW_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void testInvalidInputException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID1 = UUID.randomUUID().toString();
+ String requestID1 = UUID.randomUUID().toString();
+ String subRequestID1 = UUID.randomUUID().toString();
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input1 = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID1, requestID1, subRequestID1,new Date());
+ PowerMockito.doThrow(new InvalidInputException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output1 = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.INVALID_INPUT_PARAMETER.getResponseCode(), output1.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void testNoTransitionDefinedException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3010", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ PowerMockito.doThrow(new NoTransitionDefinedException("Invalid VNF State","Unstable","Test event")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.NO_TRANSITION_DEFINE.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void rejectInvalidRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ PowerMockito.doThrow(new VNFNotFoundException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.VNF_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void testUnstableWorkingState() throws Exception {
+ logger.debug("=====================testUnstableWorkingState=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ Mockito.when(workingStateManager.isVNFStable("37")).thenReturn(true,false);
+ RequestHandlerInput input = this.getRequestHandlerInput("37", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ mockRuntimeContextAndVnfContext(input);
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+
+ RequestHandlerInput input1 = this.getRequestHandlerInput("37", VNFOperation.Configure,1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte());
+ mockRuntimeContextAndVnfContext(input1);
+ RequestHandlerOutput output1 = requestHandler.handleRequest(input1);
+
+ Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(), output1.getResponseContext().getStatus().getCode());
+ logger.debug("=====================testUnstableWorkingState=============================");
+ }
+
+ @Test
+ public void testOnRequestExecutionEndSuccessForWorkingState() throws Exception {
+ logger.debug("=====================testOnRequestExecutionEndSuccessForWorkingState=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input1 = this.getRequestHandlerInput("137", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ mockRuntimeContextAndVnfContext(input1);
+
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+
+
+ RequestHandlerOutput output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ threadSleep();
+
+ requestHandler.onRequestExecutionEnd(this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"137", "", "", ""),true);
+
+ input1 = this.getRequestHandlerInput("137", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ mockRuntimeContextAndVnfContext(input1);
+ output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ logger.debug("=====================testOnRequestExecutionEndSuccessForWorkingState=============================");
+ }
+
+ private void mockRuntimeContextAndVnfContext(RequestHandlerInput input1) throws Exception {
+ RuntimeContext runtimeContext = PowerMockito.mock(RuntimeContext.class);
+ VNFContext vnfContext = new VNFContext();
+ vnfContext.setType("SCP");
+ vnfContext.setId("137");
+ when(runtimeContext.getVnfContext()).thenReturn(vnfContext);
+ when(runtimeContext.getRequestContext()).thenReturn(input1.getRequestContext());
+ when(runtimeContext.getRpcName()).thenReturn(input1.getRpcName());
+
+
+ ResponseContext responseContext = new ResponseContext();
+ responseContext.setStatus(new Status());
+ responseContext.setAdditionalContext(new HashMap<String, String>(4));
+ responseContext.setCommonHeader(input1.getRequestContext().getCommonHeader());
+ runtimeContext.setResponseContext(responseContext);
+ when(runtimeContext.getResponseContext()).thenReturn(responseContext);
+ responseContext.setStatus(new Status());
+ runtimeContext.setResponseContext(responseContext);
+ PowerMockito.whenNew(RuntimeContext.class).withAnyArguments().thenReturn(runtimeContext);
+
+ }
+
+
+ @Test
+ public void testOnRequestExecutionEndFailureForWorkingState() throws Exception {
+ logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+
+ RequestHandlerInput input1 = this.getRequestHandlerInput("38", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ mockRuntimeContextAndVnfContext(input1);
+ RequestHandlerOutput output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ threadSleep();
+ requestHandler.onRequestExecutionEnd(this.getAsyncResponse(false,LCMCommandStatus.NO_TRANSITION_DEFINE,"38", "", "", ""),true);
+
+ input1 = this.getRequestHandlerInput("38", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ PowerMockito.doThrow(new UnstableVNFException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ mockRuntimeContextAndVnfContext(input1);
+ output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.UNSTABLE_VNF.getResponseCode(),output.getResponseContext().getStatus().getCode());
+
+ logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState=============================");
+ }
+
+ @Test
+ public void testOnRequestExecutionEndTTLExpiredForWorkingState() throws Exception {
+ logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+
+ RequestHandlerInput input1 = this.getRequestHandlerInput("39", VNFOperation.Configure, 1,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ mockRuntimeContextAndVnfContext(input1);
+
+ RequestHandlerOutput output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ threadSleep();
+ input1 = this.getRequestHandlerInput("39", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte());
+ output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState=============================");
+ }
+
+ @Test
+ public void testOnRequestTTLEndForWorkingState() throws Exception {
+ logger.debug("=====================testOnRequestTTLEndForWorkingState=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+
+ RequestHandlerInput input1 = this.getRequestHandlerInput("40", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ mockRuntimeContextAndVnfContext(input1);
+ RequestHandlerOutput output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ threadSleep();
+ RuntimeContext response = this.getAsyncResponse(false,LCMCommandStatus.EXPIRED_REQUEST_FAILURE,"40", "", "", "");
+ requestHandler.onRequestTTLEnd(response,true);
+ input1 = this.getRequestHandlerInput("40", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ PowerMockito.doThrow(new UnstableVNFException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.UNSTABLE_VNF.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ logger.debug("=====================testOnRequestTTLEndForWorkingState=============================");
+ }
+
+ @Test
+ public void testForceCommandExecution() throws Exception {
+ logger.debug("=====================testForceCommandExecution=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input1 = this.getRequestHandlerInput("138", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ mockRuntimeContextAndVnfContext(input1);
+
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ RequestHandlerOutput output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ threadSleep();
+ RuntimeContext response = this.getAsyncResponse(false,LCMCommandStatus.ACCEPTED,"138", "", "", "");
+ requestHandler.onRequestTTLEnd(response,true);
+ input1 = this.getRequestHandlerInput("138", VNFOperation.Configure, 1200,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ input1.getRequestContext().getCommonHeader().getFlags().setForce(true);
+ mockRuntimeContextAndVnfContext(input1);
+ output = requestHandler.handleRequest(input1);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode());
+ logger.debug("=====================testForceCommandExecution=============================");
+ }
+
+ @Test
+ public void testOnRequestExecutionEndSuccess() throws VNFNotFoundException {
+ logger.debug("=====================Positive TEST - On Request Execution End SUCCESS- Starts =============================");
+ Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean());
+ requestHandler.onRequestExecutionEnd(this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"201", "", "", ""),true);
+ logger.debug("=====================Positive TEST - On Request Execution End SUCCESS- Ends =============================");
+ }
+
+ @Test
+ public void testOnRequestExecutionEndFailure() throws VNFNotFoundException {
+ logger.debug("=====================Positive TEST - On Request Execution End FAILURE- Starts =============================");
+ Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean());
+ requestHandler.onRequestExecutionEnd(this.getAsyncResponse(false,LCMCommandStatus.DG_FAILURE,"202", "", "", ""),true);
+ logger.debug("=====================Positive TEST - On Request Execution End FAILURE- Ends =============================");
+ }
+
+ private RequestHandlerInput getRequestHandlerInput(String vnfID, VNFOperation action, int ttl, boolean force,String originatorId, String requestId, String subRequestId,Date timeStamp){
+ String API_VERSION= "2.0.0";
+ RequestHandlerInput input = new RequestHandlerInput();
+ RuntimeContext runtimeContext = createRuntimeContextWithSubObjects();
+ RequestContext requestContext = runtimeContext.getRequestContext();
+ input.setRequestContext(requestContext);
+ requestContext.getActionIdentifiers().setVnfId(vnfID);
+ requestContext.setAction(action);
+ input.setRpcName(convertActionNameToUrl(action.name()));
+ requestContext.getCommonHeader().setRequestId(requestId);
+ requestContext.getCommonHeader().setSubRequestId(subRequestId);
+ requestContext.getCommonHeader().setOriginatorId(originatorId);
+ requestContext.getCommonHeader().getFlags().setTtl(ttl);
+ requestContext.getCommonHeader().getFlags().setForce(force);
+ requestContext.getCommonHeader().setTimestamp(timeStamp);
+ requestContext.getCommonHeader().setApiVer(API_VERSION);
+ return input;
+ }
+
+ private RuntimeContext getAsyncResponse(boolean wfStatus, LCMCommandStatus commandStatus, String vnfId, String originatorId, String requestId, String subRequestId)
+ {
+ RuntimeContext output = createRuntimeContextWithSubObjects();
+
+
+ output.getRequestContext().getActionIdentifiers().setVnfId(vnfId);
+ output.getVnfContext().setId(vnfId);
+ output.getResponseContext().getCommonHeader().setApiVer("2.0.0");
+ output.getResponseContext().getCommonHeader().setTimestamp(new Date());
+ output.getResponseContext().getStatus().setCode(LCMCommandStatus.SUCCESS.getResponseCode());
+ output.setTimeStart(new Date());
+ output.getResponseContext().getCommonHeader().setOriginatorId(originatorId);
+ output.getResponseContext().getCommonHeader().setRequestId(requestId);
+ output.getResponseContext().getCommonHeader().setSubRequestId(subRequestId);
+
+ output.getVnfContext().setType("FIREWALL");
+ output.getRequestContext().setAction(VNFOperation.Configure);
+ output.setRpcName("configure");
+ output.getResponseContext().setPayload("");
+ return output;
+ }
+
+ @Test
+ public void rejectDuplicateRequest() throws Exception {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("301", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ mockRuntimeContextAndVnfContext(input);
+
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+
+ input = this.getRequestHandlerInput("309", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+
+ PowerMockito.doThrow(new DuplicateRequestException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+ output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.DUPLICATE_REQUEST.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void removeRequestFromRegistryOnRequestCompletion() throws Exception {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("302", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ mockRuntimeContextAndVnfContext(input);
+
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+
+ RuntimeContext asyncResponse = this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"302",originatorID,requestID,subRequestID);
+ requestHandler.onRequestExecutionEnd(asyncResponse,true);
+
+ input = this.getRequestHandlerInput("310", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ mockRuntimeContextAndVnfContext(input);
+ output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ @Test
+ public void removeRequestFromRegistryOnTTLExpiration() throws Exception {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+
+ PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class));
+
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("303", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ mockRuntimeContextAndVnfContext(input);
+ RequestHandlerOutput output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+
+ RuntimeContext asyncResponse = this.getAsyncResponse(true,LCMCommandStatus.ACCEPTED,"303",originatorID,requestID,subRequestID);
+ requestHandler.onRequestTTLEnd(asyncResponse,false);
+
+ output = requestHandler.handleRequest(input);
+ Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode());
+ }
+
+ /*@Test
+ public void getMetricserviceTest() throws Exception{
+ Method method = RequestHandlerImpl.class.getDeclaredMethod("getMetricservice", null);
+ method.setAccessible(true);
+ method.invoke(null, null);
+
+ }*/
+ @Test
+ public void onRequestExecutionStartTest() throws Exception{
+ Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean());
+ requestHandler.onRequestExecutionStart("303",false, null, true);
+ Assert.assertNotNull(requestHandler);
+ }
+
+
+ private RuntimeContext createRuntimeContextWithSubObjects() {
+ RuntimeContext runtimeContext = new RuntimeContext();
+ RequestContext requestContext = new RequestContext();
+ runtimeContext.setRequestContext(requestContext);
+ ResponseContext responseContext = createResponseContextWithSuObjects();
+ runtimeContext.setResponseContext(responseContext);
+ CommonHeader commonHeader = new CommonHeader();
+ requestContext.setCommonHeader(commonHeader);
+ Flags flags = new Flags();
+ commonHeader.setFlags(flags);
+ ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
+ requestContext.setActionIdentifiers(actionIdentifiers);
+ VNFContext vnfContext = new VNFContext();
+ runtimeContext.setVnfContext(vnfContext);
+ return runtimeContext;
+
+ }
+
+ private ResponseContext createResponseContextWithSuObjects(){
+ ResponseContext responseContext = new ResponseContext();
+ CommonHeader commonHeader = new CommonHeader();
+ Flags flags = new Flags();
+ Status status = new Status();
+ responseContext.setCommonHeader(commonHeader);
+ responseContext.setStatus(status);
+ commonHeader.setFlags(flags);
+ return responseContext;
+ }
+
+ private String convertActionNameToUrl(String action) {
+ String regex = "([a-z])([A-Z]+)";
+ String replacement = "$1-$2";
+ return action.replaceAll(regex, replacement)
+ .toLowerCase();
+ }
+}
+
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java
new file mode 100644
index 000000000..6c287a580
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java
@@ -0,0 +1,626 @@
+/*-
+ * ============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.requesthandler;
+
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.openecomp.appc.domainmodel.lcm.*;
+import org.openecomp.appc.executor.UnstableVNFException;
+import org.openecomp.appc.lifecyclemanager.LifecycleManager;
+import org.openecomp.appc.lifecyclemanager.objects.LifecycleException;
+import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException;
+import org.openecomp.appc.requesthandler.exceptions.*;
+import org.openecomp.appc.requesthandler.impl.RequestHandlerImpl;
+import org.openecomp.appc.requesthandler.impl.RequestValidatorImpl;
+import org.openecomp.appc.requesthandler.objects.RequestHandlerInput;
+import org.openecomp.appc.transactionrecorder.TransactionRecorder;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowExistsOutput;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workingstatemanager.WorkingStateManager;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.openecomp.sdnc.sli.SvcLogicResource;
+import org.openecomp.sdnc.sli.aai.AAIService;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+import static junit.framework.TestCase.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.*;
+
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class})
+public class TestRequestValidator {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class);
+
+ private static final String TTL_FLAG= "TTL";
+
+ private RequestValidatorImpl requestValidator;
+
+ AAIService aaiAdapter ;
+ LifecycleManager lifecyclemanager;
+ WorkFlowManager workflowManager;
+ WorkingStateManager workingStateManager ;
+// AppcDAOImpl dao ;
+
+ private final BundleContext bundleContext= Mockito.mock(BundleContext.class);
+ private final Bundle bundleService=Mockito.mock(Bundle.class);
+ private final ServiceReference sref=Mockito.mock(ServiceReference.class);
+
+
+
+ @Before
+ public void init() throws Exception {
+
+// dao = Mockito.mock(AppcDAOImpl.class);
+// PowerMockito.whenNew(AppcDAOImpl.class).withNoArguments().thenReturn(dao);
+// Mockito.doNothing().when(dao).storeTransactionRecord((TransactionRecord)anyObject());
+ // PowerMockito.when(dao.queryWorkflow(anyString(),anyString())).thenReturn(true);
+
+ // ***
+ AAIService aaiService = Mockito.mock(AAIService.class);;
+ PowerMockito.mockStatic(FrameworkUtil.class);
+ PowerMockito.when(FrameworkUtil.getBundle(AAIService.class)).thenReturn(bundleService);
+ PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext);
+ PowerMockito.when(bundleContext.getServiceReference(AAIService.class.getName())).thenReturn(sref);
+ PowerMockito.when(bundleContext.getService(sref)).thenReturn(aaiService);
+ PowerMockito.when(aaiService.query(anyString(),anyBoolean(),anyString(),anyString(),anyString(),anyString(),(SvcLogicContext)anyObject())).thenAnswer(new Answer<SvcLogicResource.QueryStatus>() {
+ @Override
+ public SvcLogicResource.QueryStatus answer(InvocationOnMock invocation) throws Throwable {
+ Object[] args = invocation.getArguments();
+ SvcLogicContext ctx =(SvcLogicContext)args[6];
+ String prefix = (String)args[4];
+ String key = (String)args[3];
+ if(key.contains("'28'")){
+ return SvcLogicResource.QueryStatus.FAILURE ;
+ }else if ( key.contains("'8'")) {
+ return SvcLogicResource.QueryStatus.NOT_FOUND ;
+ }else {
+ ctx.setAttribute(prefix + ".vnf-type", "FIREWALL");
+ ctx.setAttribute(prefix + ".orchestration-status", "Instantiated");
+ }
+ return SvcLogicResource.QueryStatus.SUCCESS ;
+ }
+ });
+ PowerMockito.when(aaiService.update(anyString(),anyString(),(Map)anyObject(),anyString(),(SvcLogicContext)anyObject())).thenReturn(SvcLogicResource.QueryStatus.SUCCESS);
+ //PowerMockito.when(requestHandler.getVnfdata(anyString(), anyString(), (SvcLogicContext)anyObject())).thenReturn()
+ // ***
+
+
+ aaiAdapter = Mockito.mock(AAIService.class);
+ lifecyclemanager= Mockito.mock(LifecycleManager.class);
+ workflowManager= Mockito.mock(WorkFlowManager.class);
+ workingStateManager = Mockito.mock(WorkingStateManager.class);
+
+ // transactionRecorder= spy(TransactionRecorder.class);
+ requestValidator = new RequestValidatorImpl();
+// requestValidator = Mockito.mock(RequestValidator.class);
+ requestValidator.setWorkflowManager(workflowManager);
+ requestValidator.setLifecyclemanager(lifecyclemanager);
+ requestValidator.setWorkingStateManager(workingStateManager);
+
+
+ /* Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true);
+ Mockito.when(aaiAdapter.requestGenericVnfData("1")).thenReturn(getGenericVnf("FIREWALL","INSTNATIATED"));*/
+ // Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(true);
+
+ /*PowerMockito.when(getAaiadapter().requestGenericVnfData("39")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("8")).thenThrow(new AAIAdapterException("404"));
+ Mockito.when(workingStateManager.isVNFStable("8")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("9")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("9")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("10")).thenReturn(getGenericVnf("WrongRouter","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("10")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("11")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("11")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("12")).thenReturn(getGenericVnf("FIREWALL","NOT_INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("12")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("13")).thenReturn(getGenericVnf("FIREWALL","TESTING"));
+ Mockito.when(workingStateManager.isVNFStable("13")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("14")).thenReturn(getGenericVnf("FIREWALL","REBUILDING"));
+ Mockito.when(workingStateManager.isVNFStable("14")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("26")).thenReturn(getGenericVnf("FIREWALL","NOT_INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("26")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("27")).thenReturn(getGenericVnf("FIREWALL","RESTARTING"));
+ Mockito.when(workingStateManager.isVNFStable("27")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("28")).thenThrow(new RuntimeException("AAI Down Excpetion"));
+ Mockito.when(workingStateManager.isVNFStable("28")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("35")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("35")).thenReturn(true);*/
+
+ /*for(Integer i=130; i<=140 ; i++)
+ {
+ PowerMockito.when(getAaiadapter().requestGenericVnfData(i.toString())).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable(i.toString())).thenReturn(true);
+ }
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("39")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("40")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("40")).thenReturn(true).thenReturn(false);
+
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("38")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("38")).thenReturn(true).thenReturn(false);
+
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("201")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")).thenReturn(getGenericVnf("FIREWALL","CONFIGURED"));
+ Mockito.when(workingStateManager.isVNFStable("201")).thenReturn(true);
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("202")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")).thenReturn(getGenericVnf("FIREWALL","ERROR"));
+ Mockito.when(workingStateManager.isVNFStable("202")).thenReturn(true).thenReturn(false);
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("301")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true).thenReturn(false);
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("302")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("302")).thenReturn(true).thenReturn(true);
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("303")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("303")).thenReturn(true).thenReturn(true);
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("309")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true).thenReturn(true);
+
+ PowerMockito.when(getAaiadapter().requestGenericVnfData("310")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED"));
+ Mockito.when(workingStateManager.isVNFStable("310")).thenReturn(true).thenReturn(true);*/
+ }
+ public AAIService getAaiadapter() {
+ return this.aaiAdapter;
+ }
+/* public GenericVnf getGenericVnf(String vnfType, String operationalState) {
+ GenericVnf genericVnf = new GenericVnf();
+ genericVnf.setVnfType(vnfType);
+ // genericVnf.setOperationalState(operationalState);
+ genericVnf.setOrchestrationStatus(operationalState);
+ return genericVnf;
+ }*/
+ private RequestHandlerInput getRequestHandlerInput(String vnfID, VNFOperation action, int ttl, boolean force, String originatorId, String requestId, String subRequestId, Date timeStamp){
+ String API_VERSION= "2.0.0";
+ RequestHandlerInput input = new RequestHandlerInput();
+ RuntimeContext runtimeContext = createRuntimeContextWithSubObjects();
+ RequestContext requestContext = runtimeContext.getRequestContext();
+ input.setRequestContext(requestContext);
+ requestContext.getActionIdentifiers().setVnfId(vnfID);
+ requestContext.setAction(action);
+ if (action != null) {
+ input.setRpcName(convertActionNameToUrl(action.name()));
+ }
+ else{
+ input.setRpcName(null);
+ }
+ requestContext.getCommonHeader().setRequestId(requestId);
+ requestContext.getCommonHeader().setSubRequestId(subRequestId);
+ requestContext.getCommonHeader().setOriginatorId(originatorId);
+ requestContext.getCommonHeader().getFlags().setTtl(ttl);
+ requestContext.getCommonHeader().getFlags().setForce(force);
+ requestContext.getCommonHeader().getTimeStamp();
+ requestContext.getCommonHeader().setApiVer(API_VERSION);
+ requestContext.getCommonHeader().setTimestamp(timeStamp);
+ return input;
+ }
+ @Test
+ public void testNullVnfID() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testNullVnfID=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput(null, VNFOperation.Configure, 30,
+ false, UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(InvalidInputException e ) {
+ ex = e;
+ }
+// assertEquals(new InvalidInputException("vnfID or command is null") ,ex);
+ assertNotNull(ex);
+ logger.debug("=====================testNullVnfID=============================");
+ }
+
+ @Test
+ public void testPositiveFlowWithConfigure() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testPositiveFlowWithConfigure=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true);
+ RequestHandlerInput input = this.getRequestHandlerInput("1", VNFOperation.Configure, 30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNull(ex);
+ logger.debug("testPositiveFlowWithConfigure");
+ logger.debug("=====================testPositiveFlowWithConfigure=============================");
+ }
+
+ @Test
+ public void testVnfNotFound() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testVnfNotFound=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("8", VNFOperation.Configure, 30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testVnfNotFound=============================");
+ }
+
+
+
+ @Test
+ public void testNullCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testNullCommand=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput("7", null,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(InvalidInputException e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testNullCommand=============================");
+ }
+
+ @Test
+ public void testNullVnfIDAndCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testNullVnfIDAndCommand=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ RequestHandlerInput input = this.getRequestHandlerInput(null, null,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(InvalidInputException e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testNullVnfIDAndCommand=============================");
+ }
+
+ @Test
+ public void testWorkflowNotFound() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testWorkflowNotFound=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(false,false));
+ RequestHandlerInput input = this.getRequestHandlerInput("10", VNFOperation.Configure, 30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testWorkflowNotFound=============================");
+ }
+
+ @Test
+ public void testUnstableVnfWithConfigure() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testUnstableVnfWithConfigure=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","",""));
+
+ RequestHandlerInput input = this.getRequestHandlerInput("11", VNFOperation.Configure, 30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testUnstableVnfWithConfigure=============================");
+ }
+
+ @Test
+ public void testUnstableVnfWithTest() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testUnstableVnfWithTest=============================");
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","",""));
+ RequestHandlerInput input = this.getRequestHandlerInput("12", VNFOperation.Test,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testUnstableVnfWithTest=============================");
+ }
+
+ @Test
+ public void testUnstableVnfWithStart() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testUnstableVnfWithStart=============================");
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","",""));
+
+ RequestHandlerInput input = this.getRequestHandlerInput("13", VNFOperation.Start,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testUnstableVnfWithStart=============================");
+ }
+
+ @Test
+ public void testUnstableVnfWithTerminate() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testUnstableVnfWithTerminate=============================");
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","",""));
+ RequestHandlerInput input = this.getRequestHandlerInput("14", VNFOperation.Terminate,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testUnstableVnfWithTerminate=============================");
+ }
+
+ @Test
+ public void testUnstableVnfWithRestart() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testUnstableVnfWithRestart=============================");
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","",""));
+
+ RequestHandlerInput input = this.getRequestHandlerInput("26", VNFOperation.Restart,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testUnstableVnfWithRestart=============================");
+ }
+
+ @Test
+ public void testUnstableVnfWithRebuild() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testUnstableVnfWithRebuild=============================");
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","",""));
+
+ // Mockito.doReturn(this.getGenericVnf("Firewall", "NOT_INSTANTIATED")).when(getAaiadapter()).requestGenericVnfData("8");
+ RequestHandlerInput input = this.getRequestHandlerInput("27", VNFOperation.Rebuild,30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testUnstableVnfWithRebuild=============================");
+ }
+
+
+
+
+ @Test
+ public void testAAIDown() throws Exception {
+ logger.debug("=====================testAAIDown=============================");
+ // AAIAdapter aaiAdapter = Mockito.mock(AAIAdapterImpl.class);
+ // RequestHandler requestHandler=RequestHandlerSingleton.getRequestHandler(new WorkFlowManagerImpl(),aaiAdapter,new LifecycleManagerImpl());
+ // RequestHandler requestHandler = new RequestHandlerImpl(new WorkFlowManagerImpl(),aaiAdapter,new LifecycleManagerImpl());
+ RequestHandlerInput input = this.getRequestHandlerInput("28", VNFOperation.Configure, 30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ try {
+ requestValidator.validateRequest(runtimeContext);
+
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("=====================testAAIDown=============================");
+ }
+
+ @Test
+ public void testNegativeFlowWithTimeStamp() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ logger.debug("=====================testNegativeFlowWithTimeStamp=============================");
+ Date now = new Date();
+ Date past = new Date();
+ past.setTime(now.getTime() -1000000 );
+ RequestHandlerInput input = this.getRequestHandlerInput("35", VNFOperation.Configure, 30,
+ false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),past);
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ logger.debug("testNegativeFlowWithTimeStamp");
+ logger.debug("=====================testNegativeFlowWithTimeStamp=============================");
+ }
+
+
+ @Test
+ public void rejectDuplicateRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+
+ Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true));
+ Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true);
+ Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true);
+ RequestHandlerInput input = this.getRequestHandlerInput("301", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+
+ RequestHandlerInput input1 = this.getRequestHandlerInput("309", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date());
+ Exception ex =null;
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ RuntimeContext runtimeContext1 = putInputToRuntimeContext(input1);
+
+ try {
+ requestValidator.validateRequest(runtimeContext);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNull(ex);
+
+ try {
+ requestValidator.validateRequest(runtimeContext1);
+ }catch(Exception e ) {
+ ex = e;
+ }
+ assertNotNull(ex);
+ }
+
+ @Test
+ public void testLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException {
+ Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true);
+ testOperation("no-matter", VNFOperation.Lock);
+ }
+
+ @Test
+ public void testUnlockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException {
+ Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true);
+ testOperation("no-matter", VNFOperation.Unlock);
+ }
+
+ @Test
+ public void testCheckLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException {
+ Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true);
+ testOperation("no-matter", VNFOperation.CheckLock);
+ }
+
+ @Test(expected = NoTransitionDefinedException.class)
+ public void testLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException {
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.Lock.toString()))).thenThrow(new NoTransitionDefinedException("", "", ""));
+ Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true);
+ testOperation("no-matter", VNFOperation.Lock);
+ }
+
+ @Test(expected = NoTransitionDefinedException.class)
+ public void testUnlockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException {
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.Unlock.toString()))).thenThrow(new NoTransitionDefinedException("", "", ""));
+ Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true);
+ testOperation("no-matter", VNFOperation.Unlock);
+ }
+
+ @Test(expected = NoTransitionDefinedException.class)
+ public void testCheckLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException {
+ Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.CheckLock.toString()))).thenThrow(new NoTransitionDefinedException("", "", ""));
+ Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true);
+ testOperation("no-matter", VNFOperation.CheckLock);
+ }
+
+ private void testOperation(String resource, VNFOperation operation) throws WorkflowNotFoundException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, InvalidInputException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, RequestExpiredException {
+ String originatorID = UUID.randomUUID().toString();
+ String requestID = UUID.randomUUID().toString();
+ String subRequestID = UUID.randomUUID().toString();
+
+ RequestHandlerInput input = this.getRequestHandlerInput(resource, operation, 0, false, originatorID, requestID, subRequestID, new Date());
+ RuntimeContext runtimeContext = putInputToRuntimeContext(input);
+ requestValidator.validateRequest(runtimeContext);
+ }
+
+
+ private RuntimeContext createRuntimeContextWithSubObjects() {
+ RuntimeContext runtimeContext = new RuntimeContext();
+ RequestContext requestContext = new RequestContext();
+ runtimeContext.setRequestContext(requestContext);
+ ResponseContext responseContext = createResponseContextWithSuObjects();
+ runtimeContext.setResponseContext(responseContext);
+ CommonHeader commonHeader = new CommonHeader();
+ requestContext.setCommonHeader(commonHeader);
+ Flags flags = new Flags();
+ commonHeader.setFlags(flags);
+ ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
+ requestContext.setActionIdentifiers(actionIdentifiers);
+ VNFContext vnfContext = new VNFContext();
+ runtimeContext.setVnfContext(vnfContext);
+ return runtimeContext;
+
+ }
+
+ private ResponseContext createResponseContextWithSuObjects(){
+ ResponseContext responseContext = new ResponseContext();
+ CommonHeader commonHeader = new CommonHeader();
+ Flags flags = new Flags();
+ Status status = new Status();
+ responseContext.setCommonHeader(commonHeader);
+ responseContext.setStatus(status);
+ commonHeader.setFlags(flags);
+ return responseContext;
+ }
+
+ private String convertActionNameToUrl(String action) {
+ String regex = "([a-z])([A-Z]+)";
+ String replacement = "$1-$2";
+ return action.replaceAll(regex, replacement)
+ .toLowerCase();
+ }
+
+ private RuntimeContext putInputToRuntimeContext(RequestHandlerInput input) {
+ RuntimeContext runtimeContext = createRuntimeContextWithSubObjects();
+ runtimeContext.setRequestContext(input.getRequestContext());
+ runtimeContext.setRpcName(input.getRpcName());
+ runtimeContext.getVnfContext().setId(input.getRequestContext().getActionIdentifiers().getVnfId());
+ //runtimeContext.getRequestContext().getActionIdentifiers().setVnfId(input.getRequestContext().getActionIdentifiers().getVnfId());
+ return runtimeContext;
+
+ //String vnfID, VNFOperation action, int ttl, boolean force, String originatorId, String requestId, String subRequestId, Date timeStamp
+ }
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java
new file mode 100644
index 000000000..33028465b
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java
@@ -0,0 +1,110 @@
+/*-
+ * ============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.workingstatemanager;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.dao.util.AppcJdbcConnectionFactory;
+import org.openecomp.appc.workingstatemanager.impl.WorkingStateManagerImpl;
+import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.util.UUID;
+
+
+
+public class TestWorkingStateManager {
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestWorkingStateManager.class);
+ WorkingStateManagerImpl workingStateManager;
+
+ @Before
+ public void init() throws Exception {
+ workingStateManager = new WorkingStateManagerImpl();
+ AppcJdbcConnectionFactory appcJdbcConnectionFactory = new AppcJdbcConnectionFactory();
+ String schema = "sdnctl";
+ appcJdbcConnectionFactory.setSchema(schema);
+ workingStateManager.setConnectionFactory(appcJdbcConnectionFactory);
+ String property = ConfigurationFactory.getConfiguration().getProperty(String.format("org.openecomp.appc.db.url.%s", schema));
+ logger.info(property+" will be used as connection URL to mySQL.");
+ logger.warn("you can set connection URL to other IP by adding -DmysqlIp=<MYSQL_IP> in VM Option");
+// System.getProperties().getProperty("mys")
+ }
+
+ @Test
+ // this test run on mysql you need to uncomment Ignore and to add -DmysqlIp=<MYSQL_IP> in VM Option, to make that test pass successfully.
+ @Ignore
+ public void testUpdateWorkingState() {
+ String vnfId = UUID.randomUUID().toString();
+ String myOwnerId = "myOwnerId";
+ String otherOwnerId = "otherOwnerId";
+ boolean vnfStable = workingStateManager.isVNFStable(vnfId);
+ logger.info("isVNFStable returns "+vnfStable+" for vnfId "+vnfId);
+
+ //set to unstable with force true
+ boolean updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, true);
+ Assert.assertTrue(updated);
+ Assert.assertFalse(workingStateManager.isVNFStable(vnfId));
+
+ //negative test - try to set to any value by other ownerId when vnf state is UNSTABLE
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, otherOwnerId, false);
+ Assert.assertFalse(updated);
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, otherOwnerId, false);
+ Assert.assertFalse(updated);
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, otherOwnerId, false);
+ Assert.assertFalse(updated);
+
+ //positive test - set with same ownerId and force false
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, false);
+ Assert.assertTrue(updated);
+ Assert.assertFalse(workingStateManager.isVNFStable(vnfId));
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, myOwnerId, false);
+ Assert.assertTrue(updated);
+ Assert.assertFalse(workingStateManager.isVNFStable(vnfId));
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, myOwnerId, false);
+ Assert.assertTrue(updated);
+ Assert.assertTrue(workingStateManager.isVNFStable(vnfId));
+
+ //positive test - set with otherOwnerId and force false when VNF is stable
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, otherOwnerId, false);
+ Assert.assertTrue(updated);
+ Assert.assertFalse(workingStateManager.isVNFStable(vnfId));
+
+ //negative test - try to set to any value by myOwnerId when vnf state is UNKNOWN
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, false);
+ Assert.assertFalse(updated);
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, myOwnerId, false);
+ Assert.assertFalse(updated);
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, myOwnerId, false);
+ Assert.assertFalse(updated);
+
+ //positive test - try to set to any value by myOwnerId when vnf state is UNKNOWN but with force
+ updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, true);
+ Assert.assertTrue(updated);
+ Assert.assertFalse(workingStateManager.isVNFStable(vnfId));
+ }
+
+
+}
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..2d75df419
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties
@@ -0,0 +1,107 @@
+###
+# ============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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options
+#org.openecomp.appc.bootstrap.file=executor-test.properties
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+#
+# Certificate keystore and truststore
+#
+#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE>
+#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin
+#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE>
+#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin
+org.openecomp.sdnc.sli.aai.host.certificate.ignore=true
+org.openecomp.sdnc.sli.aai.certificate.trust.all=true
+
+#
+# Configuration file for A&AI Adapter
+#
+
+# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT
+org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443
+
+org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query
+
+# service instance
+org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances
+org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance
+
+# complex
+org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes
+org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id}
+
+# vservers
+org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers
+org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}
+
+# generic-vnf
+org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/
+org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id}
+
+#
+# Formatting
+#
+org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s
+org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type
+org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id
+org.openecomp.sdnc.sli.aai.param.service.type=service-type
+
+
+org.openecomp.appc.logging.path=${user.home},etc,../etc,.
+org.openecomp.appc.logging.file=logback.xml
+
+org.openecomp.appc.db.url.%s", schema), "");
+org.openecomp.appc.db.user.%s", schema), "");
+org.openecomp.appc.db.pass.%s", schema), "");
+
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-REQ-HDLR-TEST
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=1
+dmaap.threads.poolsize.max=2
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
+
+mysqlIp=127.0.0.1
+org.openecomp.appc.db.url.sdnctl=jdbc:mysql://${mysqlIp}:3306/test
+org.openecomp.appc.db.user.sdnctl=test
+org.openecomp.appc.db.pass.sdnctl=123456
+
+org.openecomp.appc.workingstatemanager.maxAttempts=2
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore b/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml
new file mode 100644
index 000000000..453a8e62f
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-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>appc-request-handler</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>appc-request-handler-features</name>
+ <artifactId>appc-request-handler-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-request-handler-core</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-request-handler/appc-request-handler-features/src/main/resources/features.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml
new file mode 100644
index 000000000..cc8fe1192
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml
@@ -0,0 +1,36 @@
+<?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="appc-request-handler-${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='appc-request-handler' description="appc-request-handler" version='${project.version}'>
+ <bundle>mvn:org.openecomp.appc/transaction-recorder/${project.version}</bundle>
+ <bundle dependency="true">mvn:org.openecomp.appc/domain-model-lib/${project.version}</bundle>
+ <bundle start-level="75" start="true">mvn:org.openecomp.appc/appc-command-executor-api/${project.version}</bundle>
+ <bundle start-level="80" start="true">mvn:org.openecomp.appc/appc-request-handler-api/${project.version}</bundle>
+ <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-request-handler-core/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-request-handler/pom.xml b/appc-dispatcher/appc-request-handler/pom.xml
new file mode 100644
index 000000000..9f06a54dd
--- /dev/null
+++ b/appc-dispatcher/appc-request-handler/pom.xml
@@ -0,0 +1,22 @@
+<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-request-handler</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC Request Handler</name>
+ <description>APPC Request Handler</description>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-request-handler-api</module>
+ <module>appc-request-handler-core</module>
+ <module>appc-request-handler-features</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/appc-workflow-management/.gitignore b/appc-dispatcher/appc-workflow-management/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-workflow-management/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-workflow-management/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/.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-workflow-management/appc-workflow-management-api/.gitignore b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-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-workflow-management/appc-workflow-management-api/pom.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/pom.xml
new file mode 100644
index 000000000..afd545501
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/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-workflow-management</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-workflow-management-api</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-workflow-management-api</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-data-access-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>domain-model-lib</artifactId>
+ <version>${project.version}</version>
+ </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.dao.objects,org.openecomp.appc.workflow,org.openecomp.appc.workflow.helper,org.openecomp.appc.workflow.objects</Export-Package>
+ <!--<Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency>-->
+ <!--<Embed-Transitive>true</Embed-Transitive>-->
+ <!--<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.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package>-->
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.java
new file mode 100644
index 000000000..abcebb6c6
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/WorkFlowManager.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.workflow;
+
+import org.openecomp.appc.workflow.objects.WorkflowExistsOutput;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workflow.objects.WorkflowResponse;
+
+public interface WorkFlowManager {
+ /**
+ * Execute workflow and return response.
+ * This method execute workflow with following steps.
+ * Retrieve workflow(DG) details - module, version and mode from database based on command and vnf Type from incoming request.
+ * Execute workflow (DG) using SVC Logic Service reference
+ * Return response of workflow (DG) to caller.
+ * @param workflowRequest workflow execution request which contains vnfType, command, requestId, targetId, payload and (optional) confID;
+ * @return Workflow Response which contains execution status and payload from DG if any
+ */
+ WorkflowResponse executeWorkflow(WorkflowRequest workflowRequest);
+
+ /**
+ * Check if workflow (DG) exists in database
+ * @param workflowQueryParams workflow request with command and vnf Type
+ * @return WorkflowExistsOutput.mappingExist True if workflow mapping exists else False. WorkflowExistsOutput.dgExist True if DG workflow exists else False.
+ */
+ WorkflowExistsOutput workflowExists(WorkflowRequest workflowQueryParams);
+
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java
new file mode 100644
index 000000000..a88fe1e61
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowExistsOutput.java
@@ -0,0 +1,94 @@
+/*-
+ * ============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.workflow.objects;
+
+public class WorkflowExistsOutput {
+
+ private boolean mappingExist ;
+ private boolean dgExist;
+ private String workflowModule;
+ private String workflowName;
+ private String workflowVersion;
+
+
+ public WorkflowExistsOutput() {
+ }
+
+ public WorkflowExistsOutput(boolean mappingExist, boolean dgExist) {
+ this.mappingExist = mappingExist;
+ this.dgExist = dgExist;
+ }
+
+ public boolean isMappingExist() {
+ return mappingExist;
+ }
+
+ public void setMappingExist(boolean mappingExist) {
+ this.mappingExist = mappingExist;
+ }
+
+ public boolean isDgExist() {
+ return dgExist;
+ }
+
+ public void setDgExist(boolean dgExist) {
+ this.dgExist = dgExist;
+ }
+
+ public String getWorkflowName() {
+ return workflowName;
+ }
+
+ public void setWorkflowName(String workflowName) {
+ this.workflowName = workflowName;
+ }
+
+ public String getWorkflowVersion() {
+ return workflowVersion;
+ }
+
+ public void setWorkflowVersion(String workflowVersion) {
+ this.workflowVersion = workflowVersion;
+ }
+
+ public String getWorkflowModule() {
+ return workflowModule;
+ }
+
+ public void setWorkflowModule(String workflowModule) {
+ this.workflowModule = workflowModule;
+ }
+ public boolean exists(){
+ return mappingExist && dgExist;
+ }
+
+ @Override
+ public String toString() {
+ return "WorkflowExistsOutput{" +
+ "mappingExist=" + mappingExist +
+ ", dgExist=" + dgExist +
+ ", workflowModule='" + workflowModule + '\'' +
+ ", workflowName='" + workflowName + '\'' +
+ ", workflowVersion='" + workflowVersion + '\'' +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java
new file mode 100644
index 000000000..97e5f81bc
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowRequest.java
@@ -0,0 +1,67 @@
+/*-
+ * ============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.workflow.objects;
+
+import org.openecomp.appc.domainmodel.lcm.RequestContext;
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+import org.openecomp.appc.domainmodel.lcm.VNFContext;
+
+
+public class WorkflowRequest {
+
+ private RequestContext requestContext;
+ private ResponseContext responseContext;
+ private VNFContext vnfContext;
+
+ 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 "WorkflowRequest{" +
+ "requestContext=" + requestContext +
+ ", responseContext=" + responseContext +
+ ", vnfContext=" + vnfContext +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.java
new file mode 100644
index 000000000..f9584b91f
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-api/src/main/java/org/openecomp/appc/workflow/objects/WorkflowResponse.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.workflow.objects;
+
+import java.util.Properties;
+
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+
+
+public class WorkflowResponse {
+
+ private ResponseContext responseContext;
+
+ public ResponseContext getResponseContext() {
+ return responseContext;
+ }
+
+ public void setResponseContext(ResponseContext responseContext) {
+ this.responseContext = responseContext;
+ }
+
+ @Override
+ public String toString() {
+ return "WorkflowResponse{" +
+ "responseContext=" + responseContext +
+ '}';
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 000000000..f4ef8aa0a
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/.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-workflow-management/appc-workflow-management-core/pom.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml
new file mode 100644
index 000000000..e13b6e5b9
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml
@@ -0,0 +1,76 @@
+<?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">
+
+ <!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+ -->
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-workflow-management-core</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>appc-workflow-management-core Bundle</name>
+ <description>appc-workflow-management-core OSGi bundle project.</description>
+
+ <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>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-ranking-framework-lib</artifactId>
+ <version>${project.version}</version>
+ </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,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency>
+ <Embed-Transitive>true</Embed-Transitive>
+ <Export-Service>org.openecomp.appc.workflow.WorkFlowManager</Export-Service>
+ <Import-Package>org.openecomp.appc.workflow,org.openecomp.appc.workflow.objects,!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!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-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java
new file mode 100644
index 000000000..9ca021790
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/common/constant/Constants.java
@@ -0,0 +1,67 @@
+/*-
+ * ============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.common.constant;
+
+public class Constants {
+
+ public static final String DG_ATTRIBUTE_STATUS = "SvcLogic.status";
+ public static final String DG_STATUS_SUCCESS = "success";
+ public static final String DG_ATTRIBUTE_STATUS_CODE = "SvcLogic.status.code";
+ public static final String DG_OUTPUT_STATUS_CODE = "output.status.code";
+ public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message";
+
+
+ /**
+ * The name of the property that contains the VM id value in the graph's context
+ */
+ public static final String VF_ID = "org.openecomp.appc.vfid";
+
+ /**
+ * The name of the property that contains the VF Type value in the graph's context
+ */
+ public static final String VF_TYPE = "org.openecomp.appc.vftype";
+
+ /**
+ * The name of the property that contains the service request id value in the graph's context
+ */
+ public static final String REQUEST_ID = "org.openecomp.appc.reqid";
+
+ /**
+ * The name of the property that indicates which method of the IaaS adapter to call
+ */
+ public static final String ACTION = "org.openecomp.appc.action";
+
+ public static final String PAYLOAD = "payload";
+
+ public static final String CONF_ID = "org.openecomp.appc.confid";
+
+ public static final String API_VERSION = "org.openecomp.appc.apiversion";
+
+ public static final String ORIGINATOR_ID = "org.openecomp.appc.originatorid";
+
+ public static final String OBJECT_ID ="org.openecomp.appc.objectid";
+
+ public static final String SUB_REQUEST_ID = "org.openecomp.appc.subrequestid";
+
+ public static final String ERROR_MESSAGE = "error-message";
+
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java
new file mode 100644
index 000000000..6b197ef19
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java
@@ -0,0 +1,343 @@
+/*-
+ * ============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.workflow.impl;
+
+import java.text.SimpleDateFormat;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.appc.common.constant.Constants;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.domainmodel.lcm.RequestContext;
+import org.openecomp.appc.domainmodel.lcm.ResponseContext;
+import org.openecomp.appc.util.ObjectMapper;
+import org.openecomp.appc.workflow.WorkFlowManager;
+import org.openecomp.appc.workflow.objects.WorkflowExistsOutput;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.appc.workflow.objects.WorkflowResponse;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.provider.SvcLogicService;
+
+
+public class WorkFlowManagerImpl implements WorkFlowManager{
+ private SvcLogicService svcLogic = null;
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkFlowManagerImpl.class);
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ private final WorkflowResolver workflowResolver = new WorkflowResolver(
+ configuration.getIntegerProperty("org.openecomp.appc.workflow.resolver.refresh_interval", 300)
+ );
+
+ public void setSvcLogicServiceRef(SvcLogicService svcLogic) {
+ this.svcLogic = svcLogic;
+ }
+
+ /**
+ * Execute workflow and return response.
+ * This method execute workflow with following steps.
+ * Retrieve workflow(DG) details - module, version and mode from database based on command and vnf Type from incoming request.
+ * Execute workflow (DG) using SVC Logic Service reference
+ * Return response of workflow (DG) to caller.
+ *
+ * @param workflowRequest workflow execution request which contains vnfType, command, requestId, targetId, payload and (optional) confID;
+ * @return Workflow Response which contains execution status and payload from DG if any
+ */
+
+ @Override
+ public WorkflowResponse executeWorkflow(WorkflowRequest workflowRequest) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to executeWorkflow with WorkflowRequest = "+ ObjectUtils.toString(workflowRequest.toString()));
+ }
+ WorkflowResponse workflowResponse = new WorkflowResponse();
+ workflowResponse.setResponseContext(workflowRequest.getResponseContext());
+
+ try {
+
+
+ WorkflowKey workflowKey = workflowResolver.resolve(workflowRequest.getRequestContext().getAction().name(), workflowRequest.getVnfContext().getType(), null,workflowRequest.getRequestContext().getCommonHeader().getApiVer());
+
+ Properties workflowParams = new Properties();
+ String actionProperty = null;
+ String requestIdProperty=null;
+ String vfIdProperty =null;
+ if(!workflowRequest.getRequestContext().getCommonHeader().getApiVer().startsWith("1.")){
+ /*
+ The following method call (populateDGContext) populates DG context with the
+ request parameters to maintain backward compatibility with old DGs,
+ we are not altering the old way of passing (org.openecomp.appc.vnfId and so on..)
+ This is still a temporary solution, the end solution should be agreed with
+ all stakeholders and implemented.
+ */
+ populateDGContext(workflowParams,workflowRequest);
+ } else {
+ actionProperty = configuration.getProperty("org.openecomp.appc.workflow.action", String.valueOf(Constants.ACTION));
+ requestIdProperty = configuration.getProperty("org.openecomp.appc.workflow.request.id", String.valueOf(Constants.REQUEST_ID));
+ vfIdProperty = configuration.getProperty("org.openecomp.appc.workflow.vfid", String.valueOf(Constants.VF_ID));
+ String payloadProperty = configuration.getProperty("org.openecomp.appc.workflow.payload", String.valueOf(Constants.PAYLOAD));
+ String vfTypeProperty = configuration.getProperty("org.openecomp.appc.workflow.vftype", String.valueOf(Constants.VF_TYPE));
+ String apiVerProperty = configuration.getProperty("org.openecomp.appc.workflow.apiVersion", String.valueOf(Constants.API_VERSION));
+ String originatorIdProperty = configuration.getProperty("org.openecomp.appc.workflow.originatorId",Constants.ORIGINATOR_ID);
+ String subRequestId = configuration.getProperty("org.openecomp.appc.workflow.subRequestId",Constants.SUB_REQUEST_ID);
+
+ workflowParams.put(actionProperty,workflowRequest.getRequestContext().getAction().name());
+ workflowParams.put(requestIdProperty, workflowRequest.getRequestContext().getCommonHeader().getRequestId());
+ workflowParams.put(vfIdProperty, workflowRequest.getVnfContext().getId());
+ workflowParams.put(vfTypeProperty,workflowRequest.getVnfContext().getType());
+ workflowParams.put(apiVerProperty,workflowRequest.getRequestContext().getCommonHeader().getApiVer());
+ workflowParams.put(originatorIdProperty,workflowRequest.getRequestContext().getCommonHeader().getOriginatorId());
+ workflowParams.put(subRequestId,workflowRequest.getRequestContext().getCommonHeader().getSubRequestId());
+
+ Object payloadJson = workflowRequest.getRequestContext().getPayload();
+ if(payloadJson!=null) {
+ try {
+ Map<String, String> payloadProperties = ObjectMapper.map(payloadJson);
+ workflowParams.putAll(payloadProperties);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("DG properties: " + workflowParams);
+ }
+ } catch (Exception e) {
+ logger.error("Error parsing payload json string", e);
+ Properties workflowPrp = new Properties();
+ workflowPrp.setProperty("error-message", "Error parsing payload json string");
+ fillStatus(501, "Error parsing payload json string: "+e.getMessage(), workflowRequest.getResponseContext());
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from executeWorkflow with (workflowResponse = "+ObjectUtils.toString(workflowResponse)+")");
+ }
+ return workflowResponse;
+ }
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("DG parameters "+ actionProperty +":"+ workflowRequest.getRequestContext().getAction().name()+", "+
+ requestIdProperty +":"+ workflowRequest.getRequestContext().getCommonHeader().getRequestId()+", "+
+ vfIdProperty +":"+ workflowRequest.getVnfContext().getId());
+
+ logger.debug("Starting DG Execution for request "+workflowRequest.getRequestContext().getCommonHeader().getRequestId());
+ }
+ }
+ if (workflowRequest.getRequestContext().getCommonHeader().getApiVer().startsWith("1.")){
+ workflowParams.put("isBwcMode","true");
+ } else {
+ workflowParams.put("isBwcMode", "false");
+ }
+
+ SVCLogicServiceExecute(workflowKey, workflowRequest.getRequestContext(), workflowParams , workflowResponse);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Completed DG Execution for Request id: " + workflowRequest.getRequestContext().getCommonHeader().getRequestId() + "with response code: " + workflowResponse.getResponseContext().getStatus().getCode());
+ }
+ }catch (Exception e){
+ logger.error("Error Executing DG " +e.getMessage());
+ fillStatus(501, "Error Executing DG "+e.getMessage(), workflowRequest.getResponseContext());
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from executeWorkflow with (workflowResponse = "+ ObjectUtils.toString(workflowResponse.getResponseContext().getStatus().getMessage())+")");
+ }
+ return workflowResponse;
+ }
+
+ private void populateDGContext(Properties workflowParams, WorkflowRequest workflowRequest) {
+ workflowParams.put("input.common-header.timestamp",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(workflowRequest.getRequestContext().getCommonHeader().getTimeStamp()));
+ workflowParams.put("input.common-header.api-ver",workflowRequest.getRequestContext().getCommonHeader().getApiVer());
+ workflowParams.put("input.common-header.request-id",workflowRequest.getRequestContext().getCommonHeader().getRequestId());
+ workflowParams.put("input.common-header.originator-id",workflowRequest.getRequestContext().getCommonHeader().getOriginatorId());
+ workflowParams.put("input.common-header.sub-request-id",workflowRequest.getRequestContext().getCommonHeader().getSubRequestId());
+ workflowParams.put("input.action",workflowRequest.getRequestContext().getAction().toString());
+ workflowParams.put("input.payload",null != workflowRequest.getRequestContext().getPayload() ? workflowRequest.getRequestContext().getPayload() : "");
+ workflowParams.put("input.action-identifiers.vnf-id",workflowRequest.getVnfContext().getId());
+ workflowParams.put("input.action-identifiers.vnfc-name",workflowRequest.getRequestContext().getActionIdentifiers().getVnfcName()!=null?workflowRequest.getRequestContext().getActionIdentifiers().getVnfcName():"");
+ workflowParams.put("input.action-identifiers.service-instance-id",workflowRequest.getRequestContext().getActionIdentifiers().getServiceInstanceId()!=null?workflowRequest.getRequestContext().getActionIdentifiers().getServiceInstanceId():"");
+ workflowParams.put("input.action-identifiers.vserver-id",workflowRequest.getRequestContext().getActionIdentifiers().getVserverId()!=null?workflowRequest.getRequestContext().getActionIdentifiers().getVserverId():"");
+ final Map<String, String> additionalContext;
+ if ((additionalContext = workflowRequest.getRequestContext().getAdditionalContext())!=null) {
+ for (Map.Entry<String, String> entry : additionalContext.entrySet()) {
+ workflowParams.put("input." + entry.getKey(), null != entry.getValue() ? entry.getValue() : "");
+ }
+ }
+ }
+
+ /**
+ * Check if workflow (DG) exists in database
+ *
+ * @param workflowQueryParams workflow request with command and vnf Type
+ * @return True if workflow exists else False.
+ */
+ @Override
+ public WorkflowExistsOutput workflowExists(WorkflowRequest workflowQueryParams) {
+ WorkflowExistsOutput workflowExistsOutput = new WorkflowExistsOutput(false,false);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering to workflowExists with WorkflowRequest = "+ObjectUtils.toString(workflowQueryParams.toString()));
+ }
+
+ try {
+ WorkflowKey workflowKey = workflowResolver.resolve(
+ workflowQueryParams.getRequestContext().getAction().name(),
+ workflowQueryParams.getVnfContext().getType(),
+ workflowQueryParams.getVnfContext().getVersion(),
+ workflowQueryParams.getRequestContext().getCommonHeader().getApiVer());
+ if (workflowKey != null) {
+ workflowExistsOutput.setMappingExist(true);
+ workflowExistsOutput.setWorkflowModule(workflowKey.module());
+ workflowExistsOutput.setWorkflowName(workflowKey.name());
+ workflowExistsOutput.setWorkflowVersion(workflowKey.version());
+ if (isDGExists(workflowKey)) {
+ workflowExistsOutput.setDgExist(true);
+ }else{
+ logger.warn(
+ String.format("SLI doesn't have DG for resolved mapping entry: DG module - '%s', DG name - '%s', DG version - '%s'",
+ workflowKey.module(), workflowKey.name(), workflowKey.version()));
+ }
+ }else{
+ logger.warn(
+ String.format("Unable to resolve recipe matching action '%s', VNF type '%s' and VNF version '%s'",
+ workflowQueryParams.getRequestContext().getAction().name(), workflowQueryParams.getVnfContext().getType(), null));
+ }
+ } catch (RuntimeException e) {
+ logger.error("Error querying workflow from database"+e.getMessage());
+ throw e;
+ }catch (SvcLogicException e) {
+ logger.error("Error querying workflow from database"+e.getMessage());
+ throw new RuntimeException(e);
+ }
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting workflowExists");
+ }
+ return workflowExistsOutput;
+ }
+
+
+ private boolean isDGExists(WorkflowKey workflowKey) throws SvcLogicException {
+ return svcLogic.hasGraph(workflowKey.module(), workflowKey.name(), workflowKey.version(), "sync");
+ }
+
+ private void SVCLogicServiceExecute(WorkflowKey workflowKey, RequestContext requestContext, Properties workflowParams, WorkflowResponse workflowResponse) {
+ if (logger.isTraceEnabled()) {
+ logger.trace("Entering SVCLogicServiceExecute");
+ }
+
+ Properties respProps = null;
+
+ try {
+ respProps = svcLogic.execute(workflowKey.module(), workflowKey.name(), workflowKey.version(), "sync", workflowParams);
+ } catch (Exception e) {
+ setWorkFlowResponseStatus(workflowResponse.getResponseContext(), "failure", "Unexpected SLI Adapter failure", 200);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Error while executing DG " + e.getMessage() + e.getStackTrace());
+ }
+ logger.error("Error in DG", e.getMessage()+e.getStackTrace().toString());
+ }
+
+ if (respProps != null) {
+ if (!requestContext.getCommonHeader().getApiVer().startsWith("1.")) {
+ fillResponseContextByOutputFieldsFromDgContext(workflowResponse.getResponseContext(), respProps);
+ }
+
+ final String commonStatus = respProps.getProperty(Constants.DG_ATTRIBUTE_STATUS);
+ final String specificStatusMessage = respProps.getProperty(Constants.DG_OUTPUT_STATUS_MESSAGE);
+ String dgOutputStatusCode = respProps.getProperty(Constants.DG_OUTPUT_STATUS_CODE);
+ int specificStatusCode = 0;
+ if (dgOutputStatusCode != null) {
+ specificStatusCode = Integer.parseInt(dgOutputStatusCode);
+ }
+
+ setWorkFlowResponseStatus(workflowResponse.getResponseContext(), commonStatus, specificStatusMessage, specificStatusCode);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("DG Execution Status: " + commonStatus);
+ }
+ }
+
+ if (logger.isTraceEnabled()) {
+ logger.trace("Exiting from SVCLogicServiceExecute");
+ }
+ }
+
+ /**
+ * Filling response context by output.* fields from DG context. Works only for 2.* API version
+ *
+ * @param responseContext response context which you need to fill
+ * @param respProps DG context in a properties format
+ */
+ private void fillResponseContextByOutputFieldsFromDgContext(ResponseContext responseContext, Properties respProps) {
+
+ Enumeration<?> e = respProps.propertyNames();
+ while (e.hasMoreElements()){
+ String key = (String) e.nextElement();
+ if (key.startsWith("output.")){
+ if (!key.startsWith("output.common-header.") && !key.startsWith("output.status.")){
+
+ if (key.equalsIgnoreCase("output.payload")){
+ responseContext.setPayload(respProps.getProperty(key));
+ } else {
+ responseContext.addKeyValueToAdditionalContext(key, respProps.getProperty(key));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Filling responceContext status code amd message according to responce messages and codes from DG.
+ *
+ * @param responseContext response cotext
+ * @param commonStatus common status message from DG ("success" or "failure")
+ * @param specificStatusMessage specific status message from specific DG node
+ * @param specificStatusCode specific status code from specific DG node
+ */
+ private void setWorkFlowResponseStatus(ResponseContext responseContext, String commonStatus, String specificStatusMessage, int specificStatusCode) {
+ if (null == specificStatusMessage) { specificStatusMessage = ""; }
+ if (commonStatus.equalsIgnoreCase(Constants.DG_STATUS_SUCCESS)){
+ if (specificStatusCode != 0 ){
+ fillStatus(specificStatusCode, specificStatusMessage, responseContext);
+ } else {
+ fillStatus(400, commonStatus, responseContext);
+ }
+ } else {
+ String errorMsg = StringUtils.isEmpty(specificStatusMessage) ? "DG execution failure" : specificStatusMessage;
+ if (specificStatusCode != 0){
+ fillStatus(specificStatusCode, specificStatusMessage, responseContext);
+ } else {
+ fillStatus(401, specificStatusMessage, responseContext);
+ }
+ }
+ }
+
+ /**
+ * filling responseContext by status code and status message
+ *
+ * @param code 3-digit status code
+ * @param message explanation of a status code
+ * @param responceContext response context which will be store status code and status message
+ */
+ private void fillStatus(int code, String message, ResponseContext responceContext) {
+ responceContext.getStatus().setCode(code);
+ responceContext.getStatus().setMessage(message);
+ }
+
+
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.java
new file mode 100644
index 000000000..b0f68f8c6
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowKey.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.workflow.impl;
+
+class WorkflowKey {
+ private final String name;
+ private final String version;
+ private final String module;
+
+ WorkflowKey(String name, String version, String module) {
+ this.name = name;
+ this.version = version;
+ this.module = module;
+ }
+
+ String name() {
+ return name;
+ }
+
+ String version() {
+ return version;
+ }
+
+ String module() {
+ return module;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buff = new StringBuilder(128);
+ buff.append("{");
+ buff.append("module = ").append(module);
+ buff.append(", ");
+ buff.append("name = ").append(name);
+ buff.append(", ");
+ buff.append("version = ").append(version);
+ buff.append("}");
+ return buff.toString();
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java
new file mode 100644
index 000000000..1c8fb5738
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolver.java
@@ -0,0 +1,139 @@
+/*-
+ * ============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.workflow.impl;
+
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.openecomp.appc.rankingframework.RankedAttributesContext;
+import org.openecomp.appc.rankingframework.RankedAttributesResolver;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+class WorkflowResolver {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkFlowManagerImpl.class);
+
+ private long interval;
+
+ private volatile long lastUpdate = 0l;
+ private volatile boolean isUpdateInProgress = false;
+ private volatile RankedAttributesResolver<WorkflowKey> dgResolver;
+
+ private final ReentrantLock INIT_LOCK = new ReentrantLock();
+
+ WorkflowResolver(int interval) {
+ this.interval = interval * 1000;
+ }
+
+ private RankedAttributesResolver<WorkflowKey> createResolver() {
+ WorkflowResolverDataReader reader = new WorkflowResolverDataReader();
+ return reader.read();
+ }
+
+ private boolean isExpired() {
+ return (System.currentTimeMillis() - lastUpdate) > interval;
+ }
+
+ private RankedAttributesResolver<WorkflowKey> resolver() {
+
+ /*
+ * In general case, the method implementation is non-blocking. The first
+ * thread that identifies data expiration will be used to refresh it. In
+ * meanwhile, any other thread will get the old instance without waiting
+ * for the updated one. The only exception is the very first time when
+ * previous instance doesn't exist - in such a cases all the threads
+ * will be waiting on INIT_LOCK while one of them initializes the
+ * resolver instance. NOTE: The initialization is intentionally
+ * implemented in lazy manner to make sure the bundle is initialized
+ * properly on startup regardless whether or not the data is correct.
+ * Afterwards, the resolver may be instantiated as many times as needed.
+ */
+
+ try {
+
+ if (dgResolver == null) {
+ INIT_LOCK.lock();
+ if (dgResolver != null) {
+ INIT_LOCK.unlock();
+ }
+ }
+
+ if (!isUpdateInProgress && isExpired()) {
+
+ boolean doUpgrade = false;
+
+ synchronized (this) {
+ if (!isUpdateInProgress) {
+ isUpdateInProgress = true;
+ doUpgrade = true;
+ }
+ }
+
+ if (doUpgrade) {
+
+ logger.info("DG resolver configuration data has expired - initiating refresh");
+
+ try {
+ RankedAttributesResolver<WorkflowKey> temp = createResolver();
+ dgResolver = temp;
+ lastUpdate = System.currentTimeMillis();
+
+ logger.info("DG resolver configuration data has been refreshed successfully");
+ } finally {
+ isUpdateInProgress = false;
+ }
+ }
+ }
+ } finally {
+ if (INIT_LOCK.isHeldByCurrentThread()) {
+ INIT_LOCK.unlock();
+ }
+ }
+
+ return dgResolver;
+ }
+
+ WorkflowKey resolve(final String action, final String vnfType, final String vnfVersion,final String apiVersion) {
+
+ RankedAttributesContext context = new RankedAttributesContext() {
+ @Override
+ public Object getAttributeValue(String name) {
+ switch (name) {
+ case "action":
+ return action;
+ case "api_version":
+ return apiVersion;
+ case "vnf_type":
+ return vnfType;
+ case "vnf_version":
+ return vnfVersion;
+ default:
+ throw new IllegalStateException(name);
+ }
+ }
+ };
+
+ WorkflowKey wfKey = resolver().resolve(context);
+
+ return wfKey;
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java
new file mode 100644
index 000000000..3ffeddcdf
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkflowResolverDataReader.java
@@ -0,0 +1,128 @@
+/*-
+ * ============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.workflow.impl;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.openecomp.appc.dao.util.DBUtils;
+import org.openecomp.appc.rankingframework.AbstractRankedAttributesResolverFactory;
+import org.openecomp.appc.rankingframework.ConfigurationEntry;
+import org.openecomp.appc.rankingframework.ConfigurationSet;
+import org.openecomp.appc.rankingframework.RankedAttributesResolver;
+
+class WorkflowResolverDataReader {
+
+ private static final String QUERY_STMT = "SELECT action,api_version,vnf_type,vnf_version,dg_name,dg_version,dg_module FROM VNF_DG_MAPPING";
+
+ private static final Collection<String> ATTRIBUTE_NAMES = Arrays.asList("action","api_version", "vnf_type", "vnf_version");
+
+ private static class ConfigurationSetAdaptor implements ConfigurationSet<WorkflowKey> {
+
+ private final ResultSet resultSet;
+
+ private class ResultSetIterator implements Iterator<ConfigurationEntry<WorkflowKey>>, ConfigurationEntry<WorkflowKey> {
+ @Override
+ public boolean hasNext() {
+ try {
+ return resultSet.next();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public ConfigurationEntry<WorkflowKey> next() {
+ return this;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object getAttributeValue(String name) {
+ try {
+ return resultSet.getObject(name);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public WorkflowKey getResult() {
+ try {
+ return new WorkflowKey(resultSet.getString("dg_name"), resultSet.getString("dg_version"), resultSet.getString("dg_module"));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ ConfigurationSetAdaptor(ResultSet resultSet) {
+ this.resultSet = resultSet;
+ }
+
+ @Override
+ public Iterable<ConfigurationEntry<WorkflowKey>> getEntries() {
+ return new Iterable<ConfigurationEntry<WorkflowKey>>() {
+
+ @Override
+ public Iterator<ConfigurationEntry<WorkflowKey>> iterator() {
+ return new ResultSetIterator();
+ }
+ };
+ }
+
+ @Override
+ public Collection<String> getRankedAttributeNames() {
+ return ATTRIBUTE_NAMES;
+ }
+ }
+
+ RankedAttributesResolver<WorkflowKey> read() {
+ try {
+ try (Connection conn = DBUtils.getConnection("sdnctl")) {
+ try (PreparedStatement stmt = conn.prepareStatement(QUERY_STMT)) {
+ try (ResultSet res = stmt.executeQuery()) {
+ if (res.next()) {
+ res.beforeFirst();
+ ConfigurationSet<WorkflowKey> resolverConfig = new ConfigurationSetAdaptor(res);
+ return AbstractRankedAttributesResolverFactory.getInstance().create(resolverConfig);
+ } else {
+ // TODO: Return empty object
+ throw new IllegalStateException();
+ }
+ }
+ }
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
new file mode 100644
index 000000000..a03984a38
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -0,0 +1,35 @@
+<?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">
+
+ <reference id="svcLogicServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.provider.SvcLogicService" />
+
+ <bean id="workflowManagementBean" class="org.openecomp.appc.workflow.impl.WorkFlowManagerImpl" scope="singleton">
+ <property name="svcLogicServiceRef" ref="svcLogicServiceRef" />
+ </bean>
+
+ <service id="workflowManagementService" interface="org.openecomp.appc.workflow.WorkFlowManager" ref="workflowManagementBean" />
+
+</blueprint>
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..44745d049
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties
@@ -0,0 +1,52 @@
+###
+# ============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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+
+#Property below provided by appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT-WF-MGMT-MAIN
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=1
+dmaap.threads.poolsize.max=2
+
+# Tolerance interval (in seconds) between invalidation of DG resolver configuration
+org.openecomp.appc.workflow.resolver.refresh_interval=300
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java
new file mode 100644
index 000000000..0a4b0de76
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/java/org/openecomp/appc/workflow/TestWorkFlowManager.java
@@ -0,0 +1,186 @@
+/*-
+ * ============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.workflow;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.openecomp.appc.workflow.impl.WorkFlowManagerImpl;
+import org.openecomp.appc.workflow.objects.WorkflowRequest;
+import org.openecomp.sdnc.sli.SvcLogicException;
+import org.openecomp.sdnc.sli.SvcLogicGraph;
+import org.openecomp.sdnc.sli.SvcLogicNode;
+import org.openecomp.sdnc.sli.SvcLogicStore;
+import org.openecomp.sdnc.sli.provider.SvcLogicActivator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest( {SvcLogicActivator.class, FrameworkUtil.class, WorkFlowManagerImpl.class} )
+public class TestWorkFlowManager {
+ public TestWorkFlowManager() {
+ }
+
+ private WorkFlowManagerImpl workflowManger ;
+ private String command="Configure";
+ protected SvcLogicGraph svcLogicGraph=null;
+
+
+ //
+ private final SvcLogicStore svcLogicStore= Mockito.mock(SvcLogicStore.class);
+ private final BundleContext bundleContext=Mockito.mock(BundleContext.class);
+ private final Bundle bundleSvcLogicService=Mockito.mock(Bundle.class);
+ private final ServiceReference serviceReferenceSvcLogicService=Mockito.mock(ServiceReference.class);
+
+
+
+ @Before
+ public void setupMock() throws Exception {
+ /*
+ // DAO Mock
+ dao = Mockito.mock(AppcDAOImpl.class);
+ PowerMockito.whenNew(AppcDAOImpl.class).withNoArguments().thenReturn(dao);
+
+ // SVC Logic Mock
+ SvcLogicServiceImpl svcLogicService=new SvcLogicServiceImpl();
+ PowerMockito.mockStatic(SvcLogicActivator.class);
+ PowerMockito.mockStatic(FrameworkUtil.class);
+ PowerMockito.when(SvcLogicActivator.getStore()).thenReturn(svcLogicStore);
+ PowerMockito.when(FrameworkUtil.getBundle(SvcLogicService.class)).thenReturn(bundleSvcLogicService);
+ PowerMockito.when(bundleSvcLogicService.getBundleContext()).thenReturn(bundleContext);
+ PowerMockito.when(bundleContext.getServiceReference(SvcLogicService.NAME)).thenReturn(serviceReferenceSvcLogicService);
+ PowerMockito.when(bundleContext.getService(serviceReferenceSvcLogicService)).thenReturn(svcLogicService);
+
+ try {
+ PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Configure"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Configure"));
+ PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Restart"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Restart"));
+ PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Test"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Test"));
+ PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Rebuild"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Rebuild"));
+ PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Terminate"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Terminate"));
+ PowerMockito.when(svcLogicStore.fetch(anyString(), eq("FIREWALL_Start"), anyString(), anyString())).thenReturn(createGraph("FIREWALL_Start"));
+ svcLogicService.registerExecutor("switch", new SwitchNodeExecutor());
+ svcLogicService.registerExecutor("execute",new ReturnNodeExecutor());
+ svcLogicService.registerExecutor("return",new ReturnNodeExecutor());
+ } catch (SvcLogicException e) {
+ e.printStackTrace();
+ }
+
+ workflowManger = new WorkFlowManagerImpl();
+
+ PowerMockito.when(getDao().retrieveWorkflowDetails("FIREWALL","Configure")).thenReturn(getWorkflow());
+ PowerMockito.when(getDao().retrieveWorkflowDetails("FIREWALL","")).thenThrow(new DAOException());
+ PowerMockito.when(getDao().retrieveWorkflowDetails("","Configure")).thenThrow(new DAOException());
+ */
+ }
+
+ @Test
+ public void testEmptyVnfTypeFlow(){
+ /*
+ WorkflowRequest workflowRequest = getWorkflowRequest("","1","1",command);
+ setSvcLogicGraph(createGraph(""+"_"+command));
+ WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest);
+ assertFalse(response.isExecutionSuccess());
+ */
+ }
+
+ /*
+ @Test
+ public void testExecuteWorkflow(){
+ //PowerMockito.when(getDao().retrieveWorkflowDetails(anyString(),anyString())).thenReturn(getWorkflow());
+ WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command);
+ setSvcLogicGraph(createGraph("FIREWALL"+"_"+command));
+ WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest);
+ assertFalse(response.isExecutionSuccess());
+ }
+
+ @Test
+ public void testExecuteWorkflowEmptyPayload(){
+ //PowerMockito.when(getDao().retrieveWorkflowDetails(anyString(),anyString())).thenReturn(getWorkflow());
+ WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command);
+ workflowRequest.setPayload("{payload:\"payload\"}");
+ setSvcLogicGraph(createGraph(""+"_"+command));
+ WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest);
+ assertFalse(response.isExecutionSuccess());
+ }
+
+ @Test
+ public void testWorkflowExist(){
+ //PowerMockito.when(getDao().queryWorkflow(anyString(),anyString())).thenReturn(true);
+ WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command);
+ boolean success = workflowManger.workflowExists(workflowRequest);
+ assertTrue(success);
+ }
+
+ @Test
+ public void testWorkflowExistFalse(){
+ //PowerMockito.when(getDao().queryWorkflow(anyString(),anyString())).thenReturn(false);
+ WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1",command);
+ setSvcLogicGraph(createGraph(""+"_"+command));
+ boolean success = workflowManger.workflowExists(workflowRequest);
+ assertFalse(success);
+ }
+
+
+ @Test
+ public void testEmptyCommandFlow(){
+ WorkflowRequest workflowRequest = getWorkflowRequest("FIREWALL","1","1","");
+ WorkflowResponse response =workflowManger.executeWorkflow(workflowRequest);
+ assertFalse(response.isExecutionSuccess());
+ }
+ */
+
+
+ public void setSvcLogicGraph(SvcLogicGraph svcLogicGraph) {
+ this.svcLogicGraph = svcLogicGraph;
+ }
+
+ public SvcLogicGraph getSvcLogicGraph() {
+ return svcLogicGraph;
+ }
+
+ protected SvcLogicGraph createGraph(String rpc) {
+ SvcLogicGraph svcLogicGraph = new SvcLogicGraph();
+ svcLogicGraph.setModule("APPC");
+ svcLogicGraph.setRpc(rpc);
+ svcLogicGraph.setMode("sync");
+ svcLogicGraph.setVersion("2.0.0");
+ SvcLogicNode svcLogicRootNode = new SvcLogicNode(1, "switch", svcLogicGraph);
+ SvcLogicNode svcLogicConfigureNode = new SvcLogicNode(2, "return", svcLogicGraph);
+ SvcLogicNode svcLogicOtherNode = new SvcLogicNode(3, "return", svcLogicGraph);
+ try {
+ svcLogicConfigureNode.setAttribute("status", "success");
+ svcLogicOtherNode.setAttribute("status", "failure");
+ svcLogicRootNode.setAttribute("test", "$org.openecomp.appc.action");
+ svcLogicRootNode.addOutcome("Configure", svcLogicConfigureNode);
+ svcLogicRootNode.addOutcome("Other", svcLogicOtherNode);
+ } catch (SvcLogicException e) {
+ e.printStackTrace();
+ }
+ svcLogicGraph.setRootNode(svcLogicRootNode);
+ return svcLogicGraph;
+ }
+}
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties
new file mode 100644
index 000000000..713e03430
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties
@@ -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=========================================================
+###
+
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options
+#org.openecomp.appc.bootstrap.file=executor-test.properties
+org.openecomp.appc.bootstrap.file=appc.properties
+org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},.
+
+
+#
+# Certificate keystore and truststore
+#
+#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE>
+#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin
+#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE>
+#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin
+org.openecomp.sdnc.sli.aai.host.certificate.ignore=true
+org.openecomp.sdnc.sli.aai.certificate.trust.all=true
+
+#
+# Configuration file for A&AI Adapter
+#
+
+# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT
+org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443
+
+org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query
+
+# service instance
+org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances
+org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance
+
+# complex
+org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes
+org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id}
+
+# vservers
+org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers
+org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id}
+
+# generic-vnf
+org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/
+org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id}
+
+#
+# Formatting
+#
+org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s
+org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type
+org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id
+org.openecomp.sdnc.sli.aai.param.service.type=service-type
+
+
+org.openecomp.appc.logging.path=${user.home},etc,../etc,.
+org.openecomp.appc.logging.file=logback.xml
+
+org.openecomp.appc.db.url.%s", schema), "");
+org.openecomp.appc.db.user.%s", schema), "");
+org.openecomp.appc.db.pass.%s", schema), "");
+
+# This value is provided in appc.properties
+#dmaap.poolMembers=<DMAAP_IP>:3904
+
+dmaap.topic.read=APPC-TEST2
+dmaap.topic.write=APPC-TEST2
+#dmaap.topic.read.filter={"class":"Assigned","field":"request"}
+dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]}
+dmaap.client.name=APPC-TEST-CLIENT
+dmaap.client.name.id=0
+#dmaap.client.key=random
+#dmaap.client.secret=random
+
+dmaap.threads.queuesize.min=1
+dmaap.threads.queuesize.max=1000
+dmaap.threads.poolsize.min=2
+dmaap.threads.poolsize.max=2
+
+#
+# This needs to be changed so that the action can be appended to the end of the URL path
+#
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service
+#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/pom.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/pom.xml
new file mode 100644
index 000000000..93ea295ab
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-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>appc-workflow-management</artifactId>
+ <groupId>org.openecomp.appc</groupId>
+ <version>1.0.0</version>
+ </parent>
+ <name>appc-workflow-management-features</name>
+ <artifactId>appc-workflow-management-features</artifactId>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.appc</groupId>
+ <artifactId>appc-workflow-management-core</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-workflow-management/appc-workflow-management-features/src/main/resources/features.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml
new file mode 100644
index 000000000..ae1105d2b
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml
@@ -0,0 +1,34 @@
+<?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="appc-workflow-management-${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='appc-workflow-management' description="application executor" version='${project.version}'>
+ <bundle>mvn:org.openecomp.appc/appc-workflow-management-api/${project.version}</bundle>
+ <bundle>mvn:org.openecomp.appc/appc-workflow-management-core/${project.version}</bundle>
+ <bundle start="true" dependency="true">mvn:org.openecomp.appc/appc-ranking-framework-lib/${project.version}</bundle>
+ </feature>
+
+</features>
diff --git a/appc-dispatcher/appc-workflow-management/pom.xml b/appc-dispatcher/appc-workflow-management/pom.xml
new file mode 100644
index 000000000..63b8b4ee7
--- /dev/null
+++ b/appc-dispatcher/appc-workflow-management/pom.xml
@@ -0,0 +1,22 @@
+<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-workflow-management</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC Workflow Management</name>
+ <description>APPC Workflow Management</description>
+
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-workflow-management-api</module>
+ <module>appc-workflow-management-core</module>
+ <module>appc-workflow-management-features</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/appc-dispatcher/pom.xml b/appc-dispatcher/pom.xml
new file mode 100644
index 000000000..c8c851f75
--- /dev/null
+++ b/appc-dispatcher/pom.xml
@@ -0,0 +1,78 @@
+<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</artifactId>
+ <version>1.0.0</version>
+ </parent>
+ <artifactId>appc-dispatcher</artifactId>
+ <packaging>pom</packaging>
+ <name>APPC Dispatcher</name>
+ <description>APPC Dispatcher</description>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>1.6.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>1.6.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.objenesis</groupId>
+ <artifactId>objenesis</artifactId>
+ <version>2.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.3.7</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <!-- ================================================================================== -->
+ <!-- The modules we build -->
+ <!-- ================================================================================== -->
+ <modules>
+ <module>appc-dispatcher-common</module>
+ <module>appc-lifecycle-management</module>
+ <module>appc-workflow-management</module>
+ <module>appc-command-executor</module>
+ <module>appc-request-handler</module>
+ <module>appc-license-manager</module>
+ <module>appc-dispatcher-features</module>
+ <module>appc-dispatcher-installer</module>
+ </modules>
+
+</project>