[ONOS-2158]The implementation of TenantNetwork.

Change-Id: I13715bcc7687bffe878eb6f4c5f7ec1b2489e944
diff --git a/apps/pom.xml b/apps/pom.xml
index 1191205..b95d144 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -55,6 +55,7 @@
         <module>flowanalyzer</module>
         <module>vtnrsc</module>
         <module>vtn</module>
+        <module>vtnweb</module>
     </modules>
 
     <properties>
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultTenantNetwork.java b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultTenantNetwork.java
new file mode 100644
index 0000000..f287def
--- /dev/null
+++ b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultTenantNetwork.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.app.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Default implementation of  TenantNetwork interface.
+ */
+public final class DefaultTenantNetwork implements TenantNetwork {
+    private final TenantNetworkId id;
+    private final String name;
+    private final boolean adminStateUp;
+    private final State state;
+    private final boolean shared;
+    private final Type type;
+    private final TenantId tenantId;
+    private final boolean routerExternal;
+    private final PhysicalNetwork physicalNetwork;
+    private final SegmentationId segmentationId;
+
+    /**
+     * Creates a neutronNetwork element attributed to the specified provider.
+     *
+     * @param id  network identifier
+     * @param name the network name
+     * @param adminStateUp administrative state of the network
+     * @param state the network state
+     * @param shared indicates whether this network is shared across all
+     *            tenants, By default, only administrative user can change this
+     *            value
+     * @param tenantId tenant identifier
+     * @param routerExternal network routerExternal
+     * @param type the network type
+     * @param physicalNetwork physicalNetwork identifier
+     * @param segmentationId segmentation identifier
+     */
+    public DefaultTenantNetwork(TenantNetworkId id, String name,
+                                boolean adminStateUp, State state,
+                                boolean shared, TenantId tenantId,
+                                boolean routerExternal, Type type,
+                                PhysicalNetwork physicalNetwork,
+                                SegmentationId segmentationId) {
+        this.id = id;
+        this.name = name;
+        this.adminStateUp = adminStateUp;
+        this.state = state;
+        this.shared = shared;
+        this.type = type;
+        this.tenantId = tenantId;
+        this.routerExternal = routerExternal;
+        this.physicalNetwork = physicalNetwork;
+        this.segmentationId = segmentationId;
+    }
+
+    @Override
+    public TenantNetworkId id() {
+        return id;
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public boolean adminStateUp() {
+        return adminStateUp;
+    }
+
+    @Override
+    public State state() {
+        return state;
+    }
+
+    @Override
+    public boolean shared() {
+        return shared;
+    }
+
+    @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public boolean routerExternal() {
+        return routerExternal;
+    }
+
+    @Override
+    public Type type() {
+        return type;
+    }
+
+    @Override
+    public PhysicalNetwork physicalNetwork() {
+        return physicalNetwork;
+    }
+
+    @Override
+    public SegmentationId segmentationId() {
+        return segmentationId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name, adminStateUp, state, shared, tenantId,
+                            routerExternal, type, physicalNetwork,
+                            segmentationId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultTenantNetwork) {
+            final DefaultTenantNetwork that = (DefaultTenantNetwork) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.name, that.name)
+                    && Objects.equals(this.adminStateUp, that.adminStateUp)
+                    && Objects.equals(this.state, that.state)
+                    && Objects.equals(this.shared, that.shared)
+                    && Objects.equals(this.tenantId, that.tenantId)
+                    && Objects.equals(this.routerExternal, that.routerExternal)
+                    && Objects.equals(this.type, that.type)
+                    && Objects.equals(this.physicalNetwork,
+                                      that.physicalNetwork)
+                    && Objects.equals(this.segmentationId, that.segmentationId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("name", name)
+                .add("adminStateUp", adminStateUp).add("state", state)
+                .add("shared", shared).add("tenantId", tenantId)
+                .add("routeExternal", routerExternal).add("type", type)
+                .add("physicalNetwork", physicalNetwork)
+                .add("segmentationId", segmentationId).toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java
index ec3ac32..96969a0 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java
@@ -20,39 +20,40 @@
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
- * Immutable representation of a Segmentation identity.
+ * Immutable representation of a Segmentation identifier.
  */
 public final class SegmentationId {
 
-    private final String segmentationid;
+    private final String segmentationId;
 
     // Public construction is prohibited
-    private SegmentationId(String segmentationid) {
-        checkNotNull(segmentationid, "Segmentationid cannot be null");
-        this.segmentationid = segmentationid;
+    private SegmentationId(String segmentationId) {
+        checkNotNull(segmentationId, "SegmentationId cannot be null");
+        this.segmentationId = segmentationId;
     }
 
     /**
-     * Creates a network id using the segmentationid.
+     * Creates a  SegmentationId object.
      *
-     * @param segmentationid network String
+     * @param segmentationId segmentation identifier
      * @return SegmentationId
      */
-    public static SegmentationId segmentationID(String segmentationid) {
-        return new SegmentationId(segmentationid);
+    public static SegmentationId segmentationId(String segmentationId) {
+        return new SegmentationId(segmentationId);
     }
 
     /**
+     * Returns the segmentation identifier.
      *
-     * @return segmentationid
+     * @return segmentationId
      */
-    public String segmentationid() {
-        return segmentationid;
+    public String segmentationId() {
+        return segmentationId;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(segmentationid);
+        return Objects.hash(segmentationId);
     }
 
     @Override
@@ -63,14 +64,14 @@
         if (obj instanceof SegmentationId) {
             final SegmentationId that = (SegmentationId) obj;
             return this.getClass() == that.getClass()
-                    && Objects.equals(this.segmentationid, that.segmentationid);
+                    && Objects.equals(this.segmentationId, that.segmentationId);
         }
         return false;
     }
 
     @Override
     public String toString() {
-        return segmentationid;
+        return segmentationId;
     }
 
 }
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java
index e7b033c..f196f50 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java
@@ -71,14 +71,14 @@
      * Returns the administrative state of the tenantNetwork,which is up(true)
      * or down(false).
      *
-     * @return network admin state up
+     * @return true or false
      */
     boolean adminStateUp();
 
     /**
      * Returns the tenantNetwork state.
      *
-     * @return tenantNetwork state
+     * @return tenant network state
      */
     State state();
 
@@ -86,7 +86,7 @@
      * Indicates whether this tenantNetwork is shared across all tenants. By
      * default,only administrative user can change this value.
      *
-     * @return tenantNetwork shared
+     * @return true or false
      */
     boolean shared();
 
@@ -103,7 +103,7 @@
      * Returns the routerExternal.Indicates whether this network is externally
      * accessible.
      *
-     * @return true if tenantNetwork router external
+     * @return true or false
      */
     boolean routerExternal();
 
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java
index bb80feb..03ff6bf 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java
@@ -23,35 +23,36 @@
  */
 public final class TenantNetworkId {
 
-    private final String networkid;
+    private final String networkId;
 
     // Public construction is prohibited
-    private TenantNetworkId(String networkid) {
-        this.networkid = networkid;
+    private TenantNetworkId(String networkId) {
+        this.networkId = networkId;
     }
 
     /**
-     * Creates a tenantNetwork id using the networkid.
+     * Creates a TenantNetwork identifier.
      *
-     * @param networkid tenantnetwork String
-     * @return NetworkId
+     * @param networkId tenantNetwork identify string
+     * @return the attached tenantNetwork identifier
      */
-    public static TenantNetworkId networkId(String networkid) {
-        checkNotNull(networkid, "Networkid cannot be null");
-        return new TenantNetworkId(networkid);
+    public static TenantNetworkId networkId(String networkId) {
+        checkNotNull(networkId, "Networkid cannot be null");
+        return new TenantNetworkId(networkId);
     }
 
     /**
+     * Returns tenantNetwork identifier.
      *
-     * @return tenantNetworkid
+     * @return the tenantNetwork identifier
      */
-    public String networkid() {
-        return networkid;
+    public String networkId() {
+        return networkId;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(networkid);
+        return Objects.hash(networkId);
     }
 
     @Override
@@ -62,14 +63,14 @@
         if (obj instanceof TenantNetworkId) {
             final TenantNetworkId that = (TenantNetworkId) obj;
             return this.getClass() == that.getClass()
-                    && Objects.equals(this.networkid, that.networkid);
+                    && Objects.equals(this.networkId, that.networkId);
         }
         return false;
     }
 
     @Override
     public String toString() {
-        return networkid;
+        return networkId;
     }
 
 }
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
new file mode 100644
index 0000000..711cbcc
--- /dev/null
+++ b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.app.vtnrsc.tenantnetwork.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collections;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.app.vtnrsc.TenantNetwork;
+import org.onosproject.app.vtnrsc.TenantNetworkId;
+import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.MultiValuedTimestamp;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.slf4j.Logger;
+
+/**
+ * Provides implementation of the tenantNetworkService.
+ */
+@Component(immediate = true)
+@Service
+public class TenantNetworkManager implements TenantNetworkService {
+
+    private static final String NETWORK_ID_NULL = "Network ID cannot be null";
+    private static final String NETWORK_NOT_NULL = "Network ID cannot be null";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+    private EventuallyConsistentMap<TenantNetworkId, TenantNetwork> networkIdAsKeyStore;
+    private final Logger log = getLogger(getClass());
+
+    @Activate
+    public void activate() {
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(MultiValuedTimestamp.class);
+        networkIdAsKeyStore = storageService
+                .<TenantNetworkId, TenantNetwork>eventuallyConsistentMapBuilder()
+                .withName("all_network").withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        networkIdAsKeyStore.destroy();
+        log.info("Stopped");
+    }
+
+    @Override
+    public boolean exists(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORK_ID_NULL);
+        return networkIdAsKeyStore.containsKey(networkId);
+    }
+
+    @Override
+    public int getNetworkCount() {
+        return networkIdAsKeyStore.size();
+    }
+
+    @Override
+    public Iterable<TenantNetwork> getNetworks() {
+        return Collections.unmodifiableCollection(networkIdAsKeyStore.values());
+    }
+
+    @Override
+    public TenantNetwork getNetwork(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORK_ID_NULL);
+        return networkIdAsKeyStore.get(networkId);
+    }
+
+    @Override
+    public boolean createNetworks(Iterable<TenantNetwork> networks) {
+        checkNotNull(networks, NETWORK_NOT_NULL);
+        for (TenantNetwork network : networks) {
+            networkIdAsKeyStore.put(network.id(), network);
+            if (!networkIdAsKeyStore.containsKey(network.id())) {
+                log.debug("the network created failed which identifier was {}", network.id()
+                        .toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateNetworks(Iterable<TenantNetwork> networks) {
+        checkNotNull(networks, NETWORK_NOT_NULL);
+        for (TenantNetwork network : networks) {
+            if (!networkIdAsKeyStore.containsKey(network.id())) {
+                log.debug("the tenantNetwork did not exist whose identifier was {} ",
+                          network.id().toString());
+                return false;
+            }
+
+            networkIdAsKeyStore.put(network.id(), network);
+
+            if (network.equals(networkIdAsKeyStore.get(network.id()))) {
+                log.debug("the network updated failed whose identifier was {} ",
+                          network.id().toString());
+                return false;
+            }
+
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeNetworks(Iterable<TenantNetworkId> networkIds) {
+        checkNotNull(networkIds, NETWORK_NOT_NULL);
+        for (TenantNetworkId networkId : networkIds) {
+            networkIdAsKeyStore.remove(networkId);
+            if (networkIdAsKeyStore.containsKey(networkId)) {
+                log.debug("the network removed failed whose identifier was {}",
+                          networkId.toString());
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/TenantNetworkCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/TenantNetworkCodec.java
new file mode 100644
index 0000000..bad7a82
--- /dev/null
+++ b/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/TenantNetworkCodec.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.app.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.app.vtnrsc.TenantNetwork;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * TenantNetwork JSON codec.
+ */
+public final class TenantNetworkCodec extends JsonCodec<TenantNetwork> {
+
+    @Override
+    public ObjectNode encode(TenantNetwork network, CodecContext context) {
+        checkNotNull(network, "Network cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("id", network.id().toString())
+                .put("name", network.name().toString())
+                .put("admin_state_up", network.adminStateUp())
+                .put("status", "" + network.state())
+                .put("shared", network.shared())
+                .put("tenant_id", network.tenantId().toString())
+                .put("router:external", network.routerExternal())
+                .put("provider:network_type", "" + network.type())
+                .put("provider:physical_network", network.physicalNetwork().toString())
+                .put("provider:segmentation_id", network.segmentationId().toString());
+        return result;
+    }
+}
diff --git a/apps/vtnweb/pom.xml b/apps/vtnweb/pom.xml
new file mode 100644
index 0000000..974d3bf
--- /dev/null
+++ b/apps/vtnweb/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.onosproject</groupId>
+		<artifactId>onos-apps</artifactId>
+		<version>1.3.0-SNAPSHOT</version>
+		<relativePath>../pom.xml</relativePath>
+	</parent>
+
+
+	<artifactId>onos-app-vtnweb</artifactId>
+	<packaging>bundle</packaging>
+	<properties>
+		<onos.app.name>org.onosproject.vtnweb</onos.app.name>
+		<web.context>/onos/vtn</web.context>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>javax.ws.rs</groupId>
+			<artifactId>jsr311-api</artifactId>
+			<version>1.1.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.onosproject</groupId>
+			<artifactId>onos-api</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.onosproject</groupId>
+			<artifactId>onos-app-vtnrsc</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+	</dependencies>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.felix</groupId>
+				<artifactId>maven-bundle-plugin</artifactId>
+				<extensions>true</extensions>
+				<configuration>
+					<instructions>
+						<_wab>src/main/webapp/</_wab>
+						<Bundle-SymbolicName>
+							${project.groupId}.${project.artifactId}
+						</Bundle-SymbolicName>
+						<Import-Package>
+							org.slf4j,
+							org.osgi.framework,
+							javax.ws.rs,
+							javax.ws.rs.core,
+							com.sun.jersey.api.core,
+							com.sun.jersey.spi.container.servlet,
+							com.sun.jersey.server.impl.container.servlet,
+							com.fasterxml.jackson.databind,
+							com.fasterxml.jackson.databind.node,
+							com.fasterxml.jackson.core,
+							org.apache.karaf.shell.commands,
+							org.apache.commons.lang.math.*,
+							com.google.common.*,
+							org.onlab.packet.*,
+							org.onlab.rest.*,
+							org.onosproject.*,
+							org.onlab.util.*,
+							org.jboss.netty.util.*
+						</Import-Package>
+						<Web-ContextPath>${web.context}</Web-ContextPath>
+					</instructions>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>
\ No newline at end of file
diff --git a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
new file mode 100644
index 0000000..6ab1b14
--- /dev/null
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.vtnweb.resources;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+import static javax.ws.rs.core.Response.Status.OK;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+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.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.app.vtnrsc.DefaultTenantNetwork;
+import org.onosproject.app.vtnrsc.PhysicalNetwork;
+import org.onosproject.app.vtnrsc.SegmentationId;
+import org.onosproject.app.vtnrsc.TenantId;
+import org.onosproject.app.vtnrsc.TenantNetwork;
+import org.onosproject.app.vtnrsc.TenantNetwork.State;
+import org.onosproject.app.vtnrsc.TenantNetwork.Type;
+import org.onosproject.app.vtnrsc.TenantNetworkId;
+import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.app.vtnrsc.web.TenantNetworkCodec;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Maps;
+
+/**
+ * REST resource for interacting with the inventory of networks.
+ */
+@Path("networks")
+public class TenantNetworkWebResource extends AbstractWebResource {
+    public static final String NETWORK_NOT_FOUND = "Network is not found";
+    public static final String NETWORK_ID_EXIST = "Network id is existed";
+    public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";
+    public static final String CREATE_NETWORK = "create network";
+    public static final String UPDATE_NETWORK = "update network";
+    public static final String DELETE_NETWORK = "delete network";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(TenantNetworkWebResource.class);
+    private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
+            .newConcurrentMap();
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getNetworks(@QueryParam("id") String queryId,
+                                @QueryParam("name") String queryName,
+                                @QueryParam("admin_state_up") String queryadminStateUp,
+                                @QueryParam("status") String querystate,
+                                @QueryParam("shared") String queryshared,
+                                @QueryParam("tenant_id") String querytenantId,
+                                @QueryParam("router:external") String routerExternal,
+                                @QueryParam("provider:network_type") String type,
+                                @QueryParam("provider:physical_network") String physicalNetwork,
+                                @QueryParam("provider:segmentation_id") String segmentationId) {
+        Iterable<TenantNetwork> networks = get(TenantNetworkService.class)
+                .getNetworks();
+        Iterator<TenantNetwork> networkors = networks.iterator();
+        while (networkors.hasNext()) {
+            TenantNetwork network = networkors.next();
+            if ((queryId == null || queryId.equals(network.id().toString()))
+                    && (queryName == null || queryName.equals(network.name()
+                            .toString()))
+                    && (queryadminStateUp == null || queryadminStateUp
+                            .equals(network.adminStateUp()))
+                    && (querystate == null || querystate.equals(network.state()
+                            .toString()))
+                    && (queryshared == null || queryshared.equals(network
+                            .shared()))
+                    && (querytenantId == null || querytenantId.equals(network
+                            .tenantId().toString()))
+                    && (routerExternal == null || routerExternal.equals(network
+                            .routerExternal()))
+                    && (type == null || type.equals(network.type()))
+                    && (physicalNetwork == null || physicalNetwork
+                            .equals(network.physicalNetwork()))
+                    && (segmentationId == null || segmentationId.equals(network
+                            .segmentationId()))) {
+                networksMap.putIfAbsent(network.id(), network);
+            }
+        }
+        networks = Collections.unmodifiableCollection(networksMap.values());
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("networks", new TenantNetworkCodec().encode(networks, this));
+
+        return ok(result.toString()).build();
+    }
+
+    private State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return TenantNetwork.State.ACTIVE;
+        } else if (state.equals("BUILD")) {
+            return TenantNetwork.State.BUILD;
+        } else if (state.equals("DOWN")) {
+            return TenantNetwork.State.DOWN;
+        } else if (state.equals("ERROR")) {
+            return TenantNetwork.State.ERROR;
+        } else {
+            return null;
+        }
+    }
+
+    private Type isType(String type) {
+        if (type.equals("LOCAL")) {
+            return TenantNetwork.Type.LOCAL;
+        } else {
+            return null;
+        }
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getNetwork(@PathParam("id") String id) {
+
+        if (!get(TenantNetworkService.class).exists(TenantNetworkId
+                                                            .networkId(id))) {
+            return ok("The tenantNetwork does not exists").build();
+        }
+        TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)
+                .getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("network", new TenantNetworkCodec().encode(network, this));
+
+        return ok(result.toString()).build();
+
+    }
+
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createNetworks(InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonNode nodes = null;
+            Iterable<TenantNetwork> networks = null;
+            if (cfg.get("network") != null) {
+                nodes = cfg.get("network");
+                if (nodes.isArray()) {
+                    networks = changeJson2objs(nodes);
+                } else {
+                    networks = changeJson2obj(CREATE_NETWORK, null, nodes);
+                }
+            } else if (cfg.get("networks") != null) {
+                nodes = cfg.get("networks");
+                networks = changeJson2objs(nodes);
+            }
+            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
+                                                       .createNetworks(networks)),
+                                               NETWORK_NOT_FOUND);
+
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(NETWORK_ID_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Creates tenantNetwork exception {}.", e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @PUT
+    @Path("{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateNetworks(@PathParam("id") String id, InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonNode nodes = null;
+            Iterable<TenantNetwork> networks = null;
+            if (cfg.get("network") != null) {
+                nodes = cfg.get("network");
+                if (nodes.isArray()) {
+                    networks = changeJson2objs(nodes);
+                } else {
+                    networks = changeJson2obj(UPDATE_NETWORK,
+                                              TenantNetworkId.networkId(id),
+                                              nodes);
+                }
+            } else if (cfg.get("networks") != null) {
+                nodes = cfg.get("networks");
+                networks = changeJson2objs(nodes);
+            }
+            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
+                                                       .updateNetworks(networks)),
+                                               NETWORK_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(NETWORK_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Updates tenantNetwork failed because of exception {}.",
+                      e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @DELETE
+    @Path("{id}")
+    public Response deleteNetworks(@PathParam("id") String id) {
+        log.debug("Deletes network by identifier {}.", id);
+        Set<TenantNetworkId> networkSet = new HashSet<TenantNetworkId>();
+        networkSet.add(TenantNetworkId.networkId(id));
+        Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)
+                .removeNetworks(networkSet), NETWORK_NOT_FOUND);
+        if (!issuccess) {
+            log.debug("Network identifier {} is not existed", id);
+            return Response.status(INTERNAL_SERVER_ERROR)
+                    .entity(NETWORK_ID_NOT_EXIST).build();
+        }
+        return Response.status(OK).entity(issuccess.toString()).build();
+    }
+
+    /**
+     * Returns a collection of tenantNetworks.
+     *
+     * @param flag the flag
+     * @param networkId network identifier
+     * @param node the network json node
+     * @return a collection of tenantNetworks
+     */
+    public Iterable<TenantNetwork> changeJson2obj(String flag,
+                                                  TenantNetworkId networkId,
+                                                  JsonNode node) {
+        checkNotNull(node, JSON_NOT_NULL);
+        TenantNetwork network = null;
+        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
+                .newConcurrentMap();
+        if (node != null) {
+            String name = node.get("name").asText();
+            boolean adminStateUp = node.get("admin_state_up").asBoolean();
+            String state = node.get("status").asText();
+            boolean shared = node.get("shared").asBoolean();
+            String tenantId = node.get("tenant_id").asText();
+            boolean routerExternal = node.get("router:external").asBoolean();
+            String type = node.get("provider:network_type").asText();
+            String physicalNetwork = node.get("provider:physical_network")
+                    .asText();
+            String segmentationId = node.get("provider:segmentation_id")
+                    .asText();
+            TenantNetworkId id = null;
+            if (flag == CREATE_NETWORK) {
+                id = TenantNetworkId.networkId(node.get("id").asText());
+            } else if (flag == UPDATE_NETWORK) {
+                id = networkId;
+            }
+            network = new DefaultTenantNetwork(
+                                               id,
+                                               name,
+                                               adminStateUp,
+                                               isState(state),
+                                               shared,
+                                               TenantId.tenantId(tenantId),
+                                               routerExternal,
+                                               isType(type),
+                                               PhysicalNetwork
+                                                       .physicalNetwork(physicalNetwork),
+                                               SegmentationId
+                                                       .segmentationId(segmentationId));
+            networksMap.putIfAbsent(id, network);
+        }
+        return Collections.unmodifiableCollection(networksMap.values());
+    }
+
+    /**
+     * Returns a collection of tenantNetworks.
+     *
+     * @param nodes the network jsonnodes
+     * @return a collection of tenantNetworks
+     */
+    public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {
+        checkNotNull(nodes, JSON_NOT_NULL);
+        TenantNetwork network = null;
+        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
+                .newConcurrentMap();
+        if (nodes != null) {
+            for (JsonNode node : nodes) {
+                String id = node.get("id").asText();
+                String name = node.get("name").asText();
+                boolean adminStateUp = node.get("admin_state_up").asBoolean();
+                String state = node.get("status").asText();
+                boolean shared = node.get("shared").asBoolean();
+                String tenantId = node.get("tenant_id").asText();
+                boolean routerExternal = node.get("router:external")
+                        .asBoolean();
+                String type = node.get("provider:network_type").asText();
+                String physicalNetwork = node.get("provider:physical_network")
+                        .asText();
+                String segmentationId = node.get("provider:segmentation_id")
+                        .asText();
+                network = new DefaultTenantNetwork(
+                                                   TenantNetworkId
+                                                           .networkId(id),
+                                                   name,
+                                                   adminStateUp,
+                                                   isState(state),
+                                                   shared,
+                                                   TenantId.tenantId(tenantId),
+                                                   routerExternal,
+                                                   isType(type),
+                                                   PhysicalNetwork
+                                                           .physicalNetwork(physicalNetwork),
+                                                   SegmentationId
+                                                           .segmentationId(segmentationId));
+                networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);
+            }
+        }
+        return Collections.unmodifiableCollection(networksMap.values());
+    }
+
+    /**
+     * Returns the specified item if that items is null; otherwise throws not
+     * found exception.
+     *
+     * @param item item to check
+     * @param <T> item type
+     * @param message not found message
+     * @return item if not null
+     * @throws org.onlab.util.ItemNotFoundException if item is null
+     */
+    protected <T> T nullIsNotFound(T item, String message) {
+        if (item == null) {
+            throw new ItemNotFoundException(message);
+        }
+        return item;
+    }
+}
diff --git a/apps/vtnweb/src/main/webapp/WEB-INF/web.xml b/apps/vtnweb/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..c5547ba
--- /dev/null
+++ b/apps/vtnweb/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015 Open Networking Laboratory
+  ~
+  ~ 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.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>VTNRSC REST API v1.0</display-name>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+            <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+        </init-param>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.classnames</param-name>
+            <param-value>
+                org.onosproject.vtnweb.resources.TenantNetworkWebResource
+            </param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>