aboutsummaryrefslogtreecommitdiffstats
path: root/appc-dispatcher/appc-workflow-management
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/appc-workflow-management
parentc69ba05c7508aa7d7f675189a45c8c87569369ef (diff)
Moving all files to root directory
Change-Id: Ica5535fd6ec85f350fe1640b42137b49f83f10f0 Signed-off-by: Patrick Brady <pb071s@att.com>
Diffstat (limited to 'appc-dispatcher/appc-workflow-management')
-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
25 files changed, 1667 insertions, 0 deletions
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