diff --git a/adapters/mso-vnf-adapter/README.md b/adapters/mso-vnf-adapter/README.md
new file mode 100644
index 0000000..2085fc9
--- /dev/null
+++ b/adapters/mso-vnf-adapter/README.md
@@ -0,0 +1,11 @@
+This artifact is the MSO VNF adapter.  It serves both SOAP and REST requests to the following URLs:
+
+  * http://host:port/vnfs/VnfAdapter?wsdl
+  * http://host:port/vnfs/VnfAdapterAsync?wsdl
+  * http://host:port/vnfs/rest/v1/vnfs/healthcheck
+  * http://host:port/vnfs/rest/v1/vnfs/{aaiVnfId}/vf-modules
+  * http://host:port/vnfs/rest/v1/vnfs/{aaiVnfId}/vf-modules/{aaiVfModuleId}
+  * http://host:port/vnfs/rest/v1/vnfs/{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback
+  * http://host:port/vnfs/rest/v1/volume-groups
+  * http://host:port/vnfs/rest/v1/volume-groups/{aaiVolumeGroupId}
+  * http://host:port/vnfs/rest/v1/volume-groups/{aaiVolumeGroupId}/rollback
diff --git a/adapters/mso-vnf-adapter/WebContent/META-INF/MANIFEST.MF b/adapters/mso-vnf-adapter/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ b/adapters/mso-vnf-adapter/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+
diff --git a/adapters/mso-vnf-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector b/adapters/mso-vnf-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector
new file mode 100644
index 0000000..1281d32
--- /dev/null
+++ b/adapters/mso-vnf-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector
@@ -0,0 +1 @@
+com.woorea.openstack.connector.HttpClientConnector
\ No newline at end of file
diff --git a/adapters/mso-vnf-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml b/adapters/mso-vnf-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..58ddb4a
--- /dev/null
+++ b/adapters/mso-vnf-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml
@@ -0,0 +1,16 @@
+<jboss-deployment-structure>
+	<deployment>
+		<!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
+		<exclusions>
+			<module name="org.apache.log4j" />
+			<module name="org.slf4j" />
+			<module name="org.slf4j.impl" />
+		</exclusions>
+		<dependencies>
+			    <module name="org.jboss.jandex" slot="main" />
+                <module name="org.javassist" slot="main" />
+                <module name="org.antlr" slot="main" />
+                <module name="org.dom4j" slot="main" />
+		</dependencies>
+	</deployment>
+</jboss-deployment-structure>
\ No newline at end of file
diff --git a/adapters/mso-vnf-adapter/WebContent/WEB-INF/jboss-web.xml b/adapters/mso-vnf-adapter/WebContent/WEB-INF/jboss-web.xml
new file mode 100644
index 0000000..6224f07
--- /dev/null
+++ b/adapters/mso-vnf-adapter/WebContent/WEB-INF/jboss-web.xml
@@ -0,0 +1,3 @@
+<jboss-web>
+	<context-root>vnfs</context-root>
+</jboss-web>
\ No newline at end of file
diff --git a/adapters/mso-vnf-adapter/WebContent/WEB-INF/web.xml b/adapters/mso-vnf-adapter/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000..3a50781
--- /dev/null
+++ b/adapters/mso-vnf-adapter/WebContent/WEB-INF/web.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
+  <display-name>mso-vnf-adapter</display-name>
+
+  <context-param>
+	<param-name>resteasy.jndi.resources</param-name>
+	<param-value>java:module/MsoPropertiesFactory,java:module/CloudConfigFactory</param-value>
+  </context-param>
+
+  <context-param>
+    <param-name>log.configuration</param-name>
+    <param-value>logback.vnf.xml</param-value>
+  </context-param>
+  <context-param>
+    <param-name>mso.configuration</param-name>
+    <param-value>MSO_PROP_VNF_ADAPTER=mso.vnf.properties,MSO_PROP_TOPOLOGY=topology.properties</param-value>
+  </context-param>
+  <context-param>
+  	<param-name>mso.cloud_config.configuration</param-name>
+  	<param-value>cloud_config.json=2</param-value>
+  </context-param>
+  <context-param>
+    <param-name>resteasy.resources</param-name>
+    <param-value>
+	org.openecomp.mso.MsoStatusHandler,
+	org.openecomp.mso.logger.MsoLoggingServlet,
+	org.openecomp.mso.adapters.vnf.HealthCheckHandler,
+	org.openecomp.mso.adapters.vnf.VnfAdapterRest,
+	org.openecomp.mso.adapters.vnf.VolumeAdapterRest
+    </param-value>
+  </context-param>
+  <context-param>
+    <param-name>resteasy.servlet.mapping.prefix</param-name>
+    <param-value>/rest</param-value>
+  </context-param>
+  <servlet>
+    <servlet-name>Resteasy</servlet-name>
+    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>Resteasy</servlet-name>
+    <url-pattern>/rest/*</url-pattern>
+  </servlet-mapping>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>RestRequests</web-resource-name>
+            <description>Rest Ingress Requests</description>
+            <url-pattern>/rest/v1/*</url-pattern>
+            <http-method>POST</http-method>
+            <http-method>GET</http-method>
+            <http-method>PUT</http-method>
+            <http-method>DELETE</http-method>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>BPEL-Client</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>SoapRequests</web-resource-name>
+            <description>Soap Ingress Requests</description>
+            <url-pattern>/VnfAdapter</url-pattern>
+            <url-pattern>/VnfAdapterAsync</url-pattern>
+            <http-method>POST</http-method>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>BPEL-Client</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>SiteStatus</web-resource-name>
+            <description>SiteStatus APIs</description>
+            <url-pattern>/rest/setStatus/*</url-pattern>
+            <http-method>POST</http-method>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>SiteControl-Client</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>ApplicationRealm</realm-name>
+    </login-config>
+    <security-role>
+        <role-name>BPEL-Client</role-name>
+    </security-role>
+    <security-role>
+        <role-name>SiteControl-Client</role-name>
+    </security-role>
+
+    <filter>
+		<filter-name>LogFilter</filter-name>
+		<filter-class>org.openecomp.mso.logger.LogFilter</filter-class>
+  </filter>
+    <filter-mapping>
+		<filter-name>LogFilter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+</web-app>
diff --git a/adapters/mso-vnf-adapter/WebContent/check.html b/adapters/mso-vnf-adapter/WebContent/check.html
new file mode 100644
index 0000000..00f37d6
--- /dev/null
+++ b/adapters/mso-vnf-adapter/WebContent/check.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="ISO-8859-1">
+<title>Health Check</title>
+</head>
+<body>
+Application ready
+</body>
+</html>
\ No newline at end of file
diff --git a/adapters/mso-vnf-adapter/pom.xml b/adapters/mso-vnf-adapter/pom.xml
new file mode 100644
index 0000000..1914eb1
--- /dev/null
+++ b/adapters/mso-vnf-adapter/pom.xml
@@ -0,0 +1,159 @@
+<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.mso</groupId>
+		<artifactId>adapters</artifactId>
+		<version>0.0.4-SNAPSHOT</version>
+	</parent>
+	<groupId>org.openecomp.mso.adapters</groupId>
+	<artifactId>mso-vnf-adapter</artifactId>
+	<packaging>war</packaging>
+	<name>mso-vnf-adapter</name>
+	<description>Web Service and REST endpoint for VNF operations</description>
+
+	<build>
+		<finalName>${project.artifactId}-${project.version}</finalName>
+		<plugins>
+			<plugin>
+				<artifactId>maven-war-plugin</artifactId>
+				<version>2.4</version>
+				<configuration>
+					<warSourceDirectory>WebContent</warSourceDirectory>
+					<failOnMissingWebXml>false</failOnMissingWebXml>
+					<attachClasses>true</attachClasses>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.jvnet.jax-ws-commons</groupId>
+				<artifactId>jaxws-maven-plugin</artifactId>
+				<version>2.3</version>
+				<executions>
+					<execution>
+					    <id>Synch</id>
+						<goals>
+							<goal>wsgen</goal>
+						</goals>
+						<configuration>
+							<verbose>true</verbose>
+							<sei>org.openecomp.mso.adapters.vnf.MsoVnfAdapterImpl</sei>
+							<genWsdl>true</genWsdl>
+							<inlineSchemas>true</inlineSchemas>
+						</configuration>
+					</execution>
+					<execution>
+					        <id>Asynch</id>
+						<goals>
+							<goal>wsgen</goal>
+						</goals>
+						<configuration>
+							<verbose>true</verbose>
+							<sei>org.openecomp.mso.adapters.vnf.MsoVnfAdapterAsyncImpl</sei>
+							<genWsdl>true</genWsdl>
+							<inlineSchemas>true</inlineSchemas>
+						</configuration>
+					</execution>
+				</executions>
+				<dependencies>
+					<dependency>
+						<groupId>org.openecomp.mso.adapters</groupId>
+						<artifactId>mso-adapter-utils</artifactId>
+						<version>${project.version}</version>
+					</dependency>
+					<dependency>
+						<groupId>com.sun.xml.ws</groupId>
+						<artifactId>jaxws-tools</artifactId>
+						<version>2.2.7</version>
+					</dependency>
+				</dependencies>
+			</plugin>
+		</plugins>
+		<pluginManagement>
+			<plugins>
+				<!--This plugin's configuration is used to store Eclipse m2e settings
+					only. It has no influence on the Maven build itself. -->
+				<plugin>
+					<groupId>org.eclipse.m2e</groupId>
+					<artifactId>lifecycle-mapping</artifactId>
+					<version>1.0.0</version>
+					<configuration>
+						<lifecycleMappingMetadata>
+							<pluginExecutions>
+								<pluginExecution>
+									<pluginExecutionFilter>
+										<groupId>
+											org.jvnet.jax-ws-commons
+										</groupId>
+										<artifactId>
+											jaxws-maven-plugin
+										</artifactId>
+										<versionRange>
+											[2.3,)
+										</versionRange>
+										<goals>
+											<goal>wsgen</goal>
+										</goals>
+									</pluginExecutionFilter>
+									<action>
+										<ignore></ignore>
+									</action>
+								</pluginExecution>
+							</pluginExecutions>
+						</lifecycleMappingMetadata>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+	<dependencies>
+		<dependency>
+			<groupId>org.openecomp.mso.adapters</groupId>
+			<artifactId>mso-adapter-utils</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.openecomp.mso.adapters</groupId>
+			<artifactId>mso-adapters-rest-interface</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.openecomp.mso.adapters</groupId>
+			<artifactId>mso-vnf-adapter-async-client</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>javax</groupId>
+			<artifactId>javaee-web-api</artifactId>
+			<version>6.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.spec.javax.ejb</groupId>
+			<artifactId>jboss-ejb-api_3.2_spec</artifactId>
+			<version>1.0.0.Final</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.ejb3</groupId>
+			<artifactId>jboss-ejb3-ext-api</artifactId>
+			<version>2.2.0.Final</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.openecomp.mso</groupId>
+			<artifactId>status-control</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+
+		<!-- <dependency> -->
+		<!-- <groupId>org.openecomp.mso</groupId> -->
+		<!-- <artifactId>mso-catalog-db</artifactId> -->
+		<!-- <version>${project.version}</version> -->
+		<!-- </dependency> -->
+		<!-- <dependency> -->
+		<!-- <groupId>log4j</groupId> -->
+		<!-- <artifactId>log4j</artifactId> -->
+		<!-- <version>1.2.17</version> -->
+		<!-- </dependency> -->
+	</dependencies>
+</project>
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/BpelRestClient.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/BpelRestClient.java
new file mode 100644
index 0000000..e76aa40
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/BpelRestClient.java
@@ -0,0 +1,304 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.properties.MsoJavaProperties;
+import org.openecomp.mso.properties.MsoPropertiesException;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+/**
+ * This is the class that is used to POST replies from the MSO adapters to the BPEL engine.
+ * It can be configured via property file, or modified using the member methods.
+ * The properties to use are:
+ * org.openecomp.mso.adapters.vnf.bpelauth  encrypted authorization string to send to BEPL engine
+ * org.openecomp.mso.adapters.vnf.sockettimeout socket timeout value
+ * org.openecomp.mso.adapters.vnf.connecttimeout connect timeout value
+ * org.openecomp.mso.adapters.vnf.retrycount number of times to retry failed connections
+ * org.openecomp.mso.adapters.vnf.retryinterval interval (in seconds) between retries
+ * org.openecomp.mso.adapters.vnf.retrylist list of response codes that will trigger a retry (the special code
+ * 			900 means "connection was not established")
+ */
+public class BpelRestClient {
+	public  static final String MSO_PROP_VNF_ADAPTER     = "MSO_PROP_VNF_ADAPTER";
+	private static final String PROPERTY_DOMAIN          = "org.openecomp.mso.adapters.vnf";
+	private static final String BPEL_AUTH_PROPERTY       = PROPERTY_DOMAIN+".bpelauth";
+	private static final String SOCKET_TIMEOUT_PROPERTY  = PROPERTY_DOMAIN+".sockettimeout";
+	private static final String CONN_TIMEOUT_PROPERTY    = PROPERTY_DOMAIN+".connecttimeout";
+	private static final String RETRY_COUNT_PROPERTY     = PROPERTY_DOMAIN+".retrycount";
+	private static final String RETRY_INTERVAL_PROPERTY  = PROPERTY_DOMAIN+".retryinterval";
+	private static final String RETRY_LIST_PROPERTY      = PROPERTY_DOMAIN+".retrylist";
+	private static final String ENCRYPTION_KEY           = "aa3871669d893c7fb8abbcda31b88b4f";
+	private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+
+	/** Default socket timeout (in seconds) */
+	public static final int DEFAULT_SOCKET_TIMEOUT = 5;
+	/** Default connect timeout (in seconds) */
+	public static final int DEFAULT_CONNECT_TIMEOUT = 5;
+	/** By default, retry up to five times */
+	public static final int DEFAULT_RETRY_COUNT = 5;
+	/** Default interval to wait between retries (in seconds), negative means use backoff algorithm */
+	public static final int DEFAULT_RETRY_INTERVAL = -15;
+	/** Default list of response codes to trigger a retry */
+	public static final String DEFAULT_RETRY_LIST = "408,429,500,502,503,504,900";	// 900 is "connection failed"
+	/** Default credentials */
+	public static final String DEFAULT_CREDENTIALS = "";
+
+	// Properties of the BPEL client -- all are configurable
+	private int socketTimeout;
+	private int connectTimeout;
+	private int retryCount;
+	private int retryInterval;
+	private Set<Integer> retryList;
+	private String credentials;
+
+	// last response from BPEL engine
+	private int lastResponseCode;
+	private String lastResponse;
+
+	/**
+	 * Create a client to send results to the BPEL engine, using configuration from the
+	 * MSO_PROP_VNF_ADAPTER properties.
+	 */
+	public BpelRestClient() {
+		socketTimeout  = DEFAULT_SOCKET_TIMEOUT;
+		connectTimeout = DEFAULT_CONNECT_TIMEOUT;
+		retryCount     = DEFAULT_RETRY_COUNT;
+		retryInterval  = DEFAULT_RETRY_INTERVAL;
+		setRetryList(DEFAULT_RETRY_LIST);
+		credentials    = DEFAULT_CREDENTIALS;
+		lastResponseCode = 0;
+		lastResponse = "";
+
+		try {
+			MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+			MsoJavaProperties jp = msoPropertiesFactory.getMsoJavaProperties (MSO_PROP_VNF_ADAPTER);
+			socketTimeout  = jp.getIntProperty(SOCKET_TIMEOUT_PROPERTY, DEFAULT_SOCKET_TIMEOUT);
+			connectTimeout = jp.getIntProperty(CONN_TIMEOUT_PROPERTY,   DEFAULT_CONNECT_TIMEOUT);
+			retryCount     = jp.getIntProperty(RETRY_COUNT_PROPERTY,    DEFAULT_RETRY_COUNT);
+			retryInterval  = jp.getIntProperty(RETRY_INTERVAL_PROPERTY, DEFAULT_RETRY_INTERVAL);
+			setRetryList(jp.getProperty(RETRY_LIST_PROPERTY, DEFAULT_RETRY_LIST));
+			credentials    = jp.getEncryptedProperty(BPEL_AUTH_PROPERTY, DEFAULT_CREDENTIALS, ENCRYPTION_KEY);
+		} catch (MsoPropertiesException e) {
+			String error = "Unable to get properties:" + MSO_PROP_VNF_ADAPTER;
+			LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "Camunda", "", MsoLogger.ErrorCode.AvailabilityError, "MsoPropertiesException - Unable to get properties", e);
+		}
+	}
+
+	public int getSocketTimeout() {
+		return socketTimeout;
+	}
+
+	public void setSocketTimeout(int socketTimeout) {
+		this.socketTimeout = socketTimeout;
+	}
+
+	public int getConnectTimeout() {
+		return connectTimeout;
+	}
+
+	public void setConnectTimeout(int connectTimeout) {
+		this.connectTimeout = connectTimeout;
+	}
+
+	public int getRetryCount() {
+		return retryCount;
+	}
+
+	public void setRetryCount(int retryCount) {
+		if (retryCount < 0)
+			retryCount = DEFAULT_RETRY_COUNT;
+		this.retryCount = retryCount;
+	}
+
+	public int getRetryInterval() {
+		return retryInterval;
+	}
+
+	public void setRetryInterval(int retryInterval) {
+		this.retryInterval = retryInterval;
+	}
+
+	public String getCredentials() {
+		return credentials;
+	}
+
+	public void setCredentials(String credentials) {
+		this.credentials = credentials;
+	}
+
+	public String getRetryList() {
+		if (retryList.size() == 0)
+			return "";
+		String t = retryList.toString();
+		return t.substring(1, t.length()-1);
+	}
+
+	public void setRetryList(String retryList) {
+		Set<Integer> s = new TreeSet<Integer>();
+		for (String t : retryList.split("[, ]")) {
+			try {
+				s.add(Integer.parseInt(t));
+			} catch (NumberFormatException x) {
+				// ignore
+			}
+		}
+		this.retryList = s;
+	}
+
+	public int getLastResponseCode() {
+		return lastResponseCode;
+	}
+
+	public String getLastResponse() {
+		return lastResponse;
+	}
+
+	/**
+	 * Post a response to the URL of the BPEL engine.  As long as the response code is one of those in
+	 * the retryList, the post will be retried up to "retrycount" times with an interval (in seconds)
+	 * of "retryInterval".  If retryInterval is negative, then each successive retry interval will be
+	 * double the previous one.
+	 * @param toBpelStr the content (XML or JSON) to post
+	 * @param bpelUrl the URL to post to
+	 * @param isxml true if the content is XML, otherwise assumed to be JSON
+	 * @return true if the post succeeded, false if all retries failed
+	 */
+	public boolean bpelPost(final String toBpelStr, final String bpelUrl, final boolean isxml)  {
+		debug("Sending response to BPEL: " + toBpelStr);
+		int totalretries = 0;
+		int retryint = retryInterval;
+		while (true) {
+			sendOne(toBpelStr, bpelUrl, isxml);
+			// Note: really should handle response code 415 by switching between content types if needed
+			if (!retryList.contains(lastResponseCode)) {
+				debug("Got response code: " + lastResponseCode + ": returning.");
+				return true;
+			}
+			if (totalretries >= retryCount) {
+				debug("Retried " + totalretries + " times, giving up.");
+				LOGGER.error(MessageEnum.RA_SEND_VNF_NOTIF_ERR, "Could not deliver response to BPEL after "+totalretries+" tries: "+toBpelStr, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Could not deliver response to BPEL");
+				return false;
+			}
+			totalretries++;
+			int sleepinterval = retryint;
+			if (retryint < 0) {
+				// if retry interval is negative double the retry on each pass
+				sleepinterval = -retryint;
+				retryint *= 2;
+			}
+			debug("Sleeping for " + sleepinterval + " seconds.");
+			try {
+				Thread.sleep(sleepinterval * 1000L);
+			} catch (InterruptedException e) {
+				// ignore
+			}
+		}
+	}
+	private void debug(String m) {
+		LOGGER.debug(m);
+//		System.err.println(m);
+	}
+	private void sendOne(final String toBpelStr, final String bpelUrl, final boolean isxml) {
+		LOGGER.debug("Sending to BPEL server: "+bpelUrl);
+		LOGGER.debug("Content is: "+toBpelStr);
+
+		//POST
+		HttpPost post = new HttpPost(bpelUrl);
+		if (credentials != null && !credentials.isEmpty())
+			post.addHeader("Authorization", "Basic " + DatatypeConverter.printBase64Binary(credentials.getBytes()));
+
+        //ContentType
+        ContentType ctype = isxml ? ContentType.APPLICATION_XML : ContentType.APPLICATION_JSON;
+        post.setEntity(new StringEntity(toBpelStr, ctype));
+
+        //Timeouts
+		RequestConfig requestConfig = RequestConfig
+			.custom()
+			.setSocketTimeout(socketTimeout * 1000)
+			.setConnectTimeout(connectTimeout * 1000)
+			.build();
+		post.setConfig(requestConfig);
+
+        //Client 4.3+
+        //Execute & GetResponse
+        try (CloseableHttpClient client = HttpClients.createDefault();
+             CloseableHttpResponse response = client.execute(post)) {
+			if (response != null) {
+				lastResponseCode = response.getStatusLine().getStatusCode();
+				HttpEntity entity = response.getEntity();
+				lastResponse = (entity != null) ? EntityUtils.toString(entity) : "";
+			} else {
+				lastResponseCode = 900;
+				lastResponse = "";
+			}
+		} catch (Exception e) {
+			String error = "Error sending Bpel notification:" + toBpelStr;
+			LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, error, "Camunda", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Error sending Bpel notification", e);
+			lastResponseCode = 900;
+			lastResponse = "";
+		}
+		LOGGER.debug("Response code from BPEL server: "+lastResponseCode);
+		LOGGER.debug("Response body is: "+lastResponse);
+	}
+
+	public static void main(String[] a) throws MsoPropertiesException {
+		final String bpelengine = "http://mtmac1.research.att.com:8080/catch.jsp";
+		final String propfile = "/tmp/mso.vnf.properties";
+		// "/Users/eby/src/mso.rest/mso/packages/mso-config-centralized/mso-po-adapter-config/mso.vnf.properties"
+		final String xml =
+			"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
+			"<updateVolumeGroupResponse><volumeGroupId>1464013300723</volumeGroupId><volumeGroupOutputs>" +
+	        "<entry><key>clyde</key><value>10</value></entry>" +
+	        "<entry><key>wayne</key><value>99</value></entry>" +
+	        "<entry><key>mickey</key><value>7</value></entry>" +
+	        "</volumeGroupOutputs></updateVolumeGroupResponse>";
+
+		MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+		msoPropertiesFactory.initializeMsoProperties (MSO_PROP_VNF_ADAPTER, propfile);
+
+		BpelRestClient bc = new BpelRestClient();
+		System.out.println(bc.getRetryList());
+		System.out.println(bc.getCredentials()); // poAvos:Domain2.0!
+
+		bc.bpelPost(xml, bpelengine, true);
+		System.out.println("respcode = "+bc.getLastResponseCode());
+		System.out.println("resp = "+bc.getLastResponse());
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/HealthCheckHandler.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/HealthCheckHandler.java
new file mode 100644
index 0000000..108baf3
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/HealthCheckHandler.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.HealthCheckUtils;
+import org.openecomp.mso.utils.UUIDChecker;
+
+
+@Path("/")
+public class HealthCheckHandler {
+
+	private static MsoLogger msoLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+    private static final String MSO_PROP_VNF_ADAPTER = "MSO_PROP_VNF_ADAPTER";
+
+	@HEAD
+	@GET
+	@Path("/healthcheck")
+	@Produces(MediaType.TEXT_HTML)
+	public Response healthcheck (@QueryParam("requestId") String requestId) {
+		long startTime = System.currentTimeMillis ();
+		MsoLogger.setServiceName ("Healthcheck");
+		UUIDChecker.verifyOldUUID(requestId, msoLogger);
+		HealthCheckUtils healthCheck = new HealthCheckUtils ();
+		if (!healthCheck.siteStatusCheck(msoLogger, startTime)) {
+			return HealthCheckUtils.HEALTH_CHECK_NOK_RESPONSE;
+		}
+
+		if (!healthCheck.configFileCheck(msoLogger, startTime, MSO_PROP_VNF_ADAPTER)) {
+			return HealthCheckUtils.NOT_STARTED_RESPONSE;
+		}
+
+		if (!healthCheck.catalogDBCheck (msoLogger, startTime)) {
+			return HealthCheckUtils.NOT_STARTED_RESPONSE;
+		}
+		msoLogger.debug("healthcheck - Successful");
+		return HealthCheckUtils.HEALTH_CHECK_RESPONSE;
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapter.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapter.java
new file mode 100644
index 0000000..95d8ee2
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapter.java
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebParam.Mode;
+import javax.jws.WebService;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfAlreadyExists;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+import org.openecomp.mso.entity.MsoRequest;
+
+import java.util.Map;
+
+@WebService (name="VnfAdapter", targetNamespace="http://com.att.mso/vnf")
+public interface MsoVnfAdapter
+{
+	/**
+	 * This is the "Create VNF" Web Service Endpoint definition.
+	 */
+	@WebMethod
+	public void createVnf (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfType") @XmlElement(required=true) String vnfType,
+							@WebParam(name="vnfVersion") @XmlElement(required=false) String vnfVersion,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="requestType") @XmlElement(required=false) String requestType,
+							@WebParam(name="volumeGroupHeatStackId") @XmlElement(required=false) String volumeGroupHeatStackId,
+							@WebParam(name="inputs") Map<String,String> inputs,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="vnfId", mode=Mode.OUT) Holder<String> vnfId,
+							@WebParam(name="outputs", mode=Mode.OUT) Holder<Map<String,String>> outputs,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<VnfRollback> rollback )
+		throws VnfException, VnfAlreadyExists;
+	
+	@WebMethod
+	public void updateVnf (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfType") @XmlElement(required=true) String vnfType,
+							@WebParam(name="vnfVersion") @XmlElement(required=false) String vnfVersion,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="requestType") @XmlElement(required=false) String requestType,
+							@WebParam(name="volumeGroupHeatStackId") @XmlElement(required=false) String volumeGroupHeatStackId,
+							@WebParam(name="inputs") Map<String,String> inputs,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="outputs", mode=Mode.OUT) Holder<Map<String,String>> outputs,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<VnfRollback> rollback )
+		throws VnfException;
+	
+	@WebMethod
+	public void queryVnf (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="vnfExists", mode=Mode.OUT) Holder<Boolean> vnfExists,
+							@WebParam(name="vnfId", mode=Mode.OUT) Holder<String> vnfId,
+							@WebParam(name="status", mode=Mode.OUT) Holder<VnfStatus> status,
+							@WebParam(name="outputs", mode=Mode.OUT) Holder<Map<String,String>> outputs )
+		throws VnfException;
+	
+	@WebMethod
+	public void deleteVnf (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="request") MsoRequest msoRequest)
+		throws VnfException;
+	
+	
+	@WebMethod
+	public void rollbackVnf (@WebParam(name="rollback") @XmlElement(required=true) VnfRollback rollback)
+		throws VnfException;
+	
+	@WebMethod
+	public void createVfModule (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfType") @XmlElement(required=true) String vnfType,
+							@WebParam(name="vnfVersion") @XmlElement(required=false) String vnfVersion,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="requestType") @XmlElement(required=false) String requestType,
+							@WebParam(name="volumeGroupHeatStackId") @XmlElement(required=false) String volumeGroupHeatStackId,
+							@WebParam(name="baseVfHeatStackId") @XmlElement(required=false) String baseVfHeatStackId,
+							@WebParam(name="inputs") Map<String,String> inputs,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="vnfId", mode=Mode.OUT) Holder<String> vnfId,
+							@WebParam(name="outputs", mode=Mode.OUT) Holder<Map<String,String>> outputs,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<VnfRollback> rollback )
+		throws VnfException, VnfAlreadyExists;
+	
+	@WebMethod
+	public void deleteVfModule (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vfName") @XmlElement(required=true) String vfName,
+							@WebParam(name="request") MsoRequest msoRequest)
+		throws VnfException;
+	
+	@WebMethod
+	public void updateVfModule (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfType") @XmlElement(required=true) String vnfType,
+							@WebParam(name="vnfVersion") @XmlElement(required=false) String vnfVersion,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="requestType") @XmlElement(required=false) String requestType,
+							@WebParam(name="volumeGroupHeatStackId") @XmlElement(required=false) String volumeGroupHeatStackId,
+							@WebParam(name="baseVfHeatStackId") @XmlElement(required=false) String baseVfHeatStackId,
+							@WebParam(name="vfModuleStackId") @XmlElement(required=false) String vfModuleStackId,
+							@WebParam(name="inputs") Map<String,String> inputs,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="outputs", mode=Mode.OUT) Holder<Map<String,String>> outputs,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<VnfRollback> rollback )
+		throws VnfException;
+	
+	@WebMethod
+	public void healthCheck ();
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterAsync.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterAsync.java
new file mode 100644
index 0000000..d58e9ee
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterAsync.java
@@ -0,0 +1,103 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import javax.jws.Oneway;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.xml.bind.annotation.XmlElement;
+
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+import java.util.Map;
+
+/**
+ * This webservice defines the Asynchronous versions of VNF adapter calls.
+ * The notification messages for final responses are documented elsewhere
+ * (by the client service WSDL).
+ *
+ */
+@WebService (name="VnfAdapterAsync", targetNamespace="http://com.att.mso/vnfA")
+public interface MsoVnfAdapterAsync
+{
+	/**
+	 * This is the "Create VNF" Web Service Endpoint definition.
+	 */
+	@WebMethod
+	@Oneway
+	public void createVnfA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfType") @XmlElement(required=true) String vnfType,
+							@WebParam(name="vnfVersion") @XmlElement(required=false) String vnfVersion,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="requestType") @XmlElement(required=false) String requestType,
+							@WebParam(name="volumeGroupHeatStackId") @XmlElement(required=false) String volumeGroupHeatStackId,
+							@WebParam(name="inputs") Map<String,String> inputs,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="messageId") @XmlElement(required=true) String messageId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="notificationUrl") @XmlElement(required=true) String notificationUrl );
+	
+	@WebMethod
+	@Oneway
+	public void updateVnfA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfType") @XmlElement(required=true) String vnfType,
+							@WebParam(name="vnfVersion") @XmlElement(required=false) String vnfVersion,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="requestType") @XmlElement(required=false) String requestType,
+							@WebParam(name="volumeGroupHeatStackId") @XmlElement(required=false) String volumeGroupHeatStackId,
+							@WebParam(name="inputs") Map<String,String> inputs,
+							@WebParam(name="messageId") @XmlElement(required=true) String messageId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="notificationUrl") @XmlElement(required=true) String notificationUrl );
+							
+	@WebMethod
+	@Oneway
+	public void queryVnfA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="messageId") @XmlElement(required=true) String messageId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="notificationUrl") @XmlElement(required=true) String notificationUrl );
+
+	@WebMethod
+	@Oneway
+	public void deleteVnfA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="vnfName") @XmlElement(required=true) String vnfName,
+							@WebParam(name="messageId") @XmlElement(required=true) String messageId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="notificationUrl") @XmlElement(required=true) String notificationUrl );
+
+	@WebMethod
+	@Oneway
+	public void rollbackVnfA (@WebParam(name="rollback") @XmlElement(required=true) VnfRollback rollback,
+						@WebParam(name="messageId") @XmlElement(required=true) String messageId,
+						@WebParam(name="notificationUrl") @XmlElement(required=true) String notificationUrl );
+
+	
+	@WebMethod
+	public void healthCheckA ();
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterAsyncImpl.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterAsyncImpl.java
new file mode 100644
index 0000000..c192eb6
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterAsyncImpl.java
@@ -0,0 +1,652 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jws.WebService;
+import javax.xml.bind.DatatypeConverter;
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Holder;
+import javax.xml.ws.handler.MessageContext;
+
+import org.openecomp.mso.adapters.vnf.async.client.CreateVnfNotification;
+import org.openecomp.mso.adapters.vnf.async.client.QueryVnfNotification;
+import org.openecomp.mso.adapters.vnf.async.client.UpdateVnfNotification;
+import org.openecomp.mso.adapters.vnf.async.client.VnfAdapterNotify;
+import org.openecomp.mso.adapters.vnf.async.client.VnfAdapterNotify_Service;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+import org.openecomp.mso.cloud.CloudConfigFactory;
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+
+@WebService(serviceName = "VnfAdapterAsync", endpointInterface = "org.openecomp.mso.adapters.vnf.MsoVnfAdapterAsync", targetNamespace = "http://com.att.mso/vnfA")
+public class MsoVnfAdapterAsyncImpl implements MsoVnfAdapterAsync {
+
+	MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+
+	CloudConfigFactory cloudConfigFactory=new CloudConfigFactory();
+
+	public static final String MSO_PROP_VNF_ADAPTER="MSO_PROP_VNF_ADAPTER";
+    private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+    private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
+    private static final String BPEL_AUTH_PROP = "org.openecomp.mso.adapters.vnf.bpelauth";
+    private static final String ENCRYPTION_KEY = "aa3871669d893c7fb8abbcda31b88b4f";
+
+    /**
+     * Health Check web method. Does nothing but return to show the adapter is deployed.
+     */
+    @Override
+    public void healthCheckA () {
+        LOGGER.debug ("Health check call in VNF Adapter");
+    }
+
+    /**
+     * This is the asynchronous "Create VNF" web service implementation.
+     * It will create a new VNF of the requested type in the specified cloud
+     * and tenant. The tenant must exist before this service is called.
+     *
+     * If a VNF with the same name already exists, this can be considered a
+     * success or failure, depending on the value of the 'failIfExists' parameter.
+     *
+     * All VNF types will be defined in the MSO catalog. The caller must request
+     * one of these pre-defined types or an error will be returned. Within the
+     * catalog, each VNF type references (among other things) a Heat template
+     * which is used to deploy the required VNF artifacts (VMs, networks, etc.)
+     * to the cloud.
+     *
+     * Depending on the Heat template, a variable set of input parameters will
+     * be defined, some of which are required. The caller is responsible to
+     * pass the necessary input data for the VNF or an error will be thrown.
+     *
+     * The method sends an asynchronous response to the notification URL when
+     * processing completes. The createAsyncResponse contains the vnfId (the
+     * canonical name of the stack), a Map of VNF output attributes, and a
+     * VnfRollback object. This last object can be passed as-is to the
+     * rollbackVnf operation to undo everything that was created for the VNF.
+     * This is useful if a VNF is successfully created but the orchestrator
+     * fails on a subsequent operation.
+     *
+     * Note: this method is implemented by calling the synchronous web method
+     * and translating the response to an asynchronous notification.
+     *
+     * @param cloudSiteId CLLI code of the cloud site in which to create the VNF
+     * @param tenantId Openstack tenant identifier
+     * @param vnfType VNF type key, should match a VNF definition in catalog DB
+     * @param vnfName Name to be assigned to the new VNF
+     * @param inputs Map of key=value inputs for VNF stack creation
+     * @param failIfExists Flag whether already existing VNF should be considered
+     *        a success or failure
+     * @param msoRequest Request tracking information for logs
+     * @param notificationURL the target URL for asynchronous response
+     */
+    @Override
+    public void createVnfA (String cloudSiteId,
+                            String tenantId,
+                            String vnfType,
+                            String vnfVersion,
+                            String vnfName,
+                            String requestType,
+                            String volumeGroupHeatStackId,
+                            Map <String, String> inputs,
+                            Boolean failIfExists,
+                            Boolean backout,
+                            String messageId,
+                            MsoRequest msoRequest,
+                            String notificationUrl) {
+        String error;
+        String serviceName = "CreateVnfA";
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName (serviceName);
+        LOGGER.info (MessageEnum.RA_ASYNC_CREATE_VNF, vnfName, vnfType, cloudSiteId, tenantId, "", "createVnfA");
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        // Use the synchronous method to perform the actual Create
+        MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <String> vnfId = new Holder <String> ();
+        Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
+        Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
+
+        try {
+            vnfAdapter.createVnf (cloudSiteId,
+                                  tenantId,
+                                  vnfType,
+                                  vnfVersion,
+                                  vnfName,
+                                  requestType,
+                                  volumeGroupHeatStackId,
+                                  inputs,
+                                  failIfExists,
+                                  backout,
+                                  msoRequest,
+                                  vnfId,
+                                  outputs,
+                                  vnfRollback);
+            MsoLogger.setServiceName (serviceName);
+        } catch (VnfException e) {
+        	MsoLogger.setServiceName (serviceName);
+        	LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR,  vnfName, cloudSiteId, tenantId, "", "createVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException in createVnfA", e);
+            org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory.fromValue (e.getFaultInfo ()
+                                                                                                     .getCategory ()
+                                                                                                     .name ());
+            } catch (Exception e1) {
+                LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "createVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.createVnfNotification (messageId, false, exCat, eMsg, null, null, null);
+            } catch (Exception e1) {
+                error = "Error sending createVnf notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "createVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending createVnf notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            LOGGER.info (MessageEnum.RA_ASYNC_CREATE_VNF_COMPLETE, "", "createVnfA", "", "createVnfA");
+            return;
+        }
+        LOGGER.debug ("Async Create VNF: " + vnfName + " VnfId:" + vnfId.value);
+        // Build and send Asynchronous response
+        try {
+            VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.createVnfNotification (messageId,
+                                              true,
+                                              null,
+                                              null,
+                                              vnfId.value,
+                                              copyCreateOutputs (outputs),
+                                              copyVrb (vnfRollback));
+        } catch (Exception e) {
+            error = "Error sending createVnf notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "createVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending createVnf notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        LOGGER.info (MessageEnum.RA_ASYNC_CREATE_VNF_COMPLETE, "", "createVnfA");
+        return;
+    }
+
+    @Override
+    public void updateVnfA (String cloudSiteId,
+                            String tenantId,
+                            String vnfType,
+                            String vnfVersion,
+                            String vnfName,
+                            String requestType,
+                            String volumeGroupHeatStackId,
+                            Map <String, String> inputs,
+                            String messageId,
+                            MsoRequest msoRequest,
+                            String notificationUrl) {
+        String error;
+        String serviceName = "UpdateVnfA";
+        MsoLogger.setServiceName (serviceName);
+        MsoLogger.setLogContext (msoRequest);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        LOGGER.info (MessageEnum.RA_ASYNC_UPDATE_VNF, vnfName, vnfType, cloudSiteId, tenantId, "", "UpdateVnfA");
+
+        // Use the synchronous method to perform the actual Create
+        MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <String> vnfId = new Holder <String> ();
+        Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
+        Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
+
+        try {
+            vnfAdapter.updateVnf (cloudSiteId, tenantId, vnfType,vnfVersion, vnfName, requestType, volumeGroupHeatStackId, inputs, msoRequest, outputs, vnfRollback);
+            MsoLogger.setServiceName (serviceName);
+        } catch (VnfException e) {
+        	MsoLogger.setServiceName (serviceName);
+        	LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR,  vnfName, cloudSiteId, tenantId, "", "UpdateVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending updateVnf notification", e);
+            org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory.fromValue (e.getFaultInfo ()
+                                                                                                     .getCategory ()
+                                                                                                     .name ());
+            } catch (Exception e1) {
+            	LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "UpdateVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.updateVnfNotification (messageId, false, exCat, eMsg, null, null);
+            } catch (Exception e1) {
+                error = "Error sending updateVnf notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "UpdateVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending updateVnf notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            LOGGER.info (MessageEnum.RA_ASYNC_UPDATE_VNF_COMPLETE, "", "UpdateVnfA");
+            return;
+        }
+        LOGGER.debug ("Async Update VNF: " + vnfName + " VnfId:" + vnfId.value);
+        // Build and send Asynchronous response
+        try {
+            VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.updateVnfNotification (messageId,
+                                              true,
+                                              null,
+                                              null,
+                                              copyUpdateOutputs (outputs),
+                                              copyVrb (vnfRollback));
+        } catch (Exception e) {
+            error = "Error sending updateVnf notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "UpdateVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending updateVnf notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        LOGGER.info (MessageEnum.RA_ASYNC_UPDATE_VNF_COMPLETE, "", "UpdateVnfA");
+        return;
+    }
+
+    /**
+     * This is the "Query VNF" web service implementation.
+     * It will look up a VNF by name or ID in the specified cloud and tenant.
+     *
+     * The method returns an indicator that the VNF exists, its Openstack internal
+     * ID, its status, and the set of outputs (from when the stack was created).
+     *
+     * @param cloudSiteId CLLI code of the cloud site in which to query
+     * @param tenantId Openstack tenant identifier
+     * @param vnfName VNF Name or Openstack ID
+     * @param msoRequest Request tracking information for logs
+     * @param notificationURL the target URL for asynchronous response
+     */
+    @Override
+    public void queryVnfA (String cloudSiteId,
+                           String tenantId,
+                           String vnfName,
+                           String messageId,
+                           MsoRequest msoRequest,
+                           String notificationUrl) {
+        String error;
+        String serviceName = "QueryVnfA";
+        MsoLogger.setServiceName (serviceName);
+        MsoLogger.setLogContext (msoRequest);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        LOGGER.info (MessageEnum.RA_ASYNC_QUERY_VNF, vnfName, cloudSiteId, tenantId);
+
+        // Use the synchronous method to perform the actual query
+        MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <Boolean> vnfExists = new Holder <Boolean> ();
+        Holder <String> vnfId = new Holder <String> ();
+        Holder <VnfStatus> status = new Holder <VnfStatus> ();
+        Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
+
+        try {
+            vnfAdapter.queryVnf (cloudSiteId, tenantId, vnfName, msoRequest, vnfExists, vnfId, status, outputs);
+            MsoLogger.setServiceName (serviceName);
+        } catch (VnfException e) {
+        	MsoLogger.setServiceName (serviceName);
+            LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR,  vnfName, cloudSiteId, tenantId, "", "queryVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending queryVnfA notification", e);
+            org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory.fromValue (e.getFaultInfo ()
+                                                                                                     .getCategory ()
+                                                                                                     .name ());
+            } catch (Exception e1) {
+            	LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "queryVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.queryVnfNotification (messageId, false, exCat, eMsg, null, null, null, null);
+            } catch (Exception e1) {
+                error = "Error sending queryVnf notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "queryVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending queryVnf notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            LOGGER.info (MessageEnum.RA_ASYNC_QUERY_VNF_COMPLETE, "", "queryVnfA");
+            return;
+        }
+
+        if (!vnfExists.value) {
+            LOGGER.debug ("Async Query, VNF not found");
+        } else {
+            LOGGER.debug ("Async Query, VNF=" + vnfId.value + ", status=" + status.value);
+        }
+        // Build and send Asynchronous response
+        try {
+            VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            org.openecomp.mso.adapters.vnf.async.client.VnfStatus vnfS = org.openecomp.mso.adapters.vnf.async.client.VnfStatus.fromValue (status.value.name ());
+            notifyPort.queryVnfNotification (messageId,
+                                             true,
+                                             null,
+                                             null,
+                                             vnfExists.value,
+                                             vnfId.value,
+                                             vnfS,
+                                             copyQueryOutputs (outputs));
+        } catch (Exception e) {
+            error = "Error sending queryVnf notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "queryVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending queryVnf notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+
+        LOGGER.info (MessageEnum.RA_ASYNC_QUERY_VNF_COMPLETE, "", "queryVnfA");
+        return;
+    }
+
+    /**
+     * This is the Asynchronous "Delete VNF" web service implementation.
+     * It will delete a VNF by name or ID in the specified cloud and tenant.
+     *
+     * The method has no outputs.
+     *
+     * @param cloudSiteId CLLI code of the cloud site in which to delete
+     * @param tenantId Openstack tenant identifier
+     * @param vnfName VNF Name or Openstack ID
+     * @param msoRequest Request tracking information for logs
+     * @param notificationURL the target URL for asynchronous response
+     */
+    @Override
+    public void deleteVnfA (String cloudSiteId,
+                            String tenantId,
+                            String vnfName,
+                            String messageId,
+                            MsoRequest msoRequest,
+                            String notificationUrl) {
+        String error;
+        String serviceName = "DeleteVnfA";
+        MsoLogger.setServiceName (serviceName);
+        MsoLogger.setLogContext (msoRequest);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        LOGGER.info (MessageEnum.RA_ASYNC_DELETE_VNF, vnfName, cloudSiteId, tenantId);
+
+        // Use the synchronous method to perform the actual delete
+        MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        try {
+            vnfAdapter.deleteVnf (cloudSiteId, tenantId, vnfName, msoRequest);
+            MsoLogger.setServiceName (serviceName);
+        } catch (VnfException e) {
+        	MsoLogger.setServiceName (serviceName);
+        	LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR,  vnfName, cloudSiteId, tenantId, "", "deleteVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending deleteVnfA notification", e);
+            org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory.fromValue (e.getFaultInfo ()
+                                                                                                     .getCategory ()
+                                                                                                     .name ());
+            } catch (Exception e1) {
+            	LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "deleteVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.deleteVnfNotification (messageId, false, exCat, eMsg);
+            } catch (Exception e1) {
+                error = "Error sending deleteVnf notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "deleteVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending deleteVnfA notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            LOGGER.info (MessageEnum.RA_ASYNC_DELETE_VNF_COMPLETE, "", "deleteVnfA");
+            return;
+        }
+
+        LOGGER.debug ("Async Delete VNF: " + vnfName);
+        // Build and send Asynchronous response
+        try {
+            VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.deleteVnfNotification (messageId, true, null, null);
+
+        } catch (Exception e) {
+            error = "Error sending deleteVnf notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "deleteVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending deleteVnfA notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+
+        LOGGER.info (MessageEnum.RA_ASYNC_DELETE_VNF_COMPLETE, "", "deleteVnfA");
+        return;
+    }
+
+    /**
+     * This web service endpoint will rollback a previous Create VNF operation.
+     * A rollback object is returned to the client in a successful creation
+     * response. The client can pass that object as-is back to the rollbackVnf
+     * operation to undo the creation.
+     */
+    @Override
+    public void rollbackVnfA (VnfRollback rollback, String messageId, String notificationUrl) {
+        String serviceName = "RollbackVnfA";
+        MsoLogger.setServiceName (serviceName);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        String error;
+        // rollback may be null (e.g. if stack already existed when Create was called)
+        if (rollback == null) {
+            error = "Empty Rollback: No action to perform";
+            LOGGER.info (MessageEnum.RA_ROLLBACK_NULL, "", "rollbackVnfA");
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            return;
+        }
+
+        MsoLogger.setLogContext (rollback.getMsoRequest ());
+        LOGGER.info (MessageEnum.RA_ASYNC_ROLLBACK_VNF, "", "rollbackVnfA");
+
+        // Use the synchronous method to perform the actual rollback
+        MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        try {
+            vnfAdapter.rollbackVnf (rollback);
+            MsoLogger.setServiceName (serviceName);
+        } catch (VnfException e) {
+        	MsoLogger.setServiceName (serviceName);
+        	LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending rollbackVnfA notification", e);
+            org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = org.openecomp.mso.adapters.vnf.async.client.MsoExceptionCategory.fromValue (e.getFaultInfo ()
+                                                                                                     .getCategory ()
+                                                                                                     .name ());
+            } catch (Exception e1) {
+            	LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "rollbackVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.rollbackVnfNotification (messageId, false, exCat, eMsg);
+            } catch (Exception e1) {
+                error = "Error sending rollbackVnf notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "rollbackVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending rollbackVnfA notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            LOGGER.info (MessageEnum.RA_ASYNC_ROLLBACK_VNF_COMPLETE, "", "rollbackVnfA");
+            return;
+        }
+
+        LOGGER.debug ("Async Rollback VNF:" + rollback.getVnfId ());
+        // Build and send Asynchronous response
+        try {
+            VnfAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.rollbackVnfNotification (messageId, true, null, null);
+        } catch (Exception e) {
+            error = "Error sending rollbackVnf notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_SEND_VNF_NOTIF_ERR, "", "rollbackVnfA", MsoLogger.ErrorCode.BusinessProcesssError, "Exception sending rollbackVnfA notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+
+        LOGGER.info (MessageEnum.RA_ASYNC_ROLLBACK_VNF_COMPLETE, "", "rollbackVnfA");
+        return;
+    }
+
+    private org.openecomp.mso.adapters.vnf.async.client.VnfRollback copyVrb (Holder <VnfRollback> hVrb) {
+        org.openecomp.mso.adapters.vnf.async.client.VnfRollback cvrb = new org.openecomp.mso.adapters.vnf.async.client.VnfRollback ();
+
+        if (hVrb != null && hVrb.value != null) {
+            org.openecomp.mso.adapters.vnf.async.client.MsoRequest cmr = new org.openecomp.mso.adapters.vnf.async.client.MsoRequest ();
+
+            cvrb.setCloudSiteId (hVrb.value.getCloudSiteId ());
+            if (hVrb.value.getMsoRequest() != null) {
+            	cmr.setRequestId (hVrb.value.getMsoRequest ().getRequestId ());
+            	cmr.setServiceInstanceId (hVrb.value.getMsoRequest ().getServiceInstanceId ());
+            } else {
+            	cmr.setRequestId (null);
+            	cmr.setServiceInstanceId (null);
+            }
+            cvrb.setMsoRequest (cmr);
+            cvrb.setVnfId (hVrb.value.getVnfId ());
+            cvrb.setTenantId (hVrb.value.getTenantId ());
+            cvrb.setTenantCreated (hVrb.value.getTenantCreated ());
+            cvrb.setVnfCreated (hVrb.value.getVnfCreated ());
+        }
+        return cvrb;
+    }
+
+    private CreateVnfNotification.Outputs copyCreateOutputs (Holder <Map <String, String>> hMap) {
+
+        CreateVnfNotification.Outputs outputs = new CreateVnfNotification.Outputs ();
+
+        if (hMap != null && hMap.value != null) {
+            Map <String, String> sMap = new HashMap <String, String> ();
+            sMap = hMap.value;
+            CreateVnfNotification.Outputs.Entry entry = new CreateVnfNotification.Outputs.Entry ();
+
+            for (String key : sMap.keySet ()) {
+                entry.setKey (key);
+                entry.setValue (sMap.get (key));
+                outputs.getEntry ().add (entry);
+            }
+        }
+        return outputs;
+    }
+
+    private UpdateVnfNotification.Outputs copyUpdateOutputs (Holder <Map <String, String>> hMap) {
+
+        UpdateVnfNotification.Outputs outputs = new UpdateVnfNotification.Outputs ();
+
+        if (hMap != null && hMap.value != null) {
+            Map <String, String> sMap = new HashMap <String, String> ();
+            sMap = hMap.value;
+            UpdateVnfNotification.Outputs.Entry entry = new UpdateVnfNotification.Outputs.Entry ();
+
+            for (String key : sMap.keySet ()) {
+                entry.setKey (key);
+                entry.setValue (sMap.get (key));
+                outputs.getEntry ().add (entry);
+            }
+        }
+        return outputs;
+    }
+
+    private QueryVnfNotification.Outputs copyQueryOutputs (Holder <Map <String, String>> hMap) {
+
+        QueryVnfNotification.Outputs outputs = new QueryVnfNotification.Outputs ();
+
+        if (hMap != null && hMap.value != null) {
+            Map <String, String> sMap = new HashMap <String, String> ();
+            sMap = hMap.value;
+
+            QueryVnfNotification.Outputs.Entry entry = new QueryVnfNotification.Outputs.Entry ();
+
+            for (String key : sMap.keySet ()) {
+                entry.setKey (key);
+                entry.setValue (sMap.get (key));
+                outputs.getEntry ().add (entry);
+            }
+        }
+        return outputs;
+    }
+
+    private VnfAdapterNotify getNotifyEP (String notificationUrl) {
+
+        URL warWsdlLoc = null;
+        try {
+            warWsdlLoc = Thread.currentThread ().getContextClassLoader ().getResource ("VnfAdapterNotify.wsdl");
+        } catch (Exception e) {
+            LOGGER.error (MessageEnum.RA_WSDL_NOT_FOUND, "VnfAdapterNotify.wsdl", "", "getNotifyEP", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - WSDL not found", e);
+        }
+        if (warWsdlLoc == null) {
+        	LOGGER.error (MessageEnum.RA_WSDL_NOT_FOUND, "VnfAdapterNotify.wsdl", "", "getNotifyEP", MsoLogger.ErrorCode.BusinessProcesssError, "WSDL not found");
+        } else {
+            try {
+                LOGGER.debug ("VnfAdpaterNotify.wsdl location:" + warWsdlLoc.toURI ().toString ());
+            } catch (Exception e) {
+                LOGGER.error (MessageEnum.RA_WSDL_URL_CONVENTION_EXC, "VnfAdapterNotify.wsdl", "", "getNotifyEP", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - WSDL URL convention", e);
+            }
+        }
+
+        VnfAdapterNotify_Service notifySvc = new VnfAdapterNotify_Service (warWsdlLoc,
+                                                                           new QName ("http://com.att.mso/vnfNotify",
+                                                                                      "vnfAdapterNotify"));
+
+        VnfAdapterNotify notifyPort = notifySvc.getMsoVnfAdapterAsyncImplPort ();
+
+        BindingProvider bp = (BindingProvider) notifyPort;
+
+        URL epUrl = null;
+        try {
+            epUrl = new URL (notificationUrl);
+        } catch (MalformedURLException e1) {
+            LOGGER.error (MessageEnum.RA_INIT_NOTIF_EXC, "", "getNotifyEP", MsoLogger.ErrorCode.BusinessProcesssError, "MalformedURLException", e1);
+        }
+
+        LOGGER.debug ("Notification Endpoint URL: " + epUrl.toExternalForm ());
+
+        bp.getRequestContext ().put (BindingProvider.ENDPOINT_ADDRESS_PROPERTY, epUrl.toExternalForm ());
+
+        // authentication
+        try {
+            Map <String, Object> req_ctx = bp.getRequestContext ();
+            Map <String, List <String>> headers = new HashMap <String, List <String>> ();
+
+            String userCredentials = msoPropertiesFactory.getMsoJavaProperties (MSO_PROP_VNF_ADAPTER).getEncryptedProperty (BPEL_AUTH_PROP,
+                                                                                             "",
+                                                                                             ENCRYPTION_KEY);
+
+            String basicAuth = "Basic " + DatatypeConverter.printBase64Binary (userCredentials.getBytes ());
+            req_ctx.put (MessageContext.HTTP_REQUEST_HEADERS, headers);
+            headers.put ("Authorization", Collections.singletonList (basicAuth));
+        } catch (Exception e) {
+            LOGGER.error (MessageEnum.RA_SET_CALLBACK_AUTH_EXC, "", "getNotifyEP", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Unable to set authorization in callback request", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, "Unable to set authorization in callback request");
+        }
+
+        return notifyPort;
+    }
+
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterImpl.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterImpl.java
new file mode 100644
index 0000000..757f875
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/MsoVnfAdapterImpl.java
@@ -0,0 +1,2391 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.jws.WebService;
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.adapters.vnf.exceptions.VnfAlreadyExists;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfNotFound;
+import org.openecomp.mso.cloud.CloudConfigFactory;
+import org.openecomp.mso.cloud.CloudConfig;
+import org.openecomp.mso.cloud.CloudSite;
+import org.openecomp.mso.db.catalog.utils.MavenLikeVersioning;
+import org.openecomp.mso.db.catalog.CatalogDatabase;
+import org.openecomp.mso.db.catalog.beans.HeatEnvironment;
+import org.openecomp.mso.db.catalog.beans.HeatFiles;
+import org.openecomp.mso.db.catalog.beans.HeatTemplate;
+import org.openecomp.mso.db.catalog.beans.HeatTemplateParam;
+import org.openecomp.mso.db.catalog.beans.VnfResource;
+import org.openecomp.mso.db.catalog.beans.VfModule;
+import org.openecomp.mso.db.catalog.beans.VnfComponent;
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoAlarmLogger;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.openstack.beans.HeatStatus;
+import org.openecomp.mso.openstack.beans.StackInfo;
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+import org.openecomp.mso.openstack.exceptions.MsoException;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+import org.openecomp.mso.openstack.utils.MsoHeatUtils;
+import org.openecomp.mso.openstack.utils.MsoHeatUtilsWithUpdate;
+import org.openecomp.mso.openstack.utils.MsoHeatEnvironmentEntry;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.map.ObjectMapper;
+
+@WebService(serviceName = "VnfAdapter", endpointInterface = "org.openecomp.mso.adapters.vnf.MsoVnfAdapter", targetNamespace = "http://com.att.mso/vnf")
+public class MsoVnfAdapterImpl implements MsoVnfAdapter {
+
+	CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
+	protected CloudConfig cloudConfig = null;
+
+	MsoPropertiesFactory msoPropertiesFactory=new MsoPropertiesFactory();
+
+	private static final String MSO_PROP_VNF_ADAPTER = "MSO_PROP_VNF_ADAPTER";
+    private static final String MSO_CONFIGURATION_ERROR = "MsoConfigurationError";
+    private static final String VNF_ADAPTER_SERVICE_NAME = "MSO-BPMN:MSO-VnfAdapter.";
+    private static final String LOG_REPLY_NAME = "MSO-VnfAdapter:MSO-BPMN.";
+    private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+    private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
+    private static final String CHECK_REQD_PARAMS = "org.openecomp.mso.adapters.vnf.checkRequiredParameters";
+    private static final String ADD_GET_FILES_ON_VOLUME_REQ = "org.openecomp.mso.adapters.vnf.addGetFilesOnVolumeReq";
+
+    /**
+     * Health Check web method. Does nothing but return to show the adapter is deployed.
+     */
+    @Override
+    public void healthCheck () {
+        LOGGER.debug ("Health check call in VNF Adapter");
+    }
+
+    /**
+     * DO NOT use that constructor to instantiate this class, the msoPropertiesfactory will be NULL.
+     * @see MsoVnfAdapterImpl#MsoVnfAdapterImpl(MsoPropertiesFactory, CloudConfigFactory)
+     */
+    public MsoVnfAdapterImpl() {
+
+    }
+
+    /**
+     * This constructor MUST be used if this class is called with the new operator.
+     * @param msoPropFactory
+     */
+    public MsoVnfAdapterImpl(MsoPropertiesFactory msoPropFactory, CloudConfigFactory cloudConfigFact) {
+    	this.msoPropertiesFactory = msoPropFactory;
+    	this.cloudConfigFactory = cloudConfigFact;
+    }
+
+    /**
+     * This is the "Create VNF" web service implementation.
+     * It will create a new VNF of the requested type in the specified cloud
+     * and tenant. The tenant must exist before this service is called.
+     *
+     * If a VNF with the same name already exists, this can be considered a
+     * success or failure, depending on the value of the 'failIfExists' parameter.
+     *
+     * All VNF types will be defined in the MSO catalog. The caller must request
+     * one of these pre-defined types or an error will be returned. Within the
+     * catalog, each VNF type references (among other things) a Heat template
+     * which is used to deploy the required VNF artifacts (VMs, networks, etc.)
+     * to the cloud.
+     *
+     * Depending on the Heat template, a variable set of input parameters will
+     * be defined, some of which are required. The caller is responsible to
+     * pass the necessary input data for the VNF or an error will be thrown.
+     *
+     * The method returns the vnfId (the canonical name), a Map of VNF output
+     * attributes, and a VnfRollback object. This last object can be passed
+     * as-is to the rollbackVnf operation to undo everything that was created
+     * for the VNF. This is useful if a VNF is successfully created but the
+     * orchestrator fails on a subsequent operation.
+     *
+     * @param cloudSiteId CLLI code of the cloud site in which to create the VNF
+     * @param tenantId Openstack tenant identifier
+     * @param vnfType VNF type key, should match a VNF definition in catalog DB
+     * @param vnfVersion VNF version key, should match a VNF definition in catalog DB
+     * @param vnfName Name to be assigned to the new VNF
+     * @param inputs Map of key=value inputs for VNF stack creation
+     * @param failIfExists Flag whether already existing VNF should be considered
+     *        a success or failure
+     * @param msoRequest Request tracking information for logs
+     * @param vnfId Holder for output VNF Openstack ID
+     * @param outputs Holder for Map of VNF outputs from heat (assigned IPs, etc)
+     * @param rollback Holder for returning VnfRollback object
+     */
+    @Override
+    public void createVnf (String cloudSiteId,
+                           String tenantId,
+                           String vnfType,
+                           String vnfVersion,
+                           String vnfName,
+                           String requestType,
+                           String volumeGroupHeatStackId,
+                           Map <String, String> inputs,
+                           Boolean failIfExists,
+                           Boolean backout,
+                           MsoRequest msoRequest,
+                           Holder <String> vnfId,
+                           Holder <Map <String, String>> outputs,
+                           Holder <VnfRollback> rollback) throws VnfException {
+    	// Create a hook here to catch shortcut createVf requests:
+    	if (requestType != null) {
+    		if (requestType.startsWith("VFMOD")) {
+    			LOGGER.debug("Calling createVfModule from createVnf -- requestType=" + requestType);
+    			String newRequestType = requestType.substring(5);
+    			String vfVolGroupHeatStackId = "";
+    			String vfBaseHeatStackId = "";
+    			try {
+    				if (volumeGroupHeatStackId != null) {
+    					vfVolGroupHeatStackId = volumeGroupHeatStackId.substring(0, volumeGroupHeatStackId.lastIndexOf("|"));
+    					vfBaseHeatStackId = volumeGroupHeatStackId.substring(volumeGroupHeatStackId.lastIndexOf("|")+1);
+    				}
+    			} catch (Exception e) {
+    				// might be ok - both are just blank
+    				LOGGER.debug("ERROR trying to parse the volumeGroupHeatStackId " + volumeGroupHeatStackId);
+    			}
+    			this.createVfModule(cloudSiteId, 
+    					tenantId, 
+    					vnfType, 
+    					vnfVersion, 
+    					vnfName, 
+    					newRequestType, 
+    					vfVolGroupHeatStackId, 
+    					vfBaseHeatStackId, 
+    					inputs, 
+    					failIfExists, 
+    					backout, 
+    					msoRequest, 
+    					vnfId, 
+    					outputs, 
+    					rollback);
+    			return;
+    		}
+    	} 
+    	// createVf will know if the requestType starts with "X" that it's the "old" way
+    	StringBuilder newRequestTypeSb = new StringBuilder("X");
+    	String vfVolGroupHeatStackId = "";
+    	String vfBaseHeatStackId = "";
+    	if (requestType != null) {
+    		newRequestTypeSb.append(requestType);
+    	}
+		this.createVfModule(cloudSiteId, 
+				tenantId, 
+				vnfType, 
+				vnfVersion, 
+				vnfName, 
+				newRequestTypeSb.toString(), 
+				vfVolGroupHeatStackId, 
+				vfBaseHeatStackId, 
+				inputs, 
+				failIfExists, 
+				backout, 
+				msoRequest, 
+				vnfId, 
+				outputs, 
+				rollback);
+    	return;
+    	// End createVf shortcut
+    }
+
+    @Override
+    public void updateVnf (String cloudSiteId,
+                           String tenantId,
+                           String vnfType,
+                           String vnfVersion,
+                           String vnfName,
+                           String requestType,
+                           String volumeGroupHeatStackId,
+                           Map <String, String> inputs,
+                           MsoRequest msoRequest,
+                           Holder <Map <String, String>> outputs,
+                           Holder <VnfRollback> rollback) throws VnfException {
+    	MsoLogger.setLogContext (msoRequest.getRequestId (), msoRequest.getServiceInstanceId ());
+    	MsoLogger.setServiceName ("UpdateVnf");
+    	String requestTypeString = "";
+        if (requestType != null && !requestType.equals("")) {
+        	requestTypeString = requestType;
+        }
+        String nestedStackId = null;
+        if (volumeGroupHeatStackId != null && !volumeGroupHeatStackId.equals("")) {
+        	nestedStackId = volumeGroupHeatStackId;
+        }
+
+        LOGGER.debug ("Updating VNF: " + vnfName + " of type " + vnfType + "in " + cloudSiteId + "/" + tenantId);
+        LOGGER.debug("requestTypeString = " + requestTypeString + ", nestedStackId = " + nestedStackId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Build a default rollback object (no actions performed)
+        VnfRollback vnfRollback = new VnfRollback ();
+        vnfRollback.setCloudSiteId (cloudSiteId);
+        vnfRollback.setTenantId (tenantId);
+        vnfRollback.setMsoRequest (msoRequest);
+        vnfRollback.setRequestType(requestTypeString);
+
+        // First, look up to see if the VNF already exists.
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+        MsoHeatUtilsWithUpdate heatU = new MsoHeatUtilsWithUpdate (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        StackInfo heatStack = null;
+        long queryStackStarttime1 = System.currentTimeMillis ();
+        try {
+            heatStack = heat.queryStack (cloudSiteId, tenantId, vnfName);
+            LOGGER.recordMetricEvent (queryStackStarttime1, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", vnfName);
+        } catch (MsoException me) {
+            // Failed to query the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            me.addContext ("UpdateVNF");
+            String error = "Update VNF: Query " + vnfName + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (queryStackStarttime1, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", vnfName);
+            LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vnfName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateVnf", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+
+        if (heatStack == null || heatStack.getStatus () == HeatStatus.NOTFOUND) {
+            // Not Found
+            String error = "Update VNF: Stack " + vnfName + " does not exist in " + cloudSiteId + "/" + tenantId;
+            LOGGER.error (MessageEnum.RA_VNF_NOT_EXIST, vnfName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: Stack " + vnfName + " does not exist");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+            throw new VnfNotFound (cloudSiteId, tenantId, vnfName);
+        } else {
+            LOGGER.debug ("Found Existing stack, status=" + heatStack.getStatus ());
+            // Populate the outputs from the existing stack.
+            outputs.value = copyStringOutputs (heatStack.getOutputs ());
+            rollback.value = vnfRollback; // Default rollback - no updates performed
+        }
+        
+        // 1604 Cinder Volume support - handle a nestedStackId if sent (volumeGroupHeatStackId):
+        StackInfo nestedHeatStack = null;
+        long queryStackStarttime2 = System.currentTimeMillis ();
+        if (nestedStackId != null) {
+        	try {
+        		LOGGER.debug("Querying for nestedStackId = " + nestedStackId);
+        		nestedHeatStack = heat.queryStack(cloudSiteId, tenantId, nestedStackId);
+                LOGGER.recordMetricEvent (queryStackStarttime2, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", vnfName);
+        	} catch (MsoException me) {
+        	    // Failed to query the Stack due to an openstack exception.
+        	    // Convert to a generic VnfException
+        	    me.addContext ("UpdateVNF");
+        	    String error = "Update VNF: Attached heatStack ID Query " + nestedStackId + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+                LOGGER.recordMetricEvent (queryStackStarttime2, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", vnfName);
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vnfName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.AvailabilityError, "Exception trying to query nested stack", me);
+        		LOGGER.debug("ERROR trying to query nested stack= " + error);
+        	    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+        	    throw new VnfException (me);
+        	}
+        	if (nestedHeatStack == null || nestedHeatStack.getStatus() == HeatStatus.NOTFOUND) {
+        	    String error = "Update VNF: Attached heatStack ID DOES NOT EXIST " + nestedStackId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR"  ;
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vnfName, cloudSiteId, tenantId, error, "OpenStack", "QueryStack", MsoLogger.ErrorCode.AvailabilityError, "Attached heatStack ID DOES NOT EXIST");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+        	    LOGGER.debug(error);
+        	    throw new VnfException (error, MsoExceptionCategory.USERDATA);
+        	} else {
+        		LOGGER.debug("Found nested heat stack - copying values to inputs");
+        		this.sendMapToDebug(inputs);
+        		heat.copyStringOutputsToInputs(inputs, nestedHeatStack.getOutputs(), false);      
+        		this.sendMapToDebug(inputs);
+        	}
+        }
+
+        // Ready to deploy the new VNF
+
+        try(CatalogDatabase db = new CatalogDatabase ()) {
+            // Retrieve the VNF definition
+            VnfResource vnf;
+            if (vnfVersion != null && !vnfVersion.isEmpty ()) {
+                vnf = db.getVnfResource (vnfType, vnfVersion);
+            } else {
+                vnf = db.getVnfResource (vnfType);
+            }
+            if (vnf == null) {
+                String error = "Update VNF: Unknown VNF Type: " + vnfType;
+                LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "VNF Type", vnfType, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: Unknown VNF Type");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                throw new VnfException (error, MsoExceptionCategory.USERDATA);
+            }
+            LOGGER.debug ("Got VNF definition from Catalog: " + vnf.toString ());
+
+            // Currently, all VNFs are orchestrated via HEAT
+            if (!"HEAT".equals (vnf.getOrchestrationMode ())) {
+                String error = "Update VNF: Configuration error: VNF=" + vnfType;
+                LOGGER.error (MessageEnum.RA_CONFIG_EXC, " VNF=" + vnfType, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: Configuration error");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                // Alarm on this error, configuration must be fixed
+                alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+                throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+            }
+            
+            //1604 - Need to handle an updateVolume request. 
+            VnfComponent vnfComponent = null;
+            if (requestTypeString != null && !requestTypeString.equals("")) {
+            	LOGGER.debug("About to query for vnfComponent id = " + vnf.getId() + ", type = " + requestTypeString.toUpperCase());
+            	vnfComponent = db.getVnfComponent(vnf.getId(), requestTypeString.toUpperCase());
+            	if (vnfComponent == null) {
+            		String error = "Update VNF: Cannot find VNF Component entry for: " + vnfType + ", type = " + requestTypeString.toUpperCase();
+            		LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "VNF Type", vnfType, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: Cannot find VNF Component entry");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+            		throw new VnfException (error, MsoExceptionCategory.USERDATA);
+            	}
+            	LOGGER.debug("FOUND VnfComponent: " + vnfComponent.toString());
+            }
+
+            HeatTemplate heatTemplate = db.getHeatTemplate (vnf.getTemplateId ());
+            if (heatTemplate == null) {
+                String error = "Update VNF: undefined Heat Template. VNF=" + vnfType;
+                LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Template ID", String.valueOf(vnf.getTemplateId ()), "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: undefined Heat Template");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                // Alarm on this error, configuration must be fixed
+                alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+
+                throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+            }
+
+            // If this is a component request - get the template associated for volumes
+            // May change this - for now get both templates - but volume will be 2nd, which makes sense
+            // for the rest of the code. Same with envt later
+			if (vnfComponent != null) {
+				LOGGER.debug("Querying db to find component template " + vnfComponent.getHeatTemplateId());
+				heatTemplate = db.getHeatTemplate(vnfComponent
+						.getHeatTemplateId());
+				if (heatTemplate == null) {
+					String error = "Update VNF: undefined Heat Template for Volume Component. VNF="
+							+ vnfType;
+					LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM,
+							"Heat Template ID",
+							String.valueOf(vnfComponent.getHeatTemplateId()), "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: undefined Heat Template for Volume Component");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+					alarmLogger.sendAlarm(MSO_CONFIGURATION_ERROR,
+							MsoAlarmLogger.CRITICAL, error);
+					throw new VnfException(error, MsoExceptionCategory.INTERNAL);
+				}
+			}
+
+            LOGGER.debug ("Got HEAT Template from DB: " + heatTemplate.toString ());
+            
+            // Add check for any Environment variable
+            HeatEnvironment heatEnvironment = null;
+            String heatEnvironmentString = null;
+
+            if (vnf.getEnvironmentId () != null) {
+                LOGGER.debug ("about to call getHeatEnvironment with :" + vnf.getEnvironmentId () + ":");
+                heatEnvironment = db.getHeatEnvironment (vnf.getEnvironmentId ());
+                if (heatEnvironment == null) {
+
+                    String error = "Create VNF: undefined Heat Environment. VNF=" + vnfType
+                                   + ", Environment ID="
+                                   + vnf.getEnvironmentId ();
+                    LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Environment ID", String.valueOf(vnf.getEnvironmentId ()), "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Create VNF: undefined Heat Environment");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                    // Alarm on this error, configuration must be fixed
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+
+                    throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+                } else {
+                    LOGGER.debug ("Got Heat Environment from DB: " + heatEnvironment.toString ());
+                    heatEnvironmentString = heatEnvironment.getEnvironment (); //this.parseEnvironment (heatEnvironment.getEnvironment ());
+                    LOGGER.debug ("After parsing: " + heatEnvironmentString);
+                }
+            } else {
+                LOGGER.debug ("no environment parameter for this VNF " + vnfType);
+            }
+            
+            //1604 - override the VNF environment with the one for the component
+            if(vnfComponent != null) {
+                if (vnfComponent.getHeatEnvironmentId () != null) {
+                    LOGGER.debug ("about to call getHeatEnvironment with :" + vnfComponent.getHeatEnvironmentId () + ":");
+                    heatEnvironment = db.getHeatEnvironment (vnfComponent.getHeatEnvironmentId ());
+                    if (heatEnvironment == null) {
+                        String error = "Update VNF: undefined Heat Environment. VNF=" + vnfType
+                                       + ", Environment ID="
+                                       + vnfComponent.getHeatEnvironmentId ();
+                        LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Environment ID", String.valueOf(vnfComponent.getHeatEnvironmentId ()), "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: undefined Heat Environment");
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                        // Alarm on this error, configuration must be fixed
+                        alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+
+                        throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+                    } else {
+                        LOGGER.debug ("Got Heat Environment from DB: " + heatEnvironment.toString ());
+                        heatEnvironmentString = heatEnvironment.getEnvironment (); //this.parseEnvironment (heatEnvironment.getEnvironment ());
+                        LOGGER.debug ("after parsing: " + heatEnvironmentString);
+                    }
+                } else {
+                    LOGGER.debug ("no environment parameter for this VNF VOLUME component " + vnfType);
+                }
+            }
+            // End 1604
+            
+            
+            LOGGER.debug ("In MsoVnfAdapterImpl, about to call db.getNestedTemplates avec templateId="
+                          + heatTemplate.getId ());
+            Map <String, Object> nestedTemplates = db.getNestedTemplates (heatTemplate.getId ());
+            Map <String, Object> nestedTemplatesChecked = new HashMap <String, Object> ();
+            if (nestedTemplates != null) {
+                // for debugging print them out
+                LOGGER.debug ("Contents of nestedTemplates - to be added to files: on stack:");
+                for (String providerResourceFile : nestedTemplates.keySet ()) {
+                    String providerResourceFileChecked = providerResourceFile; //this.enforceFilePrefix (providerResourceFile);
+                    String childTemplateBody = (String) nestedTemplates.get (providerResourceFile);
+                    nestedTemplatesChecked.put (providerResourceFileChecked, childTemplateBody);
+                    LOGGER.debug (providerResourceFileChecked + " -> " + childTemplateBody);
+                }
+            } else {
+                LOGGER.debug ("No nested templates found - nothing to do here");
+                nestedTemplatesChecked = null;
+            }
+
+            // Also add the files: for any get_files associated with this vnf_resource_id
+            // *if* there are any
+            LOGGER.debug ("In MsoVnfAdapterImpl.updateVnf, about to call db.getHeatFiles avec vnfResourceId="
+                          + vnf.getId ());
+            Map <String, HeatFiles> heatFiles = db.getHeatFiles (vnf.getId ());
+            Map <String, Object> heatFilesObjects = new HashMap <String, Object> ();
+            if (heatFiles != null) {
+                // add these to stack - to be done in createStack
+                // here, we will map them to Map<String, Object> from Map<String, HeatFiles>
+                // this will match the nested templates format
+                LOGGER.debug ("Contents of heatFiles - to be added to files: on stack:");
+
+                for (String heatFileName : heatFiles.keySet ()) {
+                    String heatFileBody = heatFiles.get (heatFileName).getFileBody ();
+                    // Remove the file:/// enforcement for get_file:
+                    //String heatFileNameChecked = this.enforceFilePrefix (heatFileName);
+                    String heatFileNameChecked = heatFileName;
+                    LOGGER.debug (heatFileNameChecked + " -> " + heatFileBody);
+                    heatFilesObjects.put (heatFileNameChecked, heatFileBody);
+                }
+            } else {
+                LOGGER.debug ("No heat files found -nothing to do here");
+                heatFilesObjects = null;
+            }
+
+            // Check that required parameters have been supplied
+            String missingParams = null;
+            List <String> paramList = new ArrayList <String> ();
+
+            // New for 1510 - consult the PARAM_ALIAS field to see if we've been
+            // supplied an alias. Only check if we don't find it initially.
+            // Also new in 1510 - don't flag missing parameters if there's an environment - because they might be there.
+            // And also new - add parameter to turn off checking all together if we find we're blocking orders we
+            // shouldn't
+            boolean haveEnvironmentParameters = false;
+            boolean checkRequiredParameters = true;
+            try {
+                String propertyString = msoPropertiesFactory.getMsoJavaProperties (MSO_PROP_VNF_ADAPTER)
+                                                     .getProperty (MsoVnfAdapterImpl.CHECK_REQD_PARAMS,null);
+                if ("false".equalsIgnoreCase (propertyString) || "n".equalsIgnoreCase (propertyString)) {
+                    checkRequiredParameters = false;
+                    LOGGER.debug ("CheckRequiredParameters is FALSE. Will still check but then skip blocking..."
+                                  + MsoVnfAdapterImpl.CHECK_REQD_PARAMS);
+                }
+            } catch (Exception e) {
+                // No problem - default is true
+                LOGGER.debug ("An exception occured trying to get property " + MsoVnfAdapterImpl.CHECK_REQD_PARAMS, e);
+            }
+            // 1604 - Add enhanced environment & parameter checking
+            // Part 1: parse envt entries to see if reqd parameter is there (before used a simple grep
+            // Part 2: only submit to openstack the parameters in the envt that are in the heat template
+            // Note this also removes any comments
+            MsoHeatEnvironmentEntry mhee = null;
+            if (heatEnvironmentString != null && heatEnvironmentString.toLowerCase ().contains ("parameters:")) {
+            	LOGGER.debug("Enhanced environment checking enabled - 1604");
+                haveEnvironmentParameters = true;
+                StringBuilder sb = new StringBuilder(heatEnvironmentString);
+                //LOGGER.debug("About to create MHEE with " + sb);
+                mhee = new MsoHeatEnvironmentEntry(sb);
+                StringBuilder sb2 = new StringBuilder("\nHeat Template Parameters:\n");
+                for (HeatTemplateParam parm : heatTemplate.getParameters()) {
+                	sb2.append("\t" + parm.getParamName() + ", required=" + parm.isRequired());
+                }
+                if (!mhee.isValid()) {
+                	sb2.append("Environment says it's not valid! " + mhee.getErrorString());
+                } else {
+                	sb2.append("\nEnvironment:");
+                	sb2.append(mhee.toFullString());
+                }
+                LOGGER.debug(sb2.toString());
+            } else {
+            	LOGGER.debug("NO ENVIRONMENT for this entry");
+            }
+
+            for (HeatTemplateParam parm : heatTemplate.getParameters ()) {
+                LOGGER.debug ("Parameter:'" + parm.getParamName ()
+                              + "', isRequired="
+                              + parm.isRequired ()
+                              + ", alias="
+                              + parm.getParamAlias ());
+                if (parm.isRequired () && (inputs == null || !inputs.containsKey (parm.getParamName ()))) {
+                    if (inputs.containsKey (parm.getParamAlias ())) {
+                        // They've submitted using an alias name. Remove that from inputs, and add back using real name.
+                        String realParamName = parm.getParamName ();
+                        String alias = parm.getParamAlias ();
+                        String value = inputs.get (alias);
+                        LOGGER.debug ("*Found an Alias: paramName=" + realParamName
+                                      + ",alias="
+                                      + alias
+                                      + ",value="
+                                      + value);
+                        inputs.remove (alias);
+                        inputs.put (realParamName, value);
+                        LOGGER.debug (alias + " entry removed from inputs, added back using " + realParamName);
+                    } 
+                    // enhanced - check if it's in the Environment (note: that method 
+                    else if (mhee != null && mhee.containsParameter(parm.getParamName())) {
+
+                        LOGGER.debug ("Required parameter " + parm.getParamName ()
+                                      + " appears to be in environment - do not count as missing");
+                    }
+                    else {
+                        LOGGER.debug ("adding to missing parameters list: " + parm.getParamName ());
+                        if (missingParams == null) {
+                            missingParams = parm.getParamName ();
+                        } else {
+                            missingParams += "," + parm.getParamName ();
+                        }
+                    }
+                }
+                paramList.add (parm.getParamName ());
+            }
+            if (missingParams != null) {
+                // Problem - missing one or more required parameters
+            	if (checkRequiredParameters) {
+                String error = "Update VNF: Missing Required inputs: " + missingParams;
+                LOGGER.error (MessageEnum.RA_MISSING_PARAM, missingParams, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Update VNF: Missing Required inputs");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+                throw new VnfException (error, MsoExceptionCategory.USERDATA);
+            	} else {
+            		LOGGER.debug ("found missing parameters - but checkRequiredParameters is false - will not block");
+            	}
+            } else {
+                LOGGER.debug ("No missing parameters found - ok to proceed");
+            }
+            
+            // Here - modify heatEnvironmentString
+            StringBuilder parsedEnvironmentString = null; 
+            String newEnvironmentString = null;
+            if (mhee != null) {
+            	LOGGER.debug("Environment before:\n" + heatEnvironmentString);
+            	parsedEnvironmentString = mhee.toFullStringExcludeNonParams(heatTemplate.getParameters());
+            	LOGGER.debug("Environment after:\n" + parsedEnvironmentString.toString());
+            	newEnvironmentString = parsedEnvironmentString.toString();
+            }
+
+            // Remove any extraneous parameters (don't throw an error)
+            if (inputs != null) {
+                List <String> extraParams = new ArrayList <String> ();
+                extraParams.addAll (inputs.keySet ());
+                // This is not a valid parameter for this template
+                extraParams.removeAll (paramList);
+                if (!extraParams.isEmpty ()) {
+                	LOGGER.warn (MessageEnum.RA_VNF_EXTRA_PARAM, vnfType, extraParams.toString(), "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "VNF Extra params");
+                    inputs.keySet ().removeAll (extraParams);
+                }
+            }
+
+            // "Fix" the template if it has CR/LF (getting this from Oracle)
+            String template = heatTemplate.getHeatTemplate ();
+            template = template.replaceAll ("\r\n", "\n");
+
+            // Have the tenant. Now deploy the stack itself
+            // Ignore MsoTenantNotFound and MsoStackAlreadyExists exceptions
+            // because we already checked for those.
+            long updateStackStarttime = System.currentTimeMillis ();
+            try {
+                heatStack = heatU.updateStack (cloudSiteId,
+                                               tenantId,
+                                               vnfName,
+                                               template,
+                                               copyStringInputs (inputs),
+                                               true,
+                                               heatTemplate.getTimeoutMinutes (),
+                                               newEnvironmentString,
+                                               //heatEnvironmentString,
+                                               nestedTemplatesChecked,
+                                               heatFilesObjects);
+                LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "UpdateStack", vnfName);
+            } catch (MsoException me) {
+                me.addContext ("UpdateVNF");
+                String error = "Update VNF " + vnfType + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+                LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "UpdateStack", vnfName);
+                LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, vnfType, cloudSiteId, tenantId, "OpenStack", "updateStack", MsoLogger.ErrorCode.DataError, "Exception - updateStack", me);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                throw new VnfException (me);
+            }
+        }
+
+        // Reach this point if updateStack is successful.
+        // Populate remaining rollback info and response parameters.
+        vnfRollback.setVnfId (heatStack.getCanonicalName ());
+        vnfRollback.setVnfCreated (true);
+
+        outputs.value = copyStringOutputs (heatStack.getOutputs ());
+        rollback.value = vnfRollback;
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully update VNF");
+        return;
+    }
+
+    /**
+     * This is the "Query VNF" web service implementation.
+     * It will look up a VNF by name or ID in the specified cloud and tenant.
+     *
+     * The method returns an indicator that the VNF exists, its Openstack internal
+     * ID, its status, and the set of outputs (from when the stack was created).
+     *
+     * @param cloudSiteId CLLI code of the cloud site in which to query
+     * @param tenantId Openstack tenant identifier
+     * @param vnfName VNF Name or Openstack ID
+     * @param msoRequest Request tracking information for logs
+     * @param vnfExists Flag reporting the result of the query
+     * @param vnfId Holder for output VNF Openstack ID
+     * @param outputs Holder for Map of VNF outputs from heat (assigned IPs, etc)
+     */
+    @Override
+    public void queryVnf (String cloudSiteId,
+                          String tenantId,
+                          String vnfName,
+                          MsoRequest msoRequest,
+                          Holder <Boolean> vnfExists,
+                          Holder <String> vnfId,
+                          Holder <VnfStatus> status,
+                          Holder <Map <String, String>> outputs) throws VnfException {
+        MsoLogger.setLogContext (msoRequest);
+    	MsoLogger.setServiceName ("QueryVnf");
+        LOGGER.debug ("Querying VNF " + vnfName + " in " + cloudSiteId + "/" + tenantId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        StackInfo heatStack = null;
+        long subStartTime = System.currentTimeMillis ();
+        try {
+            heatStack = heat.queryStack (cloudSiteId, tenantId, vnfName);
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", vnfName);
+        } catch (MsoException me) {
+            me.addContext ("QueryVNF");
+            // Failed to query the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            String error = "Query VNF: " + vnfName + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", vnfName);
+            LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vnfName, cloudSiteId, tenantId, "OpenStack", "QueryVNF", MsoLogger.ErrorCode.DataError, "Exception - queryStack", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+
+        // Populate the outputs based on the returned Stack information
+        //
+        if (heatStack == null || heatStack.getStatus () == HeatStatus.NOTFOUND) {
+            // Not Found
+            vnfExists.value = Boolean.FALSE;
+            status.value = VnfStatus.NOTFOUND;
+            vnfId.value = null;
+            outputs.value = new HashMap <String, String> (); // Return as an empty map
+
+            LOGGER.debug ("VNF " + vnfName + " not found");
+        } else {
+            vnfExists.value = Boolean.TRUE;
+            status.value = stackStatusToVnfStatus (heatStack.getStatus ());
+            vnfId.value = heatStack.getCanonicalName ();
+            outputs.value = copyStringOutputs (heatStack.getOutputs ());
+
+            LOGGER.debug ("VNF " + vnfName + " found, ID = " + vnfId.value);
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully query VNF");
+        return;
+    }
+
+    /**
+     * This is the "Delete VNF" web service implementation.
+     * It will delete a VNF by name or ID in the specified cloud and tenant.
+     *
+     * The method has no outputs.
+     *
+     * @param cloudSiteId CLLI code of the cloud site in which to delete
+     * @param tenantId Openstack tenant identifier
+     * @param vnfName VNF Name or Openstack ID
+     * @param msoRequest Request tracking information for logs
+     */
+    @Override
+    public void deleteVnf (String cloudSiteId,
+                           String tenantId,
+                           String vnfName,
+                           MsoRequest msoRequest) throws VnfException {
+        MsoLogger.setLogContext (msoRequest);
+    	MsoLogger.setServiceName ("DeleteVnf");
+        LOGGER.debug ("Deleting VNF " + vnfName + " in " + cloudSiteId + "/" + tenantId);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        // Use the MsoHeatUtils to delete the stack. Set the polling flag to true.
+        // The possible outcomes of deleteStack are a StackInfo object with status
+        // of NOTFOUND (on success) or FAILED (on error). Also, MsoOpenstackException
+        // could be thrown.
+        long subStartTime = System.currentTimeMillis ();
+        try {
+            heat.deleteStack (tenantId, cloudSiteId, vnfName, true);
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteStack", vnfName);
+        } catch (MsoException me) {
+            me.addContext ("DeleteVNF");
+            // Failed to query the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            String error = "Delete VNF: " + vnfName + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteStack", vnfName);
+            LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, vnfName, cloudSiteId, tenantId, "OpenStack", "DeleteVNF", MsoLogger.ErrorCode.DataError, "Exception - DeleteVNF", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+
+        // On success, nothing is returned.
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully delete VNF");
+        return;
+    }
+
+    /**
+     * This web service endpoint will rollback a previous Create VNF operation.
+     * A rollback object is returned to the client in a successful creation
+     * response. The client can pass that object as-is back to the rollbackVnf
+     * operation to undo the creation.
+     */
+    @Override
+    public void rollbackVnf (VnfRollback rollback) throws VnfException {
+        long startTime = System.currentTimeMillis ();
+        MsoLogger.setServiceName ("RollbackVnf");
+    	// rollback may be null (e.g. if stack already existed when Create was called)
+        if (rollback == null) {
+            LOGGER.info (MessageEnum.RA_ROLLBACK_NULL, "OpenStack", "rollbackVnf");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, "Rollback request content is null");
+            return;
+        }
+
+        // Get the elements of the VnfRollback object for easier access
+        String cloudSiteId = rollback.getCloudSiteId ();
+        String tenantId = rollback.getTenantId ();
+        String vnfId = rollback.getVnfId ();
+
+        MsoLogger.setLogContext (rollback.getMsoRequest());
+
+        LOGGER.debug ("Rolling Back VNF " + vnfId + " in " + cloudSiteId + "/" + tenantId);
+
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        // Use the MsoHeatUtils to delete the stack. Set the polling flag to true.
+        // The possible outcomes of deleteStack are a StackInfo object with status
+        // of NOTFOUND (on success) or FAILED (on error). Also, MsoOpenstackException
+        // could be thrown.
+        long subStartTime = System.currentTimeMillis ();
+        try {
+            heat.deleteStack (tenantId, cloudSiteId, vnfId, true);
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteStack", null);
+        } catch (MsoException me) {
+            // Failed to rollback the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            me.addContext ("RollbackVNF");
+            String error = "Rollback VNF: " + vnfId + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteStack", null);
+            LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, vnfId, cloudSiteId, tenantId, "OpenStack", "DeleteStack", MsoLogger.ErrorCode.DataError, "Exception - DeleteStack", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully roll back VNF");
+        return;
+    }
+
+    private VnfStatus stackStatusToVnfStatus (HeatStatus stackStatus) {
+        switch (stackStatus) {
+            case CREATED:
+                return VnfStatus.ACTIVE;
+            case UPDATED:
+                return VnfStatus.ACTIVE;
+            case FAILED:
+                return VnfStatus.FAILED;
+            default:
+                return VnfStatus.UNKNOWN;
+        }
+    }
+
+    private Map <String, String> copyStringOutputs (Map <String, Object> stackOutputs) {
+        Map <String, String> stringOutputs = new HashMap <String, String> ();
+        for (String key : stackOutputs.keySet ()) {
+            if (stackOutputs.get (key) instanceof String) {
+                stringOutputs.put (key, (String) stackOutputs.get (key));
+            }
+        }
+        return stringOutputs;
+    }
+
+    private Map <String, Object> copyStringInputs (Map <String, String> stringInputs) {
+        return new HashMap <String, Object> (stringInputs);
+    }
+
+    /*
+     * a helper method to make sure that any resource_registry entry of the format
+     * "xx::xx" : yyy.yaml (or yyy.template)
+     * has the file name prepended with "file:///"
+     * Return a String of the environment body that's passed in.
+     * Have to be careful not to mess up the original formatting.
+     */
+    private String parseEnvironment (String environment) {
+        StringBuilder sb = new StringBuilder ();
+        try (Scanner scanner = new Scanner (environment)) {
+            scanner.useDelimiter ("\n");
+            String line = null;
+            Pattern resource = Pattern.compile ("\\s*\"\\w+::\\S+\"\\s*:");
+            LOGGER.debug ("regex pattern for finding a resource_registry: \\s*\"\\w+::\\S+\"\\s*:");
+            while (scanner.hasNextLine ()) {
+                line = scanner.nextLine ();
+                if (line.toLowerCase ().contains ("resource_registry")) {
+                    sb.append (line + "\n");
+                    boolean done = false;
+                    // basically keep scanning until EOF or parameters: section
+                    while (scanner.hasNextLine () && !done) {
+                        line = scanner.nextLine ();
+                        if ("parameters:".equalsIgnoreCase (line.trim ())) {
+                            sb.append (line + "\n");
+                            done = true;
+                            break;
+                        }
+                        Matcher m = resource.matcher (line);
+                        if (m.find ()) {
+                            sb.append (m.group ());
+                            String secondPart = line.substring (m.end ()).trim ();
+                            String output = secondPart;
+                            if (secondPart.endsWith (".yaml")
+                                || secondPart.endsWith (".template") && !secondPart.startsWith ("file:///")) {
+                                output = "file:///" + secondPart;
+                                LOGGER.debug ("changed " + secondPart + " to " + output);
+                            } // don't do anything if it's not .yaml or .template
+                            sb.append (" " + output + "\n");
+                        } else {
+                            sb.append (line + "\n");
+                        }
+                    }
+                } else {
+                    sb.append (line + "\n");
+                    continue;
+                }
+            }
+            scanner.close ();
+        } catch (Exception e) {
+            LOGGER.debug ("Error trying to scan " + environment, e);
+            return environment;
+        }
+        return sb.toString ();
+    }
+
+    /*
+     * helper class to add file:/// to the Provider_Resource_File entry in HEAT_NESTED_TEMPLATE
+     * and the File_Name entry in HEAT_FILES if the file:/// part is missing.
+     */
+    private String enforceFilePrefix (String string) {
+        if (string.trim ().startsWith ("file:///")) {
+            // just leave it
+            return string;
+        }
+        if (string.trim ().endsWith (".yaml") || string.trim ().endsWith (".template")) {
+            // only .yaml or .template are valid anyway - otherwise don't bother
+            return "file:///" + string.trim ();
+        } else {
+            LOGGER.debug (string + " is NOT a .yaml or .template file");
+        }
+        return string;
+    }
+    
+    private void sendMapToDebug(Map<String, String> inputs) {
+    	int i = 0;
+    	StringBuilder sb = new StringBuilder("inputs:");
+    	if (inputs == null) {
+    		sb.append("\tNULL");
+    	}
+    	else if (inputs.size() < 1) {
+    		sb.append("\tEMPTY");
+    	} else {
+    		for (String str : inputs.keySet()) {
+    			sb.append("\titem " + i++ + ": " + str + "=" + inputs.get(str));
+    		}
+    	}
+    	LOGGER.debug(sb.toString());
+    	return;
+    }
+
+    public void createVfModule(String cloudSiteId,
+            String tenantId,
+            String vnfType,
+            String vnfVersion,
+            String vnfName,
+            String requestType,
+            String volumeGroupHeatStackId,
+            String baseVfHeatStackId,
+            Map <String, String> inputs,
+            Boolean failIfExists,
+            Boolean backout,
+            MsoRequest msoRequest,
+            Holder <String> vnfId,
+            Holder <Map <String, String>> outputs,
+            Holder <VnfRollback> rollback) throws VnfException {
+    	String vfModuleName = vnfName;
+    	String vfModuleType = vnfType;
+    	String vfVersion = vnfVersion;
+    	MsoLogger.setLogContext (msoRequest);
+    	MsoLogger.setServiceName ("CreateVfModule");
+    	String requestTypeString = "";
+        if (requestType != null && !requestType.equals("")) {
+        	requestTypeString = requestType;
+        }
+        String nestedStackId = null;
+        if (volumeGroupHeatStackId != null && !volumeGroupHeatStackId.equals("")) {
+        	if (!volumeGroupHeatStackId.equalsIgnoreCase("null")) {
+        		nestedStackId = volumeGroupHeatStackId;
+        	}
+        }
+        String nestedBaseStackId = null;
+        if (baseVfHeatStackId != null && !baseVfHeatStackId.equals("")) {
+        	if (!baseVfHeatStackId.equalsIgnoreCase("null")) {
+        		nestedBaseStackId = baseVfHeatStackId;
+        	}
+        }
+        
+        if (inputs == null) {
+        	// Create an empty set of inputs
+        	inputs = new HashMap<String,String>();
+        	LOGGER.debug("inputs == null - setting to empty");
+        } else {
+        	this.sendMapToDebug(inputs);
+        }
+        //This method will also handle doing things the "old" way - i.e., just orchestrate a VNF
+        boolean oldWay = false;
+        if (requestTypeString.startsWith("X")) {
+        	oldWay = true;
+        	LOGGER.debug("orchestrating a VNF - *NOT* a module!");
+        	requestTypeString = requestTypeString.substring(1);
+        }
+        
+        // 1607 - let's parse out the request type we're being sent
+        boolean isBaseRequest = false;
+        boolean isVolumeRequest = false;
+        if (requestTypeString.startsWith("VOLUME")) {
+        	isVolumeRequest = true;
+        } 
+
+        LOGGER.debug("requestTypeString = " + requestTypeString + ", nestedStackId = " + nestedStackId + ", nestedBaseStackId = " + nestedBaseStackId);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Build a default rollback object (no actions performed)
+        VnfRollback vfRollback = new VnfRollback();
+        vfRollback.setCloudSiteId(cloudSiteId);
+        vfRollback.setTenantId(tenantId);
+        vfRollback.setMsoRequest(msoRequest);
+        vfRollback.setRequestType(requestTypeString);
+        vfRollback.setVolumeGroupHeatStackId(volumeGroupHeatStackId);
+        vfRollback.setBaseGroupHeatStackId(baseVfHeatStackId);
+        vfRollback.setIsBase(isBaseRequest);
+        
+        // First, look up to see if the VF already exists.
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        StackInfo heatStack = null;
+        long subStartTime1 = System.currentTimeMillis ();
+        try {
+            heatStack = heat.queryStack (cloudSiteId, tenantId, vfModuleName);
+            LOGGER.recordMetricEvent (subStartTime1, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", vfModuleName);
+        } catch (MsoException me) {
+            String error = "Create VF Module: Query " + vfModuleName + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+            LOGGER.recordMetricEvent (subStartTime1, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", vfModuleName);
+            LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Exception - queryStack", me);
+            // Failed to query the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            me.addContext ("CreateVFModule");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+        // New with 1607 - more precise handling/messaging if the stack already exists 
+        if (heatStack != null && !(heatStack.getStatus () == HeatStatus.NOTFOUND)) {
+        	// INIT, CREATED, NOTFOUND, FAILED, BUILDING, DELETING, UNKNOWN, UPDATING, UPDATED
+        	HeatStatus status = heatStack.getStatus();
+        	if (status == HeatStatus.INIT || status == HeatStatus.BUILDING || status == HeatStatus.DELETING || status == HeatStatus.UPDATING) {
+        		// fail - it's in progress - return meaningful error
+                String error = "Create VF: Stack " + vfModuleName + " already exists and has status " + status.toString() + " in " + cloudSiteId + "/" + tenantId + "; please wait for it to complete, or fix manually.";
+                LOGGER.error (MessageEnum.RA_VNF_ALREADY_EXIST, vfModuleName, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Stack " + vfModuleName + " already exists");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+                throw new VnfAlreadyExists (vfModuleName, cloudSiteId, tenantId, heatStack.getCanonicalName ());
+        	}
+        	if (status == HeatStatus.FAILED) {
+        		// fail - it exists and is in a FAILED state
+                String error = "Create VF: Stack " + vfModuleName + " already exists and is in FAILED state in " + cloudSiteId + "/" + tenantId + "; requires manual intervention.";
+                LOGGER.error (MessageEnum.RA_VNF_ALREADY_EXIST, vfModuleName, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Stack " + vfModuleName + " already exists and is in FAILED state");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+                throw new VnfAlreadyExists (vfModuleName, cloudSiteId, tenantId, heatStack.getCanonicalName ());	
+        	}
+        	if (status == HeatStatus.UNKNOWN || status == HeatStatus.UPDATED) {
+        		// fail - it exists and is in a FAILED state
+                String error = "Create VF: Stack " + vfModuleName + " already exists and has status " + status.toString() + " in " + cloudSiteId + "/" + tenantId + "; requires manual intervention.";
+                LOGGER.error (MessageEnum.RA_VNF_ALREADY_EXIST, vfModuleName, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Stack " + vfModuleName + " already exists and is in UPDATED or UNKNOWN state");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+                throw new VnfAlreadyExists (vfModuleName, cloudSiteId, tenantId, heatStack.getCanonicalName ());	
+        	}
+        	if (status == HeatStatus.CREATED) {
+        		// fail - it exists 
+        		if (failIfExists != null && failIfExists) {
+        			String error = "Create VF: Stack " + vfModuleName + " already exists in " + cloudSiteId + "/" + tenantId;
+        			LOGGER.error (MessageEnum.RA_VNF_ALREADY_EXIST, vfModuleName, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Stack " + vfModuleName + " already exists");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+        			throw new VnfAlreadyExists (vfModuleName, cloudSiteId, tenantId, heatStack.getCanonicalName ());	
+        		} else {
+        			LOGGER.debug ("Found Existing stack, status=" + heatStack.getStatus ());
+        			// Populate the outputs from the existing stack.
+        			vnfId.value = heatStack.getCanonicalName ();
+        			outputs.value = copyStringOutputs (heatStack.getOutputs ());
+        			rollback.value = vfRollback; // Default rollback - no updates performed
+        		}
+        	}
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully create VF Module");
+            return;
+        	
+        }
+        
+        // handle a nestedStackId if sent- this one would be for the volume - so applies to both Vf and Vnf
+        StackInfo nestedHeatStack = null;
+        long subStartTime2 = System.currentTimeMillis ();
+        if (nestedStackId != null) {
+        	try {
+        		LOGGER.debug("Querying for nestedStackId = " + nestedStackId);
+        		nestedHeatStack = heat.queryStack(cloudSiteId, tenantId, nestedStackId);
+                LOGGER.recordMetricEvent (subStartTime2, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", vfModuleName);
+        	} catch (MsoException me) {
+        	    // Failed to query the Stack due to an openstack exception.
+        	    // Convert to a generic VnfException
+        	    me.addContext ("CreateVFModule");
+        	    String error = "Create VFModule: Attached heatStack ID Query " + nestedStackId + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+                LOGGER.recordMetricEvent (subStartTime2, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", vfModuleName);
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.BusinessProcesssError, "MsoException trying to query nested stack", me);
+        		LOGGER.debug("ERROR trying to query nested stack= " + error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+        	    throw new VnfException (me);
+        	}
+        	if (nestedHeatStack == null || nestedHeatStack.getStatus() == HeatStatus.NOTFOUND) {
+        	    String error = "Create VFModule: Attached heatStack ID DOES NOT EXIST " + nestedStackId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR"  ;
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, error, "OpenStack", "queryStack", MsoLogger.ErrorCode.BusinessProcesssError, "Create VFModule: Attached heatStack ID DOES NOT EXIST");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+        	    LOGGER.debug(error);
+        	    throw new VnfException (error, MsoExceptionCategory.USERDATA);
+        	} else {
+        		LOGGER.debug("Found nested volume heat stack - copying values to inputs");
+        		this.sendMapToDebug(inputs);
+        		heat.copyStringOutputsToInputs(inputs, nestedHeatStack.getOutputs(), false);      
+        		this.sendMapToDebug(inputs);
+        	}
+        }
+        
+        // handle a nestedBaseStackId if sent- this is the stack ID of the base. Should be null for VNF requests
+        StackInfo nestedBaseHeatStack = null;
+        long subStartTime3 = System.currentTimeMillis ();
+        if (nestedBaseStackId != null) {
+        	try {
+        		LOGGER.debug("Querying for nestedBaseStackId = " + nestedBaseStackId);
+        		nestedBaseHeatStack = heat.queryStack(cloudSiteId, tenantId, nestedBaseStackId);
+                LOGGER.recordMetricEvent (subStartTime3, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", vfModuleName);
+        	} catch (MsoException me) {
+        	    // Failed to query the Stack due to an openstack exception.
+        	    // Convert to a generic VnfException
+        	    me.addContext ("CreateVFModule");
+        	    String error = "Create VFModule: Attached baseHeatStack ID Query " + nestedBaseStackId + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+                LOGGER.recordMetricEvent (subStartTime3, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", vfModuleName);
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.BusinessProcesssError, "MsoException trying to query nested base stack", me);
+        		LOGGER.debug("ERROR trying to query nested base stack= " + error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+        	    throw new VnfException (me);
+        	}
+        	if (nestedBaseHeatStack == null || nestedBaseHeatStack.getStatus() == HeatStatus.NOTFOUND) {
+        	    String error = "Create VFModule: Attached base heatStack ID DOES NOT EXIST " + nestedBaseStackId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR"  ;
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, error, "OpenStack", "QueryStack", MsoLogger.ErrorCode.BusinessProcesssError, "Create VFModule: Attached base heatStack ID DOES NOT EXIST");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+        	    LOGGER.debug(error);
+        	    throw new VnfException (error, MsoExceptionCategory.USERDATA);
+        	} else {
+        		LOGGER.debug("Found nested base heat stack - copying values to inputs");
+        		this.sendMapToDebug(inputs);
+        		heat.copyStringOutputsToInputs(inputs, nestedBaseHeatStack.getOutputs(), false);      
+        		this.sendMapToDebug(inputs);
+        	}
+        }
+        
+        // Ready to deploy the new VNF
+        
+        try (CatalogDatabase db = new CatalogDatabase()) {
+            // Retrieve the VF 
+        	VfModule vf = null;
+        	VnfResource vnfResource = null;
+        	LOGGER.debug("version: " + vfVersion);
+			if (!oldWay) {
+				// Need to handle old and new schema methods - for a time. Try the new way first.
+				if (vfVersion != null && !vfVersion.isEmpty()) {
+					vf = db.getVfModuleType(vfModuleType, vfVersion);
+					if (vf == null) {
+						LOGGER.debug("Unable to find " + vfModuleType + " and version=" + vfVersion + " in the TYPE column - will try in MODEL_NAME");
+						vf = db.getVfModuleModelName(vfModuleType, vfVersion);
+						if (vf == null) {
+							LOGGER.debug("Unable to find " + vfModuleType + " and version=" + vfVersion + " in the MODEL_NAME field either - ERROR");
+						}
+					}
+				} else {
+					vf = db.getVfModuleType(vfModuleType);
+					if (vf == null) {
+						LOGGER.debug("Unable to find " + vfModuleType + " in the TYPE column - will try in MODEL_NAME");
+						vf = db.getVfModuleModelName(vfModuleType);
+						if (vf == null) {
+							LOGGER.debug("Unable to find " + vfModuleType + " in the MODEL_NAME field either - ERROR");
+						}
+					}
+				}
+				if (vf == null) {
+					String error = "Create VF Module: Unable to determine specific VF Module Type: "
+							+ vfModuleType;
+					if (vfVersion != null && !vfVersion.isEmpty()) {
+						error += " with version = " + vfVersion;
+					}
+					LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM,
+							"VF Module Type", vfModuleType, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Create VF Module: Unable to determine specific VF Module Type");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+					throw new VnfException(error, MsoExceptionCategory.USERDATA);
+				}
+				LOGGER.debug("Got VF module definition from Catalog: "
+						+ vf.toString());
+
+				if (vf.isBase()) {
+					isBaseRequest = true;
+					LOGGER.debug("This is a BASE VF request!");
+				} else {
+					LOGGER.debug("This is *not* a BASE VF request!");
+					if (!isVolumeRequest && nestedBaseStackId == null) {
+						LOGGER.debug("DANGER WILL ROBINSON! This is unexpected - no nestedBaseStackId with this non-base request");
+					}
+				}
+			} else {
+				if (vfVersion != null && !vfVersion.isEmpty()) {
+					vnfResource = db.getVnfResource(vnfType, vnfVersion);
+				} else {
+					vnfResource = db.getVnfResource(vnfType);
+				}
+				if (vnfResource == null) {
+					String error = "Create VNF: Unknown VNF Type: " + vnfType;
+					LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM, "VNF Type",
+							vnfType, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Create VNF: Unknown VNF Type");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+					throw new VnfException(error, MsoExceptionCategory.USERDATA);
+				}
+				LOGGER.debug("Got VNF module definition from Catalog: "
+						+ vnfResource.toString());
+			}
+			// By here - we have either a vf or vnfResource
+
+            //1607 - Add version check
+            // First - see if it's in the VnfResource record
+            // if we have a vf Module - then we have to query to get the VnfResource record.
+            if (!oldWay) {
+            	if (vf.getVnfResourceId() != null) { 
+            		int vnfResourceId = vf.getVnfResourceId();
+            		vnfResource = db.getVnfResourceById(vnfResourceId);
+            		if (vnfResource == null) {
+            			LOGGER.debug("Unable to find vnfResource at " + vnfResourceId + " will not error for now...");
+            		}
+            	}
+            } 
+            String minVersionVnf = null;
+            String maxVersionVnf = null;
+            if (vnfResource != null) {
+            	try {
+            		minVersionVnf = vnfResource.getAicVersionMin();
+            		maxVersionVnf = vnfResource.getAicVersionMax();
+            	} catch (Exception e) {
+            		LOGGER.debug("Unable to pull min/max version for this VNF Resource entry");
+            		minVersionVnf = null;
+            		maxVersionVnf = null;
+            	}
+            	if (minVersionVnf != null && minVersionVnf.equals("")) {
+            		minVersionVnf = null;
+            	}
+            	if (maxVersionVnf != null && maxVersionVnf.equals("")) {
+            		maxVersionVnf = null;
+            	}
+            }
+			if (minVersionVnf != null && maxVersionVnf != null) {
+				MavenLikeVersioning aicV = new MavenLikeVersioning();
+				CloudSite cloudSite = null;
+				String aicVersion = "";
+				if (this.cloudConfig == null) {
+					this.cloudConfig = this.cloudConfigFactory.getCloudConfig();
+				}
+				// double check
+				if (this.cloudConfig != null) {
+					cloudSite = this.cloudConfig.getCloudSite(cloudSiteId);
+					if (cloudSite != null) {
+						aicV.setVersion(cloudSite.getAic_version());
+						if ((aicV.isMoreRecentThan(minVersionVnf) || aicV.isTheSameVersion(minVersionVnf)) // aic >= min
+								&& (aicV.isTheSameVersion(maxVersionVnf) || !(aicV.isMoreRecentThan(maxVersionVnf)))) { //aic <= max
+							LOGGER.debug("VNF Resource " + vnfResource.getVnfType() + " VersionMin=" + minVersionVnf + " VersionMax:" + maxVersionVnf + " supported on Cloud: " + cloudSite.getId() + " with AIC_Version:" + cloudSite.getAic_version());
+						} else {
+							// ERROR
+							String error = "VNF Resource type: " + vnfResource.getVnfType() + " VersionMin=" + minVersionVnf + " VersionMax:" + maxVersionVnf + " NOT supported on Cloud: " + cloudSite.getId() + " with AIC_Version:" + cloudSite.getAic_version();
+							LOGGER.error(MessageEnum.RA_CONFIG_EXC, error, "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - setVersion");
+							LOGGER.debug(error);
+							throw new VnfException(error, MsoExceptionCategory.USERDATA);
+						}
+					} // let this error out downstream to avoid introducing uncertainty at this stage
+				} else {
+					LOGGER.debug("cloudConfig is NULL - cannot check cloud site version");
+				}
+
+			} else {
+				LOGGER.debug("AIC Version not set in VNF_Resource - this is expected thru 1607 - do not error here - not checked.");
+			}
+			// End Version check 1607
+
+            // with VF_MODULE - we have both the non-vol and vol template/envs in that object
+            // with VNF_RESOURCE - we use the old methods. 
+            Integer heatTemplateId = null;
+            Integer heatEnvtId = null;
+            
+			if (!oldWay) {
+				if (isVolumeRequest) {
+					heatTemplateId = vf.getVolTemplateId();
+					heatEnvtId = vf.getVolEnvironmentId();
+				} else {
+					heatTemplateId = vf.getTemplateId();
+					heatEnvtId = vf.getEnvironmentId();
+				}
+			} else {
+				if (isVolumeRequest) {
+					VnfComponent vnfComponent = null;
+					vnfComponent = db.getVnfComponent(vnfResource.getId(), "VOLUME");
+	            	if (vnfComponent == null) {
+	            		String error = "Create VNF: Cannot find VNF Component entry for: " + vnfType + ", type = VOLUME";
+	            		LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "VNF Type", vnfType, "OpenStack", "getVnfComponent", MsoLogger.ErrorCode.DataError, "Create VNF: Cannot find VNF Component entry");
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+	            		throw new VnfException (error, MsoExceptionCategory.USERDATA);
+	            	} else {
+	            		heatTemplateId = vnfComponent.getHeatTemplateId();
+	            		heatEnvtId = vnfComponent.getHeatEnvironmentId();
+	            	}
+				} else {
+					heatTemplateId = vnfResource.getTemplateId();
+					heatEnvtId = vnfResource.getEnvironmentId();
+				}
+			}
+			// By the time we get here - heatTemplateId and heatEnvtId should be populated (or null)
+			HeatTemplate heatTemplate = null;
+			if (heatTemplateId == null) {
+				String error = "Create: No Heat Template ID defined in catalog database for " + vnfType + ", reqType=" + requestTypeString;
+				LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Template ID", vnfType, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Create: No Heat Template ID defined in catalog database");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+				alarmLogger.sendAlarm(MSO_CONFIGURATION_ERROR,
+						MsoAlarmLogger.CRITICAL, error);
+				throw new VnfException(error, MsoExceptionCategory.INTERNAL);
+			} else {
+				heatTemplate = db.getHeatTemplate(heatTemplateId);
+			}
+			if (heatTemplate == null) {
+				String error = "Create VF/VNF: no entry found for heat template ID = " + heatTemplateId;
+				LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM,
+						"Heat Template ID",
+						String.valueOf(heatTemplateId), "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create VF/VNF: no entry found for heat template ID = " + heatTemplateId);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+				alarmLogger.sendAlarm(MSO_CONFIGURATION_ERROR,
+						MsoAlarmLogger.CRITICAL, error);
+				throw new VnfException(error, MsoExceptionCategory.INTERNAL);
+			}
+			LOGGER.debug("Got HEAT Template from DB");
+            
+            HeatEnvironment heatEnvironment = null;
+            String heatEnvironmentString = null;
+
+            if (heatEnvtId != null && heatEnvtId != 0) {
+                LOGGER.debug ("about to call getHeatEnvironment with :" + heatEnvtId + ":");
+                heatEnvironment = db.getHeatEnvironment (heatEnvtId);
+                if (heatEnvironment == null) {
+                    String error = "Create VFModule: undefined Heat Environment. VFModule=" + vfModuleType
+                                   + ", Environment ID="
+                                   + heatEnvtId;
+                    LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Environment ID", String.valueOf(heatEnvtId), "OpenStack", "getHeatEnvironment", MsoLogger.ErrorCode.BusinessProcesssError, "Create VFModule: undefined Heat Environment");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                    // Alarm on this error, configuration must be fixed
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+
+                    throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+                } else {
+                    LOGGER.debug ("Got Heat Environment from DB: " + heatEnvironment.toString ());
+                    heatEnvironmentString = heatEnvironment.getEnvironment (); //this.parseEnvironment (heatEnvironment.getEnvironment ());
+                    LOGGER.debug ("after parsing: " + heatEnvironmentString);
+                }
+            } else {
+                LOGGER.debug ("no environment parameter found for this Type " + vfModuleType);
+            }
+            
+            // 1510 - Add the files: for nested templates *if* there are any
+            LOGGER.debug ("In MsoVnfAdapterImpl, createVfModule about to call db.getNestedTemplates avec templateId="
+                          + heatTemplate.getId ());
+            Map <String, Object> nestedTemplates = db.getNestedTemplates (heatTemplate.getId ());
+            Map <String, Object> nestedTemplatesChecked = new HashMap <String, Object> ();
+            if (nestedTemplates != null) {
+                // for debugging print them out
+                LOGGER.debug ("Contents of nestedTemplates - to be added to files: on stack:");
+                for (String providerResourceFile : nestedTemplates.keySet ()) {
+                    String providerResourceFileChecked = providerResourceFile; //this.enforceFilePrefix (providerResourceFile);
+                    String childTemplateBody = (String) nestedTemplates.get (providerResourceFile);
+                    LOGGER.debug (providerResourceFileChecked + " -> " + childTemplateBody);
+                    nestedTemplatesChecked.put (providerResourceFileChecked, childTemplateBody);
+                }
+            } else {
+                LOGGER.debug ("No nested templates found - nothing to do here");
+                nestedTemplatesChecked = null; // just to make sure
+            }
+
+            // 1510 - Also add the files: for any get_files associated with this vnf_resource_id
+            // *if* there are any
+            Map<String, HeatFiles> heatFiles = null;
+			Map<String, Object> heatFilesObjects = new HashMap<String, Object>();
+
+            // Add ability to turn on adding get_files with volume requests (by property).
+            boolean addGetFilesOnVolumeReq = false;
+            try {
+            	String propertyString = msoPropertiesFactory.getMsoJavaProperties(MSO_PROP_VNF_ADAPTER).getProperty(MsoVnfAdapterImpl.ADD_GET_FILES_ON_VOLUME_REQ, null);
+            	if ("true".equalsIgnoreCase(propertyString) || "y".equalsIgnoreCase(propertyString)) {
+            		addGetFilesOnVolumeReq = true;
+            		LOGGER.debug("AddGetFilesOnVolumeReq - setting to true! " + propertyString);
+            	}
+            } catch (Exception e) {
+            	LOGGER.debug("An error occured trying to get property " + MsoVnfAdapterImpl.ADD_GET_FILES_ON_VOLUME_REQ + " - default to false", e);
+            }
+
+			if (!isVolumeRequest || addGetFilesOnVolumeReq) {
+				if (oldWay) {
+					LOGGER.debug("In MsoVnfAdapterImpl createVfModule, about to call db.getHeatFiles avec vnfResourceId="
+							+ vnfResource.getId());
+					heatFiles = db.getHeatFiles(vnfResource.getId());
+				} else {
+					// 1607 - now use VF_MODULE_TO_HEAT_FILES table
+					LOGGER.debug("In MsoVnfAdapterImpl createVfModule, about to call db.getHeatFilesForVfModule avec vfModuleId="
+							+ vf.getId());
+					heatFiles = db
+							.getHeatFilesForVfModule(vf.getId());
+				}
+				if (heatFiles != null) {
+					// add these to stack - to be done in createStack
+					// here, we will map them to Map<String, Object> from
+					// Map<String, HeatFiles>
+					// this will match the nested templates format
+					LOGGER.debug("Contents of heatFiles - to be added to files: on stack:");
+
+					for (String heatFileName : heatFiles.keySet()) {
+						if (heatFileName.startsWith("_ERROR|")) {
+							// This means there was an invalid entry in VF_MODULE_TO_HEAT_FILES table - the heat file it pointed to could not be found.
+							String heatFileId = heatFileName.substring(heatFileName.lastIndexOf("|")+1);
+							String error = "Create: No HEAT_FILES entry in catalog database for " + vfModuleType + " at HEAT_FILES index=" + heatFileId;
+							LOGGER.debug(error);
+							LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "HEAT_FILES entry not found at " + heatFileId, vfModuleType, "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "HEAT_FILES entry not found");
+                            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+							// Alarm on this error, configuration must be fixed
+							alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+							throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+						}
+						String heatFileBody = heatFiles.get(heatFileName)
+								.getFileBody();
+						String heatFileNameChecked = heatFileName;
+						LOGGER.debug(heatFileNameChecked + " -> "
+								+ heatFileBody);
+						heatFilesObjects.put(heatFileNameChecked, heatFileBody);
+					}
+				} else {
+					LOGGER.debug("No heat files found -nothing to do here");
+					heatFilesObjects = null;
+				}
+			} else {
+					LOGGER.debug("Volume request - DO NOT CHECK for HEAT_FILES");
+			}
+
+            // Check that required parameters have been supplied
+            String missingParams = null;
+            List <String> paramList = new ArrayList <String> ();
+
+            // New for 1510 - consult the PARAM_ALIAS field to see if we've been
+            // supplied an alias. Only check if we don't find it initially.
+            // Also new in 1510 - don't flag missing parameters if there's an environment - because they might be there.
+            // And also new - add parameter to turn off checking all together if we find we're blocking orders we
+            // shouldn't
+            boolean haveEnvironmentParameters = false;
+            boolean checkRequiredParameters = true;
+            try {
+                String propertyString = msoPropertiesFactory.getMsoJavaProperties (MSO_PROP_VNF_ADAPTER)
+                                                     .getProperty (MsoVnfAdapterImpl.CHECK_REQD_PARAMS,null);
+                if ("false".equalsIgnoreCase (propertyString) || "n".equalsIgnoreCase (propertyString)) {
+                    checkRequiredParameters = false;
+                    LOGGER.debug ("CheckRequiredParameters is FALSE. Will still check but then skip blocking..."
+                                  + MsoVnfAdapterImpl.CHECK_REQD_PARAMS);
+                }
+            } catch (Exception e) {
+                // No problem - default is true
+                LOGGER.debug ("An exception occured trying to get property " + MsoVnfAdapterImpl.CHECK_REQD_PARAMS, e);
+            }
+            // 1604 - Add enhanced environment & parameter checking
+            // Part 1: parse envt entries to see if reqd parameter is there (before used a simple grep
+            // Part 2: only submit to openstack the parameters in the envt that are in the heat template
+            // Note this also removes any comments
+            MsoHeatEnvironmentEntry mhee = null;
+            if (heatEnvironmentString != null && heatEnvironmentString.contains ("parameters:")) {
+                //LOGGER.debug ("Have an Environment argument with a parameters: section - will bypass checking for valid params - but will still check for aliases");
+            	LOGGER.debug("Enhanced environment checking enabled - 1604");
+                haveEnvironmentParameters = true;
+                StringBuilder sb = new StringBuilder(heatEnvironmentString);
+                //LOGGER.debug("About to create MHEE with " + sb);
+                mhee = new MsoHeatEnvironmentEntry(sb);
+                StringBuilder sb2 = new StringBuilder("\nHeat Template Parameters:\n");
+                for (HeatTemplateParam parm : heatTemplate.getParameters()) {
+                	sb2.append("\t" + parm.getParamName() + ", required=" + parm.isRequired());
+                }
+                if (!mhee.isValid()) {
+                	sb2.append("Environment says it's not valid! " + mhee.getErrorString());
+                } else {
+                	sb2.append("\nEnvironment:");
+                	sb2.append(mhee.toFullString());
+                }
+                LOGGER.debug(sb2.toString());
+            } else {
+            	LOGGER.debug("NO ENVIRONMENT for this entry");
+            }
+            // This is kind of a mess. inputs is a Map<String, String> --
+            // if one of the parameters is json - we need to pass String, JsonNode -
+            // so we will store off the parameters that are json in its own HashMap
+            // if there are any json params - then we convert inputs to a Map<String, Object>
+            // and pass that to createStack
+            HashMap<String, JsonNode> jsonParams = new HashMap<String, JsonNode>();
+            boolean hasJson = false;
+
+            for (HeatTemplateParam parm : heatTemplate.getParameters ()) {
+                LOGGER.debug ("Parameter:'" + parm.getParamName ()
+                              + "', isRequired="
+                              + parm.isRequired ()
+                              + ", alias="
+                              + parm.getParamAlias ());
+                // New 1607 - support json type
+                String parameterType = parm.getParamType();
+                if (parameterType == null || parameterType.trim().equals("")) {
+                	parameterType = "String";
+                }
+                JsonNode jsonNode = null;
+                if (parameterType.equalsIgnoreCase("json") && inputs != null) {
+                	if (inputs.containsKey(parm.getParamName()) ) {
+                		hasJson = true;
+                		String jsonString = null;
+                		try {
+                			jsonString = inputs.get(parm.getParamName());
+                			jsonNode = new ObjectMapper().readTree(jsonString);
+                		} catch (JsonParseException jpe) {
+                			//TODO - what to do here?
+                			//for now - send the error to debug, but just leave it as a String
+                			String errorMessage = jpe.getMessage();
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " - " + errorMessage);
+                			hasJson = false;
+                			jsonNode = null;
+                		} catch (Exception e) {
+                			// or here?
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " " + e.getMessage());
+                			hasJson = false;
+                			jsonNode = null;
+                		}
+                		if (jsonNode != null) {
+                			jsonParams.put(parm.getParamName(), jsonNode);
+                		}
+                	} else if (inputs.containsKey(parm.getParamAlias())) {
+                		hasJson = true;
+                		String jsonString = null;
+                   		try {
+                			jsonString = inputs.get(parm.getParamAlias());
+                			jsonNode = new ObjectMapper().readTree(jsonString);
+                		} catch (JsonParseException jpe) {
+                			//TODO - what to do here?
+                			//for now - send the error to debug, but just leave it as a String
+                			String errorMessage = jpe.getMessage();
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " - " + errorMessage);
+                			hasJson = false;
+                			jsonNode = null;
+                		} catch (Exception e) {
+                			// or here?
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " " + e.getMessage());
+                			hasJson = false;
+                			jsonNode = null;
+                		}
+                   		if (jsonNode != null) {
+                   			// Notice here - we add it to the jsonParams hashMap with the actual name -
+                   			// then manipulate the inputs so when we check for aliases below - it will not
+                   			// get flagged.
+                   			jsonParams.put(parm.getParamName(), jsonNode);
+                   			inputs.remove(parm.getParamAlias());
+                   			inputs.put(parm.getParamName(), jsonString);
+                   		}
+                	} //TODO add a check for the parameter in the env file
+                }
+                if (parm.isRequired () && (inputs == null || !inputs.containsKey (parm.getParamName ()))) {
+                	// Check if they have an alias
+                	LOGGER.debug("**Parameter " + parm.getParamName() + " is required and not in the inputs...");
+                    if (inputs.containsKey (parm.getParamAlias ())) {
+                        // They've submitted using an alias name. Remove that from inputs, and add back using real name.
+                        String realParamName = parm.getParamName ();
+                        String alias = parm.getParamAlias ();
+                        String value = inputs.get (alias);
+                        LOGGER.debug ("*Found an Alias: paramName=" + realParamName
+                                      + ",alias="
+                                      + alias
+                                      + ",value="
+                                      + value);
+                        inputs.remove (alias);
+                        inputs.put (realParamName, value);
+                        LOGGER.debug (alias + " entry removed from inputs, added back using " + realParamName);
+                    } 
+                    // enhanced - check if it's in the Environment (note: that method 
+                    else if (mhee != null && mhee.containsParameter(parm.getParamName())) {
+
+                        LOGGER.debug ("Required parameter " + parm.getParamName ()
+                                      + " appears to be in environment - do not count as missing");
+                    } else {
+                        LOGGER.debug ("adding to missing parameters list: " + parm.getParamName ());
+                        if (missingParams == null) {
+                            missingParams = parm.getParamName ();
+                        } else {
+                            missingParams += "," + parm.getParamName ();
+                        }
+                    }
+                }
+                paramList.add (parm.getParamName ());
+            }
+            if (missingParams != null) {
+            	if (checkRequiredParameters) {
+            		// Problem - missing one or more required parameters
+            		String error = "Create VFModule: Missing Required inputs: " + missingParams;
+            		LOGGER.error (MessageEnum.RA_MISSING_PARAM, missingParams, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Create VFModule: Missing Required inputs");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+            		throw new VnfException (error, MsoExceptionCategory.USERDATA);
+            	} else {
+            		LOGGER.debug ("found missing parameters - but checkRequiredParameters is false - will not block");
+            	}
+            } else {
+                LOGGER.debug ("No missing parameters found - ok to proceed");
+            }
+            
+            // Here - modify heatEnvironmentString
+            StringBuilder parsedEnvironmentString = null; 
+            String newEnvironmentString = null;
+            if (mhee != null) {
+            	LOGGER.debug("Environment before:\n" + heatEnvironmentString);
+            	parsedEnvironmentString = mhee.toFullStringExcludeNonParams(heatTemplate.getParameters());
+            	LOGGER.debug("Environment after:\n" + parsedEnvironmentString.toString());
+            	newEnvironmentString = parsedEnvironmentString.toString();
+            }
+
+            // Remove any extraneous parameters (don't throw an error)
+            if (inputs != null) {
+                List <String> extraParams = new ArrayList <String> ();
+                extraParams.addAll (inputs.keySet ());
+                extraParams.removeAll (paramList);
+                if (!extraParams.isEmpty ()) {
+                    LOGGER.warn (MessageEnum.RA_VNF_EXTRA_PARAM, vnfType, extraParams.toString(), "OpenStack", "", MsoLogger.ErrorCode.DataError, "Extra params");
+                    inputs.keySet ().removeAll (extraParams);
+                }
+            }
+            // 1607 - when we get here - we have clean inputs. Check if we have
+            Map<String, Object> inputsTwo = null;
+            if (hasJson && jsonParams.size() > 0) {
+            	inputsTwo = new HashMap<String, Object>();
+            	for (String keyParamName : inputs.keySet()) {
+            		if (jsonParams.containsKey(keyParamName)) {
+            			inputsTwo.put(keyParamName, jsonParams.get(keyParamName));
+            		} else {
+            			inputsTwo.put(keyParamName, inputs.get(keyParamName));
+            		}
+            	}
+            }
+
+            // "Fix" the template if it has CR/LF (getting this from Oracle)
+            String template = heatTemplate.getHeatTemplate ();
+            template = template.replaceAll ("\r\n", "\n");
+
+            // Have the tenant. Now deploy the stack itself
+            // Ignore MsoTenantNotFound and MsoStackAlreadyExists exceptions
+            // because we already checked for those.
+            long createStackStarttime = System.currentTimeMillis ();
+            try {
+                // heatStack = heat.createStack(cloudSiteId, tenantId, vnfName, template, inputs, true,
+                // heatTemplate.getTimeoutMinutes());
+            	if (backout == null) {
+            		backout = true;
+            	}
+            	if (heat != null) {
+            		LOGGER.debug("heat is not null!!");
+            	}
+
+            	if (!hasJson) {
+            		heatStack = heat.createStack (cloudSiteId,
+                                              tenantId,
+                                              vfModuleName,
+                                              template,
+                                              inputs,
+                                              true,
+                                              heatTemplate.getTimeoutMinutes (),
+                                              newEnvironmentString,
+                                              //heatEnvironmentString,
+                                              nestedTemplatesChecked,
+                                              heatFilesObjects,
+                                              backout.booleanValue());
+                LOGGER.recordMetricEvent (createStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "CreateStack", vfModuleName);
+            	} else {
+            		heatStack = heat.createStack (cloudSiteId,
+                                              tenantId,
+                                              vfModuleName,
+                                              template,
+                                              inputsTwo,
+                                              true,
+                                              heatTemplate.getTimeoutMinutes (),
+                                              newEnvironmentString,
+                                              //heatEnvironmentString,
+                                              nestedTemplatesChecked,
+                                              heatFilesObjects,
+                                              backout.booleanValue());
+
+            	}
+                LOGGER.recordMetricEvent (createStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "CreateStack", vfModuleName);
+            } catch (MsoException me) {
+                me.addContext ("CreateVFModule");
+                String error = "Create VF Module " + vfModuleType + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+                LOGGER.recordMetricEvent (createStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "CreateStack", vfModuleName);
+                LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, vfModuleType, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "MsoException - createStack", me);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                throw new VnfException (me);
+            } catch (NullPointerException npe) {
+                String error = "Create VFModule " + vfModuleType + " in " + cloudSiteId + "/" + tenantId + ": " + npe;
+                LOGGER.recordMetricEvent (createStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "CreateStack", vfModuleName);
+                LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, vfModuleType, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "NullPointerException - createStack", npe);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                LOGGER.debug("NULL POINTER EXCEPTION at heat.createStack");
+                //npe.addContext ("CreateVNF");
+                throw new VnfException ("NullPointerException during heat.createStack");
+            } catch (Exception e) {
+                LOGGER.recordMetricEvent (createStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while creating stack with OpenStack", "OpenStack", "CreateStack", vfModuleName);
+                LOGGER.debug("unhandled exception at heat.createStack");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while creating stack with OpenStack");
+            	throw new VnfException("Exception during heat.createStack! " + e.getMessage());
+            }
+        } catch (Exception e) {
+        	LOGGER.debug("unhandled exception in create VF");
+        	throw new VnfException("Exception during create VF " + e.getMessage());
+        	
+        }
+
+        // Reach this point if createStack is successful.
+        // Populate remaining rollback info and response parameters.
+        vfRollback.setVnfId (heatStack.getCanonicalName ());
+        vfRollback.setVnfCreated (true);
+
+        vnfId.value = heatStack.getCanonicalName ();
+        outputs.value = copyStringOutputs (heatStack.getOutputs ());
+        rollback.value = vfRollback;
+
+        LOGGER.debug ("VF Module " + vfModuleName + " successfully created");
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully create VF Module");
+        return;
+
+    	
+    }
+    
+    public void deleteVfModule (String cloudSiteId,
+                           String tenantId,
+                           String vnfName,
+                           MsoRequest msoRequest) throws VnfException {
+        MsoLogger.setLogContext (msoRequest);
+    	MsoLogger.setServiceName ("DeleteVf");
+        LOGGER.debug ("Deleting VF " + vnfName + " in " + cloudSiteId + "/" + tenantId);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        // Use the MsoHeatUtils to delete the stack. Set the polling flag to true.
+        // The possible outcomes of deleteStack are a StackInfo object with status
+        // of NOTFOUND (on success) or FAILED (on error). Also, MsoOpenstackException
+        // could be thrown.
+        long subStartTime = System.currentTimeMillis ();
+        try {
+            heat.deleteStack (tenantId, cloudSiteId, vnfName, true);
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteStack", vnfName);
+        } catch (MsoException me) {
+            me.addContext ("DeleteVNF");
+            // Failed to query the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            String error = "Delete VF: " + vnfName + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteStack", vnfName);
+            LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, vnfName, cloudSiteId, tenantId, "OpenStack", "DeleteStack", MsoLogger.ErrorCode.DataError, "Exception - deleteStack", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+
+        // On success, nothing is returned.
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully delete VF");
+        return;
+    }
+
+    @Override
+    public void updateVfModule (String cloudSiteId,
+                           String tenantId,
+                           String vnfType,
+                           String vnfVersion,
+                           String vnfName,
+                           String requestType,
+                           String volumeGroupHeatStackId,
+                           String baseVfHeatStackId,
+                           String vfModuleStackId,
+                           Map <String, String> inputs,
+                           MsoRequest msoRequest,
+                           Holder <Map <String, String>> outputs,
+                           Holder <VnfRollback> rollback) throws VnfException {
+    	String vfModuleName = vnfName;
+    	String vfModuleType = vnfType;
+    	String vfVersion = vnfVersion;
+    	String methodName = "updateVfModule";
+    	MsoLogger.setLogContext (msoRequest.getRequestId (), msoRequest.getServiceInstanceId ());
+    	String serviceName = VNF_ADAPTER_SERVICE_NAME + methodName;
+    	MsoLogger.setServiceName (serviceName);
+
+    	String requestTypeString = "";
+        if (requestType != null && !requestType.equals("")) {
+        	requestTypeString = requestType;
+        }
+        String nestedStackId = null;
+        if (volumeGroupHeatStackId != null && !volumeGroupHeatStackId.equals("")) {
+        	if (!volumeGroupHeatStackId.equalsIgnoreCase("null")) {
+        		nestedStackId = volumeGroupHeatStackId;
+        	}
+        }
+        String nestedBaseStackId = null;
+        if (baseVfHeatStackId != null && !baseVfHeatStackId.equals("")) {
+        	if (!baseVfHeatStackId.equalsIgnoreCase("null")) {
+        		nestedBaseStackId = baseVfHeatStackId;
+        	}
+        }
+
+        if (inputs == null) {
+        	// Create an empty set of inputs
+        	inputs = new HashMap<String,String>();
+        	LOGGER.debug("inputs == null - setting to empty");
+        } else {
+        	this.sendMapToDebug(inputs);
+        }
+        boolean isBaseRequest = false;
+        boolean isVolumeRequest = false;
+        if (requestTypeString.startsWith("VOLUME")) {
+        	isVolumeRequest = true;
+        }
+        if (vfModuleName == null || vfModuleName.trim().equals("")) {
+        	if (vfModuleStackId != null) {
+        		vfModuleName = this.getVfModuleNameFromModuleStackId(vfModuleStackId);
+        	}
+        }
+
+        LOGGER.debug ("Updating VFModule: " + vfModuleName + " of type " + vfModuleType + "in " + cloudSiteId + "/" + tenantId);
+        LOGGER.debug("requestTypeString = " + requestTypeString + ", nestedStackId = " + nestedStackId + ", nestedBaseStackId = " + nestedBaseStackId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Build a default rollback object (no actions performed)
+        VnfRollback vfRollback = new VnfRollback ();
+        vfRollback.setCloudSiteId (cloudSiteId);
+        vfRollback.setTenantId (tenantId);
+        vfRollback.setMsoRequest (msoRequest);
+        vfRollback.setRequestType(requestTypeString);
+        vfRollback.setVolumeGroupHeatStackId(volumeGroupHeatStackId);
+        vfRollback.setBaseGroupHeatStackId(baseVfHeatStackId);
+        vfRollback.setIsBase(isBaseRequest);
+        vfRollback.setVfModuleStackId(vfModuleStackId);
+
+        // First, look up to see if the VNF already exists.
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+        MsoHeatUtilsWithUpdate heatU = new MsoHeatUtilsWithUpdate (MSO_PROP_VNF_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+        StackInfo heatStack = null;
+        long queryStackStarttime = System.currentTimeMillis ();
+        LOGGER.debug("UpdateVfModule - querying for " + vfModuleName);
+        try {
+            heatStack = heat.queryStack (cloudSiteId, tenantId, vfModuleName);
+            LOGGER.recordMetricEvent (queryStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully receive response from Open Stack", "OpenStack", "QueryStack", null);
+        } catch (MsoException me) {
+            // Failed to query the Stack due to an openstack exception.
+            // Convert to a generic VnfException
+            me.addContext ("UpdateVFModule");
+            String error = "Update VFModule: Query " + vfModuleName + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (queryStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", null);
+            LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Exception - QueryStack", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new VnfException (me);
+        }
+
+        //TODO - do we need to check for the other status possibilities?
+        if (heatStack == null || heatStack.getStatus () == HeatStatus.NOTFOUND) {
+            // Not Found
+            String error = "Update VF: Stack " + vfModuleName + " does not exist in " + cloudSiteId + "/" + tenantId;
+            LOGGER.error (MessageEnum.RA_VNF_NOT_EXIST, vfModuleName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, error);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+            throw new VnfNotFound (cloudSiteId, tenantId, vfModuleName);
+        } else {
+            LOGGER.debug ("Found Existing stack, status=" + heatStack.getStatus ());
+            // Populate the outputs from the existing stack.
+            outputs.value = copyStringOutputs (heatStack.getOutputs ());
+            rollback.value = vfRollback; // Default rollback - no updates performed
+        }
+
+        // 1604 Cinder Volume support - handle a nestedStackId if sent (volumeGroupHeatStackId):
+        StackInfo nestedHeatStack = null;
+        long queryStackStarttime2 = System.currentTimeMillis ();
+        if (nestedStackId != null) {
+        	try {
+        		LOGGER.debug("Querying for nestedStackId = " + nestedStackId);
+        		nestedHeatStack = heat.queryStack(cloudSiteId, tenantId, nestedStackId);
+                LOGGER.recordMetricEvent (queryStackStarttime2, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully receive response from Open Stack", "OpenStack", "QueryStack", null);
+        	} catch (MsoException me) {
+        	    // Failed to query the Stack due to an openstack exception.
+        	    // Convert to a generic VnfException
+        	    me.addContext ("UpdateVFModule");
+        	    String error = "Update VF: Attached heatStack ID Query " + nestedStackId + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+                LOGGER.recordMetricEvent (queryStackStarttime2, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", null);
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vnfName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Exception - " + error, me);
+        		LOGGER.debug("ERROR trying to query nested stack= " + error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+        	    throw new VnfException (me);
+        	}
+        	if (nestedHeatStack == null || nestedHeatStack.getStatus() == HeatStatus.NOTFOUND) {
+        		MsoLogger.setServiceName (serviceName);
+        	    String error = "Update VFModule: Attached volume heatStack ID DOES NOT EXIST " + nestedStackId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR"  ;
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vnfName, cloudSiteId, tenantId, error, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, error);
+        	    LOGGER.debug(error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+        	    throw new VnfException (error, MsoExceptionCategory.USERDATA);
+        	} else {
+        		LOGGER.debug("Found nested heat stack - copying values to inputs");
+        		this.sendMapToDebug(inputs);
+        		heat.copyStringOutputsToInputs(inputs, nestedHeatStack.getOutputs(), false);
+        		this.sendMapToDebug(inputs);
+        	}
+        }
+        // handle a nestedBaseStackId if sent - this is the stack ID of the base.
+        StackInfo nestedBaseHeatStack = null;
+        if (nestedBaseStackId != null) {
+            long queryStackStarttime3 = System.currentTimeMillis ();
+        	try {
+        		LOGGER.debug("Querying for nestedBaseStackId = " + nestedBaseStackId);
+        		nestedBaseHeatStack = heat.queryStack(cloudSiteId, tenantId, nestedBaseStackId);
+                LOGGER.recordMetricEvent (queryStackStarttime3, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully receive response from Open Stack", "OpenStack", "QueryStack", null);
+        	} catch (MsoException me) {
+        	    // Failed to query the Stack due to an openstack exception.
+        	    // Convert to a generic VnfException
+        	    me.addContext ("UpdateVfModule");
+        	    String error = "Update VFModule: Attached baseHeatStack ID Query " + nestedBaseStackId + " in " + cloudSiteId + "/" + tenantId + ": " + me ;
+                LOGGER.recordMetricEvent (queryStackStarttime3, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", null);
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, "Exception - " + error, me);
+        		LOGGER.debug("ERROR trying to query nested base stack= " + error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+        	    throw new VnfException (me);
+        	}
+        	if (nestedBaseHeatStack == null || nestedBaseHeatStack.getStatus() == HeatStatus.NOTFOUND) {
+        		MsoLogger.setServiceName (serviceName);
+        	    String error = "Update VFModule: Attached base heatStack ID DOES NOT EXIST " + nestedBaseStackId + " in " + cloudSiteId + "/" + tenantId + " USER ERROR"  ;
+        	    LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, vfModuleName, cloudSiteId, tenantId, error, "OpenStack", "QueryStack", MsoLogger.ErrorCode.DataError, error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+        	    LOGGER.debug(error);
+        	    throw new VnfException (error, MsoExceptionCategory.USERDATA);
+        	} else {
+        		LOGGER.debug("Found nested base heat stack - copying values to inputs");
+        		this.sendMapToDebug(inputs);
+        		heat.copyStringOutputsToInputs(inputs, nestedBaseHeatStack.getOutputs(), false);
+        		this.sendMapToDebug(inputs);
+        	}
+        }
+
+        // Ready to deploy the new VNF
+
+        try (CatalogDatabase db = new CatalogDatabase ()) {
+            // Retrieve the VF definition
+            //VnfResource vnf;
+        	VfModule vf = null;
+            if (vfVersion != null && !vfVersion.isEmpty ()) {
+            	vf = db.getVfModuleType(vfModuleType, vfVersion);
+            	if (vf == null) {
+            		LOGGER.debug("Unable to find " + vfModuleType + " and version = " + vfVersion + " in the TYPE column - will try in MODEL_NAME");
+            		vf = db.getVfModuleModelName(vfModuleType, vfVersion);
+            		if (vf == null) {
+            			LOGGER.debug("Unable to find " + vfModuleType + " and version = " + vfVersion + " in the MODEL_NAME field either - ERROR");
+            		}
+            	}
+            } else {
+                vf = db.getVfModuleType(vfModuleType);
+            	if (vf == null) {
+            		LOGGER.debug("Unable to find " + vfModuleType + " in the TYPE column - will try in MODEL_NAME");
+            		vf = db.getVfModuleModelName(vfModuleType);
+            		if (vf == null) {
+            			LOGGER.debug("Unable to find " + vfModuleType + " in the MODEL_NAME field either - ERROR");
+            		}
+            	}
+            }
+            if (vf == null) {
+                String error = "Update VFModule: Unknown VF Module Type: " + vfModuleType;
+                if (vfVersion != null && !vfVersion.isEmpty()) {
+                	error += " with version = " + vfVersion;
+                }
+                LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "VF Module Type", vfModuleType, "OpenStack", "", MsoLogger.ErrorCode.DataError, error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+                throw new VnfException (error, MsoExceptionCategory.USERDATA);
+            }
+            LOGGER.debug ("Got VF module definition from Catalog: " + vf.toString ());
+            
+            HeatTemplate heatTemplate = null;
+            Integer heatTemplateId = null;
+            Integer heatEnvtId = null;
+			if (!isVolumeRequest) {
+				heatTemplateId = vf.getTemplateId();
+				heatEnvtId = vf.getEnvironmentId();
+			} else {
+				heatTemplateId = vf.getVolTemplateId();
+				heatEnvtId = vf.getVolEnvironmentId();
+			}
+			if (heatTemplateId == null) {
+				String error = "UpdateVF: No Heat Template ID defined in catalog database for " + vfModuleType + ", reqType=" + requestTypeString;
+				LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Template ID", vfModuleType, "OpenStack", "", MsoLogger.ErrorCode.DataError, error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+				alarmLogger.sendAlarm(MSO_CONFIGURATION_ERROR,
+						MsoAlarmLogger.CRITICAL, error);
+				throw new VnfException(error, MsoExceptionCategory.INTERNAL);
+			} else {
+				heatTemplate = db.getHeatTemplate(heatTemplateId);
+			}
+
+			if (heatTemplate == null) {
+				String error = "Update VNF: undefined Heat Template. VF="
+						+ vfModuleType + ", heat template id = " + heatTemplateId;
+				LOGGER.error(MessageEnum.RA_VNF_UNKNOWN_PARAM,
+						"Heat Template ID",
+						String.valueOf(heatTemplateId), "OpenStack", "", MsoLogger.ErrorCode.DataError, error);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+				// Alarm on this error, configuration must be fixed
+				alarmLogger.sendAlarm(MSO_CONFIGURATION_ERROR,
+						MsoAlarmLogger.CRITICAL, error);
+
+				throw new VnfException(error, MsoExceptionCategory.INTERNAL);
+			}
+
+            LOGGER.debug ("Got HEAT Template from DB: " + heatTemplate.toString ());
+
+            // Add check for any Environment variable
+            HeatEnvironment heatEnvironment = null;
+            String heatEnvironmentString = null;
+
+            if (heatEnvtId != null) {
+                LOGGER.debug ("about to call getHeatEnvironment with :" + heatEnvtId + ":");
+                heatEnvironment = db.getHeatEnvironment (heatEnvtId);
+                if (heatEnvironment == null) {
+
+                    String error = "Update VNF: undefined Heat Environment. VF=" + vfModuleType
+                                   + ", Environment ID="
+                                   + heatEnvtId;
+                    LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "Heat Environment ID", String.valueOf(heatEnvtId), "OpenStack", "", MsoLogger.ErrorCode.DataError, error);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                    // Alarm on this error, configuration must be fixed
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+
+                    throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+                } else {
+                    LOGGER.debug ("Got Heat Environment from DB: " + heatEnvironment.toString ());
+                    heatEnvironmentString = heatEnvironment.getEnvironment (); //this.parseEnvironment (heatEnvironment.getEnvironment ());
+                    LOGGER.debug ("After parsing: " + heatEnvironmentString);
+                }
+            } else {
+                LOGGER.debug ("no environment parameter for this VFModuleType " + vfModuleType);
+            }
+
+
+            LOGGER.debug ("In MsoVnfAdapterImpl, about to call db.getNestedTemplates avec templateId="
+                          + heatTemplate.getId ());
+            Map <String, Object> nestedTemplates = db.getNestedTemplates (heatTemplate.getId ());
+            Map <String, Object> nestedTemplatesChecked = new HashMap <String, Object> ();
+            if (nestedTemplates != null) {
+                // for debugging print them out
+                LOGGER.debug ("Contents of nestedTemplates - to be added to files: on stack:");
+                for (String providerResourceFile : nestedTemplates.keySet ()) {
+                    String providerResourceFileChecked = providerResourceFile; //this.enforceFilePrefix (providerResourceFile);
+                    String childTemplateBody = (String) nestedTemplates.get (providerResourceFile);
+                    nestedTemplatesChecked.put (providerResourceFileChecked, childTemplateBody);
+                    LOGGER.debug (providerResourceFileChecked + " -> " + childTemplateBody);
+                }
+            } else {
+                LOGGER.debug ("No nested templates found - nothing to do here");
+                nestedTemplatesChecked = null;
+            }
+
+            // Also add the files: for any get_files associated with this VfModule
+            // *if* there are any
+            LOGGER.debug ("In MsoVnfAdapterImpl.updateVfModule, about to call db.getHeatFiles avec vfModuleId="
+                          + vf.getId ());
+
+            Map <String, HeatFiles> heatFiles = null;
+//            Map <String, HeatFiles> heatFiles = db.getHeatFiles (vnf.getId ());
+            Map <String, Object> heatFilesObjects = new HashMap <String, Object> ();
+
+            // Add ability to turn on adding get_files with volume requests (by property).
+            boolean addGetFilesOnVolumeReq = false;
+            try {
+            	String propertyString = msoPropertiesFactory.getMsoJavaProperties(MSO_PROP_VNF_ADAPTER).getProperty(MsoVnfAdapterImpl.ADD_GET_FILES_ON_VOLUME_REQ, null);
+            	if ("true".equalsIgnoreCase(propertyString) || "y".equalsIgnoreCase(propertyString)) {
+            		addGetFilesOnVolumeReq = true;
+            		LOGGER.debug("AddGetFilesOnVolumeReq - setting to true! " + propertyString);
+            	}
+            } catch (Exception e) {
+            	LOGGER.debug("An error occured trying to get property " + MsoVnfAdapterImpl.ADD_GET_FILES_ON_VOLUME_REQ + " - default to false", e);
+            }
+            if (!isVolumeRequest || addGetFilesOnVolumeReq) {
+            	heatFiles = db.getHeatFilesForVfModule(vf.getId());
+                if (heatFiles != null) {
+                    // add these to stack - to be done in createStack
+                    // here, we will map them to Map<String, Object> from Map<String, HeatFiles>
+                    // this will match the nested templates format
+                    LOGGER.debug ("Contents of heatFiles - to be added to files: on stack:");
+
+                    for (String heatFileName : heatFiles.keySet ()) {
+						if (heatFileName.startsWith("_ERROR|")) {
+							// This means there was an invalid entry in VF_MODULE_TO_HEAT_FILES table - the heat file it pointed to could not be found.
+							String heatFileId = heatFileName.substring(heatFileName.lastIndexOf("|")+1);
+							String error = "Create: No HEAT_FILES entry in catalog database for " + vfModuleType + " at HEAT_FILES index=" + heatFileId;
+							LOGGER.debug(error);
+							LOGGER.error (MessageEnum.RA_VNF_UNKNOWN_PARAM, "HEAT_FILES entry not found at " + heatFileId, vfModuleType, "OpenStack", "", MsoLogger.ErrorCode.DataError, error);
+                            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+							// Alarm on this error, configuration must be fixed
+							alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+							throw new VnfException (error, MsoExceptionCategory.INTERNAL);
+						}
+                        String heatFileBody = heatFiles.get (heatFileName).getFileBody ();
+                        LOGGER.debug (heatFileName + " -> " + heatFileBody);
+                        heatFilesObjects.put (heatFileName, heatFileBody);
+                    }
+                } else {
+                    LOGGER.debug ("No heat files found -nothing to do here");
+                    heatFilesObjects = null;
+                }
+            }
+
+            // Check that required parameters have been supplied
+            String missingParams = null;
+            List <String> paramList = new ArrayList <String> ();
+
+            // New for 1510 - consult the PARAM_ALIAS field to see if we've been
+            // supplied an alias. Only check if we don't find it initially.
+            // Also new in 1510 - don't flag missing parameters if there's an environment - because they might be there.
+            // And also new - add parameter to turn off checking all together if we find we're blocking orders we
+            // shouldn't
+            boolean haveEnvironmentParameters = false;
+            boolean checkRequiredParameters = true;
+            try {
+                String propertyString = msoPropertiesFactory.getMsoJavaProperties (MSO_PROP_VNF_ADAPTER)
+                                                     .getProperty (MsoVnfAdapterImpl.CHECK_REQD_PARAMS,null);
+                if ("false".equalsIgnoreCase (propertyString) || "n".equalsIgnoreCase (propertyString)) {
+                    checkRequiredParameters = false;
+                    LOGGER.debug ("CheckRequiredParameters is FALSE. Will still check but then skip blocking..."
+                                  + MsoVnfAdapterImpl.CHECK_REQD_PARAMS);
+                }
+            } catch (Exception e) {
+                // No problem - default is true
+                LOGGER.debug ("An exception occured trying to get property " + MsoVnfAdapterImpl.CHECK_REQD_PARAMS, e);
+            }
+            // 1604 - Add enhanced environment & parameter checking
+            // Part 1: parse envt entries to see if reqd parameter is there (before used a simple grep
+            // Part 2: only submit to openstack the parameters in the envt that are in the heat template
+            // Note this also removes any comments
+            MsoHeatEnvironmentEntry mhee = null;
+            if (heatEnvironmentString != null && heatEnvironmentString.toLowerCase ().contains ("parameters:")) {
+            	LOGGER.debug("Enhanced environment checking enabled - 1604");
+                haveEnvironmentParameters = true;
+                StringBuilder sb = new StringBuilder(heatEnvironmentString);
+                //LOGGER.debug("About to create MHEE with " + sb);
+                mhee = new MsoHeatEnvironmentEntry(sb);
+                StringBuilder sb2 = new StringBuilder("\nHeat Template Parameters:\n");
+                for (HeatTemplateParam parm : heatTemplate.getParameters()) {
+                	sb2.append("\t" + parm.getParamName() + ", required=" + parm.isRequired());
+                }
+                if (!mhee.isValid()) {
+                	sb2.append("Environment says it's not valid! " + mhee.getErrorString());
+                } else {
+                	sb2.append("\nEnvironment:");
+                	sb2.append(mhee.toFullString());
+                }
+                LOGGER.debug(sb2.toString());
+            } else {
+            	LOGGER.debug("NO ENVIRONMENT for this entry");
+            }
+
+            // New for 1607 - support params of json type
+            HashMap<String, JsonNode> jsonParams = new HashMap<String, JsonNode>();
+            boolean hasJson = false;
+            
+            for (HeatTemplateParam parm : heatTemplate.getParameters ()) {
+                LOGGER.debug ("Parameter:'" + parm.getParamName ()
+                              + "', isRequired="
+                              + parm.isRequired ()
+                              + ", alias="
+                              + parm.getParamAlias ());
+                // handle json
+                String parameterType = parm.getParamType();
+                if (parameterType == null || parameterType.trim().equals("")) {
+                	parameterType = "String";
+                }
+                JsonNode jsonNode = null;
+                if (parameterType.equalsIgnoreCase("json") && inputs != null) {
+                	if (inputs.containsKey(parm.getParamName()) ) {
+                		hasJson = true;
+                		String jsonString = null;
+                		try {
+                			jsonString = inputs.get(parm.getParamName());
+                			jsonNode = new ObjectMapper().readTree(jsonString);
+                		} catch (JsonParseException jpe) {
+                			//TODO - what to do here?
+                			//for now - send the error to debug, but just leave it as a String
+                			String errorMessage = jpe.getMessage();
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " - " + errorMessage);
+                			hasJson = false;
+                			jsonNode = null;
+                		} catch (Exception e) {
+                			// or here?
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " " + e.getMessage());
+                			hasJson = false;
+                			jsonNode = null;
+                		}
+                		if (jsonNode != null) {
+                			jsonParams.put(parm.getParamName(), jsonNode);
+                		}
+                	} else if (inputs.containsKey(parm.getParamAlias())) {
+                		hasJson = true;
+                		String jsonString = null;
+                   		try {
+                			jsonString = inputs.get(parm.getParamAlias());
+                			jsonNode = new ObjectMapper().readTree(jsonString);
+                		} catch (JsonParseException jpe) {
+                			//TODO - what to do here?
+                			//for now - send the error to debug, but just leave it as a String
+                			String errorMessage = jpe.getMessage();
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " - " + errorMessage);
+                			hasJson = false;
+                			jsonNode = null;
+                		} catch (Exception e) {
+                			// or here?
+                			LOGGER.debug("Json Error Converting " + parm.getParamName() + " " + e.getMessage());
+                			hasJson = false;
+                			jsonNode = null;
+                		}
+                   		if (jsonNode != null) {
+                   			// Notice here - we add it to the jsonParams hashMap with the actual name -
+                   			// then manipulate the inputs so when we check for aliases below - it will not
+                   			// get flagged.
+                   			jsonParams.put(parm.getParamName(), jsonNode);
+                   			inputs.remove(parm.getParamAlias());
+                   			inputs.put(parm.getParamName(), jsonString);
+                   		}
+                	} //TODO add a check for the parameter in the env file
+                }
+
+                if (parm.isRequired () && (inputs == null || !inputs.containsKey (parm.getParamName ()))) {
+                    if (inputs.containsKey (parm.getParamAlias ())) {
+                        // They've submitted using an alias name. Remove that from inputs, and add back using real name.
+                        String realParamName = parm.getParamName ();
+                        String alias = parm.getParamAlias ();
+                        String value = inputs.get (alias);
+                        LOGGER.debug ("*Found an Alias: paramName=" + realParamName
+                                      + ",alias="
+                                      + alias
+                                      + ",value="
+                                      + value);
+                        inputs.remove (alias);
+                        inputs.put (realParamName, value);
+                        LOGGER.debug (alias + " entry removed from inputs, added back using " + realParamName);
+                    }
+                    // enhanced - check if it's in the Environment (note: that method
+                    else if (mhee != null && mhee.containsParameter(parm.getParamName())) {
+
+                        LOGGER.debug ("Required parameter " + parm.getParamName ()
+                                      + " appears to be in environment - do not count as missing");
+                    }
+                    else {
+                        LOGGER.debug ("adding to missing parameters list: " + parm.getParamName ());
+                        if (missingParams == null) {
+                            missingParams = parm.getParamName ();
+                        } else {
+                            missingParams += "," + parm.getParamName ();
+                        }
+                    }
+                }
+                paramList.add (parm.getParamName ());
+            }
+            if (missingParams != null) {
+                // Problem - missing one or more required parameters
+            	if (checkRequiredParameters) {
+                String error = "Update VNF: Missing Required inputs: " + missingParams;
+                LOGGER.error (MessageEnum.RA_MISSING_PARAM, missingParams, "OpenStack", "", MsoLogger.ErrorCode.DataError, error);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                throw new VnfException (error, MsoExceptionCategory.USERDATA);
+            	} else {
+            		LOGGER.debug ("found missing parameters - but checkRequiredParameters is false - will not block");
+            	}
+            } else {
+                LOGGER.debug ("No missing parameters found - ok to proceed");
+            }
+
+            // Here - modify heatEnvironmentString
+            StringBuilder parsedEnvironmentString = null;
+            String newEnvironmentString = null;
+            if (mhee != null) {
+            	LOGGER.debug("Environment before:\n" + heatEnvironmentString);
+            	parsedEnvironmentString = mhee.toFullStringExcludeNonParams(heatTemplate.getParameters());
+            	LOGGER.debug("Environment after:\n" + parsedEnvironmentString.toString());
+            	newEnvironmentString = parsedEnvironmentString.toString();
+            }
+
+            // Remove any extraneous parameters (don't throw an error)
+            if (inputs != null) {
+                List <String> extraParams = new ArrayList <String> ();
+                extraParams.addAll (inputs.keySet ());
+                // This is not a valid parameter for this template
+                extraParams.removeAll (paramList);
+                if (!extraParams.isEmpty ()) {
+                	LOGGER.warn (MessageEnum.RA_VNF_EXTRA_PARAM, vnfType, extraParams.toString(), "OpenStack", "", MsoLogger.ErrorCode.DataError, "Extra params");
+                    inputs.keySet ().removeAll (extraParams);
+                }
+            }
+            // 1607 - when we get here - we have clean inputs. Create inputsTwo in case we have json
+            Map<String, Object> inputsTwo = null;
+            if (hasJson && jsonParams.size() > 0) {
+            	inputsTwo = new HashMap<String, Object>();
+            	for (String keyParamName : inputs.keySet()) {
+            		if (jsonParams.containsKey(keyParamName)) {
+            			inputsTwo.put(keyParamName, jsonParams.get(keyParamName));
+            		} else {
+            			inputsTwo.put(keyParamName, inputs.get(keyParamName));
+            		}
+            	}
+            }
+
+            // "Fix" the template if it has CR/LF (getting this from Oracle)
+            String template = heatTemplate.getHeatTemplate ();
+            template = template.replaceAll ("\r\n", "\n");
+
+            // Have the tenant. Now deploy the stack itself
+            // Ignore MsoTenantNotFound and MsoStackAlreadyExists exceptions
+            // because we already checked for those.
+            long updateStackStarttime = System.currentTimeMillis ();
+            try {
+            	if (!hasJson) {
+            		heatStack = heatU.updateStack (cloudSiteId,
+                                               tenantId,
+                                               vfModuleName,
+                                               template,
+                                               copyStringInputs (inputs),
+                                               true,
+                                               heatTemplate.getTimeoutMinutes (),
+                                               newEnvironmentString,
+                                               //heatEnvironmentString,
+                                               nestedTemplatesChecked,
+                                               heatFilesObjects);
+            		LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully receive response from Open Stack", "OpenStack", "UpdateStack", null);
+            	} else {
+            		heatStack = heatU.updateStack (cloudSiteId,
+                                               tenantId,
+                                               vfModuleName,
+                                               template,
+                                               inputsTwo,
+                                               true,
+                                               heatTemplate.getTimeoutMinutes (),
+                                               newEnvironmentString,
+                                               //heatEnvironmentString,
+                                               nestedTemplatesChecked,
+                                               heatFilesObjects);
+            		LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully receive response from Open Stack", "OpenStack", "UpdateStack", null);
+            		
+            	}
+            } catch (MsoException me) {
+                me.addContext ("UpdateVFModule");
+                String error = "Update VFModule " + vfModuleType + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+                LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "UpdateStack", null);
+                LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, vfModuleType, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - " + error, me);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                throw new VnfException (me);
+            }
+        }
+
+        // Reach this point if updateStack is successful.
+        // Populate remaining rollback info and response parameters.
+        vfRollback.setVnfId (heatStack.getCanonicalName ());
+        vfRollback.setVnfCreated (true);
+
+        outputs.value = copyStringOutputs (heatStack.getOutputs ());
+        rollback.value = vfRollback;
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully update VF Module");
+        return;
+    }
+
+    private String getVfModuleNameFromModuleStackId(String vfModuleStackId) {
+    	// expected format of vfModuleStackId is "MSOTEST51-vSAMP3_base_module-0/1fc1f86c-7b35-447f-99a6-c23ec176ae24"
+    	// before the "/" is the vfModuleName and after the "/" is the heat stack id in Openstack
+    	if (vfModuleStackId == null)
+    		return null;
+    	int index = vfModuleStackId.lastIndexOf('/');
+    	if (index <= 0) 
+    		return null;
+    	String vfModuleName = null;
+    	try {
+    		vfModuleName = vfModuleStackId.substring(0, index);
+    	} catch (Exception e) {
+    		vfModuleName = null;
+    	}
+    	return vfModuleName;
+    }
+
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VfRollback.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VfRollback.java
new file mode 100644
index 0000000..90ab01b
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VfRollback.java
@@ -0,0 +1,137 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+
+import org.openecomp.mso.entity.MsoRequest;
+
+public class VfRollback {
+	private String vnfId;
+	private String tenantId;
+	private String cloudSiteId;
+	private boolean tenantCreated = false;
+	private boolean vnfCreated = false;
+	private MsoRequest msoRequest;
+	private String volumeGroupName;
+	private String volumeGroupId;
+	private String requestType;
+	private String volumeGroupHeatStackId;
+	private String baseGroupHeatStackId;
+	private boolean isBase = false;
+	private String vfModuleStackId;
+
+
+	public String getVnfId() {
+		return vnfId;
+	}
+	public void setVnfId(String vnfId) {
+		this.vnfId = vnfId;
+	}
+	public String getTenantId() {
+		return tenantId;
+	}
+
+	public void setTenantId(String tenantId) {
+		this.tenantId = tenantId;
+	}
+	public String getCloudSiteId() {
+		return cloudSiteId;
+	}
+	public void setCloudSiteId(String cloudId) {
+		this.cloudSiteId = cloudId;
+	}
+	public boolean getTenantCreated() {
+		return tenantCreated;
+	}
+	public void setTenantCreated(boolean tenantCreated) {
+		this.tenantCreated = tenantCreated;
+	}
+	public boolean getVnfCreated() {
+		return vnfCreated;
+	}
+	public void setVnfCreated(boolean vnfCreated) {
+		this.vnfCreated = vnfCreated;
+	}
+	public MsoRequest getMsoRequest() {
+		return msoRequest;
+	}
+	public void setMsoRequest (MsoRequest msoRequest) {
+		this.msoRequest = msoRequest;
+	}
+	public String getVolumeGroupName() {
+		return this.volumeGroupName;
+	}
+	public void setVolumeGroupName(String volumeGroupName) {
+		this.volumeGroupName = volumeGroupName;
+	}
+	public String getVolumeGroupId() {
+		return this.volumeGroupId;
+	}
+	public void setVolumeGroupId(String volumeGroupId) {
+		this.volumeGroupId = volumeGroupId;
+	}
+	public String getRequestType() {
+		return this.requestType;
+	}
+	public void setRequestType(String requestType) {
+		this.requestType = requestType;
+	}
+	/*
+	private String volumeGroupHeatStackId;
+	private String baseGroupHeatStackId;
+	private boolean isBase = false;
+	*/
+	public String getVolumeGroupHeatStackId() {
+		return this.volumeGroupHeatStackId;
+	}
+	public void setVolumeGroupHeatStackId(String volumeGroupHeatStackId) {
+		this.volumeGroupHeatStackId = volumeGroupHeatStackId;
+	}
+	
+	public String getBaseGroupHeatStackId() {
+		return this.baseGroupHeatStackId;
+	}
+	public void setBaseGroupHeatStackId(String baseGroupHeatStackId) {
+		this.baseGroupHeatStackId = baseGroupHeatStackId;
+	}
+	
+	public boolean isBase() {
+		return this.isBase;
+	}
+	public void setIsBase(boolean isBase) {
+		this.isBase = isBase;
+	}
+	public String getVfModuleStackId() {
+		return this.vfModuleStackId;
+	}
+	public void setVfModuleStackId(String vfModuleStackId) {
+		this.vfModuleStackId = vfModuleStackId;
+	}
+
+	@Override
+    public String toString() {
+		return "VfRollback: cloud=" + cloudSiteId + ", tenant=" + tenantId +
+				", vnf=" + vnfId + ", tenantCreated=" + tenantCreated +
+				", vnfCreated=" + vnfCreated + ", requestType = " + requestType +
+				", volumeGroupHeatStackId = " + this.volumeGroupHeatStackId;
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VnfAdapterRest.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VnfAdapterRest.java
new file mode 100644
index 0000000..6906f81
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VnfAdapterRest.java
@@ -0,0 +1,628 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.xml.ws.Holder;
+
+import org.apache.http.HttpStatus;
+
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+import org.openecomp.mso.cloud.CloudConfigFactory;
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+import org.openecomp.mso.adapters.vnfrest.*;
+
+/**
+ * This class services calls to the REST interface for VF Modules (http://host:port/vnfs/rest/v1/vnfs)
+ * Both XML and JSON can be produced/consumed.  Set Accept: and Content-Type: headers appropriately.  XML is the default.
+ * For testing, call with cloudSiteId = ___TESTING___
+ * To test exceptions, also set tenantId = ___TESTING___
+ */
+@Path("/v1/vnfs")
+public class VnfAdapterRest {
+	private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+	private static final String TESTING_KEYWORD = "___TESTING___";
+	private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
+	private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+	private final MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
+	//TODO Logging, SkipAAI, CREATED flags, Integrate with BPEL, Auth,
+
+	@HEAD
+	@GET
+	@Path("/healthcheck")
+	@Produces(MediaType.TEXT_HTML)
+	public Response healthcheck () {
+		String CHECK_HTML = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Health Check</title></head><body>Application ready</body></html>";
+		return Response.ok().entity(CHECK_HTML).build();
+	}
+
+   /*
+	* URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>
+	* REQUEST:
+	* {"deleteVfModuleRequest":
+		{"cloudSiteId": "DAN",
+		"tenantId": "214b428a1f554c02935e66330f6a5409",
+		"vnfId": "somevnfid",
+		"vfModuleId": "somemodid",
+		"vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
+		"messageId": "ra.1",
+		"notificationUrl": "http://localhost:8089/vnfmock",
+		"skipAAI": true,
+		"msoRequest": {
+		"requestId": "ra1",
+		"serviceInstanceId": "sa1"
+		}}
+		}
+	*/
+	@DELETE
+	@Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response deleteVfModule (
+   		@PathParam("aaiVnfId") String aaiVnfId,
+		@PathParam("aaiVfModuleId") String aaiVfModuleId,
+		final DeleteVfModuleRequest req)
+	{
+		LOGGER.debug("Delete VfModule enter: " + req.toJsonString());
+		if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
+			LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("vnfid in URL does not match content")
+				.build();
+		}
+	   	if (aaiVfModuleId == null || !aaiVfModuleId.equals(req.getVfModuleId())) {
+			LOGGER.debug("Req rejected - aaiVfModuleId not provided or doesn't match URL");
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("vfModuleId in URL does not match content")
+				.build();
+		}
+	   	DeleteVfModuleTask task = new DeleteVfModuleTask(req);
+		if (req.isSynchronous()) {
+   			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+   				.build();
+   		} else {
+			// This is an asynchronous request
+			try {
+				Thread t1 = new Thread(task);
+   				t1.start();
+   			} catch (Exception e) {
+				// problem handling delete, send generic failure as sync resp to caller
+				LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "deleteVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in deleteVfModule", e);
+				return Response.serverError().build();
+   			}
+   			// send sync response (ACK) to caller
+   			LOGGER.debug ("deleteVNFVolumes exit");
+   			return Response.status(HttpStatus.SC_ACCEPTED).build();
+   		}
+	}
+
+	public class DeleteVfModuleTask implements Runnable {
+		private final DeleteVfModuleRequest req;
+		private DeleteVfModuleResponse response = null;
+		private VfModuleExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public DeleteVfModuleTask(DeleteVfModuleRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<DeleteVfModuleResponse>(response) {}
+				: new GenericEntity<VfModuleExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+
+		@Override
+		public void run() {
+			try {
+				String cloudsite = req.getCloudSiteId();
+				if (cloudsite != null && !cloudsite.equals(TESTING_KEYWORD)) {
+					//vnfAdapter.deleteVnf (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
+					vnfAdapter.deleteVfModule (req.getCloudSiteId(), req.getTenantId(), req.getVfModuleStackId(), req.getMsoRequest());
+				}
+				response = new DeleteVfModuleResponse(req.getVnfId(), req.getVfModuleId(), Boolean.TRUE, req.getMessageId());
+			} catch (VnfException e) {
+				LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - Delete VNF Module", e);
+				eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				BpelRestClient bpelClient = new BpelRestClient();
+				bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug ("Delete vfModule exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	/*
+	 * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaiVnfId>/vf-modules/<aaiVfModuleId>?cloudSiteId=DAN&tenantId=vfModule?&skipAAI=TRUE&msoRequest.requestId=ra1&msoRequest.serviceInstanceId=si1&vfModuleName=T2N2S1
+	 * RESP:
+	 * {"queryVfModuleResponse": {
+		   "vfModuleId": "AvfmodId",
+		   "vfModuleOutputs": {"entry": {
+			  "key": "server_private_ip_1",
+			  "value": "10.100.1.25"
+		   }},
+		   "vfModuleStackId": "RaaVnf1/abfa8a6d-feb1-40af-aea3-109403b1cf6b",
+		   "vnfId": "AvnfID",
+		   "vnfStatus": "ACTIVE"
+		}}
+	 */
+	@GET
+	@Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response queryVfModule(
+		@PathParam("aaiVnfId") String aaiVnfId,
+		@PathParam("aaiVfModuleId") String aaiVfModuleId,
+		@QueryParam("cloudSiteId") String cloudSiteId,
+		@QueryParam("tenantId") String tenantId,
+		@QueryParam("vfModuleName") String vfModuleName, //RAA? Id in doc
+		@QueryParam("skipAAI") Boolean skipAAI,
+		@QueryParam("msoRequest.requestId") String requestId,
+		@QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId)
+	{
+		//This request responds synchronously only
+		LOGGER.debug ("Query vfModule enter:" + vfModuleName);
+		MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
+
+		try {
+			int respStatus = HttpStatus.SC_OK;
+			QueryVfModuleResponse qryResp = new QueryVfModuleResponse(aaiVnfId, aaiVfModuleId, null, null, null);
+			Holder<Boolean> vnfExists = new Holder<Boolean>();
+			Holder<String> vfModuleId = new Holder<String>();
+			Holder<VnfStatus> status  = new Holder<VnfStatus>();
+			Holder<Map<String, String>> outputs = new Holder <Map <String, String>> ();
+			vnfAdapter.queryVnf (cloudSiteId, tenantId, vfModuleName, msoRequest, vnfExists, vfModuleId, status, outputs);
+			if (!vnfExists.value) {
+				LOGGER.debug ("vfModule not found");
+				respStatus = HttpStatus.SC_NOT_FOUND;
+			} else {
+				LOGGER.debug ("vfModule found" + vfModuleId.value + ", status=" + status.value);
+				qryResp.setVfModuleId(vfModuleId.value);
+				qryResp.setVnfStatus(status.value);
+				qryResp.setVfModuleOutputs(outputs.value);
+			}
+			LOGGER.debug ("Query vfModule exit");
+			return Response
+				.status(respStatus)
+				.entity(new GenericEntity<QueryVfModuleResponse>(qryResp) {})
+				.build();
+		} catch (VnfException e) {
+			LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR,  vfModuleName, "", "queryVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - queryVfModule", e);
+			VfModuleExceptionResponse excResp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
+			return Response
+				.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
+				.entity(new GenericEntity<VfModuleExceptionResponse>(excResp) {})
+				.build();
+		}
+	}
+
+	/*URL: http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules
+	 *REQUEST:
+	 * {"createVfModuleRequest":
+		{"cloudSiteId": "DAN",
+		"tenantId": "214b428a1f554c02935e66330f6a5409",
+		"vnfId": "somevnfid",
+		"vfModuleId": "somemodid",
+		"vfModuleName": "RaaVnf1",
+		"vnfType": "ApacheVnf",
+		"vfModuleParams": {"entry": [
+			{"key": "network_id",
+			"value": "59ed7b41-2983-413f-ba93-e7d437433916"},
+			{"key": "subnet_id",
+			"value": "086c9298-5c57-49b7-bb2b-6fd5730c5d92"},
+			{"key": "server_name_0",
+			"value": "RaaVnf1"}
+			]},
+		"failIfExists": true,
+		"messageId": "ra.1",
+		"notificationUrl": "http://localhost:8089/vnfmock",
+		"skipAAI": true,
+		"msoRequest": {
+		"requestId": "ra1",
+		"serviceInstanceId": "sa1"
+		}}
+		}
+	 */
+	@POST
+	@Path("{aaiVnfId}/vf-modules")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response createVfModule(
+		@PathParam("aaiVnfId") String aaiVnfId,
+		final CreateVfModuleRequest req)
+	{
+		LOGGER.debug("Create VfModule enter inside VnfAdapterRest: " + req.toJsonString());
+		if (aaiVnfId == null || !aaiVnfId.equals(req.getVnfId())) {
+			LOGGER.debug("Req rejected - aaiVnfId not provided or doesn't match URL");
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("vnfid in URL does not match content")
+				.build();
+		}
+		CreateVfModuleTask task = new CreateVfModuleTask(req);
+		if (req.isSynchronous()) {
+   			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+   				.build();
+   		} else {
+			// This is an asynchronous request
+			try {
+				Thread t1 = new Thread(task);
+   				t1.start();
+   			} catch (Exception e) {
+				// problem handling create, send generic failure as sync resp to caller
+				LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, "", "createVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - createVfModule", e);
+				return Response.serverError().build();
+   			}
+   			// send sync response (ACK) to caller
+   			LOGGER.debug ("createVfModule exit");
+   			return Response.status(HttpStatus.SC_ACCEPTED).build();
+   		}
+	}
+
+	public class CreateVfModuleTask implements Runnable {
+		private final CreateVfModuleRequest req;
+		private CreateVfModuleResponse response = null;
+		private VfModuleExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public CreateVfModuleTask(CreateVfModuleRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<CreateVfModuleResponse>(response) {}
+				: new GenericEntity<VfModuleExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+
+		@Override
+		public void run() {
+			LOGGER.debug ("CreateVfModuleTask start");
+			try {
+				// Synchronous Web Service Outputs
+				Holder <String> vfModuleStackId = new Holder <String> ();
+				Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
+				Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
+				String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
+				LOGGER.debug("completeVnfVfModuleType=" + completeVnfVfModuleType);
+				String cloudsite = req.getCloudSiteId();
+				if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
+					String tenant = req.getTenantId();
+					if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
+						throw new VnfException("testing.");
+					}
+					vnfRollback.value = new VnfRollback(req.getVnfId(), tenant, cloudsite,
+							true, false, new MsoRequest("reqid", "svcid"),
+							req.getVolumeGroupId(), req.getVolumeGroupId(), req.getRequestType());
+					vfModuleStackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
+					outputs.value = VolumeAdapterRest.testMap();
+				} else {
+//					vnfAdapter.createVnf (createReq.getCloudSiteId(),
+//						createReq.getTenantId(),
+//						createReq.getVnfType(),
+//						createReq.getVnfVersion(),
+//						createReq.getVfModuleName(),
+//						createReq.getRequestType(),
+//						createReq.getVolumeGroupStackId(),
+//						createReq.getVfModuleParams(),
+//						createReq.getFailIfExists(),
+//						createReq.getBackout(),
+//						createReq.getMsoRequest(),
+//						vfModuleStackId,
+//						outputs,
+//						vnfRollback);
+					vnfAdapter.createVfModule(req.getCloudSiteId(),
+						req.getTenantId(),
+						//req.getVnfType(),
+						completeVnfVfModuleType,
+						req.getVnfVersion(),
+						req.getVfModuleName(),
+						req.getRequestType(),
+						req.getVolumeGroupStackId(),
+						req.getBaseVfModuleStackId(),
+						req.getVfModuleParams(),
+						req.getFailIfExists(),
+						req.getBackout(),
+						req.getMsoRequest(),
+						vfModuleStackId,
+						outputs,
+						vnfRollback);
+				}
+				VfModuleRollback modRollback = new VfModuleRollback(vnfRollback.value, req.getVfModuleId(), vfModuleStackId.value, req.getMessageId());
+				response = new CreateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
+						vfModuleStackId.value, Boolean.TRUE, outputs.value, modRollback, req.getMessageId());
+			} catch (VnfException e) {
+				eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				BpelRestClient bpelClient = new BpelRestClient();
+				bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug ("CreateVfModuleTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@PUT
+	@Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response updateVfModule(
+			@PathParam("aaiVnfId") String aaiVnfId,
+			@PathParam("aaiVfModuleId") String aaiVfModuleId,
+			final UpdateVfModuleRequest req)
+	{
+		LOGGER.debug("Update VfModule enter: " + req.toJsonString());
+		UpdateVfModulesTask task = new UpdateVfModulesTask(req);
+		if (req.isSynchronous()) {
+			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+				.build();
+		} else {
+			// This is an asynchronous request
+	    	try {
+	    		Thread t1 = new Thread(task);
+	    		t1.start();
+	    	} catch (Exception e) {
+	    		// problem handling create, send generic failure as sync resp to caller
+	    		LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, "", "updateVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - updateVfModule", e);
+	    		return Response.serverError().build();
+	    	}
+	    	// send sync response (ACK) to caller
+	    	LOGGER.debug ("updateVfModules exit");
+	    	return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class UpdateVfModulesTask implements Runnable {
+		private final UpdateVfModuleRequest req;
+		private UpdateVfModuleResponse response = null;
+		private VfModuleExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public UpdateVfModulesTask(UpdateVfModuleRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<UpdateVfModuleResponse>(response) {}
+				: new GenericEntity<VfModuleExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+		@Override
+		public void run() {
+			try {
+				//MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl (msoPropertiesFactory, cloudConfigFactory);
+
+				// Synchronous Web Service Outputs
+				Holder <String> vfModuleStackId = new Holder <String> ();
+				Holder <Map <String, String>> outputs = new Holder <Map <String, String>> ();
+				Holder <VnfRollback> vnfRollback = new Holder <VnfRollback> ();
+				String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
+				LOGGER.debug("in updateVf - completeVnfVfModuleType=" + completeVnfVfModuleType);
+
+				/*
+				vnfAdapter.updateVnf (updateReq.getCloudSiteId(),
+						updateReq.getTenantId(),
+						updateReq.getVnfType(),
+						updateReq.getVnfVersion(),
+						updateReq.getVfModuleName(),
+						updateReq.getRequestType(),
+						updateReq.getVolumeGroupStackId(),
+						updateReq.getVfModuleParams(),
+						updateReq.getMsoRequest(),
+						outputs,
+						vnfRollback); 
+						*/
+				vnfAdapter.updateVfModule (req.getCloudSiteId(),
+						req.getTenantId(),
+						//req.getVnfType(),
+						completeVnfVfModuleType,
+						req.getVnfVersion(),
+						req.getVfModuleName(),
+						req.getRequestType(),
+						req.getVolumeGroupStackId(),
+						req.getBaseVfModuleId(),
+						req.getVfModuleStackId(),
+						req.getVfModuleParams(),
+						req.getMsoRequest(),
+						outputs,
+						vnfRollback); 
+
+				response = new UpdateVfModuleResponse(req.getVnfId(), req.getVfModuleId(),
+						vfModuleStackId.value, outputs.value, req.getMessageId());
+			} catch (VnfException e) {
+				eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				// This is asynch, so POST response back to caller
+				BpelRestClient bpelClient = new BpelRestClient ();
+				bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug ("Update VfModule exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+	/*
+	 * URL:http://localhost:8080/vnfs/rest/v1/vnfs/<aaivnfid>/vf-modules/<aaimodid>/rollback
+	 * REQUEST:
+	 * {"deleteVfModuleRequest":
+ 		{"cloudSiteId": "DAN",
+ 		"tenantId": "214b428a1f554c02935e66330f6a5409",
+ 		"vnfId": "somevnfid",
+ 		"vfModuleId": "somemodid",
+ 		"vfModuleStackId": "4e567676-e266-4594-a3a6-131c8a2baf73",
+ 		"messageId": "ra.1",
+ 		"notificationUrl": "http://localhost:8089/vnfmock",
+ 		"skipAAI": true,
+ 		"msoRequest": {
+ 		"requestId": "ra1",
+ 		"serviceInstanceId": "sa1"
+ 		}}
+ 		}
+	 */
+	@DELETE
+	@Path("{aaiVnfId}/vf-modules/{aaiVfModuleId}/rollback")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response rollbackVfModule (
+			@PathParam("aaiVnfId") String aaiVnfId,
+			@PathParam("aaiVfModuleId") String aaiVfModuleId,
+			//@QueryParam("rollback") String rollback,
+			final RollbackVfModuleRequest req)
+	{
+		LOGGER.debug("Rollback VfModule enter: " + req.toJsonString());
+		RollbackVfModulesTask task = new RollbackVfModulesTask(req);
+		if (req.isSynchronous()) {
+			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+				.build();
+		} else {
+			// This is an asynchronous request
+	    	try {
+	    		Thread t1 = new Thread(task);
+	    		t1.start();
+	    	} catch (Exception e) {
+	    		// problem handling create, send generic failure as sync resp to caller
+	    		LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVfModule", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
+	    		return Response.serverError().build();
+	    	}
+	    	// send sync response (ACK) to caller
+	    	LOGGER.debug ("rollbackVfModule exit");
+	    	return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class RollbackVfModulesTask implements Runnable {
+		private final RollbackVfModuleRequest req;
+		private RollbackVfModuleResponse response = null;
+		private VfModuleExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public RollbackVfModulesTask(RollbackVfModuleRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<RollbackVfModuleResponse>(response) {}
+				: new GenericEntity<VfModuleExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+		@Override
+		public void run() {
+			try {
+				VfModuleRollback vmr = req.getVfModuleRollback();
+				VnfRollback vrb = new VnfRollback(
+						vmr.getVfModuleStackId(), vmr.getTenantId(), vmr.getCloudSiteId(), true, true,
+						vmr.getMsoRequest(), null, null, null);
+				vnfAdapter.rollbackVnf (vrb);
+				response = new RollbackVfModuleResponse(Boolean.TRUE, req.getMessageId());
+			} catch (VnfException e) {
+				LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVfModule", e);
+				eresp = new VfModuleExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, false, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				// This is asynch, so POST response back to caller
+				BpelRestClient bpelClient = new BpelRestClient ();
+				bpelClient.bpelPost (getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug ("RollbackVfModulesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VolumeAdapterRest.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VolumeAdapterRest.java
new file mode 100644
index 0000000..8fa1552
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/VolumeAdapterRest.java
@@ -0,0 +1,576 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.ws.Holder;
+
+import org.apache.http.HttpStatus;
+
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+import org.openecomp.mso.adapters.vnfrest.CreateVolumeGroupRequest;
+import org.openecomp.mso.adapters.vnfrest.CreateVolumeGroupResponse;
+import org.openecomp.mso.adapters.vnfrest.DeleteVolumeGroupRequest;
+import org.openecomp.mso.adapters.vnfrest.DeleteVolumeGroupResponse;
+import org.openecomp.mso.adapters.vnfrest.QueryVolumeGroupResponse;
+import org.openecomp.mso.adapters.vnfrest.RollbackVolumeGroupRequest;
+import org.openecomp.mso.adapters.vnfrest.RollbackVolumeGroupResponse;
+import org.openecomp.mso.adapters.vnfrest.UpdateVolumeGroupRequest;
+import org.openecomp.mso.adapters.vnfrest.UpdateVolumeGroupResponse;
+import org.openecomp.mso.adapters.vnfrest.VolumeGroupExceptionResponse;
+import org.openecomp.mso.adapters.vnfrest.VolumeGroupRollback;
+import org.openecomp.mso.cloud.CloudConfigFactory;
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+/**
+ * This class services calls to the REST interface for VNF Volumes (http://host:port/vnfs/rest/v1/volume-groups)
+ * Both XML and JSON can be produced/consumed.  Set Accept: and Content-Type: headers appropriately.  XML is the default.
+ * For testing, call with cloudSiteId = ___TESTING___
+ * To test exceptions, also set tenantId = ___TESTING___
+ */
+@Path("/v1/volume-groups")
+public class VolumeAdapterRest {
+	private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA);
+	private static final String TESTING_KEYWORD = "___TESTING___";
+	private final CloudConfigFactory cloudConfigFactory = new CloudConfigFactory();
+	private final MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+	private final MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl(msoPropertiesFactory, cloudConfigFactory);
+
+	@POST
+	@Path("")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response createVNFVolumes(final CreateVolumeGroupRequest req) {
+		LOGGER.debug("createVNFVolumes enter: " + req.toJsonString());
+		CreateVNFVolumesTask task = new CreateVNFVolumesTask(req);
+		if (req.isSynchronous()) {
+			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+				.build();
+		} else {
+			// This is an asynchronous request
+			try {
+				Thread t1 = new Thread(task);
+				t1.start();
+			} catch (Exception e) {
+				// problem handling create, send generic failure as sync resp to caller
+				LOGGER.error (MessageEnum.RA_CREATE_VNF_ERR, "", "createVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - createVNFVolumes", e);
+				return Response.serverError().build();
+			}
+			// send sync response (ACK) to caller
+			LOGGER.debug ("createVNFVolumes exit");
+			return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class CreateVNFVolumesTask implements Runnable {
+		private final CreateVolumeGroupRequest req;
+		private CreateVolumeGroupResponse response = null;
+		private VolumeGroupExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public CreateVNFVolumesTask(CreateVolumeGroupRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<CreateVolumeGroupResponse>(response) {}
+				: new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+		@Override
+		public void run() {
+			LOGGER.debug ("CreateVFModule VolumesTask start");
+			try {
+				// Synchronous Web Service Outputs
+				Holder<String> stackId = new Holder<String>();
+				Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
+				Holder<VnfRollback> vnfRollback = new Holder<VnfRollback>();
+				String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
+				LOGGER.debug("in createVfModuleVolumes - completeVnfVfModuleType=" + completeVnfVfModuleType);
+
+				String cloudsite = req.getCloudSiteId();
+				if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
+					String tenant = req.getTenantId();
+					if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
+						throw new VnfException("testing.");
+					}
+					stackId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
+					outputs.value = testMap();
+				} else {
+//					vnfAdapter.createVnf(
+//							req.getCloudSiteId(),
+//							req.getTenantId(),
+//							req.getVnfType(),
+//							req.getVnfVersion(),
+//							req.getVolumeGroupName(),
+//							"VOLUME",			// request type is VOLUME
+//							null,				// not sure about this
+//							req.getVolumeGroupParams(),
+//							req.getFailIfExists(),
+//							req.getSuppressBackout(),
+//							req.getMsoRequest(),
+//							stackId,
+//							outputs,
+//							vnfRollback);
+					vnfAdapter.createVfModule(
+							req.getCloudSiteId(), //cloudSiteId, 
+							req.getTenantId(), //tenantId, 
+							//req.getVnfType(), //vnfType, 
+							completeVnfVfModuleType,
+							req.getVnfVersion(), //vnfVersion, 
+							req.getVolumeGroupName(), //vnfName, 
+							"VOLUME", //requestType, 
+							null, //volumeGroupHeatStackId, 
+							null, //baseVfHeatStackId, 
+							req.getVolumeGroupParams(), //inputs, 
+							req.getFailIfExists(), //failIfExists, 
+							req.getSuppressBackout(), //backout, 
+							req.getMsoRequest(), // msoRequest, 
+							stackId, 
+							outputs, 
+							vnfRollback);
+				}
+				VolumeGroupRollback rb = new VolumeGroupRollback(
+						req.getVolumeGroupId(),
+						stackId.value,
+						true, 						// TODO boolean volumeGroupCreated, when would it be false?
+						req.getTenantId(),
+						req.getCloudSiteId(),
+						req.getMsoRequest(),
+						req.getMessageId());
+				response = new CreateVolumeGroupResponse(
+						req.getVolumeGroupId(),
+						stackId.value,
+						true, 						// TODO boolean volumeGroupCreated, when would it be false?
+						outputs.value,
+						rb,
+						req.getMessageId());
+			} catch (VnfException e) {
+				eresp = new VolumeGroupExceptionResponse(
+					e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				// This is asynch, so POST response back to caller
+				BpelRestClient bpelClient = new BpelRestClient();
+				bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug ("CreateVFModule VolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@DELETE
+	@Path("{aaiVolumeGroupId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response deleteVNFVolumes(
+		@PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
+		final DeleteVolumeGroupRequest req
+		)
+	{
+		LOGGER.debug("deleteVNFVolumes enter: " + req.toJsonString());
+		if (aaiVolumeGroupId == null || !aaiVolumeGroupId.equals(req.getVolumeGroupId())) {
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("VolumeGroupId in URL does not match content")
+				.build();
+		}
+		DeleteVNFVolumesTask task = new DeleteVNFVolumesTask(req);
+		if (req.isSynchronous()) {
+			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+				.build();
+		} else {
+			// This is an asynchronous request
+			try {
+				Thread t1 = new Thread(task);
+				t1.start();
+			} catch (Exception e) {
+				// problem handling create, send generic failure as sync resp to caller
+				LOGGER.error (MessageEnum.RA_DELETE_VNF_ERR, "", "deleteVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - deleteVNFVolumes", e);
+				return Response.serverError().build();
+			}
+			// send sync response (ACK) to caller
+			LOGGER.debug ("deleteVNFVolumes exit");
+			return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class DeleteVNFVolumesTask implements Runnable {
+		private final DeleteVolumeGroupRequest req;
+		private DeleteVolumeGroupResponse response = null;
+		private VolumeGroupExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public DeleteVNFVolumesTask(DeleteVolumeGroupRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<DeleteVolumeGroupResponse>(response) {}
+				: new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+		@Override
+		public void run() {
+			LOGGER.debug("DeleteVNFVolumesTask start");
+			try {
+				if (!req.getCloudSiteId().equals(TESTING_KEYWORD)) {
+					vnfAdapter.deleteVnf(req.getCloudSiteId(), req.getTenantId(), req.getVolumeGroupStackId(), req.getMsoRequest());
+				}
+				response = new DeleteVolumeGroupResponse(true, req.getMessageId());
+			} catch (VnfException e) {
+				eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				// This is asynch, so POST response back to caller
+				BpelRestClient bpelClient = new BpelRestClient();
+				bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug("DeleteVNFVolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@DELETE
+	@Path("{aaiVolumeGroupId}/rollback")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response rollbackVNFVolumes(
+		@PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
+		final RollbackVolumeGroupRequest req
+		)
+	{
+		LOGGER.debug("rollbackVNFVolumes enter: " + req.toJsonString());
+		if (aaiVolumeGroupId == null || req.getVolumeGroupRollback() == null || !aaiVolumeGroupId.equals(req.getVolumeGroupRollback().getVolumeGroupId())) {
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("VolumeGroupId in URL does not match content")
+				.build();
+		}
+		RollbackVNFVolumesTask task = new RollbackVNFVolumesTask(req);
+		if (req.isSynchronous()) {
+			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+				.build();
+		} else {
+			// This is an asynchronous request
+			try {
+				Thread t1 = new Thread(task);
+				t1.start();
+			} catch (Exception e) {
+				// problem handling create, send generic failure as sync resp to caller
+				LOGGER.error (MessageEnum.RA_ROLLBACK_VNF_ERR, "", "rollbackVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - rollbackVNFVolumes", e);
+				return Response.serverError().build();
+			}
+			// send sync response (ACK) to caller
+			LOGGER.debug("rollbackVNFVolumes exit");
+			return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class RollbackVNFVolumesTask implements Runnable {
+		private final RollbackVolumeGroupRequest req;
+		private RollbackVolumeGroupResponse response = null;
+		private VolumeGroupExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public RollbackVNFVolumesTask(RollbackVolumeGroupRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<RollbackVolumeGroupResponse>(response) {}
+				: new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+		@Override
+		public void run() {
+			LOGGER.debug("DeleteVNFVolumesTask start");
+			try {
+				VolumeGroupRollback vgr = req.getVolumeGroupRollback();
+				VnfRollback vrb = new VnfRollback(
+						vgr.getVolumeGroupStackId(), vgr.getTenantId(), vgr.getCloudSiteId(), true, true,
+						vgr.getMsoRequest(), null, null, null);
+				vnfAdapter.rollbackVnf(vrb);
+				response = new RollbackVolumeGroupResponse(true, req.getMessageId());
+			} catch (VnfException e) {
+				eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				// This is asynch, so POST response back to caller
+				BpelRestClient bpelClient = new BpelRestClient();
+				bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug("DeleteVNFVolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@PUT
+	@Path("{aaiVolumeGroupId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response updateVNFVolumes(
+		@PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
+		final UpdateVolumeGroupRequest req
+		)
+	{
+		LOGGER.debug("updateVNFVolumes enter: " + req.toJsonString());
+		if (aaiVolumeGroupId == null || !aaiVolumeGroupId.equals(req.getVolumeGroupId())) {
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("VolumeGroupId in URL does not match content")
+				.build();
+		}
+		UpdateVNFVolumesTask task = new UpdateVNFVolumesTask(req);
+		if (req.isSynchronous()) {
+			// This is a synchronous request
+			task.run();
+			return Response
+				.status(task.getStatusCode())
+				.entity(task.getGenericEntityResponse())
+				.build();
+		} else {
+			// This is an asynchronous request
+	    	try {
+	    		Thread t1 = new Thread(task);
+	    		t1.start();
+	    	} catch (Exception e) {
+	    		// problem handling create, send generic failure as sync resp to caller
+	    		LOGGER.error (MessageEnum.RA_UPDATE_VNF_ERR, "", "updateVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - updateVNFVolumes", e);
+	    		return Response.serverError().build();
+	    	}
+	    	// send sync response (ACK) to caller
+	    	LOGGER.debug ("updateVNFVolumes exit");
+	    	return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class UpdateVNFVolumesTask implements Runnable {
+		private final UpdateVolumeGroupRequest req;
+		private UpdateVolumeGroupResponse response = null;
+		private VolumeGroupExceptionResponse eresp = null;
+		private boolean sendxml;
+
+		public UpdateVNFVolumesTask(UpdateVolumeGroupRequest req) {
+			this.req = req;
+			this.sendxml = true; // can be set with a field or header later
+		}
+		public int getStatusCode() {
+			return (response != null) ? HttpStatus.SC_OK : HttpStatus.SC_BAD_REQUEST;
+		}
+		public Object getGenericEntityResponse() {
+			return (response != null)
+				? new GenericEntity<UpdateVolumeGroupResponse>(response) {}
+				: new GenericEntity<VolumeGroupExceptionResponse>(eresp) {};
+		}
+		private String getResponse() {
+			if (response != null) {
+				return sendxml ? response.toXmlString() : response.toJsonString();
+			} else {
+				return sendxml ? eresp.toXmlString() : eresp.toJsonString();
+			}
+		}
+		@Override
+		public void run() {
+			LOGGER.debug("UpdateVNFVolumesTask start");
+			try {
+				@SuppressWarnings("unused")
+				Holder<String> stackId = new Holder<String> ();
+				Holder<Map<String, String>> outputs = new Holder<Map <String, String>> ();
+				Holder<VnfRollback> vnfRollback = new Holder<VnfRollback> ();
+				String completeVnfVfModuleType = req.getVnfType() + "::" + req.getVfModuleType();
+				LOGGER.debug("in updateVfModuleVolume - completeVnfVfModuleType=" + completeVnfVfModuleType);
+
+				if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
+					outputs.value = testMap();
+				} else {
+					//vnfAdapter.updateVnf(
+					//		req.getCloudSiteId(),
+					//		req.getTenantId(),
+					//		req.getVnfType(),
+					//		req.getVnfVersion(),
+					//		req.getVfModuleType(),
+					//		"VOLUME",			// request type is VOLUME
+					//		req.getVolumeGroupStackId(),
+					//		req.getVolumeGroupParams(),
+					//		req.getMsoRequest(),
+					//		outputs,
+					//		vnfRollback);
+					vnfAdapter.updateVfModule (req.getCloudSiteId(),
+							req.getTenantId(),
+							//req.getVnfType(),
+							completeVnfVfModuleType,
+							req.getVnfVersion(),
+							req.getVolumeGroupStackId(),
+							"VOLUME",
+							null,
+							null,
+							req.getVolumeGroupStackId(),
+							req.getVolumeGroupParams(),
+							req.getMsoRequest(),
+							outputs,
+							vnfRollback); 
+				}
+				response = new UpdateVolumeGroupResponse(
+						req.getVolumeGroupId(), req.getVolumeGroupStackId(),
+						outputs.value, req.getMessageId());
+			} catch (VnfException e) {
+				eresp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, true, req.getMessageId());
+			}
+			if (!req.isSynchronous()) {
+				// This is asynch, so POST response back to caller
+				BpelRestClient bpelClient = new BpelRestClient();
+				bpelClient.bpelPost(getResponse(), req.getNotificationUrl(), sendxml);
+			}
+			LOGGER.debug("UpdateVNFVolumesTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@GET
+	@Path("{aaiVolumeGroupId}")
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response queryVNFVolumes(
+		@PathParam("aaiVolumeGroupId") String aaiVolumeGroupId,
+		@QueryParam("cloudSiteId") String cloudSiteId,
+		@QueryParam("tenantId") String tenantId,
+		@QueryParam("volumeGroupStackId") String volumeGroupStackId,
+		@QueryParam("skipAAI") Boolean skipAAI,
+		@QueryParam("msoRequest.requestId") String requestId,
+		@QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId
+		)
+	{
+    	//This request responds synchronously only
+    	LOGGER.debug ("queryVNFVolumes enter:" + aaiVolumeGroupId + " " + volumeGroupStackId);
+    	MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
+
+    	try {
+        	int respStatus = HttpStatus.SC_OK;
+        	QueryVolumeGroupResponse qryResp = new QueryVolumeGroupResponse(aaiVolumeGroupId, volumeGroupStackId, null, null);
+        	Holder<Boolean> vnfExists = new Holder<Boolean>();
+        	Holder<String> vfModuleId = new Holder<String>();
+        	Holder<VnfStatus> status = new Holder<VnfStatus>();
+        	Holder<Map<String, String>> outputs = new Holder<Map<String, String>>();
+			if (cloudSiteId != null && cloudSiteId.equals(TESTING_KEYWORD)) {
+				if (tenantId != null && tenantId.equals(TESTING_KEYWORD)) {
+					throw new VnfException("testing.");
+				}
+				vnfExists.value = true;
+				vfModuleId.value = TESTING_KEYWORD;
+				status.value = VnfStatus.ACTIVE;
+				outputs.value = testMap();
+			} else {
+				vnfAdapter.queryVnf(cloudSiteId, tenantId, volumeGroupStackId, msoRequest, vnfExists, vfModuleId, status, outputs);
+			}
+    		if (!vnfExists.value) {
+    			LOGGER.debug ("VNFVolumes not found");
+    			qryResp.setVolumeGroupStatus(status.value);
+    			respStatus = HttpStatus.SC_NOT_FOUND;
+    		} else {
+    			LOGGER.debug ("VNFVolumes found " + vfModuleId.value + ", status=" + status.value);
+    			qryResp.setVolumeGroupStatus(status.value);
+    			qryResp.setVolumeGroupOutputs(outputs.value);
+    		}
+        	LOGGER.debug("Query queryVNFVolumes exit");
+    		return Response
+    			.status(respStatus)
+    			.entity(new GenericEntity<QueryVolumeGroupResponse>(qryResp) {})
+    			.build();
+    	} catch (VnfException e) {
+    		LOGGER.error(MessageEnum.RA_QUERY_VNF_ERR,  aaiVolumeGroupId, "", "queryVNFVolumes", MsoLogger.ErrorCode.BusinessProcesssError, "VnfException - queryVNFVolumes", e);
+    		VolumeGroupExceptionResponse excResp = new VolumeGroupExceptionResponse(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.FALSE, null);
+        	LOGGER.debug("Query queryVNFVolumes exit");
+    		return Response
+    			.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
+    			.entity(new GenericEntity<VolumeGroupExceptionResponse>(excResp) {})
+    			.build();
+		}
+	}
+    public static Map<String, String> testMap() {
+		Map<String, String> m = new HashMap<String, String>();
+		m.put("mickey", "7");
+		m.put("clyde", "10");
+		m.put("wayne", "99");
+		return m;
+    }
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfAlreadyExists.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfAlreadyExists.java
new file mode 100644
index 0000000..7cec0cd
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfAlreadyExists.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.exceptions;
+
+
+
+import javax.xml.ws.WebFault;
+
+/**
+ * This class reports an exception when trying to create a VNF when another
+ * VNF of the same name already exists in the target cloud/tenant.  Note that
+ * the createVnf method suppresses this exception by default.
+ * 
+ *
+ */
+@WebFault (name="VnfAlreadyExists", faultBean="org.openecomp.mso.adapters.vnf.exceptions.VnfExceptionBean", targetNamespace="http://com.att.mso/vnf")
+public class VnfAlreadyExists extends VnfException {
+
+	private static final long serialVersionUID = 1L;
+
+	public VnfAlreadyExists (String name, String cloudId, String tenantId, String vnfId) {
+		super("VNF " + name + " already exists in cloud/tenant " + cloudId + "/" + tenantId + " with ID " + vnfId);
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfException.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfException.java
new file mode 100644
index 0000000..ceef76b
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfException.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.exceptions;
+
+
+
+import javax.xml.ws.WebFault;
+
+import org.openecomp.mso.openstack.exceptions.MsoException;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+/**
+ * This class simply extends Exception (without addition additional functionality)
+ * to provide an identifier for VNF related exceptions on create, delete, query.
+ * 
+ *
+ */
+@WebFault (name="VnfException", faultBean="org.openecomp.mso.adapters.vnf.exceptions.VnfExceptionBean", targetNamespace="http://com.att.mso/vnf")
+public class VnfException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	private VnfExceptionBean faultInfo;
+	
+	public VnfException (String msg) {
+		super(msg);
+		faultInfo = new VnfExceptionBean (msg);
+	}
+	
+	public VnfException (Throwable e) {
+		super(e);
+		faultInfo = new VnfExceptionBean (e.getMessage());
+	}
+	
+	public VnfException (String msg, Throwable e) {
+		super (msg, e);
+		faultInfo = new VnfExceptionBean (msg);
+	}
+
+	public VnfException (String msg, MsoExceptionCategory category) {
+		super(msg);
+		faultInfo = new VnfExceptionBean (msg, category);
+	}
+	
+	public VnfException (String msg, MsoExceptionCategory category, Throwable e) {
+		super (msg, e);
+		faultInfo = new VnfExceptionBean (msg, category);
+	}
+	
+	public VnfException (MsoException e) {
+		super (e);
+		faultInfo = new VnfExceptionBean (e.getContextMessage(), e.getCategory());
+	}
+	
+	public VnfExceptionBean getFaultInfo() {
+		return faultInfo;
+	}
+
+	public void setFaultInfo(VnfExceptionBean faultInfo) {
+		this.faultInfo = faultInfo;
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfExceptionBean.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfExceptionBean.java
new file mode 100644
index 0000000..15918ea
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfExceptionBean.java
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.exceptions;
+
+
+import java.io.Serializable;
+
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+/**
+ * Jax-WS Fault Bean for Vnf Exception
+ */
+public class VnfExceptionBean implements Serializable {
+
+    private static final long serialVersionUID = -5699310749783790095L;
+
+    private String message;
+	private MsoExceptionCategory category;
+	private Boolean rolledBack;
+
+	public VnfExceptionBean () {}
+
+	public VnfExceptionBean (String message) {
+		this.message = message;
+	}
+
+	public VnfExceptionBean (String message, MsoExceptionCategory category) {
+		this.message = message;
+		this.category = category;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public MsoExceptionCategory getCategory () {
+		return category;
+	}
+
+	public void setCategory (MsoExceptionCategory category) {
+		this.category = category;
+	}
+
+	public Boolean isRolledBack() {
+		return rolledBack;
+	}
+
+	public void setRolledBack(Boolean rolledBack) {
+		this.rolledBack = rolledBack;
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfNotFound.java b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfNotFound.java
new file mode 100644
index 0000000..3c27d03
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/main/java/org/openecomp/mso/adapters/vnf/exceptions/VnfNotFound.java
@@ -0,0 +1,43 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.exceptions;
+
+
+import javax.xml.ws.WebFault;
+
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+
+/**
+ * This class reports an exception when trying to update a Network that does
+ * not exist in the target cloud/tenant.  Note that deleteNetwork suppresses
+ * this exception (deletion of non-existent network is considered a success).
+ * 
+ *
+ */
+@WebFault (name="VnfNotFound", faultBean="org.openecomp.mso.adapters.vnf.exceptions.VnfExceptionBean", targetNamespace="http://com.att.mso/vnf")
+public class VnfNotFound extends VnfException {
+
+	private static final long serialVersionUID = 1L;
+
+	public VnfNotFound (String cloudId, String tenantId, String vnfName) {
+		super("VNF " + vnfName + " not found in cloud/tenant " + cloudId + "/" + tenantId);
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/QueryTest.java b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/QueryTest.java
new file mode 100644
index 0000000..96e50d0
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/QueryTest.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.test;
+
+
+import java.util.Map;
+
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapter;
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapterImpl;
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+
+public class QueryTest {
+	public final static void main (String args[])
+	{
+		MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl();
+		log ("Got a VnfAdapter");
+		
+		String cloudId = "MT";
+		String tenantId = "MSO_Test";
+		String vnfName = "VNF_TEST1";
+		Holder<Boolean> vnfExists = new Holder<Boolean>();
+		Holder<String> vnfId = new Holder<String>();
+		Holder<VnfStatus> status = new Holder<VnfStatus>();
+		Holder<Map<String,String>> outputs = new Holder<Map<String,String>>();
+		
+		try {
+			vnfAdapter.queryVnf(cloudId, tenantId, vnfName, null,
+						vnfExists, vnfId, status, outputs);
+		} catch (VnfException e) {
+			log ("Got an Exception: " + e);
+		}
+		
+		if (! vnfExists.value){
+			log ("VNF Not Found");
+		} else {
+			log ("Found VNF, ID = " + vnfId.value + ", status=" + status.value);
+		}
+	}
+	
+	private static void log (String msg) {
+		System.out.println (msg);
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfCreateTest.java b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfCreateTest.java
new file mode 100644
index 0000000..0269172
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfCreateTest.java
@@ -0,0 +1,87 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.test;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapter;
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapterImpl;
+import org.openecomp.mso.openstack.beans.VnfRollback;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+
+public class VnfCreateTest {
+	public final static void main (String args[])
+	{
+		MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl();
+		log ("Got a VnfAdapter");
+		
+		// Web Service Inputs
+		String cloudId = "MT";
+		String tenantName = "John_Test";
+		String vnfType = "ApacheDemo";
+		String vnfName = "AdapterTest";
+		Map<String,String> inputs = new HashMap<String,String>();
+		inputs.put("vnf_id", "abc");
+		inputs.put("extra", "whocares");
+		inputs.put("private_subnet_gateway", "10.4.1.1");
+		inputs.put("private_subnet_cidr", "10.4.1.0/29");
+		
+		// Web Service Outputs
+		Holder<String> vnfId = new Holder<String>();
+		Holder<Map<String,String>> outputs = new Holder<Map<String,String>>();
+		Holder<VnfRollback> vnfRollback = new Holder<VnfRollback>();
+
+		try {
+			vnfAdapter.createVnf(cloudId, tenantName, vnfType,null, vnfName, null, null, inputs, false, true, null,
+					vnfId, outputs, vnfRollback);
+		} catch (VnfException e) {
+			log ("Got a Create Exception: " + e);
+			System.exit(1);
+		}
+		
+		log ("Created VNF, ID = " + vnfId.value);
+		for (String key : outputs.value.keySet()) {
+			log ("   " + key + " = " + outputs.value.get(key));
+		}
+		if (vnfRollback.value != null)
+			log (vnfRollback.value.toString());
+		
+		try {
+			Thread.sleep(5000);
+		} catch (InterruptedException e) {}
+		
+		log ("Rolling Back VNF");
+		try {
+			vnfAdapter.rollbackVnf(vnfRollback.value);
+		} catch (VnfException e) {
+			log ("Got a Rollback Exception: " + e);
+		}
+		log ("VNF Rolled Back");
+	}
+	
+	private static void log (String msg) {
+		System.out.println (msg);
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfDeleteTest.java b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfDeleteTest.java
new file mode 100644
index 0000000..0c35da7
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfDeleteTest.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.test;
+
+
+
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapter;
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapterImpl;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+
+public class VnfDeleteTest {
+	public final static void main (String args[])
+	{
+		MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl();
+		log ("Got a VnfAdapter");
+		
+		// Web Service Inputs
+		String cloudId = "MT";
+		String tenantName = "MSO_Test";
+		String vnfName = "AdapterTest";
+
+		try {
+			vnfAdapter.deleteVnf(cloudId, tenantName, vnfName, null);
+		} catch (VnfException e) {
+			log ("Got an Exception: " + e);
+		}
+		
+		log ("Deleted VNF");
+	}
+	
+	private static void log (String msg) {
+		System.out.println (msg);
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfQueryTest.java b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfQueryTest.java
new file mode 100644
index 0000000..923c222
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/test/java/org/openecomp/mso/adapters/vnf/test/VnfQueryTest.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.mso.adapters.vnf.test;
+
+
+import java.util.Map;
+
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapter;
+import org.openecomp.mso.adapters.vnf.MsoVnfAdapterImpl;
+import org.openecomp.mso.openstack.beans.VnfStatus;
+import org.openecomp.mso.adapters.vnf.exceptions.VnfException;
+
+public class VnfQueryTest {
+	public final static void main (String args[])
+	{
+		MsoVnfAdapter vnfAdapter = new MsoVnfAdapterImpl();
+		log ("Got a VnfAdapter");
+		
+		String cloudId = "MT";
+		String tenantId = "MSO_Test";
+		String vnfName = "VNF_TEST1";
+		Holder<Boolean> vnfExists = new Holder<Boolean>();
+		Holder<String> vnfId = new Holder<String>();
+		Holder<VnfStatus> status = new Holder<VnfStatus>();
+		Holder<Map<String,String>> outputs = new Holder<Map<String,String>>();
+		
+		try {
+			vnfAdapter.queryVnf(cloudId, tenantId, vnfName, null,
+						vnfExists, vnfId, status, outputs);
+		} catch (VnfException e) {
+			log ("Got an Exception: " + e);
+		}
+		
+		if (! vnfExists.value){
+			log ("VNF Not Found");
+		} else {
+			log ("Found VNF, ID = " + vnfId.value + ", status=" + status.value);
+		}
+	}
+	
+	private static void log (String msg) {
+		System.out.println (msg);
+	}
+}
diff --git a/adapters/mso-vnf-adapter/src/test/resources/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector b/adapters/mso-vnf-adapter/src/test/resources/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector
new file mode 100644
index 0000000..1281d32
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/test/resources/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector
@@ -0,0 +1 @@
+com.woorea.openstack.connector.HttpClientConnector
\ No newline at end of file
diff --git a/adapters/mso-vnf-adapter/src/test/resources/logback-test.xml b/adapters/mso-vnf-adapter/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..238980e
--- /dev/null
+++ b/adapters/mso-vnf-adapter/src/test/resources/logback-test.xml
@@ -0,0 +1,48 @@
+<!--
+  ============LICENSE_START=======================================================
+  ECOMP MSO
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR 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 >
+
+  
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%thread|%X{ServiceName}|%X{InstanceUUID}|%.-5level|%X{AlertSeverity}||%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}||%X{Timer}|%msg%n</pattern>
+    </encoder>
+  </appender>
+
+
+  <logger name="com.att.eelf.audit" level="info" additivity="false">
+    <appender-ref ref="STDOUT" />
+  </logger>
+  
+  <logger name="com.att.eelf.metrics" level="info" additivity="false">
+        <appender-ref ref="STDOUT" />
+  </logger>
+
+  <logger name="com.att.eelf.error" level="trace" additivity="false">
+    <appender-ref ref="STDOUT" />
+  </logger> 
+
+  <root level="info">
+    <appender-ref ref="STDOUT" />
+  </root>
+ 
+
+</configuration>
