diff --git a/adapters/mso-network-adapter/README b/adapters/mso-network-adapter/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/adapters/mso-network-adapter/README
diff --git a/adapters/mso-network-adapter/WebContent/META-INF/MANIFEST.MF b/adapters/mso-network-adapter/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ b/adapters/mso-network-adapter/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: 
+
diff --git a/adapters/mso-network-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector b/adapters/mso-network-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector
new file mode 100644
index 0000000..1281d32
--- /dev/null
+++ b/adapters/mso-network-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-network-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml b/adapters/mso-network-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..58ddb4a
--- /dev/null
+++ b/adapters/mso-network-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-network-adapter/WebContent/WEB-INF/jboss-web.xml b/adapters/mso-network-adapter/WebContent/WEB-INF/jboss-web.xml
new file mode 100644
index 0000000..251a78b
--- /dev/null
+++ b/adapters/mso-network-adapter/WebContent/WEB-INF/jboss-web.xml
@@ -0,0 +1,3 @@
+<jboss-web>
+	<context-root>networks</context-root>
+</jboss-web>
\ No newline at end of file
diff --git a/adapters/mso-network-adapter/WebContent/WEB-INF/web.xml b/adapters/mso-network-adapter/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000..a0c726a
--- /dev/null
+++ b/adapters/mso-network-adapter/WebContent/WEB-INF/web.xml
@@ -0,0 +1,102 @@
+<?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-network-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.network.xml</param-value>
+  </context-param>
+  <context-param>
+  	<param-name>mso.configuration</param-name>
+  	<param-value>MSO_PROP_NETWORK_ADAPTER=mso.network.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.network.HealthCheckHandler,
+		org.openecomp.mso.adapters.network.NetworkAdapterRest
+    </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>SoapRequests</web-resource-name>
+            <description>Soap Ingress Requests</description>
+            <url-pattern>/NetworkAdapter</url-pattern>
+            <url-pattern>/NetworkAdapterAsync</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>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>RestRequests</web-resource-name>
+            <description>Rest Ingress Requests</description>
+            <url-pattern>/rest/v1/networks/*</url-pattern>
+            <http-method>DELETE</http-method>
+            <http-method>GET</http-method>
+            <http-method>POST</http-method>
+            <http-method>PUT</http-method>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>BPEL-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>
+  <welcome-file-list>
+    <welcome-file>check.html</welcome-file>
+  </welcome-file-list>
+</web-app>
+
diff --git a/adapters/mso-network-adapter/WebContent/check.html b/adapters/mso-network-adapter/WebContent/check.html
new file mode 100644
index 0000000..00f37d6
--- /dev/null
+++ b/adapters/mso-network-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-network-adapter/pom.xml b/adapters/mso-network-adapter/pom.xml
new file mode 100644
index 0000000..3991bf3
--- /dev/null
+++ b/adapters/mso-network-adapter/pom.xml
@@ -0,0 +1,154 @@
+<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-network-adapter</artifactId>
+	<packaging>war</packaging>
+	<name>mso-network-adapter</name>
+	<description>Web service endpoint for Network operations</description>
+
+	<!-- <properties> -->
+	<!-- <project.build.sourceEncoding/> -->
+	<!-- <project.reporting.outputEncoding/> -->
+	<!-- </properties> -->
+
+	<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>
+						<goals>
+							<goal>wsgen</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<verbose>true</verbose>
+					<sei>org.openecomp.mso.adapters.network.MsoNetworkAdapterImpl</sei>
+					<genWsdl>true</genWsdl>
+					<inlineSchemas>true</inlineSchemas>
+				</configuration>
+				<dependencies>
+					<dependency>
+						<groupId>com.sun.xml.ws</groupId>
+						<artifactId>jaxws-tools</artifactId>
+						<version>2.2.7</version>
+					</dependency>
+					<dependency>
+						<groupId>org.openecomp.mso.adapters</groupId>
+						<artifactId>mso-adapter-utils</artifactId>
+						<version>${project.version}</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>javax</groupId>
+			<artifactId>javaee-web-api</artifactId>
+			<version>6.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<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-network-adapter-async-client</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.mockito</groupId>
+			<artifactId>mockito-all</artifactId>
+			<version>1.10.19</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>javax.servlet-api</artifactId>
+			<version>3.1.0</version>
+			<scope>test</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>
+
+	</dependencies>
+</project>
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/BpelRestClient.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/BpelRestClient.java
new file mode 100644
index 0000000..dcd12d2
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/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.network;
+
+
+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_NETWORK_ADAPTER = "MSO_PROP_NETWORK_ADAPTER";
+	private static final String PROPERTY_DOMAIN          = "org.openecomp.mso.adapters.network";
+	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_NETWORK_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_NETWORK_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_NETWORK_ADAPTER;
+			LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "", "", MsoLogger.ErrorCode.DataError, "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.DataError, "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.AvailabilityError, "Exception 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_NETWORK_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-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailPolicyRef.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailPolicyRef.java
new file mode 100644
index 0000000..6e2644d
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailPolicyRef.java
@@ -0,0 +1,78 @@
+/*-
+ * ============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.network;
+
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.openstack.exceptions.MsoAdapterException;
+
+public class ContrailPolicyRef {
+	private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+	 
+	@JsonProperty("network_policy_refs_data_sequence")
+	private ContrailPolicyRefSeq seq;
+	
+	public JsonNode toJsonNode()
+	{
+		JsonNode node = null;
+		try
+		{
+			ObjectMapper mapper = new ObjectMapper(); 
+			node = mapper.convertValue(this, JsonNode.class);
+		}
+		catch (Exception e)
+		{
+			LOGGER.error (MessageEnum.RA_MARSHING_ERROR, "Error creating JsonString for Contrail Policy Ref", "", "", MsoLogger.ErrorCode.SchemaError, "Exception creating JsonString for Contrail Policy Ref", e);
+		}
+		
+		return node;
+	}
+	
+	public String toJsonString()
+	{
+		String jsonString = null;
+		try
+		{
+			ObjectMapper mapper = new ObjectMapper(); 
+			jsonString = mapper.writeValueAsString(this);
+		}
+		catch (Exception e)
+		{
+			LOGGER.error (MessageEnum.RA_MARSHING_ERROR, "Error creating JsonString for Contrail Policy Ref", "", "", MsoLogger.ErrorCode.SchemaError, "Exception creating JsonString for Contrail Policy Ref", e);
+		}
+		
+		return jsonString;
+	}
+	
+	public void populate(String major, String minor)
+	{
+		seq = new ContrailPolicyRefSeq(major, minor);
+		return;
+	}
+	
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailPolicyRefSeq.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailPolicyRefSeq.java
new file mode 100644
index 0000000..b5d7502
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailPolicyRefSeq.java
@@ -0,0 +1,65 @@
+/*-
+ * ============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.network;
+
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class ContrailPolicyRefSeq {
+	
+	@JsonProperty("network_policy_refs_data_sequence_major")
+	private String major;
+	
+	@JsonProperty("network_policy_refs_data_sequence_minor")
+	private String minor;
+
+	public ContrailPolicyRefSeq() {
+	}
+	
+	public ContrailPolicyRefSeq(String major, String minor) {
+		super();
+		this.major = major;
+		this.minor = minor;
+	}
+
+	public String getMajor() {
+		return major;
+	}
+
+	public void setMajor(String major) {
+		this.major = major;
+	}
+
+	public String getMinor() {
+		return minor;
+	}
+
+	public void setMinor(String minor) {
+		this.minor = minor;
+	}
+
+	@Override
+	public String toString() {
+		return "ContrailPolicyRefSeq [major=" + major + ", minor=" + minor
+				+ "]";
+	} 
+
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnet.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnet.java
new file mode 100644
index 0000000..3df1014
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnet.java
@@ -0,0 +1,196 @@
+/*-
+ * ============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.network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import org.openecomp.mso.logger.MessageEnum;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.openstack.beans.Pool;
+import org.openecomp.mso.openstack.beans.Subnet;
+import static org.openecomp.mso.openstack.utils.MsoCommonUtils.isNullOrEmpty;
+
+public class ContrailSubnet {
+	private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_subnet")
+	private ContrailSubnetIp subnet = new ContrailSubnetIp();
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_default_gateway")
+	private String default_gateway;
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_subnet_name")
+	private String subnet_name;
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_enable_dhcp")
+	private Boolean enable_dhcp;
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_addr_from_start")
+	private Boolean addr_from_start = true;
+	
+	/** future - leave this commented
+	private String subnet_uuid;
+	private String dns_server_address;
+	private List<String> dns_nameservers;
+	private String dhcp_option_list;
+	private String host_routes;
+	**/
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_allocation_pools")
+	private List<ContrailSubnetPool> allocation_pools =  new ArrayList <ContrailSubnetPool> ();
+
+	public ContrailSubnet() {
+		super();
+	}
+
+	public String getDefault_gateway() {
+		return default_gateway;
+	}
+
+	public void setDefault_gateway(String default_gateway) {
+		this.default_gateway = default_gateway;
+	}
+
+	public ContrailSubnetIp getSubnet() {
+		return subnet;
+	}
+
+	public void setSubnet(ContrailSubnetIp subnet) {
+		this.subnet = subnet;
+	}
+
+	public Boolean isEnable_dhcp() {
+		return enable_dhcp;
+	}
+
+	public void setEnable_dhcp(Boolean enable_dhcp) {
+		this.enable_dhcp = enable_dhcp;
+	}
+
+	public String getSubnet_name() {
+		return subnet_name;
+	}
+
+	public void setSubnet_name(String subnet_name) {
+		this.subnet_name = subnet_name;
+	}
+
+	public List<ContrailSubnetPool> getAllocation_pools() {
+		return allocation_pools;
+	}
+
+	public void setPools(List<ContrailSubnetPool> allocation_pools) {
+		this.allocation_pools = allocation_pools;
+	}
+
+	public Boolean isAddr_from_start() {
+		return addr_from_start;
+	}
+
+	public void setAddr_from_start(Boolean addr_from_start) {
+		this.addr_from_start = addr_from_start;
+	}
+
+	public JsonNode toJsonNode()
+	{
+		JsonNode node = null;
+		try
+		{
+			ObjectMapper mapper = new ObjectMapper();
+			node = mapper.convertValue(this, JsonNode.class);
+		}
+		catch (Exception e)
+		{
+			String error = "Error creating JsonNode for Contrail Subnet:" + subnet_name;
+			LOGGER.error (MessageEnum.RA_MARSHING_ERROR, error, "", "", MsoLogger.ErrorCode.SchemaError, "Exception creating JsonNode for Contrail Subnet", e);
+		}
+		
+		return node;
+	}
+	
+	public String toJsonString()
+	{
+		String jsonString = null;
+		try
+		{
+			ObjectMapper mapper = new ObjectMapper();
+			jsonString = mapper.writeValueAsString(this);
+		}
+		catch (Exception e)
+		{
+			String error = "Error creating JsonString for Contrail Subnet:" + subnet_name;
+			LOGGER.error (MessageEnum.RA_MARSHING_ERROR, error, "", "", MsoLogger.ErrorCode.SchemaError, "Exception creating JsonString for Contrail Subnet", e);
+		}
+		
+		return jsonString;
+	}
+	//poulate contrail subnet with input(from bopel) subnet
+	public void populateWith(Subnet i_subnet)
+	{
+		if (i_subnet != null)
+		{
+			if (!isNullOrEmpty(i_subnet.getSubnetName()))
+				subnet_name = i_subnet.getSubnetName();
+			else
+				subnet_name = i_subnet.getSubnetId();
+			enable_dhcp = i_subnet.getEnableDHCP();
+			default_gateway = i_subnet.getGatewayIp();
+			if (!isNullOrEmpty(i_subnet.getCidr()) )
+			{
+				int idx = i_subnet.getCidr().indexOf("/");
+				if (idx != -1)
+				{
+					subnet.setIp_prefix(i_subnet.getCidr().substring(0, idx));
+					subnet.setIp_prefix_len(i_subnet.getCidr().substring(idx+1));
+				}
+			}
+			if (i_subnet.getAllocationPools() != null)
+			{
+				for (Pool pool : i_subnet.getAllocationPools())
+				{
+					if ( !isNullOrEmpty(pool.getStart()) && !isNullOrEmpty(pool.getEnd()) )
+					{		
+						ContrailSubnetPool csp = new ContrailSubnetPool();
+						csp.populateWith(pool);
+						allocation_pools.add (csp);
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public String toString() {
+		
+		StringBuilder buf = new StringBuilder ();
+		for (ContrailSubnetPool pool : allocation_pools)
+		{
+			 buf.append(pool.toString());
+		}
+		return "ContrailSubnet [subnet=" + subnet.toString() + " default_gateway=" + default_gateway
+				+ " enable_dhcp=" + enable_dhcp +  " addr_from_start=" + addr_from_start + " subnet_name=" + subnet_name + " allocation_pools=" + buf + " ]";
+	}
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnetIp.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnetIp.java
new file mode 100644
index 0000000..c0a5311
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnetIp.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.network;
+
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class ContrailSubnetIp {
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_subnet_ip_prefix")
+	private String ip_prefix;
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_subnet_ip_prefix_len")
+	private String ip_prefix_len; 
+
+	public ContrailSubnetIp() {
+	}
+
+	public String getIp_prefix() {
+		return ip_prefix;
+	}
+
+	public void setIp_prefix(String ip_prefix) {
+		this.ip_prefix = ip_prefix;
+	}
+
+	public String getIp_prefix_len() {
+		return ip_prefix_len;
+	}
+
+	public void setIp_prefix_len(String ip_prefix_len) {
+		this.ip_prefix_len = ip_prefix_len;
+	}
+
+	@Override
+	public String toString() {
+		return "ContrailSubnetIp [ip_prefix=" + ip_prefix + ", ip_prefix_len=" + ip_prefix_len + "]";
+	}
+
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnetPool.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnetPool.java
new file mode 100644
index 0000000..5b40ba2
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/ContrailSubnetPool.java
@@ -0,0 +1,67 @@
+/*-
+ * ============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.network;
+
+
+import org.openecomp.mso.openstack.beans.Pool;
+import org.codehaus.jackson.annotate.JsonProperty;
+public class ContrailSubnetPool {
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_allocation_pools_start")
+	private String start;
+	
+	@JsonProperty("network_ipam_refs_data_ipam_subnets_allocation_pools_end")
+	private String end;
+
+	public ContrailSubnetPool() {
+	}
+
+	public String getStart() {
+		return start;
+	}
+
+	public void setStart(String start) {
+		this.start = start;
+	}
+
+	public String getEnd() {
+		return end;
+	}
+
+	public void setEnd(String end) {
+		this.end = end;
+	}
+	
+	public void populateWith(Pool pool)
+	{
+		if (pool != null)
+		{
+			start = pool.getStart();
+			end = pool.getEnd();
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "ContrailSubnetPool [start=" + start + ", end=" + end + "]";
+	}
+	
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/HealthCheckHandler.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/HealthCheckHandler.java
new file mode 100644
index 0000000..2767baf
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/HealthCheckHandler.java
@@ -0,0 +1,67 @@
+/*-
+ * ============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.network;
+
+
+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.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_NETWORK_ADAPTER = "MSO_PROP_NETWORK_ADAPTER";
+
+	    @HEAD
+	    @GET
+	    @Path("/healthcheck")
+	    @Produces("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_NETWORK_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-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapter.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapter.java
new file mode 100644
index 0000000..4960877
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapter.java
@@ -0,0 +1,216 @@
+/*-
+ * ============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.network;
+
+
+import java.util.List;
+import java.util.Map;
+
+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.adapters.network.exceptions.NetworkException;
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.openstack.beans.NetworkRollback;
+import org.openecomp.mso.openstack.beans.NetworkStatus;
+import org.openecomp.mso.openstack.beans.Subnet;
+
+@WebService (name="NetworkAdapter", targetNamespace="http://com.att.mso/network")
+public interface MsoNetworkAdapter
+{
+	// TODO:  Rename all of these to include Vlan in the service name?  At least for the
+	// create and update calls, since they are specific to VLAN-based provider networks.
+
+	/**
+	 * This is the "Create Network" Web Service Endpoint definition.
+	 */
+	@WebMethod
+	public void createNetwork (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkName") @XmlElement(required=true) String networkName,
+							@WebParam(name="physicalNetworkName") String physicalNetworkName,
+							@WebParam(name="vlans") List<Integer> vlans,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="subnets") List<Subnet> subnets,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="networkId", mode=Mode.OUT) Holder<String> networkId,
+							@WebParam(name="neutronNetworkId", mode=Mode.OUT) Holder<String> neutronNetworkId,
+							@WebParam(name="subnetIdMap", mode=Mode.OUT) Holder<Map<String, String>> subnetIdMap,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<NetworkRollback> rollback )
+		throws NetworkException;
+
+	@WebMethod
+	public void createNetworkContrail (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkName") @XmlElement(required=true) String networkName,
+							@WebParam(name="routeTargets") List<String> routeTargets,
+							@WebParam(name="shared") String shared,
+							@WebParam(name="external") String external,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="subnets") List<Subnet> subnets,
+							@WebParam(name="policyFqdns") List<String> policyFqdns,
+							@WebParam(name="routeTableFqdns") List<String> routeTableFqdns,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="networkId", mode=Mode.OUT) Holder<String> networkId,
+							@WebParam(name="neutronNetworkId", mode=Mode.OUT) Holder<String> neutronNetworkId,
+							@WebParam(name="networkFqdn", mode=Mode.OUT) Holder<String> networkFqdn,
+							@WebParam(name="subnetIdMap", mode=Mode.OUT) Holder<Map<String, String>> subnetIdMap,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<NetworkRollback> rollback )
+		throws NetworkException;
+
+	/**
+	 * This is the "Update VLANs" Web Service Endpoint definition.
+	 * This webservice replaces the set of VLANs on a network.
+	 */
+	@WebMethod
+	public void updateNetwork (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+							@WebParam(name="networkName") @XmlElement(required=true) String networkName,
+							@WebParam(name="physicalNetworkName") @XmlElement(required=true) String physicalNetworkName,
+							@WebParam(name="vlans") @XmlElement(required=true) List<Integer> vlans,
+							@WebParam(name="subnets") List<Subnet> subnets,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="subnetIdMap", mode=Mode.OUT) Holder<Map<String, String>> subnetIdMap,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<NetworkRollback> rollback )
+		throws NetworkException;
+
+	@WebMethod
+	public void updateNetworkContrail (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+							@WebParam(name="networkName") @XmlElement(required=true) String networkName,
+							@WebParam(name="routeTargets") List<String> routeTargets,
+							@WebParam(name="shared") String shared,
+							@WebParam(name="external") String external,
+							@WebParam(name="subnets") List<Subnet> subnets,
+							@WebParam(name="policyFqdns") List<String> policyFqdns,
+							@WebParam(name="routeTableFqdns") List<String> routeTableFqdns,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="subnetIdMap", mode=Mode.OUT) Holder<Map<String, String>> subnetIdMap,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<NetworkRollback> rollback )
+		throws NetworkException;
+
+	/**
+	 * TODO:
+	 * This is the "Add VLAN" Web Service Endpoint definition.
+	 * This webservice adds a VLAN to a network.
+	 * This service assumes that PO supports querying the current vlans in real time.
+	 * Otherwise, the caller must have the complete list and should use updateVlans instead.
+	@WebMethod
+	public void addVlan (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+							@WebParam(name="physicalNetworkName") @XmlElement(required=true) String physicalNetworkName,
+							@WebParam(name="vlan") @XmlElement(required=true) Integer vlan,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<NetworkRollback> rollback )
+		throws NetworkException;
+	 */
+
+	/**
+	 * TODO:
+	 * This is the "Remove VLAN" Web Service Endpoint definition.
+	 * This webservice removes a VLAN from a network.
+	 * This service assumes that PO supports querying the current vlans in real time.
+	 * Otherwise, the caller must have the complete list and should use updateVlans instead.
+	 *
+	 * This service returns an indicator (noMoreVLans) if the VLAN that was removed was
+	 * the last one on the network.
+	 *
+	 * It is not clear that Rollback will work for delete.  The network can be
+	 * recreated from the NetworkRollback object, but the network ID (and stack ID
+	 * for Heat-based orchestration) will be different.  The caller will need to know
+	 * to update these identifiers in the inventory DB (A&AI).
+	@WebMethod
+	public void removeVlan (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+							@WebParam(name="physicalNetworkName") @XmlElement(required=true) String physicalNetworkName,
+							@WebParam(name="vlan") @XmlElement(required=true) Integer vlan,
+							@WebParam(name="noMoreVlans", mode=Mode.OUT) Holder<Boolean> noMoreVlans,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<NetworkRollback> rollback )
+		throws NetworkException;
+	 */
+
+	/**
+	 * This is the "Query Network" Web Service Endpoint definition.
+	 * TODO: Should this just return the NetworkInfo complete structure?
+	 */
+	@WebMethod
+	public void queryNetwork (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkNameOrId") @XmlElement(required=true) String networkNameOrId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="networkExists", mode=Mode.OUT) Holder<Boolean> networkExists,
+							@WebParam(name="networkId", mode=Mode.OUT) Holder<String> networkId,
+							@WebParam(name="neutronNetworkId", mode=Mode.OUT) Holder<String> neutronNetworkId,
+							@WebParam(name="status", mode=Mode.OUT) Holder<NetworkStatus> status,
+							@WebParam(name="vlans", mode=Mode.OUT) Holder<List<Integer>> vlans,
+							@WebParam(name="subnetIdMap", mode=Mode.OUT) Holder<Map<String, String>> subnetIdMap)
+		throws NetworkException;
+
+	@WebMethod
+	public void queryNetworkContrail (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkNameOrId") @XmlElement(required=true) String networkNameOrId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="networkExists", mode=Mode.OUT) Holder<Boolean> networkExists,
+							@WebParam(name="networkId", mode=Mode.OUT) Holder<String> networkId,
+							@WebParam(name="neutronNetworkId", mode=Mode.OUT) Holder<String> neutronNetworkId,
+							@WebParam(name="status", mode=Mode.OUT) Holder<NetworkStatus> status,
+							@WebParam(name="routeTargets", mode=Mode.OUT) Holder<List<String>> routeTargets,
+							@WebParam(name="subnetIdMap", mode=Mode.OUT) Holder<Map<String, String>> subnetIdMap)
+		throws NetworkException;
+
+	/**
+	 * This is the "Delete Network" Web Service endpoint definition.
+	 */
+	@WebMethod
+	public void deleteNetwork (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="networkDeleted", mode=Mode.OUT) Holder<Boolean> networkDeleted)
+		throws NetworkException;
+
+	/**
+	 * This is the "Rollback Network" Web Service endpoint definition.
+	 */
+	@WebMethod
+	public void rollbackNetwork (@WebParam(name="rollback") @XmlElement(required=true) NetworkRollback rollback)
+		throws NetworkException;
+
+	@WebMethod
+	public void healthCheck ();
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterAsync.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterAsync.java
new file mode 100644
index 0000000..e79ba12
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterAsync.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.network;
+
+
+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.Subnet;
+import org.openecomp.mso.openstack.beans.NetworkRollback;
+
+import java.util.List;
+/**
+ * This webservice defines the Asynchronous versions of NETWORK adapter calls.
+ * The notification messages for final responses are documented elsewhere
+ * (by the client service WSDL).
+ *
+ */
+@WebService (name="NetworkAdapterAsync", targetNamespace="http://com.att.mso/networkA")
+public interface MsoNetworkAdapterAsync
+{
+	/**
+	 * This is the "Create NETWORK" Web Service Endpoint definition.
+	 */
+	@WebMethod
+	@Oneway
+	public void createNetworkA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkName") @XmlElement(required=true) String networkName,
+							@WebParam(name="physicalNetworkName") String physicalNetworkName,
+							@WebParam(name="vlans") List<Integer> vlans,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="subnets") List<Subnet> subnets,
+							@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 updateNetworkA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+						@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+						@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+						@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+						@WebParam(name="networkName") @XmlElement(required=true) String networkName,
+						@WebParam(name="physicalNetworkName") @XmlElement(required=true) String physicalNetworkName,
+						@WebParam(name="vlans") @XmlElement(required=true) List<Integer> vlans,
+						@WebParam(name="subnets") List<Subnet> subnets,
+						@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 queryNetworkA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkNameOrId") @XmlElement(required=true) String networkNameOrId,
+							@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 deleteNetworkA (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="networkType") @XmlElement(required=true) String networkType,
+							@WebParam(name="networkId") @XmlElement(required=true) String networkId,
+							@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 rollbackNetworkA (@WebParam(name="rollback") @XmlElement(required=true) NetworkRollback 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-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterAsyncImpl.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterAsyncImpl.java
new file mode 100644
index 0000000..75cbc63
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterAsyncImpl.java
@@ -0,0 +1,679 @@
+/*-
+ * ============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.network;
+
+
+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.network.async.client.CreateNetworkNotification;
+import org.openecomp.mso.adapters.network.async.client.MsoExceptionCategory;
+import org.openecomp.mso.adapters.network.async.client.NetworkAdapterNotify;
+import org.openecomp.mso.adapters.network.async.client.NetworkAdapterNotify_Service;
+import org.openecomp.mso.adapters.network.async.client.QueryNetworkNotification;
+import org.openecomp.mso.adapters.network.async.client.UpdateNetworkNotification;
+import org.openecomp.mso.adapters.network.exceptions.NetworkException;
+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.openstack.beans.NetworkRollback;
+import org.openecomp.mso.openstack.beans.NetworkStatus;
+import org.openecomp.mso.openstack.beans.Subnet;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+
+@WebService(serviceName = "NetworkAdapterAsync", endpointInterface = "org.openecomp.mso.adapters.network.MsoNetworkAdapterAsync", targetNamespace = "http://com.att.mso/networkA")
+public class MsoNetworkAdapterAsyncImpl implements MsoNetworkAdapterAsync {
+
+	MsoPropertiesFactory msoPropertiesFactory=new MsoPropertiesFactory();
+
+	CloudConfigFactory cloudConfigFactory=new CloudConfigFactory();
+
+	public static final String MSO_PROP_NETWORK_ADAPTER="MSO_PROP_NETWORK_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.network.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 Network Adapter");
+    }
+
+    /**
+     * This is the "Create Network" web service implementation.
+     * It will create a new Network of the requested type in the specified cloud
+     * and tenant. The tenant must exist at the time this service is called.
+     *
+     * If a network with the same name already exists, this can be considered a
+     * success or failure, depending on the value of the 'failIfExists' parameter.
+     *
+     * There will be a pre-defined set of network types defined in the MSO Catalog.
+     * All such networks will have a similar configuration, based on the allowable
+     * Openstack networking definitions. This includes basic networks, provider
+     * networks (with a single VLAN), and multi-provider networks (one or more VLANs)
+     *
+     * Initially, all provider networks must be "vlan" type, and multiple segments in
+     * a multi-provider network must be multiple VLANs on the same physical network.
+     *
+     * This service supports two modes of Network creation/update:
+     * - via Heat Templates
+     * - via Neutron API
+     * The network orchestration mode for each network type is declared in its
+     * catalog definition. All Heat-based templates must support some subset of
+     * the same input parameters: network_name, physical_network, vlan(s).
+     *
+     * The method returns the network ID and a NetworkRollback object. This latter
+     * object can be passed as-is to the rollbackNetwork operation to undo everything
+     * that was created. This is useful if a network is successfully created but
+     * the orchestration fails on a subsequent operation.
+     */
+    @Override
+    public void createNetworkA (String cloudSiteId,
+                                String tenantId,
+                                String networkType,
+                                String networkName,
+                                String physicalNetworkName,
+                                List <Integer> vlans,
+                                Boolean failIfExists,
+                                Boolean backout,
+                                List <Subnet> subnets,
+                                String messageId,
+                                MsoRequest msoRequest,
+                                String notificationUrl) {
+        String error;
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("CreateNetworkA");
+        LOGGER.debug ("Async Create Network: " + networkName
+                                      + " of type "
+                                      + networkType
+                                      + " in "
+                                      + cloudSiteId
+                                      + "/"
+                                      + tenantId);
+
+        // Use the synchronous method to perform the actual Create
+        MsoNetworkAdapter networkAdapter = new MsoNetworkAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <String> networkId = new Holder <String> ();
+        Holder <String> neutronNetworkId = new Holder <String> ();
+        Holder <NetworkRollback> networkRollback = new Holder <NetworkRollback> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <Map <String, String>> ();
+
+        try {
+            networkAdapter.createNetwork (cloudSiteId,
+                                          tenantId,
+                                          networkType,
+                                          networkName,
+                                          physicalNetworkName,
+                                          vlans,
+                                          failIfExists,
+                                          backout,
+                                          subnets,
+                                          msoRequest,
+                                          networkId,
+                                          neutronNetworkId,
+                                          subnetIdMap,
+                                          networkRollback);
+        } catch (NetworkException e) {
+            LOGGER.debug ("Got a NetworkException on createNetwork: ", e);
+            MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = MsoExceptionCategory.fromValue (e.getFaultInfo ().getCategory ().name ());
+            } catch (Exception e1) {
+                LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.createNetworkNotification (messageId, false, exCat, eMsg, null, null, null, null);
+            } catch (Exception e1) {
+                error = "Error sending createNetwork notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            return;
+        }
+        LOGGER.debug ("Async Create Network:Name " + networkName + " physicalNetworkName:" + physicalNetworkName);
+        // Build and send Asynchronous response
+        try {
+            NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.createNetworkNotification (messageId,
+                                                  true,
+                                                  null,
+                                                  null,
+                                                  networkId.value,
+                                                  neutronNetworkId.value,
+                                                  copyCreateSubnetIdMap (subnetIdMap),
+                                                  copyNrb (networkRollback));
+        } catch (Exception e) {
+            error = "Error sending createNetwork notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        return;
+    }
+
+    /**
+     * This is the "Update Network" web service implementation.
+     * It will update an existing Network of the requested type in the specified cloud
+     * and tenant. The typical use will be to replace the VLANs with the supplied
+     * list (to add or remove a VLAN), but other properties may be updated as well.
+     *
+     * There will be a pre-defined set of network types defined in the MSO Catalog.
+     * All such networks will have a similar configuration, based on the allowable
+     * Openstack networking definitions. This includes basic networks, provider
+     * networks (with a single VLAN), and multi-provider networks (one or more VLANs).
+     *
+     * Initially, all provider networks must currently be "vlan" type, and multi-provider
+     * networks must be multiple VLANs on the same physical network.
+     *
+     * This service supports two modes of Network update:
+     * - via Heat Templates
+     * - via Neutron API
+     * The network orchestration mode for each network type is declared in its
+     * catalog definition. All Heat-based templates must support some subset of
+     * the same input parameters: network_name, physical_network, vlan, segments.
+     *
+     * The method returns a NetworkRollback object. This object can be passed
+     * as-is to the rollbackNetwork operation to undo everything that was updated.
+     * This is useful if a network is successfully updated but orchestration
+     * fails on a subsequent operation.
+     */
+    @Override
+    public void updateNetworkA (String cloudSiteId,
+                                String tenantId,
+                                String networkType,
+                                String networkId,
+                                String networkName,
+                                String physicalNetworkName,
+                                List <Integer> vlans,
+                                List <Subnet> subnets,
+                                String messageId,
+                                MsoRequest msoRequest,
+                                String notificationUrl) {
+        String error;
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        String serviceName = "UpdateNetworkA";
+        MsoLogger.setServiceName (serviceName);
+        MsoLogger.setLogContext (msoRequest);
+        LOGGER.debug ("Async Update Network: " + networkId
+                      + " of type "
+                      + networkType
+                      + "in "
+                      + cloudSiteId
+                      + "/"
+                      + tenantId);
+
+        // Use the synchronous method to perform the actual Create
+        MsoNetworkAdapter networkAdapter = new MsoNetworkAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <NetworkRollback> networkRollback = new Holder <NetworkRollback> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <Map <String, String>> ();
+
+        try {
+            networkAdapter.updateNetwork (cloudSiteId,
+                                          tenantId,
+                                          networkType,
+                                          networkId,
+                                          networkName,
+                                          physicalNetworkName,
+                                          vlans,
+                                          subnets,
+                                          msoRequest,
+                                          subnetIdMap,
+                                          networkRollback);
+            MsoLogger.setServiceName (serviceName);
+        } catch (NetworkException e) {
+        	MsoLogger.setServiceName (serviceName);
+            LOGGER.debug ("Got a NetworkException on updateNetwork: ", e);
+            MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = MsoExceptionCategory.fromValue (e.getFaultInfo ().getCategory ().name ());
+            } catch (Exception e1) {
+                LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.updateNetworkNotification (messageId, false, exCat, eMsg, null, copyNrb (networkRollback));
+            } catch (Exception e1) {
+                error = "Error sending updateNetwork notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending updateNetwork notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            return;
+        }
+        LOGGER.debug ("Async Update Network:Name " + networkName + " NetworkId:" + networkId);
+        // Build and send Asynchronous response
+        try {
+            NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.updateNetworkNotification (messageId,
+                                                  true,
+                                                  null,
+                                                  null,
+                                                  copyUpdateSubnetIdMap (subnetIdMap),
+                                                  copyNrb (networkRollback));
+        } catch (Exception e) {
+            error = "Error sending updateNotification request" + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending updateNotification request", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        return;
+    }
+
+    /**
+     * This is the queryNetwork method. It returns the existence and status of
+     * the specified network, along with its Neutron UUID and list of VLANs.
+     * This method attempts to find the network using both Heat and Neutron.
+     * Heat stacks are first searched based on the provided network name/id.
+     * If none is found, the Neutron is directly queried.
+     */
+    @Override
+    public void queryNetworkA (String cloudSiteId,
+                               String tenantId,
+                               String networkNameOrId,
+                               String messageId,
+                               MsoRequest msoRequest,
+                               String notificationUrl) {
+        String error;
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        MsoLogger.setLogContext (msoRequest);
+        String serviceName = "QueryNetworkA";
+        MsoLogger.setServiceName (serviceName);
+        LOGGER.debug ("Async Query Network " + networkNameOrId + " in " + cloudSiteId + "/" + tenantId);
+
+        // Use the synchronous method to perform the actual Create
+        MsoNetworkAdapter networkAdapter = new MsoNetworkAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <Boolean> networkExists = new Holder <Boolean> ();
+        Holder <String> networkId = new Holder <String> ();
+        Holder <String> neutronNetworkId = new Holder <String> ();
+        Holder <NetworkStatus> status = new Holder <NetworkStatus> ();
+        Holder <List <Integer>> vlans = new Holder <List <Integer>> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <Map <String, String>> ();
+
+        try {
+            networkAdapter.queryNetwork (cloudSiteId,
+                                         tenantId,
+                                         networkNameOrId,
+                                         msoRequest,
+                                         networkExists,
+                                         networkId,
+                                         neutronNetworkId,
+                                         status,
+                                         vlans,
+                                         subnetIdMap);
+            MsoLogger.setServiceName (serviceName);
+        } catch (NetworkException e) {
+        	MsoLogger.setServiceName (serviceName);
+            LOGGER.debug ("Got a NetworkException on createNetwork: ", e);
+            MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = MsoExceptionCategory.fromValue (e.getFaultInfo ().getCategory ().name ());
+            } catch (Exception e1) {
+                LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.queryNetworkNotification (messageId, false, exCat, eMsg, null, null, null, null, null, null);
+            } catch (Exception e1) {
+                error = "Error sending createNetwork notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            return;
+        }
+        LOGGER.debug ("Async Query Network:NameOrId " + networkNameOrId + " tenantId:" + tenantId);
+        // Build and send Asynchronous response
+        try {
+            NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            org.openecomp.mso.adapters.network.async.client.NetworkStatus networkS = org.openecomp.mso.adapters.network.async.client.NetworkStatus.fromValue (status.value.name ());
+            notifyPort.queryNetworkNotification (messageId,
+                                                 true,
+                                                 null,
+                                                 null,
+                                                 networkExists.value,
+                                                 networkId.value,
+                                                 neutronNetworkId.value,
+                                                 networkS,
+                                                 vlans.value,
+                                                 copyQuerySubnetIdMap (subnetIdMap));
+        } catch (Exception e) {
+            error = "Error sending createNetwork notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        return;
+    }
+
+    /**
+     * This is the "Delete Network" web service implementation.
+     * It will delete a Network in the specified cloud and tenant.
+     *
+     * If the network is not found, it is treated as a success.
+     *
+     * This service supports two modes of Network creation/update/delete:
+     * - via Heat Templates
+     * - via Neutron API
+     * The network orchestration mode for each network type is declared in its
+     * catalog definition.
+     *
+     * For Heat-based orchestration, the networkId should be the stack ID.
+     * For Neutron-based orchestration, the networkId should be the Neutron network UUID.
+     *
+     * The method returns nothing on success. Rollback is not possible for delete
+     * commands, so any failure on delete will require manual fallout in the client.
+     */
+    @Override
+    public void deleteNetworkA (String cloudSiteId,
+                                String tenantId,
+                                String networkType,
+                                String networkId,
+                                String messageId,
+                                MsoRequest msoRequest,
+                                String notificationUrl) {
+        String error;
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        MsoLogger.setLogContext (msoRequest);
+        String serviceName = "DeleteNetworkA";
+        MsoLogger.setServiceName (serviceName);
+        LOGGER.debug ("Async Delete Network " + networkId + " in " + cloudSiteId + "/" + tenantId);
+
+        // Use the synchronous method to perform the actual Create
+        MsoNetworkAdapter networkAdapter = new MsoNetworkAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        // Synchronous Web Service Outputs
+        Holder <Boolean> networkDeleted = new Holder <Boolean> ();
+
+        try {
+            networkAdapter.deleteNetwork (cloudSiteId, tenantId, networkType, networkId, msoRequest, networkDeleted);
+            MsoLogger.setServiceName (serviceName);
+        } catch (NetworkException e) {
+        	MsoLogger.setServiceName (serviceName);
+            LOGGER.debug ("Got a NetworkException on createNetwork: ", e);
+            MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = MsoExceptionCategory.fromValue (e.getFaultInfo ().getCategory ().name ());
+            } catch (Exception e1) {
+                LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.deleteNetworkNotification (messageId, false, exCat, eMsg, null);
+            } catch (Exception e1) {
+                error = "Error sending createNetwork notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending createNetwork notification", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            return;
+        }
+        LOGGER.debug ("Async Delete NetworkId: " + networkId + " tenantId:" + tenantId);
+        // Build and send Asynchronous response
+        try {
+            NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.deleteNetworkNotification (messageId, true, null, null, networkDeleted.value);
+        } catch (Exception e) {
+            error = "Error sending deleteNetwork notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception sending deleteNetwork notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        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 rollbackNetwork
+     * operation to undo the creation.
+     *
+     * The rollback includes removing the VNF and deleting the tenant if the
+     * tenant did not exist prior to the VNF creation.
+     */
+    @Override
+    public void rollbackNetworkA (NetworkRollback rollback, String messageId, String notificationUrl) {
+        String error;
+        String serviceName = "RollbackNetworkA";
+        MsoLogger.setServiceName (serviceName);
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+        // rollback may be null (e.g. if network already existed when Create was called)
+        if (rollback == null) {
+            LOGGER.warn (MessageEnum.RA_ROLLBACK_NULL, "", "", MsoLogger.ErrorCode.SchemaError, "Rollback is null");
+            return;
+        }
+
+        MsoLogger.setLogContext (rollback.getMsoRequest ());
+        LOGGER.info (MessageEnum.RA_ASYNC_ROLLBACK, rollback.getNetworkStackId (), "", "");
+        // Use the synchronous method to perform the actual Create
+        MsoNetworkAdapter networkAdapter = new MsoNetworkAdapterImpl (msoPropertiesFactory,cloudConfigFactory);
+
+        try {
+            networkAdapter.rollbackNetwork (rollback);
+            MsoLogger.setServiceName (serviceName);
+        } catch (NetworkException e) {
+        	MsoLogger.setServiceName (serviceName);
+            LOGGER.debug ("Got a NetworkException on rollbackNetwork: ", e);
+            // Build and send Asynchronous error response
+            MsoExceptionCategory exCat = null;
+            String eMsg = null;
+            try {
+                eMsg = e.getFaultInfo ().getMessage ();
+                exCat = MsoExceptionCategory.fromValue (e.getFaultInfo ().getCategory ().name ());
+            } catch (Exception e1) {
+                LOGGER.error (MessageEnum.RA_FAULT_INFO_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception in get fault info", e1);
+            }
+            // Build and send Asynchronous error response
+            try {
+                NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+                notifyPort.rollbackNetworkNotification (rollback.getMsoRequest ().getRequestId (), false, exCat, eMsg);
+            } catch (Exception e1) {
+                error = "Error sending createNetwork notification " + e1.getMessage ();
+                LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception in sending createNetwork notification ", e1);
+                alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+            }
+            return;
+        }
+        LOGGER.debug ("Async Rollback NetworkId: " + rollback.getNetworkStackId () + " tenantId:" + rollback.getTenantId ());
+        // Build and send Asynchronous response
+        try {
+            NetworkAdapterNotify notifyPort = getNotifyEP (notificationUrl);
+            notifyPort.rollbackNetworkNotification (rollback.getMsoRequest ().getRequestId (), true, null, null);
+        } catch (Exception e) {
+            error = "Error sending rollbackNetwork notification " + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_CREATE_NETWORK_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception in sending rollbackNetwork notification", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error);
+        }
+        return;
+    }
+
+    private org.openecomp.mso.adapters.network.async.client.NetworkRollback copyNrb (Holder <NetworkRollback> hNrb) {
+        org.openecomp.mso.adapters.network.async.client.NetworkRollback cnrb = new org.openecomp.mso.adapters.network.async.client.NetworkRollback ();
+
+        if (hNrb != null && hNrb.value != null) {
+            org.openecomp.mso.adapters.network.async.client.MsoRequest cmr = new org.openecomp.mso.adapters.network.async.client.MsoRequest ();
+
+            cnrb.setCloudId (hNrb.value.getCloudId ());
+            cmr.setRequestId (hNrb.value.getMsoRequest ().getRequestId ());
+            cmr.setServiceInstanceId (hNrb.value.getMsoRequest ().getServiceInstanceId ());
+            cnrb.setMsoRequest (cmr);
+            cnrb.setNetworkId (hNrb.value.getNetworkId ());
+            cnrb.setNetworkStackId (hNrb.value.getNetworkStackId ());
+            cnrb.setNeutronNetworkId (hNrb.value.getNeutronNetworkId ());
+            cnrb.setTenantId (hNrb.value.getTenantId ());
+            cnrb.setNetworkType (hNrb.value.getNetworkType ());
+            cnrb.setNetworkCreated (hNrb.value.getNetworkCreated ());
+            cnrb.setNetworkName (hNrb.value.getNetworkName ());
+            cnrb.setPhysicalNetwork (hNrb.value.getPhysicalNetwork ());
+            List <Integer> vlansc = cnrb.getVlans ();
+            List <Integer> vlansh = hNrb.value.getVlans ();
+            if (vlansh != null) {
+                vlansc.addAll (vlansh);
+            }
+        }
+        return cnrb;
+    }
+
+    private NetworkAdapterNotify getNotifyEP (String notificationUrl) {
+
+        URL warWsdlLoc = null;
+        try {
+            warWsdlLoc = Thread.currentThread ().getContextClassLoader ().getResource ("NetworkAdapterNotify.wsdl");
+        } catch (Exception e) {
+            LOGGER.error (MessageEnum.RA_WSDL_NOT_FOUND, "NetworkAdpaterNotify.wsdl", "", "", MsoLogger.ErrorCode.DataError, "Exception - WSDL not found", e);
+        }
+        if (warWsdlLoc == null) {
+            LOGGER.error (MessageEnum.RA_WSDL_NOT_FOUND, "NetworkAdpaterNotify.wsdl", "", "", MsoLogger.ErrorCode.DataError, "WSDL not found");
+        } else {
+            try {
+                LOGGER.debug ("NetworkAdpaterNotify.wsdl location:" + warWsdlLoc.toURI ().toString ());
+            } catch (Exception e) {
+                LOGGER.error (MessageEnum.RA_WSDL_URL_CONVENTION_EXC, "NetworkAdpaterNotify.wsdl", "", "", MsoLogger.ErrorCode.SchemaError, "Exception - WSDL URL convention", e);
+            }
+        }
+
+        NetworkAdapterNotify_Service notifySvc = new NetworkAdapterNotify_Service (warWsdlLoc,
+                                                                                   new QName ("http://com.att.mso/networkNotify",
+                                                                                              "networkAdapterNotify"));
+
+        NetworkAdapterNotify notifyPort = notifySvc.getMsoNetworkAdapterAsyncImplPort ();
+
+        BindingProvider bp = (BindingProvider) notifyPort;
+
+        URL epUrl = null;
+        try {
+            epUrl = new URL (notificationUrl);
+        } catch (MalformedURLException e1) {
+            LOGGER.error (MessageEnum.RA_INIT_NOTIF_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - init notification", e1);
+        }
+
+        LOGGER.debug ("Notification Endpoint URL: " + epUrl.toExternalForm ());
+
+        bp.getRequestContext ().put (BindingProvider.ENDPOINT_ADDRESS_PROPERTY, epUrl.toExternalForm ());
+
+        // authentication
+        try {
+            Map <String, Object> reqCtx = bp.getRequestContext ();
+            Map <String, List <String>> headers = new HashMap <String, List <String>> ();
+
+            String userCredentials = msoPropertiesFactory.getMsoJavaProperties (MSO_PROP_NETWORK_ADAPTER).getEncryptedProperty (BPEL_AUTH_PROP,
+                                                                                             "",
+                                                                                          ENCRYPTION_KEY);
+
+            String basicAuth = "Basic " + DatatypeConverter.printBase64Binary (userCredentials.getBytes ());
+            reqCtx.put (MessageContext.HTTP_REQUEST_HEADERS, headers);
+            headers.put ("Authorization", Collections.singletonList (basicAuth));
+        } catch (Exception e) {
+            String error1 = "Unable to set authorization in callback request" + e.getMessage ();
+            LOGGER.error (MessageEnum.RA_SET_CALLBACK_AUTH_EXC, "", "", MsoLogger.ErrorCode.DataError, "Exception - Unable to set authorization in callback request", e);
+            alarmLogger.sendAlarm ("MsoInternalError", MsoAlarmLogger.CRITICAL, error1);
+        }
+
+        return notifyPort;
+    }
+
+    private CreateNetworkNotification.SubnetIdMap copyCreateSubnetIdMap (Holder <Map <String, String>> hMap) {
+
+        CreateNetworkNotification.SubnetIdMap subnetIdMap = new CreateNetworkNotification.SubnetIdMap ();
+
+        if (hMap != null && hMap.value != null) {
+            Map <String, String> sMap = new HashMap <String, String> ();
+            sMap = hMap.value;
+            CreateNetworkNotification.SubnetIdMap.Entry entry = new CreateNetworkNotification.SubnetIdMap.Entry ();
+
+            for (String key : sMap.keySet ()) {
+                entry.setKey (key);
+                entry.setValue (sMap.get (key));
+                subnetIdMap.getEntry ().add (entry);
+            }
+        }
+        return subnetIdMap;
+    }
+
+    private UpdateNetworkNotification.SubnetIdMap copyUpdateSubnetIdMap (Holder <Map <String, String>> hMap) {
+
+        UpdateNetworkNotification.SubnetIdMap subnetIdMap = new UpdateNetworkNotification.SubnetIdMap ();
+
+        if (hMap != null && hMap.value != null) {
+            Map <String, String> sMap = new HashMap <String, String> ();
+            sMap = hMap.value;
+            UpdateNetworkNotification.SubnetIdMap.Entry entry = new UpdateNetworkNotification.SubnetIdMap.Entry ();
+
+            for (String key : sMap.keySet ()) {
+                entry.setKey (key);
+                entry.setValue (sMap.get (key));
+                subnetIdMap.getEntry ().add (entry);
+            }
+        }
+        return subnetIdMap;
+    }
+
+    private QueryNetworkNotification.SubnetIdMap copyQuerySubnetIdMap (Holder <Map <String, String>> hMap) {
+
+        QueryNetworkNotification.SubnetIdMap subnetIdMap = new QueryNetworkNotification.SubnetIdMap ();
+
+        if (hMap != null && hMap.value != null) {
+            Map <String, String> sMap = new HashMap <String, String> ();
+            sMap = hMap.value;
+            QueryNetworkNotification.SubnetIdMap.Entry entry = new QueryNetworkNotification.SubnetIdMap.Entry ();
+
+            for (String key : sMap.keySet ()) {
+                entry.setKey (key);
+                entry.setValue (sMap.get (key));
+                subnetIdMap.getEntry ().add (entry);
+            }
+        }
+        return subnetIdMap;
+    }
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterImpl.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterImpl.java
new file mode 100644
index 0000000..97624da
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/MsoNetworkAdapterImpl.java
@@ -0,0 +1,2052 @@
+/*-
+ * ============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.network;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.xml.ws.Holder;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import org.openecomp.mso.adapters.network.exceptions.NetworkException;
+import org.openecomp.mso.cloud.CloudConfig;
+import org.openecomp.mso.cloud.CloudConfigFactory;
+import org.openecomp.mso.cloud.CloudSite;
+import org.openecomp.mso.db.catalog.CatalogDatabase;
+import org.openecomp.mso.db.catalog.beans.HeatTemplate;
+import org.openecomp.mso.db.catalog.beans.NetworkResource;
+import org.openecomp.mso.db.catalog.utils.MavenLikeVersioning;
+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.NetworkInfo;
+import org.openecomp.mso.openstack.beans.NetworkRollback;
+import org.openecomp.mso.openstack.beans.NetworkStatus;
+import org.openecomp.mso.openstack.beans.Pool;
+import org.openecomp.mso.openstack.beans.StackInfo;
+import org.openecomp.mso.openstack.beans.Subnet;
+import org.openecomp.mso.openstack.exceptions.MsoAdapterException;
+import org.openecomp.mso.openstack.exceptions.MsoException;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+import org.openecomp.mso.openstack.utils.MsoCommonUtils;
+import org.openecomp.mso.openstack.utils.MsoHeatUtils;
+import org.openecomp.mso.openstack.utils.MsoHeatUtilsWithUpdate;
+import org.openecomp.mso.openstack.utils.MsoNeutronUtils;
+import org.openecomp.mso.openstack.utils.MsoNeutronUtils.NetworkType;
+import org.openecomp.mso.properties.MsoPropertiesException;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+import static org.openecomp.mso.openstack.utils.MsoCommonUtils.isNullOrEmpty;
+
+@WebService(serviceName = "NetworkAdapter", endpointInterface = "org.openecomp.mso.adapters.network.MsoNetworkAdapter", targetNamespace = "http://com.att.mso/network")
+public class MsoNetworkAdapterImpl implements MsoNetworkAdapter {
+
+	MsoPropertiesFactory msoPropertiesFactory=new MsoPropertiesFactory();
+
+	CloudConfigFactory cloudConfigFactory=new CloudConfigFactory();
+
+	private static final String AIC3_NW_PROPERTY= "org.openecomp.mso.adapters.network.aic3nw";
+	private static final String AIC3_NW="OS::ContrailV2::VirtualNetwork";
+	public static final String MSO_PROP_NETWORK_ADAPTER="MSO_PROP_NETWORK_ADAPTER";
+    private static final String VLANS = "vlans";
+    private static final String PHYSICAL_NETWORK = "physical_network";
+    private static final String UPDATE_NETWORK_CONTEXT = "UpdateNetwork";
+    private static final String NETWORK_ID = "network_id";
+    private static final String NETWORK_FQDN = "network_fqdn";
+    private static final String CREATE_NETWORK_CONTEXT = "CreateNetwork";
+    private static final String MSO_CONFIGURATION_ERROR = "MsoConfigurationError";
+    private static final String NEUTRON_MODE = "NEUTRON";
+    private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+    private static MsoAlarmLogger alarmLogger = new MsoAlarmLogger ();
+    protected CloudConfig cloudConfig;
+
+    /**
+     * Health Check web method. Does nothing but return to show the adapter is deployed.
+     */
+    @Override
+    public void healthCheck () {
+        LOGGER.debug ("Health check call in Network Adapter");
+    }
+
+    /**
+     * Do not use this constructor or the msoPropertiesFactory will be NULL.
+     *
+  	 * @see MsoNetworkAdapterImpl#MsoNetworkAdapterImpl(MsoPropertiesFactory)
+     */
+    public MsoNetworkAdapterImpl() {
+    }
+
+    /**
+     * This constructor MUST be used if this class if called with the new operator.
+     * @param msoPropFactory
+
+     */
+    public MsoNetworkAdapterImpl(MsoPropertiesFactory msoPropFactory,CloudConfigFactory cloudConfigFact) {
+    	this.msoPropertiesFactory = msoPropFactory;
+    	this.cloudConfigFactory=cloudConfigFact;
+    	cloudConfig = cloudConfigFactory.getCloudConfig ();
+    }
+
+    @Override
+    public void createNetwork (String cloudSiteId,
+                               String tenantId,
+                               String networkType,
+                               String networkName,
+                               String physicalNetworkName,
+                               List <Integer> vlans,
+                               Boolean failIfExists,
+                               Boolean backout,
+                               List <Subnet> subnets,
+                               MsoRequest msoRequest,
+                               Holder <String> networkId,
+                               Holder <String> neutronNetworkId,
+                               Holder <Map <String, String>> subnetIdMap,
+                               Holder <NetworkRollback> rollback) throws NetworkException {
+    	Holder <String> networkFqdn = new Holder <String> ();
+        createNetwork (cloudSiteId,
+                       tenantId,
+                       networkType,
+                       networkName,
+                       physicalNetworkName,
+                       vlans,
+                       null,
+                       null,
+                       null,
+                       failIfExists,
+                       backout,
+                       subnets,
+                       null,
+                       null,
+                       msoRequest,
+                       networkId,
+                       neutronNetworkId,
+                       networkFqdn,
+                       subnetIdMap,
+                       rollback);
+    }
+
+    @Override
+    public void createNetworkContrail (String cloudSiteId,
+                                       String tenantId,
+                                       String networkType,
+                                       String networkName,
+                                       List <String> routeTargets,
+                                       String shared,
+                                       String external,
+                                       Boolean failIfExists,
+                                       Boolean backout,
+                                       List <Subnet> subnets,
+                                       List <String> policyFqdns,
+                                       List<String> routeTableFqdns,
+                                       MsoRequest msoRequest,
+                                       Holder <String> networkId,
+                                       Holder <String> neutronNetworkId,
+                                       Holder <String> networkFqdn,
+                                       Holder <Map <String, String>> subnetIdMap,
+                                       Holder <NetworkRollback> rollback) throws NetworkException {
+        createNetwork (cloudSiteId,
+                       tenantId,
+                       networkType,
+                       networkName,
+                       null,
+                       null,
+                       routeTargets,
+                       shared,
+                       external,
+                       failIfExists,
+                       backout,
+                       subnets,
+                       policyFqdns,
+                       routeTableFqdns,
+                       msoRequest,
+                       networkId,
+                       neutronNetworkId,
+                       networkFqdn,
+                       subnetIdMap,
+                       rollback);
+    }
+
+    /**
+     * This is the "Create Network" web service implementation.
+     * It will create a new Network of the requested type in the specified cloud
+     * and tenant. The tenant must exist at the time this service is called.
+     *
+     * If a network with the same name already exists, this can be considered a
+     * success or failure, depending on the value of the 'failIfExists' parameter.
+     *
+     * There will be a pre-defined set of network types defined in the MSO Catalog.
+     * All such networks will have a similar configuration, based on the allowable
+     * Openstack networking definitions. This includes basic networks, provider
+     * networks (with a single VLAN), and multi-provider networks (one or more VLANs)
+     *
+     * Initially, all provider networks must be "vlan" type, and multiple segments in
+     * a multi-provider network must be multiple VLANs on the same physical network.
+     *
+     * This service supports two modes of Network creation/update:
+     * - via Heat Templates
+     * - via Neutron API
+     * The network orchestration mode for each network type is declared in its
+     * catalog definition. All Heat-based templates must support some subset of
+     * the same input parameters: network_name, physical_network, vlan(s).
+     *
+     * The method returns the network ID and a NetworkRollback object. This latter
+     * object can be passed as-is to the rollbackNetwork operation to undo everything
+     * that was created. This is useful if a network is successfully created but
+     * the orchestration fails on a subsequent operation.
+     */
+
+    private void createNetwork (String cloudSiteId,
+                               String tenantId,
+                               String networkType,
+                               String networkName,
+                               String physicalNetworkName,
+                               List <Integer> vlans,
+                               List <String> routeTargets,
+                               String shared,
+                               String external,
+                               Boolean failIfExists,
+                               Boolean backout,
+                               List <Subnet> subnets,
+                               List <String> policyFqdns,
+                               List <String> routeTableFqdns,
+                               MsoRequest msoRequest,
+                               Holder <String> networkId,
+                               Holder <String> neutronNetworkId,
+                               Holder <String> networkFqdn,
+                               Holder <Map <String, String>> subnetIdMap,
+                               Holder <NetworkRollback> rollback) throws NetworkException {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("CreateNetwork");
+
+        LOGGER.debug ("*** CREATE Network: " + networkName
+                      + " of type "
+                      + networkType
+                      + " in "
+                      + cloudSiteId
+                      + "/"
+                      + tenantId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Build a default rollback object (no actions performed)
+        NetworkRollback networkRollback = new NetworkRollback ();
+        networkRollback.setCloudId (cloudSiteId);
+        networkRollback.setTenantId (tenantId);
+        networkRollback.setMsoRequest (msoRequest);
+
+        // tenant query is not required here.
+        // If the tenant doesn’t exist, the Heat calls will fail anyway (when the HeatUtils try to obtain a token).
+        // So this is just catching that error in a bit more obvious way up front.
+
+        cloudConfig = cloudConfigFactory.getCloudConfig ();
+        CloudSite cloudSite = cloudConfig.getCloudSite (cloudSiteId);
+        if (cloudSite == null)
+        {
+        	String error = "Configuration Error. Stack " + networkName + " in "
+        			+ cloudSiteId
+        			+ "/"
+        			+ tenantId
+        			+ ": "
+        			+ " CloudSite does not exist in MSO Configuration";
+        	LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "", "", MsoLogger.ErrorCode.DataError, "Configuration Error");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+        	// Set the detailed error as the Exception 'message'
+        	throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+        }
+
+        try (CatalogDatabase db = getCatalogDb()) {
+            NetworkResource networkResource = networkCheck (db,
+                                                            startTime,
+                                                            networkType,
+                                                            networkName,
+                                                            physicalNetworkName,
+                                                            vlans,
+                                                            routeTargets,
+                                                            cloudSite);
+            String mode = networkResource.getOrchestrationMode ();
+            NetworkType neutronNetworkType = NetworkType.valueOf (networkResource.getNeutronNetworkType ());
+
+            if (NEUTRON_MODE.equals (mode)) {
+
+                // Use an MsoNeutronUtils for all neutron commands
+                MsoNeutronUtils neutron = new MsoNeutronUtils (MSO_PROP_NETWORK_ADAPTER, cloudConfigFactory);
+
+                // See if the Network already exists (by name)
+                NetworkInfo netInfo = null;
+                long queryNetworkStarttime = System.currentTimeMillis ();
+                try {
+                    netInfo = neutron.queryNetwork (networkName, tenantId, cloudSiteId);
+                    LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Response successfully received from OpenStack", "OpenStack", "QueryNetwork", null);
+                } catch (MsoException me) {
+                    LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while querying network from OpenStack", "OpenStack", "QueryNetwork", null);
+                    String error = "Create Network (neutron): query network " + networkName
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.error (MessageEnum.RA_QUERY_NETWORK_EXC, networkName, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while querying network from OpenStack", me);
+                    me.addContext (CREATE_NETWORK_CONTEXT);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while querying network from OpenStack");
+                    throw new NetworkException (me);
+                }
+
+                if (netInfo != null) {
+                    // Exists. If that's OK, return success with the network ID.
+                    // Otherwise, return an exception.
+                    if (failIfExists != null && failIfExists) {
+                        String error = "Create Nework: Network " + networkName
+                                       + " already exists in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + " with ID " + netInfo.getId();
+                        LOGGER.error (MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Network already exists");
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+                        throw new NetworkException(error, MsoExceptionCategory.USERDATA);
+                    } else {
+                        // Populate the outputs from the existing network.
+                        networkId.value = netInfo.getId ();
+                        neutronNetworkId.value = netInfo.getId ();
+                        rollback.value = networkRollback; // Default rollback - no updates performed
+                        String msg = "Found Existing network, status=" + netInfo.getStatus () + " for Neutron mode";
+                        LOGGER.warn (MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId, "", "", MsoLogger.ErrorCode.DataError, "Found Existing network, status=" + netInfo.getStatus ());
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, msg);
+                    }
+                    return;
+                }
+
+                long createNetworkStarttime = System.currentTimeMillis ();
+                try {
+                    netInfo = neutron.createNetwork (cloudSiteId,
+                                                     tenantId,
+                                                     neutronNetworkType,
+                                                     networkName,
+                                                     physicalNetworkName,
+                                                     vlans);
+                    LOGGER.recordMetricEvent (createNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Response successfully received from OpenStack", "OpenStack", "CreateNetwork", null);
+                } catch (MsoException me) {
+                	me.addContext (CREATE_NETWORK_CONTEXT);
+                    LOGGER.recordMetricEvent (createNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with OpenStack", "OpenStack", "CreateNetwork", null);
+                	String error = "Create Network: type " + neutronNetworkType
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, networkName, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception while communicate with OpenStack", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+
+                    throw new NetworkException (me);
+                }
+
+                // Note: ignoring MsoNetworkAlreadyExists because we already checked.
+
+                // If reach this point, network creation is successful.
+                // Since directly created via Neutron, networkId tracked by MSO is the same
+                // as the neutron network ID.
+                networkId.value = netInfo.getId ();
+                neutronNetworkId.value = netInfo.getId ();
+
+                networkRollback.setNetworkCreated (true);
+                networkRollback.setNetworkId (netInfo.getId ());
+                networkRollback.setNeutronNetworkId (netInfo.getId ());
+                networkRollback.setNetworkType (networkType);
+
+                LOGGER.debug ("Network " + networkName + " created, id = " + netInfo.getId ());
+            } else if ("HEAT".equals (mode)) {
+
+                // Use an MsoHeatUtils for all Heat commands
+                MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_NETWORK_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+                
+                HeatTemplate heatTemplate = db.getHeatTemplate (networkResource.getTemplateId ());
+                if (heatTemplate == null) {
+                    String error = "Network error - undefined Heat Template. Network Type = " + networkType;
+                    LOGGER.error (MessageEnum.RA_PARAM_NOT_FOUND, "Heat Template", "Network Type", networkType, "Openstack", "", MsoLogger.ErrorCode.DataError, "Network error - undefined Heat Template. Network Type = " + networkType);
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error); // Alarm on this
+                                                                                                     // error,
+                                                                                                     // configuration
+                                                                                                     // must be fixed
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataNotFound, error);
+                    throw new NetworkException (error, MsoExceptionCategory.INTERNAL);
+                }
+
+                LOGGER.debug ("Got HEAT Template from DB: " + heatTemplate.toString ());
+                
+                // "Fix" the template if it has CR/LF (getting this from Oracle)
+                String template = heatTemplate.getHeatTemplate ();
+                template = template.replaceAll ("\r\n", "\n");
+                
+                boolean aic3template=false;
+                String aic3nw = AIC3_NW;
+                try {
+                	aic3nw = msoPropertiesFactory.getMsoJavaProperties(MSO_PROP_NETWORK_ADAPTER).getProperty(AIC3_NW_PROPERTY, AIC3_NW);
+        		} catch (MsoPropertiesException e) {
+        			String error = "Unable to get properties:" + MSO_PROP_NETWORK_ADAPTER;
+        			LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "", "", MsoLogger.ErrorCode.DataError, "Exception - Unable to get properties", e);
+        		}
+            	
+                if (template.contains(aic3nw))
+                	aic3template = true;
+                
+                // First, look up to see if the Network already exists (by name).
+                // For HEAT orchestration of networks, the stack name will always match the network name
+                StackInfo heatStack = null;
+                long queryNetworkStarttime = System.currentTimeMillis ();
+                try {
+                    heatStack = heat.queryStack (cloudSiteId, tenantId, networkName);
+                    LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Response successfully received from OpenStack", "OpenStack", "QueryNetwork", null);
+                } catch (MsoException me) {
+                    me.addContext (CREATE_NETWORK_CONTEXT);
+                    LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while querying stack from OpenStack", "OpenStack", "QueryNetwork", null);
+                	String error = "Create Network (heat): query network " + networkName
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.error (MessageEnum.RA_QUERY_NETWORK_EXC, networkName, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception while querying stack from OpenStack", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+
+                if (heatStack != null && !(heatStack.getStatus () == HeatStatus.NOTFOUND)) {
+                    // Stack exists. Return success or error depending on input directive
+                    if (failIfExists != null && failIfExists) {
+                        String error = "CreateNetwork: Stack " + networkName
+                                       + " already exists in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + " as " + heatStack.getCanonicalName();
+                        LOGGER.error (MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId, "", "", MsoLogger.ErrorCode.DataError, "Network already exists");
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Conflict, error);
+                        throw new NetworkException(error, MsoExceptionCategory.USERDATA);
+                    } else {
+                        // Populate the outputs from the existing stack.
+                        networkId.value = heatStack.getCanonicalName ();
+                        neutronNetworkId.value = (String) heatStack.getOutputs ().get (NETWORK_ID);
+                        rollback.value = networkRollback; // Default rollback - no updates performed
+                        if (aic3template)
+                        {
+                        	networkFqdn.value = (String) heatStack.getOutputs().get(NETWORK_FQDN);
+                        }
+                        Map <String, Object> outputs = heatStack.getOutputs ();
+                        Map <String, String> sMap = new HashMap <String, String> ();
+                        if (outputs != null) {
+                        	for (String key : outputs.keySet ()) {
+                        		if (key != null && key.startsWith ("subnet")) {
+                        			if (aic3template) //one subnet_id output 
+                        			{
+                        				 Map <String, String> map = getSubnetUUId(key, outputs, subnets); 
+                        				 sMap.putAll(map);
+                        			}
+                        			else //multiples subnet_%aaid% outputs
+                        			{
+                        				String subnetUUId = (String) outputs.get(key); 
+                        				sMap.put (key.substring("subnet_id_".length()), subnetUUId);
+                        			}
+                        		}
+                        	}
+                        }
+                        subnetIdMap.value = sMap;
+                        String msg = "Found Existing network stack, status=" + heatStack.getStatus () + " for Heat mode";
+                        LOGGER.warn (MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId, "", "", MsoLogger.ErrorCode.DataError, "Found Existing network stack, status=" + heatStack.getStatus ());
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Suc, "Found Existing network stack");
+                    }
+                    return;
+                }
+
+                // Ready to deploy the new Network
+                // Build the common set of HEAT template parameters
+                Map <String, Object> stackParams = populateNetworkParams (neutronNetworkType,
+                                                                          networkName,
+                                                                          physicalNetworkName,
+                                                                          vlans,
+                                                                          routeTargets,
+                                                                          shared, 
+                                                                          external,
+                                                                          aic3template);
+
+                // Validate (and update) the input parameters against the DB definition
+                // Shouldn't happen unless DB config is wrong, since all networks use same inputs
+                // and inputs were already validated.
+                try {
+                    stackParams = heat.validateStackParams (stackParams, heatTemplate);
+                } catch (IllegalArgumentException e) {
+                    String error = "Create Network: Configuration Error: " + e.getMessage ();
+                    LOGGER.error (MessageEnum.RA_CONFIG_EXC, e.getMessage(), "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception - Create Network, Configuration Error", e);
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error); // Alarm on this
+                                                                                                     // error,
+                                                                                                     // configuration
+                                                                                                     // must be fixed
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+                    // Input parameters were not valid
+                    throw new NetworkException (error, MsoExceptionCategory.INTERNAL);
+                }
+
+                if (subnets != null) {
+                	try {
+                		if (aic3template)
+                		{
+                			template = mergeSubnetsAIC3 (template, subnets, stackParams);
+                		}
+                		else
+                		{
+                			template = mergeSubnets (template, subnets);
+                		}
+                	} catch (MsoException me) {
+                		me.addContext (CREATE_NETWORK_CONTEXT);
+                		String error = "Create Network (heat): type " + neutronNetworkType
+                				+ " in "
+                				+ cloudSiteId
+                				+ "/"
+                				+ tenantId
+                				+ ": "
+                				+ me;
+                		LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, neutronNetworkType.toString(), cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception Create Network, merging subnets", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, error);
+                		throw new NetworkException (me);
+                	}
+                }
+
+                if (policyFqdns != null && !policyFqdns.isEmpty() && aic3template) {
+                    try {
+                        mergePolicyRefs (policyFqdns, stackParams);
+                    } catch (MsoException me) {
+                        me.addContext (CREATE_NETWORK_CONTEXT);
+                    	String error = "Create Network (heat) mergePolicyRefs type " + neutronNetworkType
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, neutronNetworkType.toString(), cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception Create Network, merging policyRefs", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, error);
+                        throw new NetworkException (me);
+                    }
+                }
+                
+                if (routeTableFqdns != null && !routeTableFqdns.isEmpty() && aic3template) {
+                    try {
+                        mergeRouteTableRefs (routeTableFqdns, stackParams);
+                    } catch (MsoException me) {
+                        me.addContext (CREATE_NETWORK_CONTEXT);
+                    	String error = "Create Network (heat) mergeRouteTableRefs type " + neutronNetworkType
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, neutronNetworkType.toString(), cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception Create Network, merging routeTableRefs", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, error);
+                        throw new NetworkException (me);
+                    }
+                }
+
+                // Deploy the network stack
+                // Ignore MsoStackAlreadyExists exception because we already checked.
+                long createStackStartTime = System.currentTimeMillis ();
+                try {
+                	if (backout == null)
+                		backout = true;
+                    heatStack = heat.createStack (cloudSiteId,
+                                                  tenantId,
+                                                  networkName,
+                                                  template,
+                                                  stackParams,
+                                                  true,
+                                                  heatTemplate.getTimeoutMinutes (),
+                                                  null,
+                                                  null,
+                                                  null,
+                                                  backout.booleanValue());
+                } catch (MsoException me) {
+                    me.addContext (CREATE_NETWORK_CONTEXT);
+                	String error = "Create Network (heat): type " + neutronNetworkType
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.error (MessageEnum.RA_CREATE_NETWORK_EXC, networkName, cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception creating network", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+
+                // Reach this point if createStack is successful.
+
+                // For Heat-based orchestration, the MSO-tracked network ID is the heat stack,
+                // and the neutronNetworkId is the network UUID returned in stack outputs.
+                networkId.value = heatStack.getCanonicalName ();
+                neutronNetworkId.value = (String) heatStack.getOutputs ().get (NETWORK_ID);
+                if (aic3template)
+                {
+                	networkFqdn.value = (String) heatStack.getOutputs().get(NETWORK_FQDN);
+                }
+                Map <String, Object> outputs = heatStack.getOutputs ();
+                Map <String, String> sMap = new HashMap <String, String> ();
+                if (outputs != null) {
+                    for (String key : outputs.keySet ()) {
+                        if (key != null && key.startsWith ("subnet")) {
+                        	if (aic3template) //one subnet output expected
+                			{
+                				 Map <String, String> map = getSubnetUUId(key, outputs, subnets); 
+                				 sMap.putAll(map);
+                			}
+                			else //multiples subnet_%aaid% outputs allowed
+                			{
+                				String subnetUUId = (String) outputs.get(key); 
+                				sMap.put (key.substring("subnet_id_".length()), subnetUUId);
+                			}
+                        }
+                    }
+                }
+                subnetIdMap.value = sMap;
+
+                rollback.value = networkRollback;
+                // Populate remaining rollback info and response parameters.
+                networkRollback.setNetworkStackId (heatStack.getCanonicalName ());
+                networkRollback.setNeutronNetworkId ((String) heatStack.getOutputs ().get (NETWORK_ID));
+                networkRollback.setNetworkCreated (true);
+                networkRollback.setNetworkType (networkType);
+
+                LOGGER.debug ("Network " + networkName + " successfully created via HEAT");
+            }
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.Suc, "Successfully created network");
+        return;
+    }
+
+    @Override
+    public void updateNetwork (String cloudSiteId,
+                               String tenantId,
+                               String networkType,
+                               String networkId,
+                               String networkName,
+                               String physicalNetworkName,
+                               List <Integer> vlans,
+                               List <Subnet> subnets,
+                               MsoRequest msoRequest,
+                               Holder <Map <String, String>> subnetIdMap,
+                               Holder <NetworkRollback> rollback) throws NetworkException {
+        updateNetwork (cloudSiteId,
+                       tenantId,
+                       networkType,
+                       networkId,
+                       networkName,
+                       physicalNetworkName,
+                       vlans,
+                       null,
+                       null,
+                       null,
+                       subnets,
+                       null,
+                       null,
+                       msoRequest,
+                       subnetIdMap,
+                       rollback);
+
+    }
+
+    @Override
+    public void updateNetworkContrail (String cloudSiteId,
+                                       String tenantId,
+                                       String networkType,
+                                       String networkId,
+                                       String networkName,
+                                       List <String> routeTargets,
+                                       String shared,
+                                       String external,
+                                       List <Subnet> subnets,
+                                       List <String> policyFqdns,
+                                       List<String> routeTableFqdns,
+                                       MsoRequest msoRequest,
+                                       Holder <Map <String, String>> subnetIdMap,
+                                       Holder <NetworkRollback> rollback) throws NetworkException {
+        updateNetwork (cloudSiteId,
+                       tenantId,
+                       networkType,
+                       networkId,
+                       networkName,
+                       null,
+                       null,
+                       routeTargets,
+                       shared,
+                       external,
+                       subnets,
+                       policyFqdns,
+                       routeTableFqdns,
+                       msoRequest,
+                       subnetIdMap,
+                       rollback);
+    }
+
+    /**
+     * This is the "Update Network" web service implementation.
+     * It will update an existing Network of the requested type in the specified cloud
+     * and tenant. The typical use will be to replace the VLANs with the supplied
+     * list (to add or remove a VLAN), but other properties may be updated as well.
+     *
+     * There will be a pre-defined set of network types defined in the MSO Catalog.
+     * All such networks will have a similar configuration, based on the allowable
+     * Openstack networking definitions. This includes basic networks, provider
+     * networks (with a single VLAN), and multi-provider networks (one or more VLANs).
+     *
+     * Initially, all provider networks must currently be "vlan" type, and multi-provider
+     * networks must be multiple VLANs on the same physical network.
+     *
+     * This service supports two modes of Network update:
+     * - via Heat Templates
+     * - via Neutron API
+     * The network orchestration mode for each network type is declared in its
+     * catalog definition. All Heat-based templates must support some subset of
+     * the same input parameters: network_name, physical_network, vlan, segments.
+     *
+     * The method returns a NetworkRollback object. This object can be passed
+     * as-is to the rollbackNetwork operation to undo everything that was updated.
+     * This is useful if a network is successfully updated but orchestration
+     * fails on a subsequent operation.
+     */
+    private void updateNetwork (String cloudSiteId,
+                               String tenantId,
+                               String networkType,
+                               String networkId,
+                               String networkName,
+                               String physicalNetworkName,
+                               List <Integer> vlans,
+                               List <String> routeTargets,
+                               String shared,
+                               String external,
+                               List <Subnet> subnets,
+                               List <String> policyFqdns,
+                               List<String> routeTableFqdns,
+                               MsoRequest msoRequest,
+                               Holder <Map <String, String>> subnetIdMap,
+                               Holder <NetworkRollback> rollback) throws NetworkException {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("UpdateNetwork");
+        LOGGER.debug ("***UPDATE Network adapter with Network: " + networkName
+                + " of type "
+                + networkType
+                + " in "
+                + cloudSiteId
+                + "/"
+                + tenantId);
+
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Build a default rollback object (no actions performed)
+        NetworkRollback networkRollback = new NetworkRollback ();
+        networkRollback.setCloudId (cloudSiteId);
+        networkRollback.setTenantId (tenantId);
+        networkRollback.setMsoRequest (msoRequest);
+
+        cloudConfig = cloudConfigFactory.getCloudConfig ();
+        CloudSite cloudSite = cloudConfig.getCloudSite (cloudSiteId);
+        if (cloudSite == null) {
+        	   String error = "UpdateNetwork: Configuration Error. Stack " + networkName + " in "
+                       + cloudSiteId
+                       + "/"
+                       + tenantId
+                       + ": "
+                       + " CloudSite does not exist in MSO Configuration";
+        	   LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "Openstack", "", MsoLogger.ErrorCode.DataError, "CloudSite does not exist in MSO Configuration");
+               LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+        	   // Set the detailed error as the Exception 'message'
+        	   throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+        }
+
+        try(CatalogDatabase db = getCatalogDb()) {
+            NetworkResource networkResource = networkCheck (db,
+                                                            startTime,
+                                                            networkType,
+                                                            networkName,
+                                                            physicalNetworkName,
+                                                            vlans,
+                                                            routeTargets,
+                                                            cloudSite);
+            String mode = networkResource.getOrchestrationMode ();
+            NetworkType neutronNetworkType = NetworkType.valueOf (networkResource.getNeutronNetworkType ());
+
+            // Use an MsoNeutronUtils for all Neutron commands
+            MsoNeutronUtils neutron = new MsoNeutronUtils (MSO_PROP_NETWORK_ADAPTER, cloudConfigFactory);
+
+            if (NEUTRON_MODE.equals (mode)) {
+
+                // Verify that the Network exists
+                // For Neutron-based orchestration, the networkId is the Neutron Network UUID.
+                NetworkInfo netInfo = null;
+                long queryNetworkStarttime = System.currentTimeMillis ();
+                try {
+                    netInfo = neutron.queryNetwork (networkId, tenantId, cloudSiteId);
+                    LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryNetwork", null);
+                } catch (MsoException me) {
+                    me.addContext (UPDATE_NETWORK_CONTEXT);
+                	String error = "Update Network (neutron): query " + networkId
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryNetwork", null);
+                    LOGGER.error (MessageEnum.RA_QUERY_NETWORK_EXC, networkId, cloudSiteId, tenantId, "OpenStack", "QueryNetwork", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - queryNetwork", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+
+                if (netInfo == null) {
+                    String error = "Update Nework: Network " + networkId
+                                   + " does not exist in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId;
+                    LOGGER.error (MessageEnum.RA_NETWORK_NOT_FOUND, networkId, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Network not found");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                    // Does not exist. Throw an exception (can't update a non-existent network)
+                    throw new NetworkException(error, MsoExceptionCategory.USERDATA);
+                }
+                long updateNetworkStarttime = System.currentTimeMillis ();
+                try {
+                    netInfo = neutron.updateNetwork (cloudSiteId,
+                                                     tenantId,
+                                                     networkId,
+                                                     neutronNetworkType,
+                                                     physicalNetworkName,
+                                                     vlans);
+                    LOGGER.recordMetricEvent (updateNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "UpdateNetwork", null);
+                } catch (MsoException me) {
+                    me.addContext (UPDATE_NETWORK_CONTEXT);
+                    String error = "Update Network (neutron): " + networkId
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, networkId, cloudSiteId, tenantId, "Openstack", "updateNetwork", MsoLogger.ErrorCode.DataError, "Exception - updateNetwork", me);
+                    LOGGER.recordMetricEvent (updateNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "UpdateNetwork", null);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+
+                // Add the network ID and previously queried vlans to the rollback object
+                networkRollback.setNetworkId (netInfo.getId ());
+                networkRollback.setNeutronNetworkId (netInfo.getId ());
+                networkRollback.setNetworkType (networkType);
+                // Save previous parameters
+                networkRollback.setNetworkName (netInfo.getName ());
+                networkRollback.setPhysicalNetwork (netInfo.getProvider ());
+                networkRollback.setVlans (netInfo.getVlans ());
+
+                LOGGER.debug ("Network " + networkId + " updated, id = " + netInfo.getId ());
+            } else if ("HEAT".equals (mode)) {
+
+                // Use an MsoHeatUtils for all Heat commands
+                MsoHeatUtilsWithUpdate heat = new MsoHeatUtilsWithUpdate (MSO_PROP_NETWORK_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+                // First, look up to see that the Network already exists.
+                // For Heat-based orchestration, the networkId is the network Stack ID.
+                StackInfo heatStack = null;
+                long queryStackStarttime = System.currentTimeMillis ();
+                try {
+                    heatStack = heat.queryStack (cloudSiteId, tenantId, networkName);
+                    LOGGER.recordMetricEvent (queryStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", null);
+                } catch (MsoException me) {
+                    me.addContext (UPDATE_NETWORK_CONTEXT);
+                    String error = "UpdateNetwork (heat): query " + networkName
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.recordMetricEvent (queryStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryStack", null);
+                    LOGGER.error (MessageEnum.RA_QUERY_NETWORK_EXC, networkId, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Exception - QueryStack", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+
+                if (heatStack == null || (heatStack.getStatus () == HeatStatus.NOTFOUND)) {
+                    String error = "UpdateNetwork: Stack " + networkName
+                                   + " does not exist in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId;
+                    LOGGER.error (MessageEnum.RA_NETWORK_NOT_FOUND, networkId, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Network not found");
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                    // Network stack does not exist. Return an error
+                    throw new NetworkException(error, MsoExceptionCategory.USERDATA);
+                }
+
+                // Get the previous parameters for rollback
+                Map <String, Object> heatParams = heatStack.getParameters ();
+
+                String previousNetworkName = (String) heatParams.get ("network_name");
+                String previousPhysicalNetwork = (String) heatParams.get (PHYSICAL_NETWORK);
+
+                List <Integer> previousVlans = new ArrayList <Integer> ();
+                String vlansParam = (String) heatParams.get (VLANS);
+                if (vlansParam != null) {
+                    for (String vlan : vlansParam.split (",")) {
+                        try {
+                            previousVlans.add (Integer.parseInt (vlan));
+                        } catch (NumberFormatException e) {
+                            LOGGER.warn (MessageEnum.RA_VLAN_PARSE, networkId, vlansParam, "", "", MsoLogger.ErrorCode.DataError, "Exception - VLAN parse", e);
+                        }
+                    }
+                }
+                LOGGER.debug ("Update Stack:  Previous VLANS: " + previousVlans);
+
+                // Ready to deploy the updated Network via Heat
+
+                HeatTemplate heatTemplate = db.getHeatTemplate (networkResource.getTemplateId ());
+                if (heatTemplate == null) {
+                    String error = "Network error - undefined Heat Template. Network Type=" + networkType;
+                    LOGGER.error (MessageEnum.RA_PARAM_NOT_FOUND, "Heat Template", "Network Type", networkType, "OpenStack", "getHeatTemplate", MsoLogger.ErrorCode.DataError, "Network error - undefined Heat Template. Network Type=" + networkType);
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                    throw new NetworkException (error, MsoExceptionCategory.INTERNAL);
+                }
+
+                LOGGER.debug ("Got HEAT Template from DB: " + heatTemplate.toString ());
+                
+                // "Fix" the template if it has CR/LF (getting this from Oracle)
+                String template = heatTemplate.getHeatTemplate ();
+                template = template.replaceAll ("\r\n", "\n");
+                
+                boolean aic3template=false;
+                String aic3nw = AIC3_NW;
+                try {
+                	aic3nw = msoPropertiesFactory.getMsoJavaProperties(MSO_PROP_NETWORK_ADAPTER).getProperty(AIC3_NW_PROPERTY, AIC3_NW);
+        		} catch (MsoPropertiesException e) {
+        			String error = "Unable to get properties:" + MSO_PROP_NETWORK_ADAPTER;
+        			LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - Unable to get properties", e);
+        		}
+                if (template.contains(aic3nw))
+                	aic3template = true;
+
+                // Build the common set of HEAT template parameters
+                Map <String, Object> stackParams = populateNetworkParams (neutronNetworkType,
+                                                                          networkName,
+                                                                          physicalNetworkName,
+                                                                          vlans,
+                                                                          routeTargets,
+                                                                          shared,
+                                                                          external,
+                                                                          aic3template);
+
+                // Validate (and update) the input parameters against the DB definition
+                // Shouldn't happen unless DB config is wrong, since all networks use same inputs
+                try {
+                    stackParams = heat.validateStackParams (stackParams, heatTemplate);
+                } catch (IllegalArgumentException e) {
+                    String error = "UpdateNetwork: Configuration Error: Network Type=" + networkType;
+                    LOGGER.error (MessageEnum.RA_CONFIG_EXC, "Network Type=" + networkType, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - UpdateNetwork: Configuration Error");
+                    alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.SchemaError, error);
+                    throw new NetworkException (error, MsoExceptionCategory.INTERNAL, e);
+                }
+
+                if (subnets != null) {
+                    try {
+                    	if (aic3template)
+                		{
+                			template = mergeSubnetsAIC3 (template, subnets, stackParams);
+                		}
+                		else
+                		{
+                			template = mergeSubnets (template, subnets);
+                		}
+                    } catch (MsoException me) {
+                        me.addContext (UPDATE_NETWORK_CONTEXT);
+                        String error = "Update Network (heat): type " + neutronNetworkType
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, neutronNetworkType.toString(), cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - UpdateNetwork mergeSubnets ", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, error);
+                        throw new NetworkException (me);
+                    }
+                }
+
+                if (policyFqdns != null && aic3template) {
+                    try {
+                    	mergePolicyRefs (policyFqdns, stackParams);
+                    } catch (MsoException me) {
+                        me.addContext (UPDATE_NETWORK_CONTEXT);
+                    	String error = "UpdateNetwork (heat) mergePolicyRefs type " + neutronNetworkType
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, neutronNetworkType.toString(), cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - UpdateNetwork mergePolicyRefs", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, error);
+                        throw new NetworkException (me);
+                    }
+                }
+                
+                if (routeTableFqdns != null && !routeTableFqdns.isEmpty() && aic3template) {
+                    try {
+                        mergeRouteTableRefs (routeTableFqdns, stackParams);
+                    } catch (MsoException me) {
+                        me.addContext (UPDATE_NETWORK_CONTEXT);
+                    	String error = "UpdateNetwork (heat) mergeRouteTableRefs type " + neutronNetworkType
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, neutronNetworkType.toString(), cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception - UpdateNetwork mergeRouteTableRefs", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.InternalError, error);
+                        throw new NetworkException (me);
+                    }
+                }
+                
+                // Update the network stack
+                // Ignore MsoStackNotFound exception because we already checked.
+                long updateStackStarttime = System.currentTimeMillis ();
+                try {
+                    heatStack = heat.updateStack (cloudSiteId,
+                                                  tenantId,
+                                                  networkId,
+                                                  template,
+                                                  stackParams,
+                                                  true,
+                                                  heatTemplate.getTimeoutMinutes ());
+                    LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "UpdateStack", null);
+                } catch (MsoException me) {
+                    me.addContext (UPDATE_NETWORK_CONTEXT);
+                    String error = "Update Network: " + networkId + " in " + cloudSiteId + "/" + tenantId + ": " + me;
+                    LOGGER.recordMetricEvent (updateStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "UpdateStack", null);
+                    LOGGER.error (MessageEnum.RA_UPDATE_NETWORK_ERR, networkId, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - update network", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+
+                Map <String, Object> outputs = heatStack.getOutputs ();
+                Map <String, String> sMap = new HashMap <String, String> ();
+                if (outputs != null) {
+                    for (String key : outputs.keySet ()) {
+                        if (key != null && key.startsWith ("subnet")) {
+                        	if (aic3template) //one subnet output expected
+                			{
+                				 Map <String, String> map = getSubnetUUId(key, outputs, subnets); 
+                				 sMap.putAll(map);
+                			}
+                			else //multiples subnet_%aaid% outputs allowed
+                			{
+                				String subnetUUId = (String) outputs.get(key); 
+                				sMap.put (key.substring("subnet_id_".length()), subnetUUId);
+                			}
+                        }
+                    }
+                }
+                subnetIdMap.value = sMap;
+
+                // Reach this point if createStack is successful.
+                // Populate remaining rollback info and response parameters.
+                networkRollback.setNetworkStackId (heatStack.getCanonicalName ());
+                networkRollback.setNeutronNetworkId ((String) outputs.get (NETWORK_ID));
+                networkRollback.setNetworkType (networkType);
+                // Save previous parameters
+                networkRollback.setNetworkName (previousNetworkName);
+                networkRollback.setPhysicalNetwork (previousPhysicalNetwork);
+                networkRollback.setVlans (previousVlans);
+
+                rollback.value = networkRollback;
+
+                LOGGER.debug ("Network " + networkId + " successfully updated via HEAT");
+            }
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully updated network");
+        return;
+    }
+
+    private NetworkResource networkCheck (CatalogDatabase db,
+                                          long startTime,
+                                          String networkType,
+                                          String networkName,
+                                          String physicalNetworkName,
+                                          List <Integer> vlans,
+                                          List <String> routeTargets,
+                                          CloudSite cloudSite) throws NetworkException {
+        // Retrieve the Network Resource definition
+        NetworkResource networkResource = db.getNetworkResource (networkType);
+        if (networkResource == null) {
+            String error = "CreateNetwork: Unknown Network Type: " + networkType;
+            LOGGER.error (MessageEnum.RA_UNKOWN_PARAM, "Network Type", networkType, "OpenStack", "", MsoLogger.ErrorCode.DataError, "CreateNetwork: Unknown Network Type");
+
+            throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+        }
+        LOGGER.debug ("Got Network definition from Catalog: " + networkResource.toString ());
+
+        String mode = networkResource.getOrchestrationMode ();
+        NetworkType neutronNetworkType = NetworkType.valueOf (networkResource.getNeutronNetworkType ());
+
+        // All Networks are orchestrated via HEAT or Neutron
+        if (!("HEAT".equals (mode) || NEUTRON_MODE.equals (mode))) {
+            String error = "CreateNetwork: Configuration Error: Network Type = " + networkType;
+            LOGGER.error (MessageEnum.RA_NETWORK_ORCHE_MODE_NOT_SUPPORT, mode, "OpenStack", "", MsoLogger.ErrorCode.DataError, "CreateNetwork: Configuration Error");
+            // Alarm on this error, configuration must be fixed
+            alarmLogger.sendAlarm (MSO_CONFIGURATION_ERROR, MsoAlarmLogger.CRITICAL, error);
+
+            throw new NetworkException (error, MsoExceptionCategory.INTERNAL);
+        }
+
+        MavenLikeVersioning aicV = new MavenLikeVersioning();
+		aicV.setVersion(cloudSite.getAic_version());
+		if ((aicV.isMoreRecentThan(networkResource.getAicVersionMin()) || aicV.isTheSameVersion(networkResource.getAicVersionMin())) // aic >= min
+				&& (aicV.isTheSameVersion(networkResource.getAicVersionMax()) || !(aicV.isMoreRecentThan(networkResource.getAicVersionMax())))) //aic <= max
+		{
+			LOGGER.debug ("Network Type:" + networkType 
+				+   " VersionMin:" + networkResource.getAicVersionMin() 
+				+	" VersionMax:" + networkResource.getAicVersionMax() 
+				+	" supported on Cloud:" + cloudSite.getId()
+				+	" with AIC_Version:" + cloudSite.getAic_version());
+		}
+		else
+		{
+			String error = "Network Type:" + networkType
+					+ " Version_Min:" + networkResource.getAicVersionMin() 
+					+ " Version_Max:" + networkResource.getAicVersionMax() 
+					+ " not supported on Cloud:" + cloudSite.getId()
+					+ " with AIC_Version:"  + cloudSite.getAic_version();
+			LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Network Type not supported on Cloud");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+			throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+		}
+
+
+        // Validate the Network parameters.
+        String missing = validateNetworkParams (neutronNetworkType,
+                                                networkName,
+                                                physicalNetworkName,
+                                                vlans,
+                                                routeTargets);
+        if (!missing.isEmpty ()) {
+            String error = "Create Network: Missing parameters: " + missing;
+            LOGGER.error (MessageEnum.RA_MISSING_PARAM, missing, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Create Network: Missing parameters");
+
+            throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+        }
+        return networkResource;
+    }
+
+    @Override
+    public void queryNetwork (String cloudSiteId,
+                              String tenantId,
+                              String networkNameOrId,
+                              MsoRequest msoRequest,
+                              Holder <Boolean> networkExists,
+                              Holder <String> networkId,
+                              Holder <String> neutronNetworkId,
+                              Holder <NetworkStatus> status,
+                              Holder <List <Integer>> vlans,
+                              Holder <Map <String, String>> subnetIdMap) throws NetworkException {
+        queryNetwork (cloudSiteId,
+                      tenantId,
+                      networkNameOrId,
+                      msoRequest,
+                      networkExists,
+                      networkId,
+                      neutronNetworkId,
+                      status,
+                      vlans,
+                      null,
+                      subnetIdMap);
+    }
+
+    @Override
+    public void queryNetworkContrail (String cloudSiteId,
+                                      String tenantId,
+                                      String networkNameOrId,
+                                      MsoRequest msoRequest,
+                                      Holder <Boolean> networkExists,
+                                      Holder <String> networkId,
+                                      Holder <String> neutronNetworkId,
+                                      Holder <NetworkStatus> status,
+                                      Holder <List <String>> routeTargets,
+                                      Holder <Map <String, String>> subnetIdMap) throws NetworkException {
+        queryNetwork (cloudSiteId,
+                      tenantId,
+                      networkNameOrId,
+                      msoRequest,
+                      networkExists,
+                      networkId,
+                      neutronNetworkId,
+                      status,
+                      null,
+                      routeTargets,
+                      subnetIdMap);
+    }
+
+    /**
+     * This is the queryNetwork method. It returns the existence and status of
+     * the specified network, along with its Neutron UUID and list of VLANs.
+     * This method attempts to find the network using both Heat and Neutron.
+     * Heat stacks are first searched based on the provided network name/id.
+     * If none is found, the Neutron is directly queried.
+     */
+    private void queryNetwork (String cloudSiteId,
+                              String tenantId,
+                              String networkNameOrId,
+                              MsoRequest msoRequest,
+                              Holder <Boolean> networkExists,
+                              Holder <String> networkId,
+                              Holder <String> neutronNetworkId,
+                              Holder <NetworkStatus> status,
+                              Holder <List <Integer>> vlans,
+                              Holder <List <String>> routeTargets,
+                              Holder <Map <String, String>> subnetIdMap) throws NetworkException {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("QueryNetwork");
+        LOGGER.debug ("*** QUERY Network with Network: " + networkNameOrId
+                + " in "
+                + cloudSiteId
+                + "/"
+                + tenantId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        if (isNullOrEmpty (cloudSiteId)
+            || isNullOrEmpty(tenantId)
+            || isNullOrEmpty(networkNameOrId)) {
+
+            String error = "Missing mandatory parameter cloudSiteId, tenantId or networkId";
+            LOGGER.error (MessageEnum.RA_MISSING_PARAM, "cloudSiteId or tenantId or networkNameOrId", "OpenStack", "", MsoLogger.ErrorCode.DataError, "Missing mandatory parameter cloudSiteId, tenantId or networkId");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+            throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+        }
+
+        cloudConfig = cloudConfigFactory.getCloudConfig ();
+        CloudSite cloudSite = cloudConfig.getCloudSite (cloudSiteId);
+        if (cloudSite == null)
+        {
+        	String error = "Configuration Error. Stack " + networkNameOrId + " in "
+        			+ cloudSiteId
+        			+ "/"
+        			+ tenantId
+        			+ ": "
+        			+ " CloudSite does not exist in MSO Configuration";
+        	LOGGER.error (MessageEnum.RA_CONFIG_EXC, error, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Configuration Error");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+        	// Set the detailed error as the Exception 'message'
+        	throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+        }
+
+        // Use MsoNeutronUtils for all NEUTRON commands
+        MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_NETWORK_ADAPTER,msoPropertiesFactory,cloudConfigFactory);
+        MsoNeutronUtils neutron = new MsoNeutronUtils (MSO_PROP_NETWORK_ADAPTER, cloudConfigFactory);
+
+        String mode = null;
+        String neutronId = null;
+        // Try Heat first, since networks may be named the same as the Heat stack
+        StackInfo heatStack = null;
+        long queryStackStarttime = System.currentTimeMillis ();
+        try {
+            heatStack = heat.queryStack (cloudSiteId, tenantId, networkNameOrId);
+            LOGGER.recordMetricEvent (queryStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryStack", null);
+        } catch (MsoException me) {
+        	me.addContext ("QueryNetwork");
+            String error = "Query Network (heat): " + networkNameOrId
+                           + " in "
+                           + cloudSiteId
+                           + "/"
+                           + tenantId
+                           + ": "
+                           + me;
+            LOGGER.recordMetricEvent (queryStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "BPMN", "QueryStack", null);
+            LOGGER.error (MessageEnum.RA_QUERY_NETWORK_EXC, networkNameOrId, cloudSiteId, tenantId, "OpenStack", "queryStack", MsoLogger.ErrorCode.DataError, "Exception - Query Network (heat)", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new NetworkException (me);
+        }
+
+        // Populate the outputs based on the returned Stack information
+        if (heatStack != null && heatStack.getStatus () != HeatStatus.NOTFOUND) {
+            // Found it. Get the neutronNetworkId for further query
+            Map <String, Object> outputs = heatStack.getOutputs ();
+            neutronId = (String) outputs.get (NETWORK_ID);
+            mode = "HEAT";
+
+            Map <String, String> sMap = new HashMap <String, String> ();
+            if (outputs != null) {
+            	for (String key : outputs.keySet ()) {
+            		if (key != null && key.startsWith ("subnet_id_")) //multiples subnet_%aaid% outputs
+            		{
+            			String subnetUUId = (String) outputs.get(key); 
+            			sMap.put (key.substring("subnet_id_".length()), subnetUUId);
+            		}
+            		else if (key != null && key.startsWith ("subnet")) //one subnet output expected
+            		{
+            			Map <String, String> map = getSubnetUUId(key, outputs, null); 
+            			sMap.putAll(map);
+            		}
+
+            	}
+            }
+            subnetIdMap.value = sMap;
+        } else {
+            // Input ID was not a Heat stack ID. Try it directly in Neutron
+            neutronId = networkNameOrId;
+            mode = NEUTRON_MODE;
+        }
+
+        // Query directly against the Neutron Network for the details
+        // no RouteTargets available for ContrailV2 in neutron net-show
+        // networkId is heatStackId
+        long queryNetworkStarttime = System.currentTimeMillis ();
+        try {
+            NetworkInfo netInfo = neutron.queryNetwork (neutronId, tenantId, cloudSiteId);
+            LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryNetwork", null);
+            if (netInfo != null) {
+                // Found. Populate the output elements
+                networkExists.value = Boolean.TRUE;
+                if ("HEAT".equals (mode)) {
+                    networkId.value = heatStack.getCanonicalName ();
+                } else {
+                    networkId.value = netInfo.getId ();
+                }
+                neutronNetworkId.value = netInfo.getId ();
+                status.value = netInfo.getStatus ();
+                if (vlans != null)
+                	vlans.value = netInfo.getVlans ();
+
+                LOGGER.debug ("Network " + networkNameOrId
+                              + " found ("
+                              + mode
+                              + "), ID = "
+                              + networkId.value
+                              + ("HEAT".equals (mode) ? ",NeutronId = " + neutronNetworkId.value : ""));
+            } else {
+                // Not found. Populate the status fields, leave the rest null
+                networkExists.value = Boolean.FALSE;
+                status.value = NetworkStatus.NOTFOUND;
+                neutronNetworkId.value = null;
+                if (vlans != null)
+                	vlans.value = new ArrayList <Integer> ();
+
+                LOGGER.debug ("Network " + networkNameOrId + " not found");
+            }
+        } catch (MsoException me) {
+            me.addContext ("QueryNetwork");
+            String error = "Query Network (neutron): " + networkNameOrId
+                           + " in "
+                           + cloudSiteId
+                           + "/"
+                           + tenantId
+                           + ": "
+                           + me;
+            LOGGER.recordMetricEvent (queryNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryNetwork", null);
+            LOGGER.error (MessageEnum.RA_QUERY_NETWORK_EXC, networkNameOrId, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - Query Network (neutron)", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new NetworkException (me);
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully queried network");
+        return;
+    }
+
+    /**
+     * This is the "Delete Network" web service implementation.
+     * It will delete a Network in the specified cloud and tenant.
+     *
+     * If the network is not found, it is treated as a success.
+     *
+     * This service supports two modes of Network creation/update/delete:
+     * - via Heat Templates
+     * - via Neutron API
+     * The network orchestration mode for each network type is declared in its
+     * catalog definition.
+     *
+     * For Heat-based orchestration, the networkId should be the stack ID.
+     * For Neutron-based orchestration, the networkId should be the Neutron network UUID.
+     *
+     * The method returns nothing on success. Rollback is not possible for delete
+     * commands, so any failure on delete will require manual fallout in the client.
+     */
+    @Override
+    public void deleteNetwork (String cloudSiteId,
+                               String tenantId,
+                               String networkType,
+                               String networkId,
+                               MsoRequest msoRequest,
+                               Holder <Boolean> networkDeleted) throws NetworkException {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("DeleteNetwork");
+        LOGGER.debug ("*** DELETE Network adapter with Network: " + networkId
+                                      + " in "
+                                      + cloudSiteId
+                                      + "/"
+                                      + tenantId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        try (CatalogDatabase db = getCatalogDb()) {
+            if (isNullOrEmpty (cloudSiteId)
+                            || isNullOrEmpty(tenantId)
+                            || isNullOrEmpty(networkId)) {
+                String error = "Missing mandatory parameter cloudSiteId, tenantId or networkId";
+                LOGGER.error (MessageEnum.RA_MISSING_PARAM, "cloudSiteId or tenantId or networkId", "Openstack", "", MsoLogger.ErrorCode.DataError, "Missing mandatory parameter cloudSiteId, tenantId or networkId");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+            }
+
+            // Retrieve the Network Resource definition
+            NetworkResource networkResource = db.getNetworkResource (networkType);
+            if (networkResource == null) {
+                String error = "Unknown Network Type: " + networkType;
+                LOGGER.error (MessageEnum.RA_UNKOWN_PARAM, "Network Type", networkType, "Openstack", "", MsoLogger.ErrorCode.DataError, "Unknown Network Type");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+            }
+            LOGGER.debug ("Got Network definition from Catalog: " + networkResource.toString ());
+
+            String mode = networkResource.getOrchestrationMode ();
+
+            if (NEUTRON_MODE.equals (mode)) {
+
+                // Use MsoNeutronUtils for all NEUTRON commands
+                MsoNeutronUtils neutron = new MsoNeutronUtils (MSO_PROP_NETWORK_ADAPTER, cloudConfigFactory);
+                long deleteNetworkStarttime = System.currentTimeMillis ();
+                try {
+                    // The deleteNetwork function in MsoNeutronUtils returns success if the network
+                    // was not found. So don't bother to query first.
+                    boolean deleted = neutron.deleteNetwork (networkId, tenantId, cloudSiteId);
+                    LOGGER.recordMetricEvent (deleteNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteNetwork", null);
+                    networkDeleted.value = deleted;
+                } catch (MsoException me) {
+                    me.addContext ("DeleteNetwork");
+                	String error = "Delete Network (neutron): " + networkId
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.recordMetricEvent (deleteNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteNetwork", null);
+                    LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Delete Network (neutron)", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+            } else if ("HEAT".equals (mode)) {
+                long deleteStackStarttime = System.currentTimeMillis ();
+                // Use MsoHeatUtils for all HEAT commands
+                MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_NETWORK_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+
+                try {
+                    // The deleteStack function in MsoHeatUtils returns NOTFOUND if the stack was not found or if the stack was deleted.
+                    //  So query first to report back if stack WAS deleted or just NOTOFUND 
+                	StackInfo heatStack = null;
+                	heatStack = heat.queryStack(cloudSiteId, tenantId, networkId);
+                	if (heatStack != null && heatStack.getStatus() != HeatStatus.NOTFOUND)
+                	{
+                		heat.deleteStack (tenantId, cloudSiteId, networkId, true);
+                		LOGGER.recordMetricEvent (deleteStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteStack", null);
+                		networkDeleted.value = true;
+                	}
+                	else
+                	{
+                		networkDeleted.value = false;
+                	}
+                } catch (MsoException me) {
+                    me.addContext ("DeleteNetwork");
+                	String error = "Delete Network (heat): " + networkId
+                                   + " in "
+                                   + cloudSiteId
+                                   + "/"
+                                   + tenantId
+                                   + ": "
+                                   + me;
+                    LOGGER.recordMetricEvent (deleteStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteStack", null);
+                    LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Delete Network (heat)", me);
+                    LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                    throw new NetworkException (me);
+                }
+            }
+        }
+
+        // On success, nothing is returned.
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully deleted network");
+        return;
+    }
+
+    public CatalogDatabase getCatalogDb() {
+        return new CatalogDatabase();
+    }
+
+    /**
+     * 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.
+     *
+     * The rollback includes removing the VNF and deleting the tenant if the
+     * tenant did not exist prior to the VNF creation.
+     */
+    @Override
+    public void rollbackNetwork (NetworkRollback rollback) throws NetworkException {
+        MsoLogger.setServiceName ("RollbackNetwork");
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        if (rollback == null) {
+        	LOGGER.error (MessageEnum.RA_ROLLBACK_NULL, "Openstack", "", MsoLogger.ErrorCode.DataError, "rollback is null");
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, "No action to perform");
+            return;
+        }
+
+        MsoLogger.setLogContext (rollback.getMsoRequest());
+
+        // Get the elements of the VnfRollback object for easier access
+        String cloudSiteId = rollback.getCloudId ();
+        String tenantId = rollback.getTenantId ();
+        String networkId = rollback.getNetworkStackId ();
+        String networkType = rollback.getNetworkType ();
+
+        LOGGER.debug ("*** ROLLBACK Network " + networkId + " in " + cloudSiteId + "/" + tenantId);
+
+        // rollback may be null (e.g. if network already existed when Create was called)
+        // Get a handle to the Catalog Database
+
+        try (CatalogDatabase db = getCatalogDb()){
+
+            // Retrieve the Network Resource definition
+            NetworkResource networkResource = db.getNetworkResource (networkType);
+            if (networkResource == null) {
+                String error = "Rollback Network: Unknown Network Type: " + networkType;
+                LOGGER.error (MessageEnum.RA_UNKOWN_PARAM, "Network Type", networkType, "Openstack", "", MsoLogger.ErrorCode.DataError, "Rollback Network: Unknown Network Type");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.BadRequest, error);
+                throw new NetworkException (error, MsoExceptionCategory.USERDATA);
+            }
+            LOGGER.debug ("Got Network definition from Catalog: " + networkResource.toString ());
+
+            String mode = networkResource.getOrchestrationMode ();
+
+            if (rollback.getNetworkCreated ()) {
+                // Rolling back a newly created network, so delete it.
+                if (NEUTRON_MODE.equals (mode)) {
+                    // Use MsoNeutronUtils for all NEUTRON commands
+                    MsoNeutronUtils neutron = new MsoNeutronUtils (MSO_PROP_NETWORK_ADAPTER, cloudConfigFactory);
+                    long deleteNetworkStarttime = System.currentTimeMillis ();
+                    try {
+                        // The deleteNetwork function in MsoNeutronUtils returns success if the network
+                        // was not found. So don't bother to query first.
+                        neutron.deleteNetwork (networkId, tenantId, cloudSiteId);
+                        LOGGER.recordMetricEvent (deleteNetworkStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteNetwork", null);
+                    } catch (MsoException me) {
+                        me.addContext ("RollbackNetwork");
+                        String error = "Rollback Network (neutron): " + networkId
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.recordMetricEvent (deleteNetworkStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteNetwork", null);
+                        LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Rollback Network (neutron)", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                        throw new NetworkException (me);
+                    }
+                } else if ("HEAT".equals (mode)) {
+                    // Use MsoHeatUtils for all HEAT commands
+                    MsoHeatUtils heat = new MsoHeatUtils (MSO_PROP_NETWORK_ADAPTER, msoPropertiesFactory,cloudConfigFactory);
+                    long deleteStackStarttime = System.currentTimeMillis ();
+                    try {
+                        // The deleteStack function in MsoHeatUtils returns success if the stack
+                        // was not found. So don't bother to query first.
+                        heat.deleteStack (tenantId, cloudSiteId, networkId, true);
+                        LOGGER.recordMetricEvent (deleteStackStarttime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "DeleteStack", null);
+                    } catch (MsoException me) {
+                        me.addContext ("RollbackNetwork");
+                        String error = "Rollback Network (heat): " + networkId
+                                       + " in "
+                                       + cloudSiteId
+                                       + "/"
+                                       + tenantId
+                                       + ": "
+                                       + me;
+                        LOGGER.recordMetricEvent (deleteStackStarttime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteStack", null);
+                        LOGGER.error (MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId, "OpenStack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception - Rollback Network (heat)", me);
+                        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                        throw new NetworkException (me);
+                    }
+                }
+            } 
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully rolled back network");
+        return;
+    }
+
+    private String validateNetworkParams (NetworkType neutronNetworkType,
+                                          String networkName,
+                                          String physicalNetwork,
+                                          List <Integer> vlans,
+                                          List <String> routeTargets) {
+        String sep = "";
+        StringBuilder missing = new StringBuilder ();
+        if (isNullOrEmpty(networkName)) {
+            missing.append ("networkName");
+            sep = ",";
+        }
+
+        if (neutronNetworkType == NetworkType.PROVIDER || neutronNetworkType == NetworkType.MULTI_PROVIDER) {
+            if (isNullOrEmpty(physicalNetwork)) {
+                missing.append (sep).append ("physicalNetworkName");
+                sep = ",";
+            }
+            if (vlans == null || vlans.isEmpty ()) {
+                missing.append (sep).append (VLANS);
+            }
+        }
+
+        return missing.toString ();
+    }
+
+    private Map <String, Object> populateNetworkParams (NetworkType neutronNetworkType,
+                                                        String networkName,
+                                                        String physicalNetwork,
+                                                        List <Integer> vlans,
+                                                        List <String> routeTargets,
+                                                        String shared,
+                                                        String external,
+                                                        boolean aic3template) {
+        // Build the common set of HEAT template parameters
+        Map <String, Object> stackParams = new HashMap <String, Object> ();
+        stackParams.put ("network_name", networkName);
+
+        if (neutronNetworkType == NetworkType.PROVIDER) {
+            // For Provider type
+            stackParams.put (PHYSICAL_NETWORK, physicalNetwork);
+            stackParams.put ("vlan", vlans.get (0).toString ());
+        } else if (neutronNetworkType == NetworkType.MULTI_PROVIDER) {
+            // For Multi-provider, PO supports a custom resource extension of ProviderNet.
+            // It supports all ProviderNet properties except segmentation_id, and adds a
+            // comma-separated-list of VLANs as a "segments" property.
+            // Note that this does not match the Neutron definition of Multi-Provider network,
+            // which contains a list of 'segments', each having physical_network, network_type,
+            // and segmentation_id.
+            StringBuilder buf = new StringBuilder ();
+            String sep = "";
+            for (Integer vlan : vlans) {
+                buf.append (sep).append (vlan.toString ());
+                sep = ",";
+            }
+            String csl = buf.toString ();
+
+            stackParams.put (PHYSICAL_NETWORK, physicalNetwork);
+            stackParams.put (VLANS, csl);
+        }
+        if (routeTargets != null && !routeTargets.isEmpty()) {
+            StringBuilder buf = new StringBuilder ();
+            String sep = "";
+            for (String rt : routeTargets) {
+            	if (!isNullOrEmpty(rt))
+            	{
+            		if (aic3template)
+            			buf.append (sep).append ("target:" + rt.toString ());
+            		else
+            			buf.append (sep).append (rt.toString ());
+
+            		sep = ",";
+            	}
+            }
+            String csl = buf.toString ();
+
+            stackParams.put ("route_targets", csl);
+        }
+        if (isNullOrEmpty(shared)) {
+            stackParams.put ("shared", "False");
+        } else {
+            stackParams.put ("shared", shared);
+        }
+        if (isNullOrEmpty(external)) {
+            stackParams.put ("external", "False");
+        } else {
+            stackParams.put ("external", external);
+        }
+        return stackParams;
+    }
+    
+
+    
+    /** policyRef_list structure in stackParams
+    [
+     {
+         "network_policy_refs_data_sequence": {
+             "network_policy_refs_data_sequence_major": "1",
+             "network_policy_refs_data_sequence_minor": "0"
+         }
+     },
+     {
+         "network_policy_refs_data_sequence": {
+             "network_policy_refs_data_sequence_major": "2",
+             "network_policy_refs_data_sequence_minor": "0"
+         }
+     }
+ 	]
+    **/
+    private void mergePolicyRefs(List <String> pFqdns, Map <String, Object> stackParams) throws MsoException {
+		//Resource Property
+		List<ContrailPolicyRef> prlist =  new ArrayList <ContrailPolicyRef> ();
+		int index = 1;
+		for (String pf : pFqdns) {
+			if (!isNullOrEmpty(pf))
+			{
+				ContrailPolicyRef pr = new ContrailPolicyRef();
+				pr.populate(String.valueOf(index), "0");
+				index++;
+				LOGGER.debug("Contrail PolicyRefs Data:" + pr.toString());
+				prlist.add(pr);
+			}
+		}
+		
+		JsonNode node = null;
+		try
+		{
+			ObjectMapper mapper = new ObjectMapper(); 
+			node = mapper.convertValue(prlist, JsonNode.class);
+			String jsonString = mapper.writeValueAsString(prlist);
+			LOGGER.debug("Json PolicyRefs Data:" + jsonString);
+		}
+		catch (Exception e)
+		{
+			String error = "Error creating JsonNode for policyRefs Data";
+			LOGGER.error (MessageEnum.RA_MARSHING_ERROR, error, "Openstack", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception creating JsonNode for policyRefs Data", e);
+			throw new MsoAdapterException (error);
+		}
+		//update parameters
+		if (pFqdns != null && node != null)
+		{
+			StringBuilder buf = new StringBuilder ();
+			String sep = "";
+			for (String pf : pFqdns) {
+				if (!isNullOrEmpty(pf))
+				{
+					buf.append (sep).append (pf.toString ());
+					sep = ",";
+				}
+			}
+			String csl = buf.toString ();
+			stackParams.put ("policy_refs", csl);
+			stackParams.put ("policy_refsdata", node);
+		}
+
+		LOGGER.debug ("StackParams updated with policy refs");
+		return;
+    }
+    
+    private void mergeRouteTableRefs(List <String> rtFqdns, Map <String, Object> stackParams) throws MsoException {
+		
+		//update parameters
+		if (rtFqdns != null)
+		{
+			StringBuilder buf = new StringBuilder ();
+			String sep = "";
+			for (String rtf : rtFqdns) {
+				if (!isNullOrEmpty(rtf))
+				{
+					buf.append (sep).append (rtf.toString ());
+					sep = ",";
+				}
+			}
+			String csl = buf.toString ();
+			stackParams.put ("route_table_refs", csl);
+		}
+
+		LOGGER.debug ("StackParams updated with route_table refs");
+		return;
+    }
+
+    
+    /*** Subnet Output structure from Juniper
+     {
+    "ipam_subnets": [
+        {
+            "subnet": {
+                "ip_prefix": "10.100.1.0",
+                "ip_prefix_len": 28
+            },
+            "addr_from_start": null,
+            "enable_dhcp": false,
+            "default_gateway": "10.100.1.1",
+            "dns_nameservers": [],
+            "dhcp_option_list": null,
+            "subnet_uuid": "10391fbf-6b9c-4160-825d-2d018b7649cf",
+            "allocation_pools": [
+                {
+                    "start": "10.100.1.3",
+                    "end": "10.100.1.5"
+                },
+                {
+                    "start": "10.100.1.6",
+                    "end": "10.100.1.9"
+                }
+            ],
+            "host_routes": null,
+            "dns_server_address": "10.100.1.13",
+            "subnet_name": "subnet_MsoNW1_692c9032-e1a2-4d64-828c-7b9a4fcc05b0"
+        },
+        {
+            "subnet": {
+                "ip_prefix": "10.100.2.16",
+                "ip_prefix_len": 28
+            },
+            "addr_from_start": null,
+            "enable_dhcp": true,
+            "default_gateway": "10.100.2.17",
+            "dns_nameservers": [],
+            "dhcp_option_list": null,
+            "subnet_uuid": "c7aac5ea-66fe-443a-85f9-9c38a608c0f6",
+            "allocation_pools": [
+                {
+                    "start": "10.100.2.18",
+                    "end": "10.100.2.20"
+                }
+            ],
+            "host_routes": null,
+            "dns_server_address": "10.100.2.29",
+            "subnet_name": "subnet_MsoNW1_692c9032-e1a2-4d64-828c-7b9a4fcc05b1"
+        }
+    ],
+    "host_routes": null
+	}
+    ***/
+    private String mergeSubnetsAIC3 (String heatTemplate, List <Subnet> subnets, Map <String, Object> stackParams) throws MsoException {
+
+		//Resource Property
+		List<ContrailSubnet> cslist =  new ArrayList <ContrailSubnet> ();
+		for (Subnet subnet : subnets) {
+			ContrailSubnet cs = new ContrailSubnet();
+			LOGGER.debug("Input Subnet:" + subnet.toString());
+			cs.populateWith(subnet);
+			LOGGER.debug("Contrail Subnet:" + cs.toString());
+			cslist.add(cs);
+		}
+
+		JsonNode node = null;
+		try
+		{
+			ObjectMapper mapper = new ObjectMapper();
+			node = mapper.convertValue(cslist, JsonNode.class);
+			String jsonString = mapper.writeValueAsString(cslist);
+			LOGGER.debug("Json Subnet List:" + jsonString);
+		}
+		catch (Exception e)
+		{
+			String error = "Error creating JsonNode from input subnets";
+			LOGGER.error (MessageEnum.RA_MARSHING_ERROR, error, "", "", MsoLogger.ErrorCode.DataError, "Exception creating JsonNode from input subnets", e);
+			throw new MsoAdapterException (error);
+		}
+		//update parameters
+		if (node != null)
+		{
+			stackParams.put ("subnet_list", node);
+		}
+		//Outputs - All subnets are in one ipam_subnets structure
+		String outputTempl = "  subnet:\n" + "    description: Openstack subnet identifier\n"
+				+ "    value: { get_attr: [network, network_ipam_refs, 0, attr]}\n";
+
+		// append outputs in heatTemplate
+		int outputsIdx = heatTemplate.indexOf ("outputs:");
+		heatTemplate = insertStr (heatTemplate, outputTempl, outputsIdx + 8);
+		LOGGER.debug ("Template updated with all AIC3.0 subnets:" + heatTemplate);
+		return heatTemplate;
+    }
+
+
+    private String mergeSubnets (String heatTemplate, List <Subnet> subnets) throws MsoException {
+
+    		String resourceTempl = "  subnet_%subnetId%:\n" + "    type: OS::Neutron::Subnet\n"
+    				+ "    properties:\n"
+    				+ "      name: %name%\n"
+    				+ "      network_id: { get_resource: network }\n"
+    				+ "      cidr: %cidr%\n";
+
+    		/* make these optional
+                               + "      ip_version: %ipversion%\n"
+                               + "      enable_dhcp: %enabledhcp%\n"
+                               + "      gateway_ip: %gatewayip%\n" 
+                               + "      allocation_pools:\n"
+                               + "       - start: %poolstart%\n"
+                               + "         end: %poolend%\n";
+
+    		 */
+    		
+    		String outputTempl = "  subnet_id_%subnetId%:\n" + "    description: Openstack subnet identifier\n"
+    				+ "    value: {get_resource: subnet_%subnetId%}\n";
+
+    		String curR = "";
+    		String curO = "";
+    		StringBuilder resourcesBuf = new StringBuilder ();
+    		StringBuilder outputsBuf = new StringBuilder ();
+    		for (Subnet subnet : subnets) {
+
+    			// build template for each subnet
+    			curR = resourceTempl;
+    			if (subnet.getSubnetId () != null) {
+    				curR = curR.replace ("%subnetId%", subnet.getSubnetId ());
+    			} else {
+    				String error = "Missing Required AAI SubnetId for subnet in HEAT Template";
+    				LOGGER.error (MessageEnum.RA_MISSING_PARAM, error, "Openstack", "", MsoLogger.ErrorCode.DataError, "Missing Required AAI ID  for subnet in HEAT Template");
+    				throw new MsoAdapterException (error);
+    			}
+    			
+    			if (subnet.getSubnetName () != null) {
+    				curR = curR.replace ("%name%", subnet.getSubnetName ());
+    			} else {
+    				curR = curR.replace ("%name%", subnet.getSubnetId ());
+    			}
+    			
+    			if (subnet.getCidr () != null) {
+    				curR = curR.replace ("%cidr%", subnet.getCidr ());
+    			} else {
+    				String error = "Missing Required cidr for subnet in HEAT Template";
+    				LOGGER.error (MessageEnum.RA_MISSING_PARAM, error, "Openstack", "", MsoLogger.ErrorCode.DataError, "Missing Required cidr for subnet in HEAT Template");
+    				throw new MsoAdapterException (error);
+    			}
+
+    			if (subnet.getIpVersion () != null) {
+    				curR = curR + "      ip_version: " + subnet.getIpVersion () + "\n";
+    			}
+    			if (subnet.getEnableDHCP () != null) {
+    				curR = curR + "      enable_dhcp: " +  Boolean.toString (subnet.getEnableDHCP ()) + "\n";
+    			}
+    			if (subnet.getGatewayIp () != null && !subnet.getGatewayIp ().isEmpty() ) {
+    				curR = curR + "      gateway_ip: " + subnet.getGatewayIp () + "\n";
+    			}  	
+
+    			if (subnet.getAllocationPools() != null) { 
+    				curR = curR + "      allocation_pools:\n";
+    				for (Pool pool : subnet.getAllocationPools()) 
+    				{
+    					if (!isNullOrEmpty(pool.getStart()) && !isNullOrEmpty(pool.getEnd()))
+    					{
+    						curR = curR + "       - start: " + pool.getStart () + "\n";
+    						curR = curR + "         end: " + pool.getEnd () + "\n";
+    					}
+    				}
+    			}
+
+    			resourcesBuf.append (curR);
+
+    			curO = outputTempl;
+    			curO = curO.replace ("%subnetId%", subnet.getSubnetId ());
+
+    			outputsBuf.append (curO);
+
+    		}
+    		// append resources and outputs in heatTemplate
+    		LOGGER.debug ("Tempate initial:" + heatTemplate);
+    		int outputsIdx = heatTemplate.indexOf ("outputs:");
+    		heatTemplate = insertStr (heatTemplate, outputsBuf.toString (), outputsIdx + 8);
+    		int resourcesIdx = heatTemplate.indexOf ("resources:");
+    		heatTemplate = insertStr (heatTemplate, resourcesBuf.toString (), resourcesIdx + 10);
+
+    		LOGGER.debug ("Template updated with all subnets:" + heatTemplate);
+    		return heatTemplate;
+    }
+
+    private Map <String, String> getSubnetUUId(String key,  Map <String, Object> outputs, List <Subnet> subnets) {
+
+    	Map <String, String> sMap = new HashMap <String, String> ();
+
+    	try{
+    		Object obj = outputs.get(key);
+    		ObjectMapper mapper = new ObjectMapper();
+    		String jStr = mapper.writeValueAsString(obj);
+    		LOGGER.debug ("Subnet_Ipam Output JSON String:" + obj.getClass() + " " + jStr);
+
+    		JsonNode rootNode = mapper.readTree(jStr);
+    		for (JsonNode sNode : rootNode.path("ipam_subnets"))
+    		{
+    			LOGGER.debug("Output Subnet Node" + sNode.toString());
+    			String name = sNode.path("subnet_name").getTextValue();
+    			String uuid = sNode.path("subnet_uuid").getTextValue();
+    			String aaiId = name; // default
+    			// try to find aaiId for name in input subnetList
+    			if (subnets != null)
+    			{
+    				for (Subnet subnet : subnets)
+    				{
+    					if ( subnet !=  null && !isNullOrEmpty(subnet.getSubnetName()))
+    					{		
+    						if (subnet.getSubnetName().equals(name))
+    						{
+    							aaiId = subnet.getSubnetId(); 
+    							break;
+    						}
+    					}
+    				}
+    			}
+    			sMap.put(aaiId, uuid); //bpmn needs aaid to uuid map
+    		}
+    	}
+    	catch (Exception e)
+    	{
+    		LOGGER.error (MessageEnum.RA_MARSHING_ERROR, "error getting subnet-uuids", "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception getting subnet-uuids", e);
+    	}
+
+    	LOGGER.debug ("Return sMap" + sMap.toString());
+    	return sMap;
+    }
+
+    private static String insertStr (String template, String snippet, int index) {
+
+        String updatedTemplate = "";
+
+        LOGGER.debug ("Index:" + index + " Snippet:" + snippet);
+
+        String templateBeg = template.substring (0, index);
+        String templateEnd = template.substring (index);
+
+        updatedTemplate = templateBeg + "\n" + snippet + templateEnd;
+
+        LOGGER.debug ("Template updated with a subnet:" + updatedTemplate);
+        return updatedTemplate;
+    }
+
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java
new file mode 100644
index 0000000..c813534
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/NetworkAdapterRest.java
@@ -0,0 +1,595 @@
+/*-
+ * ============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.network;
+
+
+import java.util.HashMap;
+import java.util.List;
+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.network.exceptions.NetworkException;
+import org.openecomp.mso.adapters.nwrest.ContrailNetwork;
+import org.openecomp.mso.adapters.nwrest.CreateNetworkError;
+import org.openecomp.mso.adapters.nwrest.CreateNetworkRequest;
+import org.openecomp.mso.adapters.nwrest.CreateNetworkResponse;
+import org.openecomp.mso.adapters.nwrest.DeleteNetworkError;
+import org.openecomp.mso.adapters.nwrest.DeleteNetworkRequest;
+import org.openecomp.mso.adapters.nwrest.DeleteNetworkResponse;
+import org.openecomp.mso.adapters.nwrest.ProviderVlanNetwork;
+import org.openecomp.mso.adapters.nwrest.QueryNetworkError;
+import org.openecomp.mso.adapters.nwrest.QueryNetworkResponse;
+import org.openecomp.mso.adapters.nwrest.RollbackNetworkError;
+import org.openecomp.mso.adapters.nwrest.RollbackNetworkRequest;
+import org.openecomp.mso.adapters.nwrest.RollbackNetworkResponse;
+import org.openecomp.mso.adapters.nwrest.UpdateNetworkError;
+import org.openecomp.mso.adapters.nwrest.UpdateNetworkRequest;
+import org.openecomp.mso.adapters.nwrest.UpdateNetworkResponse;
+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.NetworkRollback;
+import org.openecomp.mso.openstack.beans.NetworkStatus;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+
+@Path("/v1/networks")
+public class NetworkAdapterRest {
+	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 MsoNetworkAdapterImpl adapter = new MsoNetworkAdapterImpl(msoPropertiesFactory, cloudConfigFactory);
+
+	@POST
+	@Path("")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response createNetwork(CreateNetworkRequest req) {
+		LOGGER.debug("createNetwork enter: " + req.toJsonString());
+		CreateNetworkTask task = new CreateNetworkTask(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_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while create network", e);
+				return Response.serverError().build();
+			}
+			// send sync response (ACK) to caller
+			LOGGER.debug ("createNetwork exit");
+			return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class CreateNetworkTask implements Runnable {
+		private final CreateNetworkRequest req;
+		private CreateNetworkResponse response = null;
+		private CreateNetworkError eresp = null;
+		private boolean sendxml;
+
+		public CreateNetworkTask(CreateNetworkRequest 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<CreateNetworkResponse>(response) {}
+				: new GenericEntity<CreateNetworkError>(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 ("CreateNetworkTask start");
+			try {
+				// Synchronous Web Service Outputs
+				Holder<String> networkId = new Holder<String>();
+				Holder<String> neutronNetworkId = new Holder<String>();
+				Holder<String> networkFqdn = new Holder<String>();
+				Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
+				Holder<NetworkRollback> rollback = new Holder<NetworkRollback>();
+
+				String cloudsite = req.getCloudSiteId();
+				if (cloudsite != null && cloudsite.equals(TESTING_KEYWORD)) {
+					String tenant = req.getTenantId();
+					if (tenant != null && tenant.equals(TESTING_KEYWORD)) {
+						throw new NetworkException("testing.");
+					}
+					networkId.value = "479D3D8B-6360-47BC-AB75-21CC91981484";
+					neutronNetworkId.value = "55e55884-28fa-11e6-8971-0017f20fe1b8";
+					networkFqdn.value = "086f70b6-28fb-11e6-8260-0017f20fe1b8";
+					subnetIdMap.value = testMap();
+					rollback.value = new NetworkRollback();
+				} else if (req.isContrailRequest()) {
+					ContrailNetwork ctn = req.getContrailNetwork();
+					if (ctn == null) {
+						ctn = new ContrailNetwork();
+						req.setContrailNetwork(ctn);
+					}
+					adapter.createNetworkContrail(
+						req.getCloudSiteId(),
+						req.getTenantId(),
+						req.getNetworkType(),
+						req.getNetworkName(),
+                        req.getContrailNetwork().getRouteTargets(),
+                        req.getContrailNetwork().getShared(),
+                        req.getContrailNetwork().getExternal(),
+                        req.getFailIfExists(),
+                        req.getBackout(),
+                        req.getSubnets(),
+                        req.getContrailNetwork().getPolicyFqdns(),
+                        req.getContrailNetwork().getRouteTableFqdns(),
+              			req.getMsoRequest(),
+       					networkId,
+						neutronNetworkId,
+						networkFqdn,
+						subnetIdMap,
+						rollback);
+				} else {
+					ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
+					if (pvn == null) {
+						pvn = new ProviderVlanNetwork();
+						req.setProviderVlanNetwork(pvn);
+					}
+					adapter.createNetwork(
+						req.getCloudSiteId(),
+						req.getTenantId(),
+						req.getNetworkType(),
+						req.getNetworkName(),
+						req.getProviderVlanNetwork().getPhysicalNetworkName(),
+						req.getProviderVlanNetwork().getVlans(),
+                        req.getFailIfExists(),
+                        req.getBackout(),
+                        req.getSubnets(),
+                        req.getMsoRequest(),
+    					networkId,
+    					neutronNetworkId,
+    					subnetIdMap,
+    					rollback);
+				}
+				response = new CreateNetworkResponse(
+						req.getNetworkId(),
+						neutronNetworkId.value,
+						rollback.value.getNetworkStackId(),
+						networkFqdn.value,
+						rollback.value.getNetworkCreated(),
+						subnetIdMap.value,
+						rollback.value,
+						req.getMessageId());
+			} catch (NetworkException e) {
+				eresp = new CreateNetworkError(
+					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 ("CreateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@DELETE
+	@Path("{aaiNetworkId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response deleteNetwork(
+		@PathParam("aaiNetworkId") String aaiNetworkId,
+		DeleteNetworkRequest req)
+	{
+		LOGGER.debug("deleteNetwork enter: " + req.toJsonString());
+		if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
+				.build();
+		}
+		DeleteNetworkTask task = new DeleteNetworkTask(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_NETWORK_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception while delete network", e);
+				return Response.serverError().build();
+			}
+			// send sync response (ACK) to caller
+			LOGGER.debug ("deleteNetwork exit");
+			return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class DeleteNetworkTask implements Runnable {
+		private final DeleteNetworkRequest req;
+		private DeleteNetworkResponse response = null;
+		private DeleteNetworkError eresp = null;
+		private boolean sendxml;
+
+		public DeleteNetworkTask(DeleteNetworkRequest 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<DeleteNetworkResponse>(response) {}
+				: new GenericEntity<DeleteNetworkError>(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("DeleteNetworkTask start");
+			try {
+				Holder<Boolean> networkDeleted = new Holder<Boolean>();
+				if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
+					networkDeleted.value = true;
+				} else {
+					adapter.deleteNetwork(
+						req.getCloudSiteId(),
+						req.getTenantId(),
+						req.getNetworkType(),
+						req.getNetworkStackId(),
+						req.getMsoRequest(),
+						networkDeleted);
+				}
+				response = new DeleteNetworkResponse(req.getNetworkId(), networkDeleted.value, req.getMessageId());
+			} catch (NetworkException e) {
+				eresp = new DeleteNetworkError(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("DeleteNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@GET
+	@Path("{aaiNetworkId}")
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response queryNetwork(
+		@QueryParam("cloudSiteId") String cloudSiteId,
+		@QueryParam("tenantId") String tenantId,
+		@QueryParam("networkStackId") String networkStackId,
+		@QueryParam("skipAAI") String skipAAI,
+		@QueryParam("msoRequest.requestId") String requestId,
+		@QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId,
+		@PathParam("aaiNetworkId") String aaiNetworkId)
+	{
+		//This request responds synchronously only
+		LOGGER.debug ("Query network enter:" + aaiNetworkId);
+		MsoRequest msoRequest = new MsoRequest(requestId, serviceInstanceId);
+
+		try {
+			int respStatus = HttpStatus.SC_OK;
+			QueryNetworkResponse resp = new QueryNetworkResponse(networkStackId, null, networkStackId, null, null);
+			Holder<Boolean> networkExists = new Holder<Boolean>();
+            Holder<String> networkId = new Holder<String>();
+            Holder<String> neutronNetworkId = new Holder<String>();
+            Holder<NetworkStatus> status = new Holder<NetworkStatus>();
+            Holder<List<String>> routeTargets = new Holder<List<String>>();
+            Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
+
+			adapter.queryNetworkContrail(cloudSiteId,  tenantId, aaiNetworkId,  msoRequest,
+				networkExists, networkId, neutronNetworkId, status, routeTargets, subnetIdMap);
+
+			if (!networkExists.value) {
+				LOGGER.debug ("network not found");
+				respStatus = HttpStatus.SC_NOT_FOUND;
+			} else {
+				LOGGER.debug ("network found" + networkId.value + ", status=" + status.value);
+				resp.setNetworkExists(networkExists.value);
+				resp.setNetworkId(networkId.value);
+				resp.setNeutronNetworkId(neutronNetworkId.value);
+				resp.setNetworkStatus(status.value);
+				resp.setRouteTargets(routeTargets.value);
+				resp.setSubnetIdMap(subnetIdMap.value);
+			}
+			LOGGER.debug ("Query network exit");
+			return Response
+				.status(respStatus)
+				.entity(new GenericEntity<QueryNetworkResponse>(resp) {})
+				.build();
+		} catch (NetworkException e) {
+			LOGGER.error (MessageEnum.RA_QUERY_VNF_ERR, aaiNetworkId, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception when query VNF", e);
+			QueryNetworkError err = new QueryNetworkError();
+			err.setMessage(e.getMessage());
+			err.setCategory(MsoExceptionCategory.INTERNAL);
+			return Response
+				.status(HttpStatus.SC_INTERNAL_SERVER_ERROR)
+				.entity(new GenericEntity<QueryNetworkError>(err) {})
+				.build();
+		}
+	}
+
+	@DELETE
+	@Path("{aaiNetworkId}/rollback")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response rollbackNetwork(
+		RollbackNetworkRequest req)
+	{
+		LOGGER.debug("rollbackNetwork enter: " + req.toJsonString());
+		RollbackNetworkTask task = new RollbackNetworkTask(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_NULL, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in rollbackNetwork", e);
+				return Response.serverError().build();
+			}
+			// send sync response (ACK) to caller
+			LOGGER.debug("rollbackNetwork exit");
+			return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class RollbackNetworkTask implements Runnable {
+		private final RollbackNetworkRequest req;
+		private RollbackNetworkResponse response = null;
+		private RollbackNetworkError eresp = null;
+		private boolean sendxml;
+
+		public RollbackNetworkTask(RollbackNetworkRequest 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<RollbackNetworkResponse>(response) {}
+				: new GenericEntity<RollbackNetworkError>(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("RollbackNetworkTask start");
+			try {
+				NetworkRollback nwr = req.getNetworkRollback();
+				adapter.rollbackNetwork(nwr);
+				response = new RollbackNetworkResponse(true, req.getMessageId());
+			} catch (NetworkException e) {
+				eresp = new RollbackNetworkError(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("RollbackNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	@PUT
+	@Path("{aaiNetworkId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response updateNetwork(
+		@PathParam("aaiNetworkId") String aaiNetworkId,
+		UpdateNetworkRequest req)
+	{
+		LOGGER.debug("updateNetwork enter: " + req.toJsonString());
+		if (aaiNetworkId == null || !aaiNetworkId.equals(req.getNetworkId())) {
+			return Response
+				.status(HttpStatus.SC_BAD_REQUEST)
+				.type(MediaType.TEXT_PLAIN)
+				.entity("A&AI NetworkId in URL ("+aaiNetworkId+") does not match content ("+req.getNetworkId()+")")
+				.build();
+		}
+		UpdateNetworkTask task = new UpdateNetworkTask(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_NETWORK_ERR, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in updateNetwork", e);
+	    		return Response.serverError().build();
+	    	}
+	    	// send sync response (ACK) to caller
+	    	LOGGER.debug ("updateNetwork exit");
+	    	return Response.status(HttpStatus.SC_ACCEPTED).build();
+		}
+	}
+
+	public class UpdateNetworkTask implements Runnable {
+		private final UpdateNetworkRequest req;
+		private UpdateNetworkResponse response = null;
+		private UpdateNetworkError eresp = null;
+		private boolean sendxml;
+
+		public UpdateNetworkTask(UpdateNetworkRequest 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<UpdateNetworkResponse>(response) {}
+				: new GenericEntity<UpdateNetworkError>(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("UpdateNetworkTask start");
+			try {
+				Holder<Map<String, String>> subnetIdMap = new Holder<Map<String, String>>();
+				Holder<NetworkRollback> rollback = new Holder<NetworkRollback> ();
+
+				if (req.getCloudSiteId().equals(TESTING_KEYWORD)) {
+					subnetIdMap.value = testMap();
+			        NetworkRollback rb = new NetworkRollback ();
+			        rb.setCloudId(req.getCloudSiteId());
+			        rb.setTenantId(req.getTenantId());
+			        rb.setMsoRequest(req.getMsoRequest());
+			        rollback.value = rb;
+				} else if (req.isContrailRequest()) {
+					ContrailNetwork ctn = req.getContrailNetwork();
+					if (ctn == null) {
+						ctn = new ContrailNetwork();
+						req.setContrailNetwork(ctn);
+					}
+					adapter.updateNetworkContrail(
+						req.getCloudSiteId(),
+						req.getTenantId(),
+						req.getNetworkType(),
+						req.getNetworkStackId(),
+						req.getNetworkName(),
+						req.getContrailNetwork().getRouteTargets(),
+	                    req.getContrailNetwork().getShared(),
+	                    req.getContrailNetwork().getExternal(),
+	                    req.getSubnets(),
+	                    req.getContrailNetwork().getPolicyFqdns(),
+	                    req.getContrailNetwork().getRouteTableFqdns(),
+	                    req.getMsoRequest(),
+	                    subnetIdMap,
+	                    rollback);
+				} else {
+					ProviderVlanNetwork pvn = req.getProviderVlanNetwork();
+					if (pvn == null) {
+						pvn = new ProviderVlanNetwork();
+						req.setProviderVlanNetwork(pvn);
+					}
+					adapter.updateNetwork(
+						req.getCloudSiteId(),
+						req.getTenantId(),
+						req.getNetworkType(),
+						req.getNetworkStackId(),
+						req.getNetworkName(),
+						req.getProviderVlanNetwork().getPhysicalNetworkName(),
+						req.getProviderVlanNetwork().getVlans(),
+						req.getSubnets(),
+						req.getMsoRequest(),
+						subnetIdMap,
+						rollback);
+				}
+				response = new UpdateNetworkResponse(
+					req.getNetworkId(),
+					null,	// NeutronNetworkId is not available from an update
+					subnetIdMap.value,
+					req.getMessageId());
+			} catch (NetworkException e) {
+				eresp = new UpdateNetworkError(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("UpdateNetworkTask exit: code=" + getStatusCode() + ", resp="+ getResponse());
+		}
+	}
+
+	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-network-adapter/src/main/java/org/openecomp/mso/adapters/network/exceptions/NetworkException.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/exceptions/NetworkException.java
new file mode 100644
index 0000000..0fd4d02
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/exceptions/NetworkException.java
@@ -0,0 +1,81 @@
+/*-
+ * ============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.network.exceptions;
+
+
+
+import javax.xml.ws.WebFault;
+
+import org.openecomp.mso.adapters.network.exceptions.NetworkExceptionBean;
+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 Network related exceptions on create, delete, query.
+ * 
+ *
+ */
+@WebFault (name="NetworkException", faultBean="org.openecomp.mso.adapters.network.exceptions.NetworkExceptionBean", targetNamespace="http://com.att.mso/network")
+public class NetworkException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	private NetworkExceptionBean faultInfo;
+	
+	public NetworkException (String msg) {
+		super(msg);
+		faultInfo = new NetworkExceptionBean (msg);
+	}
+	
+	public NetworkException (Throwable e) {
+		super(e);
+		faultInfo = new NetworkExceptionBean (e.getMessage());
+	}
+	
+	public NetworkException (String msg, Throwable e) {
+		super (msg, e);
+		faultInfo = new NetworkExceptionBean (msg);
+	}
+
+	public NetworkException (String msg, MsoExceptionCategory category) {
+		super(msg);
+		faultInfo = new NetworkExceptionBean (msg, category);
+	}
+	
+	public NetworkException (String msg, MsoExceptionCategory category, Throwable e) {
+		super (msg, e);
+		faultInfo = new NetworkExceptionBean (msg, category);
+	}
+	
+	public NetworkException (MsoException e) {
+		super (e);
+		faultInfo = new NetworkExceptionBean (e.getContextMessage(), e.getCategory());
+	}
+	
+	public NetworkExceptionBean getFaultInfo() {
+		return faultInfo;
+	}
+
+	public void setFaultInfo(NetworkExceptionBean faultInfo) {
+		this.faultInfo = faultInfo;
+	}
+}
diff --git a/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/exceptions/NetworkExceptionBean.java b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/exceptions/NetworkExceptionBean.java
new file mode 100644
index 0000000..af4e0e3
--- /dev/null
+++ b/adapters/mso-network-adapter/src/main/java/org/openecomp/mso/adapters/network/exceptions/NetworkExceptionBean.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.network.exceptions;
+
+
+import java.io.Serializable;
+
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+/**
+ * Jax-WS Fault Bean for Network Exceptions
+ */
+public class NetworkExceptionBean implements Serializable {
+
+    private static final long serialVersionUID = 1655343530371342871L;
+
+    private String message;
+	private MsoExceptionCategory category;
+	private Boolean rolledBack;
+
+	public NetworkExceptionBean () {}
+
+	public NetworkExceptionBean (String message) {
+		this.message = message;
+	}
+
+	public NetworkExceptionBean (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-network-adapter/src/test/java/org/openecomp/mso/adapters/network/NetworkAdapterTest.java b/adapters/mso-network-adapter/src/test/java/org/openecomp/mso/adapters/network/NetworkAdapterTest.java
new file mode 100644
index 0000000..41cc3f5
--- /dev/null
+++ b/adapters/mso-network-adapter/src/test/java/org/openecomp/mso/adapters/network/NetworkAdapterTest.java
@@ -0,0 +1,266 @@
+/*-
+ * ============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.network;
+
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.ws.Holder;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import org.openecomp.mso.adapters.network.exceptions.NetworkException;
+import org.openecomp.mso.db.catalog.CatalogDatabase;
+import org.openecomp.mso.db.catalog.beans.NetworkResource;
+import org.openecomp.mso.entity.MsoRequest;
+import org.openecomp.mso.openstack.beans.NetworkStatus;
+import org.openecomp.mso.openstack.beans.Subnet;
+import org.openecomp.mso.openstack.beans.NetworkRollback;
+
+public class NetworkAdapterTest {
+
+    @Mock
+    private static MsoNetworkAdapterImpl adapter;
+
+    @Mock
+    private static CatalogDatabase db;
+
+    @BeforeClass
+    public static final void prepare () {
+        adapter = Mockito.spy (new MsoNetworkAdapterImpl ());
+        db = Mockito.mock (CatalogDatabase.class);
+        NetworkResource networkResource = new NetworkResource ();
+        networkResource.setNetworkType ("PROVIDER");
+        networkResource.setNeutronNetworkType ("PROVIDER");
+        networkResource.setId (1);
+        networkResource.setOrchestrationMode ("toto");
+        Mockito.when (db.getNetworkResource ("PROVIDER")).thenReturn (networkResource);
+        Mockito.when (adapter.getCatalogDb()).thenReturn (db);
+    }
+
+    @Test
+    public void createTest () {
+
+        List <Integer> vlans = new LinkedList <> ();
+        vlans.add (1);
+        vlans.add (2);
+        List <Subnet> subnets = new LinkedList <> ();
+        subnets.add (new Subnet ());
+        MsoRequest msoRequest = new MsoRequest ();
+        Holder <String> networkId = new Holder <> ();
+        Holder <String> neutronNetworkId = new Holder <> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <> ();
+        Holder <NetworkRollback> rollback = new Holder <> ();
+        try {
+            adapter.createNetwork ("toto",
+                                   "tenant",
+                                   "PROVIDER",
+                                   "networkName",
+                                   "physicalNetworkName",
+                                   vlans,
+                                   Boolean.TRUE,
+                                   Boolean.TRUE,
+                                   subnets,
+                                   msoRequest,
+                                   networkId,
+                                   neutronNetworkId,
+                                   subnetIdMap,
+                                   rollback);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Configuration Error"));
+        }
+    }
+
+    @Test
+    public void createTest2 () {
+        List <Integer> vlans = new LinkedList <> ();
+        vlans.add (1);
+        vlans.add (2);
+        List <Subnet> subnets = new LinkedList <> ();
+        List <String> routeTargets = new LinkedList <> ();
+        subnets.add (new Subnet ());
+        List <String> policyFqdns = new LinkedList <> ();
+        policyFqdns.add("pfqdn1");
+        policyFqdns.add("pfqdn2");
+        List <String> routeTableFqdns = new LinkedList <> ();
+        routeTableFqdns.add("rtfqdn1");
+        routeTableFqdns.add("rtfqdn2");
+        MsoRequest msoRequest = new MsoRequest ();
+        Holder <String> networkId = new Holder <> ();
+        Holder <String> neutronNetworkId = new Holder <> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <> ();
+        Holder <NetworkRollback> rollback = new Holder <> ();
+        Holder <String> networkFqdn= new Holder <> ();
+        try {
+            adapter.createNetworkContrail ("toto",
+                                           "tenant",
+                                           "PROVIDER",
+                                           "networkName",
+                                           routeTargets,
+                                           "shared",
+                                           "external",
+                                           Boolean.TRUE,
+                                           Boolean.TRUE,
+                                           subnets,
+                                           policyFqdns,
+                                           routeTableFqdns,
+                                           msoRequest,
+                                           networkId,
+                                           neutronNetworkId,
+                                           networkFqdn,
+                                           subnetIdMap,
+                                           rollback);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Configuration Error"));
+        }
+    }
+
+    @Test
+    public void updateTest () {
+        List <Integer> vlans = new LinkedList <> ();
+        vlans.add (1);
+        vlans.add (2);
+        List <Subnet> subnets = new LinkedList <> ();
+        subnets.add (new Subnet ());
+        MsoRequest msoRequest = new MsoRequest ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <> ();
+        Holder <NetworkRollback> rollback = new Holder <> ();
+        try {
+            adapter.updateNetwork ("toto",
+                                   "tenant",
+                                   "PROVIDER",
+                                   "networkId",
+                                   "networkName",
+                                   "physicalNetworkName",
+                                   vlans,
+                                   subnets,
+                                   msoRequest,
+                                   subnetIdMap,
+                                   rollback);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Configuration Error"));
+        }
+    }
+
+    @Test
+    public void updateTest2 () {
+        List <Integer> vlans = new LinkedList <> ();
+        vlans.add (1);
+        vlans.add (2);
+        List <Subnet> subnets = new LinkedList <> ();
+        List <String> routeTargets = new LinkedList <> ();
+        subnets.add (new Subnet ());
+        List <String> policyFqdns = new LinkedList <> ();
+        policyFqdns.add("pfqdn1");
+        List <String> routeTableFqdns = new LinkedList <> ();
+        routeTableFqdns.add("rtfqdn1");
+        routeTableFqdns.add("rtfqdn2");
+        MsoRequest msoRequest = new MsoRequest ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <> ();
+        Holder <NetworkRollback> rollback = new Holder <> ();
+        try {
+            adapter.updateNetworkContrail ("toto",
+                                           "tenant",
+                                           "PROVIDER",
+                                           "networkId",
+                                           "networkName",
+                                           routeTargets,
+                                           "shared",
+                                           "external",
+                                           subnets,
+                                           policyFqdns,
+                                           routeTableFqdns,
+                                           msoRequest,
+                                           subnetIdMap,
+                                           rollback);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Configuration Error"));
+        }
+    }
+
+    @Test
+    public void queryTest () {
+        Holder <List <Integer>> vlans = new Holder <> ();
+        Holder <NetworkStatus> status = new Holder <> ();
+        MsoRequest msoRequest = new MsoRequest ();
+        Holder <String> networkId = new Holder <> ();
+        Holder <Boolean> result = new Holder <> ();
+        Holder <String> neutronNetworkId = new Holder <> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <> ();
+        try {
+            adapter.queryNetwork (null,
+                                  "tenant",
+                                  "networkName",
+                                  msoRequest,
+                                  result,
+                                  networkId,
+                                  neutronNetworkId,
+                                  status,
+                                  vlans,
+                                  subnetIdMap);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Missing mandatory parameter"));
+        }
+    }
+
+    @Test
+    public void queryTest2 () {
+        Holder <List <String>> routeTargets = new Holder <> ();
+        Holder <NetworkStatus> status = new Holder <> ();
+        MsoRequest msoRequest = new MsoRequest ();
+        Holder <String> networkId = new Holder <> ();
+        Holder <Boolean> result = new Holder <> ();
+        Holder <String> neutronNetworkId = new Holder <> ();
+        Holder <Map <String, String>> subnetIdMap = new Holder <> ();
+        try {
+            adapter.queryNetworkContrail (null,
+                                          "tenant",
+                                          "networkName",
+                                          msoRequest,
+                                          result,
+                                          networkId,
+                                          neutronNetworkId,
+                                          status,
+                                          routeTargets,
+                                          subnetIdMap);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Missing mandatory parameter"));
+        }
+    }
+
+    @Test
+    public void deleteTest () {
+        Holder <Boolean> networkDeleted = new Holder<> ();
+        MsoRequest msoRequest = new MsoRequest ();
+        try {
+            adapter.deleteNetwork ("toto", "tenant", "PROVIDER", "networkId", msoRequest, networkDeleted);
+        } catch (NetworkException e) {
+            assertTrue (e.getMessage ().contains ("Configuration Error"));
+        }
+    }
+}
diff --git a/adapters/mso-network-adapter/src/test/resources/logback-test.xml b/adapters/mso-network-adapter/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..d2c1719
--- /dev/null
+++ b/adapters/mso-network-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>
