Initial OpenECOMP MSO commit

Change-Id: Ia6a7574859480717402cc2f22534d9973a78fa6d
Signed-off-by: ChrisC <cc697w@intl.att.com>
diff --git a/adapters/mso-tenant-adapter/README.md b/adapters/mso-tenant-adapter/README.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/adapters/mso-tenant-adapter/README.md
diff --git a/adapters/mso-tenant-adapter/WebContent/META-INF/MANIFEST.MF b/adapters/mso-tenant-adapter/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ b/adapters/mso-tenant-adapter/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0

+Class-Path: 

+

diff --git a/adapters/mso-tenant-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector b/adapters/mso-tenant-adapter/WebContent/META-INF/services/com.woorea.openstack.base.client.OpenStackClientConnector
new file mode 100644
index 0000000..1281d32
--- /dev/null
+++ b/adapters/mso-tenant-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-tenant-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml b/adapters/mso-tenant-adapter/WebContent/WEB-INF/jboss-deployment-structure.xml
new file mode 100644
index 0000000..58ddb4a
--- /dev/null
+++ b/adapters/mso-tenant-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-tenant-adapter/WebContent/WEB-INF/jboss-web.xml b/adapters/mso-tenant-adapter/WebContent/WEB-INF/jboss-web.xml
new file mode 100644
index 0000000..5583b34
--- /dev/null
+++ b/adapters/mso-tenant-adapter/WebContent/WEB-INF/jboss-web.xml
@@ -0,0 +1,3 @@
+<jboss-web>

+	<context-root>tenants</context-root>

+</jboss-web>
\ No newline at end of file
diff --git a/adapters/mso-tenant-adapter/WebContent/WEB-INF/web.xml b/adapters/mso-tenant-adapter/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000..9118bba
--- /dev/null
+++ b/adapters/mso-tenant-adapter/WebContent/WEB-INF/web.xml
@@ -0,0 +1,103 @@
+<?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-tenant-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.tenant.xml</param-value>
+  </context-param>
+  <context-param>
+  	<param-name>mso.configuration</param-name>
+  	<param-value>MSO_PROP_TENANT_ADAPTER=mso.tenant.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.logger.MsoLoggingServlet,
+    	org.openecomp.mso.MsoStatusHandler,
+    	org.openecomp.mso.adapters.tenant.HealthCheckHandler,
+    	org.openecomp.mso.adapters.tenant.TenantAdapterRest
+    </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>/admin/*</url-pattern> -->
+    <url-pattern>/rest/*</url-pattern>
+  </servlet-mapping>
+
+    <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>
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>SoapRequests</web-resource-name>
+            <description>Soap Ingress Requests</description>
+            <url-pattern>/TenantAdapter</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/tenants/*</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>
+</web-app>
+
diff --git a/adapters/mso-tenant-adapter/WebContent/check.html b/adapters/mso-tenant-adapter/WebContent/check.html
new file mode 100644
index 0000000..00f37d6
--- /dev/null
+++ b/adapters/mso-tenant-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-tenant-adapter/pom.xml b/adapters/mso-tenant-adapter/pom.xml
new file mode 100644
index 0000000..c649e9e
--- /dev/null
+++ b/adapters/mso-tenant-adapter/pom.xml
@@ -0,0 +1,155 @@
+<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-tenant-adapter</artifactId>
+	<packaging>war</packaging>
+	<name>mso-tenant-adapter</name>
+	<description>Web Service endpoint for Tenant operations</description>
+
+	<build>
+		<finalName>${project.artifactId}-${project.version}</finalName>
+		<plugins>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-resources-plugin</artifactId>
+				<version>2.6</version>
+				<executions>
+					<execution>
+						<id>copy-resources</id>
+						<phase>validate</phase>
+						<goals>
+							<goal>copy-resources</goal>
+						</goals>
+						<configuration>
+							<resources>
+								<resource>
+									<directory>./src/main/resources/META-INF</directory>
+									<filtering>false</filtering>
+								</resource>
+							</resources>
+							<outputDirectory>${project.build.directory}/${project.build.finalName}/META-INF/</outputDirectory>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<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.tenant.MsoTenantAdapterImpl</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>org.openecomp.mso.adapters</groupId>
+			<artifactId>mso-adapter-utils</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.openecomp.mso.adapters</groupId>
+			<artifactId>mso-adapters-rest-interface</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>javax</groupId>
+			<artifactId>javaee-web-api</artifactId>
+			<version>6.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.spec.javax.ejb</groupId>
+			<artifactId>jboss-ejb-api_3.2_spec</artifactId>
+			<version>1.0.0.Final</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jboss.ejb3</groupId>
+			<artifactId>jboss-ejb3-ext-api</artifactId>
+			<version>2.2.0.Final</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.openecomp.mso</groupId>
+			<artifactId>status-control</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/HealthCheckHandler.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/HealthCheckHandler.java
new file mode 100644
index 0000000..7916be2
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/HealthCheckHandler.java
@@ -0,0 +1,59 @@
+/*-
+ * ============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.tenant;
+
+
+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);
+		@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.catalogDBCheck (msoLogger, startTime)) {
+				return HealthCheckUtils.NOT_STARTED_RESPONSE;
+			}
+			msoLogger.debug("healthcheck - Successful");
+			return HealthCheckUtils.HEALTH_CHECK_RESPONSE;
+	    }
+
+}
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/MsoTenantAdapter.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/MsoTenantAdapter.java
new file mode 100644
index 0000000..a86c938
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/MsoTenantAdapter.java
@@ -0,0 +1,77 @@
+/*-
+ * ============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.tenant;
+
+
+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.tenant.exceptions.TenantAlreadyExists;
+import org.openecomp.mso.adapters.tenant.exceptions.TenantException;
+import org.openecomp.mso.adapters.tenantrest.TenantRollback;
+import org.openecomp.mso.entity.MsoRequest;
+
+@WebService (name="TenantAdapter", targetNamespace="http://com.att.mso/tenant")
+public interface MsoTenantAdapter
+{
+	/**
+	 * This is the "Create Tenant" Web Service Endpoint definition.
+	 */
+	@WebMethod
+	public void createTenant (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantName") @XmlElement(required=true) String tenantName,
+							@WebParam(name="metadata") Map<String,String> metadata,
+							@WebParam(name="failIfExists") Boolean failIfExists,
+							@WebParam(name="backout") Boolean backout,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="tenantId", mode=Mode.OUT) Holder<String> tenantId,
+							@WebParam(name="rollback", mode=Mode.OUT) Holder<TenantRollback> rollback )
+		throws TenantException, TenantAlreadyExists;
+	
+	@WebMethod
+	public void queryTenant (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantNameOrId") @XmlElement(required=true) String tenantNameOrId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="tenantId", mode=Mode.OUT) Holder<String> tenantId,
+							@WebParam(name="tenantName", mode=Mode.OUT) Holder<String> tenantName,
+							@WebParam(name="metadata", mode=Mode.OUT) Holder<Map<String,String>> metadata )
+		throws TenantException;
+	
+	@WebMethod
+	public void deleteTenant (@WebParam(name="cloudSiteId") @XmlElement(required=true) String cloudSiteId,
+							@WebParam(name="tenantId") @XmlElement(required=true) String tenantId,
+							@WebParam(name="request") MsoRequest msoRequest,
+							@WebParam(name="tenantDeleted", mode=Mode.OUT) Holder<Boolean> tenantDeleted)
+		throws TenantException;
+	
+	@WebMethod
+	public void rollbackTenant (@WebParam(name="rollback") @XmlElement(required=true) TenantRollback rollback)
+		throws TenantException;
+	
+	@WebMethod
+	public void healthCheck ();
+}
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/MsoTenantAdapterImpl.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/MsoTenantAdapterImpl.java
new file mode 100644
index 0000000..040c682
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/MsoTenantAdapterImpl.java
@@ -0,0 +1,279 @@
+/*-
+ * ============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.tenant;
+
+
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.jws.WebService;
+import javax.xml.ws.Holder;
+import javax.xml.ws.WebServiceContext;
+
+import org.openecomp.mso.properties.MsoPropertiesFactory;
+import org.openecomp.mso.adapters.tenant.exceptions.TenantAlreadyExists;
+import org.openecomp.mso.adapters.tenant.exceptions.TenantException;
+import org.openecomp.mso.adapters.tenantrest.TenantRollback;
+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.MsoTenant;
+import org.openecomp.mso.openstack.exceptions.MsoException;
+import org.openecomp.mso.openstack.utils.MsoTenantUtils;
+import org.openecomp.mso.openstack.utils.MsoTenantUtilsFactory;
+
+@WebService(serviceName = "TenantAdapter", endpointInterface = "org.openecomp.mso.adapters.tenant.MsoTenantAdapter", targetNamespace = "http://com.att.mso/tenant")
+public class MsoTenantAdapterImpl implements MsoTenantAdapter {
+
+	MsoPropertiesFactory msoPropertiesFactory = new MsoPropertiesFactory();
+	MsoTenantUtilsFactory tFactory = new MsoTenantUtilsFactory(MSO_PROP_TENANT_ADAPTER);
+	
+	public static final String MSO_PROP_TENANT_ADAPTER="MSO_PROP_TENANT_ADAPTER";
+	
+    @Resource
+    WebServiceContext wsContext;
+
+    private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+    /**
+     * Health Check web method. Does nothing but return to show the adapter is deployed.
+     */
+    @Override
+    public void healthCheck () {
+        LOGGER.debug ("Health check call in Tenant Adapter");
+    }
+
+    /**
+     * This is the "Create Tenant" web service implementation. It will create
+     * a new Tenant in the specified cloud. If the tenant already exists, this
+     * can be considered a success or failure, depending on the value of the
+     * 'failIfExists' parameter.
+     *
+     * The method returns the tenantId (the Openstack ID), and a TenantRollback
+     * object. This last object can be passed as-is to the rollbackTenant method
+     * to undo what (if anything) was created. This is useful if a Tenant is
+     * successfully created but the orchestrator fails on a subsequent operation.
+     */
+    @Override
+    public void createTenant (String cloudSiteId,
+                              String tenantName,
+                              Map <String, String> metadata,
+                              Boolean failIfExists,
+                              Boolean backout,
+                              MsoRequest msoRequest,
+                              Holder <String> tenantId,
+                              Holder <TenantRollback> rollback) throws TenantException, TenantAlreadyExists {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("CreateTenant");
+
+        LOGGER.debug ("Call to MSO createTenant adapter. Creating Tenant: " + tenantName
+                                      + "in "
+                                      + cloudSiteId);
+
+        // Will capture total time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Start building up rollback object
+        TenantRollback tenantRollback = new TenantRollback ();
+        tenantRollback.setCloudId (cloudSiteId);
+        tenantRollback.setMsoRequest (msoRequest);
+        
+        MsoTenantUtils tUtils = tFactory.getTenantUtils (cloudSiteId);
+
+        MsoTenant newTenant = null;
+        String newTenantId = null;
+        long queryTenantStartTime = System.currentTimeMillis ();
+        try {
+            newTenant = tUtils.queryTenantByName (tenantName, cloudSiteId);
+            LOGGER.recordMetricEvent (queryTenantStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryTenant", null);
+        } catch (MsoException me) {
+            LOGGER.recordMetricEvent (queryTenantStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with Open Stack", "OpenStack", "QueryTenant", null);
+            String error = "Create Tenant " + tenantName + ": " + me;
+            LOGGER.error (MessageEnum.RA_CREATE_TENANT_ERR, me.getMessage(), "OpenStack", "createTenant", MsoLogger.ErrorCode.DataError, "Exception while communicate with Open Stack", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new TenantException (me);
+        }
+        if (newTenant == null) {
+            if (backout == null)
+                backout = true;
+            long createTenantStartTime = System.currentTimeMillis ();
+            try {
+                newTenantId = tUtils.createTenant (tenantName, cloudSiteId, metadata, backout.booleanValue ());
+                LOGGER.recordMetricEvent (createTenantStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "CreateTenant", null);
+            } catch (MsoException me) {
+                LOGGER.recordMetricEvent (createTenantStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, "Exception while communicate with Open Stack", "OpenStack", "CreateTenant", null);
+                String error = "Create Tenant " + tenantName + ": " + me;
+                LOGGER.error (MessageEnum.RA_CREATE_TENANT_ERR, me.getMessage(), "OpenStack", "createTenant", MsoLogger.ErrorCode.DataError, "Exception while communicate with Open Stack", me);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                throw new TenantException (me);
+            }
+            tenantRollback.setTenantId (newTenantId);
+            tenantRollback.setTenantCreated (true);
+            LOGGER.debug ("Tenant " + tenantName + " successfully created with ID " + newTenantId);
+        } else {
+            if (failIfExists != null && failIfExists) {
+                String error = "CreateTenant: Tenant " + tenantName + " already exists in " + cloudSiteId;
+                LOGGER.error (MessageEnum.RA_TENANT_ALREADY_EXIST, tenantName, cloudSiteId, "OpenStack", "", MsoLogger.ErrorCode.DataError, "CreateTenant, Tenant already exists");
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.DataError, error);
+                throw new TenantAlreadyExists (tenantName, cloudSiteId, newTenant.getTenantId ());
+            }
+
+            newTenantId = newTenant.getTenantId ();
+            tenantRollback.setTenantCreated (false);
+            LOGGER.debug ("Tenant " + tenantName + " already exists with ID " + newTenantId);
+        }
+
+
+        tenantId.value = newTenantId;
+        rollback.value = tenantRollback;
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully create tenant");
+        return;
+    }
+
+    @Override
+    public void queryTenant (String cloudSiteId,
+                             String tenantNameOrId,
+                             MsoRequest msoRequest,
+                             Holder <String> tenantId,
+                             Holder <String> tenantName,
+                             Holder <Map <String, String>> metadata) throws TenantException {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("QueryTenant");
+        LOGGER.debug ("Querying Tenant " + tenantNameOrId + " in " + cloudSiteId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        MsoTenantUtils tUtils = tFactory.getTenantUtils (cloudSiteId);
+        
+        MsoTenant qTenant = null;
+        long subStartTime = System.currentTimeMillis ();
+        try {
+            qTenant = tUtils.queryTenant (tenantNameOrId, cloudSiteId);
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully received response from Open Stack", "OpenStack", "QueryTenant", null);
+            if (qTenant == null) {
+                // Not found by ID, Try by name.
+                qTenant = tUtils.queryTenantByName (tenantNameOrId, cloudSiteId);
+            }
+
+            if (qTenant == null) {
+                LOGGER.debug ("QueryTenant: Tenant " + tenantNameOrId + " not found");
+                tenantId.value = null;
+                tenantName.value = null;
+                metadata.value = null;
+            } else {
+                LOGGER.debug ("QueryTenant: Tenant " + tenantNameOrId + " found with ID " + qTenant.getTenantId ());
+                tenantId.value = qTenant.getTenantId ();
+                tenantName.value = qTenant.getTenantName ();
+                metadata.value = qTenant.getMetadata ();
+            }
+        } catch (MsoException me) {
+            String error = "Query Tenant " + tenantNameOrId + ": " + me;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "QueryTenant", null);
+            LOGGER.error (MessageEnum.RA_GENERAL_EXCEPTION, me.getMessage(), "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception in queryTenant", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new TenantException (me);
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully query tenant");
+        return;
+    }
+
+    @Override
+    public void deleteTenant (String cloudSiteId,
+                              String tenantId,
+                              MsoRequest msoRequest,
+                              Holder <Boolean> tenantDeleted) throws TenantException {
+        MsoLogger.setLogContext (msoRequest);
+        MsoLogger.setServiceName ("DeleteTenant");
+
+        LOGGER.debug ("Deleting Tenant " + tenantId + " in " + cloudSiteId);
+
+        // Will capture execution time for metrics
+        long startTime = System.currentTimeMillis ();
+
+        // Delete the Tenant.
+        long subStartTime = System.currentTimeMillis ();
+        try {
+        	
+        	MsoTenantUtils tUtils = tFactory.getTenantUtils (cloudSiteId);
+            boolean deleted = tUtils.deleteTenant (tenantId, cloudSiteId);
+            tenantDeleted.value = deleted;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully communicate with Open Stack", "OpenStack", "DeleteTenant", null);
+        } catch (MsoException me) {
+            String error = "Delete Tenant " + tenantId + ": " + me;
+            LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "DeleteTenant", null);
+            LOGGER.error (MessageEnum.RA_DELETE_TEMAMT_ERR, me.getMessage(), "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception - DeleteTenant", me);
+            LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+            throw new TenantException (me);
+        }
+
+        // On success, nothing is returned.
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully delete tenant");
+        return;
+    }
+
+    /**
+     * This web service endpoint will rollback a previous Create VNF operation.
+     * A rollback object is returned to the client in a successful creation
+     * response. The client can pass that object as-is back to the rollbackVnf
+     * operation to undo the creation.
+     *
+     * The rollback includes removing the VNF and deleting the tenant if the
+     * tenant did not exist prior to the VNF creation.
+     */
+    @Override
+    public void rollbackTenant (TenantRollback rollback) throws TenantException {
+        long startTime = System.currentTimeMillis ();
+        MsoLogger.setServiceName ("RollbackTenant");
+        // rollback may be null (e.g. if stack already existed when Create was called)
+        if (rollback == null) {
+            LOGGER.warn (MessageEnum.RA_ROLLBACK_NULL, "OpenStack", "rollbackTenant", MsoLogger.ErrorCode.DataError, "rollbackTenant, rollback is null");
+            return;
+        }
+
+        // Get the elements of the VnfRollback object for easier access
+        String cloudSiteId = rollback.getCloudId ();
+        String tenantId = rollback.getTenantId ();
+
+        MsoLogger.setLogContext (rollback.getMsoRequest ());
+        LOGGER.debug ("Rolling Back Tenant " + rollback.getTenantId () + " in " + cloudSiteId);
+
+        long subStartTime = System.currentTimeMillis ();
+        if (rollback.getTenantCreated ()) {
+            try {
+            	 
+            	MsoTenantUtils tUtils = tFactory.getTenantUtils (cloudSiteId);
+                tUtils.deleteTenant (tenantId, cloudSiteId);
+                LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully communicate with Open Stack", "OpenStack", "RollbackTenant", null);
+            } catch (MsoException me) {
+                me.addContext ("RollbackTenant");
+                // Failed to delete the tenant.
+                String error = "Rollback Tenant " + tenantId + ": " + me;
+                LOGGER.recordMetricEvent (subStartTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error, "OpenStack", "RollbackTenant", null);
+                LOGGER.error (MessageEnum.RA_ROLLBACK_TENANT_ERR, me.getMessage(), "OpenStack", "rollbackTenant", MsoLogger.ErrorCode.DataError, "Exception - rollbackTenant", me);
+                LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.ERROR, MsoLogger.ResponseCode.CommunicationError, error);
+                throw new TenantException (me);
+            }
+        }
+        LOGGER.recordAuditEvent (startTime, MsoLogger.StatusCode.COMPLETE, MsoLogger.ResponseCode.Suc, "Successfully roll back tenant");
+        return;
+    }
+}
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/TenantAdapterRest.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/TenantAdapterRest.java
new file mode 100644
index 0000000..0c9993c
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/TenantAdapterRest.java
@@ -0,0 +1,297 @@
+/*-
+ * ============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.tenant;
+
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.adapters.tenant.exceptions.TenantAlreadyExists;
+import org.openecomp.mso.adapters.tenant.exceptions.TenantException;
+import org.openecomp.mso.adapters.tenantrest.CreateTenantError;
+import org.openecomp.mso.adapters.tenantrest.CreateTenantRequest;
+import org.openecomp.mso.adapters.tenantrest.CreateTenantResponse;
+import org.openecomp.mso.adapters.tenantrest.DeleteTenantError;
+import org.openecomp.mso.adapters.tenantrest.DeleteTenantRequest;
+import org.openecomp.mso.adapters.tenantrest.DeleteTenantResponse;
+import org.openecomp.mso.adapters.tenantrest.QueryTenantError;
+import org.openecomp.mso.adapters.tenantrest.QueryTenantResponse;
+import org.openecomp.mso.adapters.tenantrest.RollbackTenantError;
+import org.openecomp.mso.adapters.tenantrest.RollbackTenantRequest;
+import org.openecomp.mso.adapters.tenantrest.RollbackTenantResponse;
+import org.openecomp.mso.adapters.tenantrest.TenantRollback;
+import org.openecomp.mso.logger.MsoLogger;
+import org.openecomp.mso.openstack.beans.MsoTenant;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+/**
+ * This class services calls to the REST interface for Tenants (http://host:port/vnfs/rest/v1/tenants)
+ * Both XML and JSON can be produced/consumed.  Set Accept: and Content-Type: headers appropriately.  XML is the default.
+ */
+@Path("/v1/tenants")
+public class TenantAdapterRest {
+	private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA);
+
+	//RAA? No logging in wrappers
+
+	@HEAD
+	@GET
+	@Path("/healthcheck")
+	@Produces(MediaType.TEXT_HTML)
+	public Response healthcheck () {
+		String CHECK_HTML = "<!DOCTYPE html><html><head><meta charset=\"ISO-8859-1\"><title>Health Check</title></head><body>Application ready</body></html>";
+		return Response.status (HttpServletResponse.SC_OK).entity (CHECK_HTML).build ();
+	}
+
+	/*
+	URL:
+	EP: http://host:8080/tenants/rest
+	Resource: v1/tenants
+	REQ - metadata?
+	{
+	"cloudSiteId": "DAN",
+	"tenantName": "RAA_1",
+	"failIfExists": true,
+	"msoRequest": {
+	"requestId": "ra1",
+	"serviceInstanceId": "sa1"
+	}}
+	RESP-
+	{
+   "cloudSiteId": "DAN",
+   "tenantId": "128e10b9996d43a7874f19bbc4eb6749",
+   "tenantCreated": true,
+   "tenantRollback":    {
+      "tenantId": "128e10b9996d43a7874f19bbc4eb6749",
+      "cloudId": "DAN", // RAA? cloudId instead of cloudSiteId
+      "tenantCreated": true,
+      "msoRequest":       {
+         "requestId": "ra1",
+         "serviceInstanceId": "sa1"
+      }
+   	 }
+	}
+	*/
+	@POST
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response createTenant(CreateTenantRequest req) {
+		LOGGER.debug("createTenant enter: " + req.toJsonString());
+
+		String newTenantId = null;
+		TenantRollback tenantRollback = new TenantRollback ();
+
+		try {
+			Holder<String> htenant = new Holder<String>();
+			Holder<TenantRollback> hrollback = new Holder<TenantRollback>();
+			MsoTenantAdapter impl = new MsoTenantAdapterImpl();
+		    impl.createTenant(
+		    	req.getCloudSiteId(),
+		    	req.getTenantName(),
+		    	req.getMetadata(),
+		    	req.getFailIfExists(),
+                req.getBackout(),
+                req.getMsoRequest(),
+                htenant,
+                hrollback);
+		    newTenantId = htenant.value;
+		    tenantRollback = hrollback.value;
+//			TenantAdapterCore TAImpl = new TenantAdapterCore();
+//			newTenantId =  TAImpl.createTenant (req.getCloudSiteId(),
+//												req.getTenantName(),
+//												req.getFailIfExists(),
+//												req.getBackout(),
+//												req.getMetadata(),
+//												req.getMsoRequest(),
+//												tenantRollback);
+		}
+		catch (TenantAlreadyExists tae) {
+			CreateTenantError exc = new CreateTenantError(tae.getMessage(), tae.getFaultInfo().getCategory(), Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_NOT_IMPLEMENTED).entity(exc).build();
+		}
+		catch (TenantException te) {
+			CreateTenantError exc = new CreateTenantError(te.getFaultInfo().getMessage(), te.getFaultInfo().getCategory(), Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+		catch (Exception e) {
+			CreateTenantError exc = new CreateTenantError(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+
+		CreateTenantResponse resp = new CreateTenantResponse (req.getCloudSiteId(), newTenantId, tenantRollback.getTenantCreated(), tenantRollback);
+		return Response.status(HttpServletResponse.SC_OK).entity(resp).build();
+	}
+
+	/*
+	URL:
+	http://host:8080/tenants/rest
+	Resource: v1/tenant/tennatId
+	REQ:
+	{"cloudSiteId": "DAN",
+	"tenantId": "ca84cd3d3df44272845da554656b3ace",
+	"msoRequest": {
+	"requestId": "ra1",
+	"serviceInstanceId": "sa1"
+	}
+	}
+	RESP:
+	{"tenantDeleted": true}
+	 */
+	@DELETE
+	@Path("{tenantId}")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response deleteTenant(
+		@PathParam("tenantId") String tenantId,
+		DeleteTenantRequest req)
+	{
+		boolean tenantDeleted = false;
+
+		try {
+			Holder<Boolean> deleted = new Holder<Boolean>();
+			MsoTenantAdapter impl = new MsoTenantAdapterImpl();
+		    impl.deleteTenant(
+		    	req.getCloudSiteId(),
+		    	req.getTenantId(),
+		    	req.getMsoRequest(),
+		    	deleted);
+		    tenantDeleted = deleted.value;
+		}
+		catch (TenantException te) {
+			DeleteTenantError exc = new DeleteTenantError(te.getFaultInfo().getMessage(), te.getFaultInfo().getCategory(), Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+		catch (Exception e) {
+			DeleteTenantError exc = new DeleteTenantError(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+		DeleteTenantResponse resp = new DeleteTenantResponse();
+		resp.setTenantDeleted(tenantDeleted);
+		return Response.status(HttpServletResponse.SC_OK).entity(resp).build();
+	}
+
+	/*
+	URL
+	EP://http://host:8080/tenants/rest
+	Resource: /v1/tenants
+	Params:?tenantNameOrId=RAA_1&cloudSiteId=DAN
+	RESP
+	{
+		   "tenantId": "214b428a1f554c02935e66330f6a5409",
+		   "tenantName": "RAA_1",
+		   "metadata": {}
+	}
+	*/
+	@GET
+	@Path("{tenantId}")
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response queryTenant(
+			@PathParam("tenantId") String tenantId,
+//			@QueryParam("tenantNameOrId") String tenantNameOrId, //RAA? diff from doc
+			@QueryParam("cloudSiteId") String cloudSiteId,
+			@QueryParam("msoRequest.requestId") String requestId,
+			@QueryParam("msoRequest.serviceInstanceId") String serviceInstanceId)
+	{
+		MsoTenant tenant = null;
+		try {
+			Holder<String> htenant = new Holder<String>();
+			Holder<String> tenantName = new Holder<String>();
+			Holder<Map<String,String>> metadata = new Holder<Map<String,String>>();
+			MsoTenantAdapter impl = new MsoTenantAdapterImpl();
+		    impl.queryTenant(
+		    	cloudSiteId,
+		    	tenantId,
+		    	null,
+		    	htenant,
+		    	tenantName,
+		    	metadata
+		    	);
+		    tenant = new MsoTenant(htenant.value, tenantName.value, metadata.value);
+//			TenantAdapterCore TAImpl = new TenantAdapterCore();
+//			MsoRequest msoReq = new MsoRequest();
+//			tenant = TAImpl.queryTenant (cloudSiteId, tenantId, msoReq);
+		}
+		catch (TenantException te) {
+			QueryTenantError exc = new QueryTenantError(te.getFaultInfo().getMessage(), te.getFaultInfo().getCategory());
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+		catch (Exception e) {
+			QueryTenantError exc = new QueryTenantError(e.getMessage(), MsoExceptionCategory.INTERNAL);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+		QueryTenantResponse resp = new QueryTenantResponse(tenant.getTenantId(), tenant.getTenantName(), tenant.getMetadata());
+		return Response.status(HttpServletResponse.SC_OK).entity(resp).build();
+	}
+
+	/*
+	URL
+	EP: //http://host:8080/tenants/rest
+	Resource: /v1/tenants/rollback
+	REQ
+	{"cloudSiteId": "DAN",
+	"tenantId": "f58abb05041d4ff384d4d22d1ccd2a6c",
+	"msoRequest": {
+	"requestId": "ra1",
+	"serviceInstanceId": "sa1"
+	}
+	}
+	RESP:
+	{"tenantDeleted": true}
+	 */
+	@DELETE
+	@Path("")
+	@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+	public Response rollbackTenant(
+		@QueryParam("rollback") String action, // WTF?
+		RollbackTenantRequest req)
+	{
+		try {
+			MsoTenantAdapter impl = new MsoTenantAdapterImpl();
+		    impl.rollbackTenant(req.getTenantRollback());
+		}
+		catch (TenantException te) {
+			RollbackTenantError exc = new RollbackTenantError(te.getFaultInfo().getMessage(), te.getFaultInfo().getCategory(), Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+		catch (Exception e) {
+			RollbackTenantError exc = new RollbackTenantError(e.getMessage(), MsoExceptionCategory.INTERNAL, Boolean.TRUE);
+			return Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR).entity(exc).build();
+		}
+
+		RollbackTenantResponse resp = new RollbackTenantResponse ();
+		resp.setTenantRolledback(req != null);
+		return Response.status(HttpServletResponse.SC_OK).entity(resp).build();
+	}
+}
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantAlreadyExists.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantAlreadyExists.java
new file mode 100644
index 0000000..cc80b94
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantAlreadyExists.java
@@ -0,0 +1,45 @@
+/*-
+ * ============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.tenant.exceptions;
+
+
+
+import javax.xml.ws.WebFault;
+
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+
+/**
+ * This class reports an exception when trying to create a VNF when another
+ * VNF of the same name already exists in the target cloud/tenant.  Note that
+ * the createVnf method suppresses this exception by default.
+ * 
+ *
+ */
+@WebFault (name="TenantAlreadyExists", faultBean="org.openecomp.mso.adapters.tenant.exceptions.TenantExceptionBean", targetNamespace="http://com.att.mso/tenant")
+public class TenantAlreadyExists extends TenantException {
+
+	private static final long serialVersionUID = 1L;
+
+	public TenantAlreadyExists (String name, String cloudId, String tenantId) {
+		super("Tenant " + name + " already exists in " + cloudId + " with ID " + tenantId, MsoExceptionCategory.USERDATA);
+	}
+}
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantException.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantException.java
new file mode 100644
index 0000000..f68b0fa
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantException.java
@@ -0,0 +1,76 @@
+/*-
+ * ============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.tenant.exceptions;
+
+
+
+import javax.xml.ws.WebFault;
+
+import org.openecomp.mso.adapters.tenant.exceptions.TenantExceptionBean;
+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 Tenant related exceptions on create, delete, query.
+ * 
+ *
+ */
+@WebFault (name="TenantException", faultBean="org.openecomp.mso.adapters.tenant.exceptions.TenantExceptionBean", targetNamespace="http://com.att.mso/tenant")
+public class TenantException extends Exception {
+
+	private static final long serialVersionUID = 1L;
+
+	private TenantExceptionBean faultInfo;
+	
+	public TenantException (String msg) {
+		super(msg);
+		faultInfo = new TenantExceptionBean (msg);
+	}
+	
+	public TenantException (String msg, Throwable e) {
+		super (msg, e);
+		faultInfo = new TenantExceptionBean (msg);
+	}
+
+	public TenantException (String msg, MsoExceptionCategory category) {
+		super(msg);
+		faultInfo = new TenantExceptionBean (msg, category);
+	}
+	
+	public TenantException (String msg, MsoExceptionCategory category, Throwable e) {
+		super (msg, e);
+		faultInfo = new TenantExceptionBean (msg, category);
+	}
+	
+	public TenantException (MsoException e) {
+		super (e);
+		faultInfo = new TenantExceptionBean (e.getContextMessage(), e.getCategory());
+	}
+
+	public TenantExceptionBean getFaultInfo() {
+		return faultInfo;
+	}
+
+	public void setFaultInfo(TenantExceptionBean faultInfo) {
+		this.faultInfo = faultInfo;
+	}
+}
diff --git a/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantExceptionBean.java b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantExceptionBean.java
new file mode 100644
index 0000000..61c8f33
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/main/java/org/openecomp/mso/adapters/tenant/exceptions/TenantExceptionBean.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.mso.adapters.tenant.exceptions;
+
+
+import java.io.Serializable;
+
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+/**
+ * Jax-WS Fault Bean for Network Exceptions
+ */
+public class TenantExceptionBean implements Serializable {
+
+    private static final long serialVersionUID = -9062290006520066109L;
+
+    private String message;
+	private MsoExceptionCategory category;
+
+	public TenantExceptionBean () {}
+
+	public TenantExceptionBean (String message) {
+		this.message = message;
+	}
+
+	public TenantExceptionBean (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;
+	}
+}
diff --git a/adapters/mso-tenant-adapter/src/test/java/org/openecomp/mso/adapters/tenant/test/TenantTest.java b/adapters/mso-tenant-adapter/src/test/java/org/openecomp/mso/adapters/tenant/test/TenantTest.java
new file mode 100644
index 0000000..dac0e6e
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/test/java/org/openecomp/mso/adapters/tenant/test/TenantTest.java
@@ -0,0 +1,132 @@
+/*-
+ * ============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.tenant.test;
+
+
+
+import java.util.Map;
+
+import javax.xml.ws.Holder;
+
+import org.openecomp.mso.adapters.tenant.MsoTenantAdapter;
+import org.openecomp.mso.adapters.tenant.MsoTenantAdapterImpl;
+import org.openecomp.mso.adapters.tenant.exceptions.TenantException;
+import org.openecomp.mso.adapters.tenantrest.TenantRollback;
+
+public class TenantTest {
+	public static final void main (String args[])
+	{
+		String cloudId = "MT";
+		 cloudId = "AIC_GAMMALAB";
+		
+		MsoTenantAdapter tenantAdapter = new MsoTenantAdapterImpl();
+		
+		Holder<String> tenantId = new Holder<String>();
+		Holder<String> tenantName = new Holder<String>();
+		Holder<Map<String,String>> tenantMetadata = new Holder<Map<String,String>>();
+		Holder<Boolean> tenantDeleted = new Holder<Boolean>();
+		Holder<TenantRollback> rollback = new Holder<TenantRollback>();
+		
+		try {
+			tenantAdapter.queryTenant (cloudId, "934a4ac9c4bd4b8d9d8ab3ef900281b0", null, tenantId, tenantName, tenantMetadata);
+			System.out.println ("Got Tenant ID=" + tenantId.value + ", name=" + tenantName.value + ", metadata = " + tenantMetadata.value);
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception: " + e);
+			System.exit(1);
+		}
+/*		
+		Map<String,String> metadata = new HashMap<String,String>();
+		metadata.put("sdn-global-id", "abc");
+		metadata.put("service-type", "gamma");
+		
+		// Create a new tenant
+		try {
+			tenantAdapter.createTenant(cloudId, "TEST_META6", metadata, true, tenantId, rollback);
+			System.out.println ("Created Tenant ID " + tenantId.value);
+		}
+		catch (TenantAlreadyExists e) {
+			System.out.println ("Create: Tenant already exists: " + "TEST_META6");
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception on Create: " + e);
+			System.exit(1);
+		}
+		
+		// Query the new tenant
+		try {
+			tenantAdapter.queryTenant (cloudId, "TEST_META6", tenantId, tenantName, tenantMetadata);
+			System.out.println ("Queried Tenant ID=" + tenantId.value + ", name=" + tenantName.value + ", metadata = " + tenantMetadata.value);
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception on Query: " + e);
+			System.exit(1);
+		}
+		
+		try {
+			Thread.sleep(10000);
+		} catch (InterruptedException e1) {}
+		
+		// Delete the new tenant
+		try {
+			tenantAdapter.deleteTenant (cloudId, tenantId.value, tenantDeleted);
+			if (tenantDeleted.value)
+				System.out.println ("Deleted Tenant " + tenantId.value);
+			else
+				System.out.println ("Delete: Tenant " + tenantId.value + " does not exist");
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception on Delete: " + e);
+		}
+/*
+		// Create another new tenant
+		try {
+			tenantAdapter.createTenant(cloudId, "TEST_MSO2", null, false, tenantId, rollback);
+			System.out.println ("Created Tenant ID " + tenantId.value);
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception on Create: " + e);
+		}
+		
+		// Query the new tenant
+		try {
+			tenantAdapter.queryTenant (cloudId, "TEST_MSO2", tenantId, tenantName);
+			System.out.println ("Queried Tenant ID=" + tenantId.value + ", name=" + tenantName.value);
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception on Query: " + e);
+		}
+		
+		try {
+			Thread.sleep(10000);
+		} catch (InterruptedException e1) {}
+
+		// Rollback the new tenant
+		try {
+			tenantAdapter.rollbackTenant(rollback.value);
+			System.out.println ("Rolled Back Tenant ID " + tenantId.value);
+		}
+		catch (TenantException e) {
+			System.out.println ("Got Tenant Exception on Rollback: " + e);
+		}
+*/
+	}
+}
diff --git a/adapters/mso-tenant-adapter/src/test/resources/logback-test.xml b/adapters/mso-tenant-adapter/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..a23395f
--- /dev/null
+++ b/adapters/mso-tenant-adapter/src/test/resources/logback-test.xml
@@ -0,0 +1,47 @@
+<!--
+  ============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>