diff --git a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
index aa73d26..779777f 100644
--- a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
@@ -1,319 +1,361 @@
-/*
- * 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 java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-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.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onlab.packet.IpPrefix;
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.app.vtnrsc.AllocationPool;
-import org.onosproject.app.vtnrsc.DefaultAllocationPool;
-import org.onosproject.app.vtnrsc.DefaultHostRoute;
-import org.onosproject.app.vtnrsc.DefaultSubnet;
-import org.onosproject.app.vtnrsc.HostRoute;
-import org.onosproject.app.vtnrsc.Subnet;
-import org.onosproject.app.vtnrsc.Subnet.Mode;
-import org.onosproject.app.vtnrsc.SubnetId;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.subnet.SubnetService;
-import org.onosproject.app.vtnrsc.web.SubnetCodec;
-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;
-
-@Path("subnets")
-public class SubnetWebResource extends AbstractWebResource {
-    private final Logger log = LoggerFactory.getLogger(SubnetWebResource.class);
-    public static final String SUBNET_NOT_CREATE = "Subnets is failed to create!";
-    public static final String SUBNET_NOT_FOUND = "Subnets is failed to update!";
-    public static final String JSON_NOT_NULL = "JsonNode can not be null";
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response listSubnets() {
-        Iterable<Subnet> subnets = get(SubnetService.class).getSubnets();
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("subnets", new SubnetCodec().encode(subnets, this));
-        return ok(result.toString()).build();
-    }
-
-    @GET
-    @Path("{subnetUUID}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getSubnet(@PathParam("subnetUUID") String id) {
-
-        if (!get(SubnetService.class).exists(SubnetId.subnetId(id))) {
-            return ok("the subnet does not exists").build();
-        }
-        Subnet sub = nullIsNotFound(get(SubnetService.class)
-                                            .getSubnet(SubnetId.subnetId(id)),
-                                    SUBNET_NOT_FOUND);
-
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("subnet", new SubnetCodec().encode(sub, this));
-        return ok(result.toString()).build();
-    }
-
-    @POST
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response createSubnet(final InputStream input) {
-
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode subnode = mapper.readTree(input);
-            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
-            Boolean result = nullIsNotFound((get(SubnetService.class)
-                                                    .createSubnets(subnets)),
-                                            SUBNET_NOT_CREATE);
-
-            if (!result) {
-                return Response.status(204).entity(SUBNET_NOT_CREATE).build();
-            }
-            return Response.status(202).entity(result.toString()).build();
-        } catch (Exception e) {
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @PUT
-    @Path("{subnetUUID}")
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response updateSubnet(@PathParam("id") String id,
-                                 final InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode subnode = mapper.readTree(input);
-            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
-            Boolean result = nullIsNotFound(get(SubnetService.class)
-                    .updateSubnets(subnets), SUBNET_NOT_FOUND);
-            if (!result) {
-                return Response.status(204).entity(SUBNET_NOT_FOUND).build();
-            }
-            return Response.status(203).entity(result.toString()).build();
-        } catch (Exception e) {
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @Path("{subnetUUID}")
-    @DELETE
-    public Response deleteSingleSubnet(@PathParam("subnetUUID") String id)
-            throws IOException {
-        try {
-            SubnetId subId = SubnetId.subnetId(id);
-            Set<SubnetId> subIds = new HashSet<SubnetId>();
-            subIds.add(subId);
-            get(SubnetService.class).removeSubnets(subIds);
-            return Response.status(201).entity("SUCCESS").build();
-        } catch (Exception e) {
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    private Iterable<Subnet> createOrUpdateByInputStream(JsonNode subnode) {
-        checkNotNull(subnode, JSON_NOT_NULL);
-        Iterable<Subnet> subnets = null;
-        JsonNode subnetNodes = subnode.get("subnets");
-        if (subnetNodes == null) {
-            subnetNodes = subnode.get("subnet");
-        }
-        log.debug("subnetNodes is {}", subnetNodes.toString());
-        if (subnetNodes.isArray()) {
-            subnets = changeJsonToSubs(subnetNodes);
-        } else {
-            subnets = changeJsonToSub(subnetNodes);
-        }
-        return subnets;
-    }
-
-    /**
-     * Returns a collection of subnets from subnetNodes.
-     *
-     * @param subnetNodes the subnet json node
-     * @return subnets a collection of subnets
-     */
-    public Iterable<Subnet> changeJsonToSubs(JsonNode subnetNodes) {
-        checkNotNull(subnetNodes, JSON_NOT_NULL);
-        Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
-        for (JsonNode subnetNode : subnetNodes) {
-            if (subnetNode.hasNonNull("id")) {
-                return null;
-            }
-            SubnetId id = SubnetId.subnetId(subnetNode.get("id").asText());
-            String subnetName = subnetNode.get("name").asText();
-            TenantId tenantId = TenantId.tenantId(subnetNode.get("tenant_id")
-                    .asText());
-            TenantNetworkId networkId = TenantNetworkId.networkId(subnetNode
-                    .get("network_id").asText());
-            Version ipVersion = Version.valueOf(subnetNode.get("ip_version")
-                    .asText());
-            IpPrefix cidr = IpPrefix.valueOf(subnetNode.get("cidr").asText());
-            IpAddress gatewayIp = IpAddress.valueOf(subnetNode
-                    .get("gateway_ip").asText());
-            Boolean dhcpEnabled = subnetNode.get("enable_dhcp").asBoolean();
-            Boolean shared = subnetNode.get("shared").asBoolean();
-            JsonNode hostRoutes = subnetNode.get("host_routes");
-            Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
-            JsonNode allocationPools = subnetNode.get("allocation_pools");
-            Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
-            Mode ipV6AddressMode = Mode.valueOf(subnetNode
-                    .get("ipv6_address_mode").asText());
-            Mode ipV6RaMode = Mode.valueOf(subnetNode.get("ipv6_ra_mode")
-                    .asText());
-            Subnet subnet = new DefaultSubnet(id, subnetName, networkId,
-                                              tenantId, ipVersion, cidr,
-                                              gatewayIp, dhcpEnabled, shared,
-                                              hostRoutesIt, ipV6AddressMode,
-                                              ipV6RaMode, allocationPoolsIt);
-            subMap.put(id, subnet);
-        }
-        return Collections.unmodifiableCollection(subMap.values());
-    }
-
-    /**
-     * Returns a collection of subnets from subnetNodes.
-     *
-     * @param subnetNodes the subnet json node
-     * @return subnets a collection of subnets
-     */
-    public Iterable<Subnet> changeJsonToSub(JsonNode subnetNodes) {
-        checkNotNull(subnetNodes, JSON_NOT_NULL);
-        Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
-        SubnetId id = SubnetId.subnetId(subnetNodes.get("id").asText());
-        String subnetName = subnetNodes.get("name").asText();
-        TenantId tenantId = TenantId.tenantId(subnetNodes.get("tenant_id")
-                .asText());
-        TenantNetworkId networkId = TenantNetworkId.networkId(subnetNodes
-                .get("network_id").asText());
-        Version ipVersion = Version.valueOf(subnetNodes.get("ip_version")
-                .asText());
-        IpPrefix cidr = IpPrefix.valueOf(subnetNodes.get("cidr").asText());
-        IpAddress gatewayIp = IpAddress.valueOf(subnetNodes.get("gateway_ip")
-                .asText());
-        Boolean dhcpEnabled = subnetNodes.get("enable_dhcp").asBoolean();
-        Boolean shared = subnetNodes.get("shared").asBoolean();
-        JsonNode hostRoutes = subnetNodes.get("host_routes");
-        Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
-        JsonNode allocationPools = subnetNodes.get("allocation_pools");
-        Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
-        Mode ipV6AddressMode = Mode.valueOf(subnetNodes
-                .get("ipv6_address_mode").asText());
-        Mode ipV6RaMode = Mode
-                .valueOf(subnetNodes.get("ipv6_ra_mode").asText());
-        Subnet subnet = new DefaultSubnet(id, subnetName, networkId, tenantId,
-                                          ipVersion, cidr, gatewayIp,
-                                          dhcpEnabled, shared, hostRoutesIt,
-                                          ipV6AddressMode, ipV6RaMode,
-                                          allocationPoolsIt);
-        subMap.put(id, subnet);
-        return Collections.unmodifiableCollection(subMap.values());
-    }
-
-    /**
-     * Changes JsonNode alocPools to a collection of the alocPools.
-     *
-     * @param allocationPools the allocationPools JsonNode
-     * @return a collection of allocationPools
-     */
-    public Iterable<AllocationPool> jsonNodeToAllocationPools(JsonNode allocationPools) {
-        checkNotNull(allocationPools, JSON_NOT_NULL);
-        ConcurrentMap<Integer, AllocationPool> alocplMaps = Maps
-                .newConcurrentMap();
-        Integer i = 0;
-        for (JsonNode node : allocationPools) {
-            IpAddress startIp = IpAddress.valueOf(node.get("start").asText());
-            IpAddress endIp = IpAddress.valueOf(node.get("end").asText());
-            AllocationPool alocPls = new DefaultAllocationPool(startIp, endIp);
-            alocplMaps.putIfAbsent(i, alocPls);
-            i++;
-        }
-        return Collections.unmodifiableCollection(alocplMaps.values());
-    }
-
-    /**
-     * Changes hostRoutes JsonNode to a collection of the hostRoutes.
-     *
-     * @param hostRoutes the hostRoutes json node
-     * @return a collection of hostRoutes
-     */
-    public Iterable<HostRoute> jsonNodeToHostRoutes(JsonNode hostRoutes) {
-        checkNotNull(hostRoutes, JSON_NOT_NULL);
-        ConcurrentMap<Integer, HostRoute> hostRouteMaps = Maps
-                .newConcurrentMap();
-        Integer i = 0;
-        for (JsonNode node : hostRoutes) {
-            IpAddress nexthop = IpAddress.valueOf(node.get("nexthop").asText());
-            IpPrefix destination = IpPrefix.valueOf(node.get("destination")
-                    .asText());
-            HostRoute hostRoute = new DefaultHostRoute(nexthop, destination);
-            hostRouteMaps.putIfAbsent(i, hostRoute);
-            i++;
-        }
-        return Collections.unmodifiableCollection(hostRouteMaps.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;
-    }
-
-}
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+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.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpAddress.Version;
+import org.onlab.packet.IpPrefix;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.AllocationPool;
+import org.onosproject.vtnrsc.DefaultAllocationPool;
+import org.onosproject.vtnrsc.DefaultHostRoute;
+import org.onosproject.vtnrsc.DefaultSubnet;
+import org.onosproject.vtnrsc.HostRoute;
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.Subnet.Mode;
+import org.onosproject.vtnrsc.subnet.SubnetService;
+import org.onosproject.vtnrsc.web.SubnetCodec;
+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;
+
+@Path("subnets")
+public class SubnetWebResource extends AbstractWebResource {
+    private final Logger log = LoggerFactory.getLogger(SubnetWebResource.class);
+    public static final String SUBNET_NOT_CREATE = "Subnets is failed to create!";
+    public static final String SUBNET_NOT_FOUND = "Subnets is failed to update!";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response listSubnets() {
+        Iterable<Subnet> subnets = get(SubnetService.class).getSubnets();
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("subnets", new SubnetCodec().encode(subnets, this));
+        return ok(result.toString()).build();
+    }
+
+    @GET
+    @Path("{subnetUUID}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getSubnet(@PathParam("subnetUUID") String id) {
+
+        if (!get(SubnetService.class).exists(SubnetId.subnetId(id))) {
+            return ok("The subnet does not exists").build();
+        }
+        Subnet sub = nullIsNotFound(get(SubnetService.class)
+                                            .getSubnet(SubnetId.subnetId(id)),
+                                    SUBNET_NOT_FOUND);
+
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("subnet", new SubnetCodec().encode(sub, this));
+        return ok(result.toString()).build();
+    }
+
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createSubnet(final InputStream input) {
+
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode subnode = mapper.readTree(input);
+            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
+            Boolean result = nullIsNotFound((get(SubnetService.class)
+                                                    .createSubnets(subnets)),
+                                            SUBNET_NOT_CREATE);
+
+            if (!result) {
+                return Response.status(204).entity(SUBNET_NOT_CREATE).build();
+            }
+            return Response.status(202).entity(result.toString()).build();
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @PUT
+    @Path("{subnetUUID}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateSubnet(@PathParam("id") String id,
+                                 final InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode subnode = mapper.readTree(input);
+            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
+            Boolean result = nullIsNotFound(get(SubnetService.class)
+                    .updateSubnets(subnets), SUBNET_NOT_FOUND);
+            if (!result) {
+                return Response.status(204).entity(SUBNET_NOT_FOUND).build();
+            }
+            return Response.status(203).entity(result.toString()).build();
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @Path("{subnetUUID}")
+    @DELETE
+    public Response deleteSingleSubnet(@PathParam("subnetUUID") String id)
+            throws IOException {
+        try {
+            SubnetId subId = SubnetId.subnetId(id);
+            Set<SubnetId> subIds = new HashSet<SubnetId>();
+            subIds.add(subId);
+            get(SubnetService.class).removeSubnets(subIds);
+            return Response.status(201).entity("SUCCESS").build();
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    private Iterable<Subnet> createOrUpdateByInputStream(JsonNode subnode) {
+        checkNotNull(subnode, JSON_NOT_NULL);
+        Iterable<Subnet> subnets = null;
+        JsonNode subnetNodes = subnode.get("subnets");
+        if (subnetNodes == null) {
+            subnetNodes = subnode.get("subnet");
+        }
+        log.debug("subnetNodes is {}", subnetNodes.toString());
+        if (subnetNodes.isArray()) {
+            subnets = changeJsonToSubs(subnetNodes);
+        } else {
+            subnets = changeJsonToSub(subnetNodes);
+        }
+        return subnets;
+    }
+
+    /**
+     * Returns a collection of subnets from subnetNodes.
+     *
+     * @param subnetNodes the subnet json node
+     * @return subnets a collection of subnets
+     */
+    public Iterable<Subnet> changeJsonToSubs(JsonNode subnetNodes) {
+        checkNotNull(subnetNodes, JSON_NOT_NULL);
+        Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
+        for (JsonNode subnetNode : subnetNodes) {
+            if (!subnetNode.hasNonNull("id")) {
+                return null;
+            }
+            SubnetId id = SubnetId.subnetId(subnetNode.get("id").asText());
+            String subnetName = subnetNode.get("name").asText();
+            TenantId tenantId = TenantId
+                    .tenantId(subnetNode.get("tenant_id").asText());
+            TenantNetworkId networkId = TenantNetworkId
+                    .networkId(subnetNode.get("network_id").asText());
+            Version ipVersion = Version
+                    .valueOf(subnetNode.get("ip_version").asText());
+            IpPrefix cidr = IpPrefix.valueOf(subnetNode.get("cidr").asText());
+            IpAddress gatewayIp = IpAddress
+                    .valueOf(subnetNode.get("gateway_ip").asText());
+            Boolean dhcpEnabled = subnetNode.get("enable_dhcp").asBoolean();
+            Boolean shared = subnetNode.get("shared").asBoolean();
+            JsonNode hostRoutes = subnetNode.get("host_routes");
+            Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
+            JsonNode allocationPools = subnetNode.get("allocation_pools");
+            Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
+            Mode ipV6AddressMode = Mode
+                    .valueOf(subnetNode.get("ipv6_address_mode").asText());
+            Mode ipV6RaMode = Mode
+                    .valueOf(subnetNode.get("ipv6_ra_mode").asText());
+            Subnet subnet = new DefaultSubnet(id, subnetName, networkId,
+                                              tenantId, ipVersion, cidr,
+                                              gatewayIp, dhcpEnabled, shared,
+                                              hostRoutesIt, ipV6AddressMode,
+                                              ipV6RaMode, allocationPoolsIt);
+            subMap.put(id, subnet);
+        }
+        return Collections.unmodifiableCollection(subMap.values());
+    }
+
+    /**
+     * Returns a collection of subnets from subnetNodes.
+     *
+     * @param subnetNodes the subnet json node
+     * @return subnets a collection of subnets
+     */
+    public Iterable<Subnet> changeJsonToSub(JsonNode subnetNodes) {
+        checkNotNull(subnetNodes, JSON_NOT_NULL);
+        Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
+        if (!subnetNodes.hasNonNull("id")) {
+            return null;
+        }
+        SubnetId id = SubnetId.subnetId(subnetNodes.get("id").asText());
+        String subnetName = subnetNodes.get("name").asText();
+        TenantId tenantId = TenantId
+                .tenantId(subnetNodes.get("tenant_id").asText());
+        TenantNetworkId networkId = TenantNetworkId
+                .networkId(subnetNodes.get("network_id").asText());
+        String version = subnetNodes.get("ip_version").asText();
+        Version ipVersion;
+        switch (version) {
+        case "4":
+            ipVersion = Version.INET;
+            break;
+        case "6":
+            ipVersion = Version.INET;
+            break;
+        default:
+            ipVersion = null;
+        }
+
+        IpPrefix cidr = IpPrefix.valueOf(subnetNodes.get("cidr").asText());
+        IpAddress gatewayIp = IpAddress
+                .valueOf(subnetNodes.get("gateway_ip").asText());
+        Boolean dhcpEnabled = subnetNodes.get("enable_dhcp").asBoolean();
+        Boolean shared = subnetNodes.get("shared").asBoolean();
+        JsonNode hostRoutes = subnetNodes.get("host_routes");
+        Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
+        JsonNode allocationPools = subnetNodes.get("allocation_pools");
+        Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
+
+        Mode ipV6AddressMode = getMode(subnetNodes.get("ipv6_address_mode")
+                .asText());
+        Mode ipV6RaMode = getMode(subnetNodes.get("ipv6_ra_mode").asText());
+
+        Subnet subnet = new DefaultSubnet(id, subnetName, networkId, tenantId,
+                                          ipVersion, cidr, gatewayIp,
+                                          dhcpEnabled, shared, hostRoutesIt,
+                                          ipV6AddressMode, ipV6RaMode,
+                                          allocationPoolsIt);
+        subMap.put(id, subnet);
+        return Collections.unmodifiableCollection(subMap.values());
+    }
+
+    /**
+     * Gets ipv6_address_mode or ipv6_ra_mode type.
+     *
+     * @param mode the String value in JsonNode
+     * @return ipV6Mode Mode of the ipV6Mode
+     */
+    private Mode getMode(String mode) {
+        Mode ipV6Mode;
+        if (mode == null) {
+            return null;
+        }
+        switch (mode) {
+        case "dhcpv6-stateful":
+            ipV6Mode = Mode.DHCPV6_STATEFUL;
+            break;
+        case "dhcpv6-stateless":
+            ipV6Mode = Mode.DHCPV6_STATELESS;
+            break;
+        case "slaac":
+            ipV6Mode = Mode.SLAAC;
+            break;
+        default:
+            ipV6Mode = null;
+        }
+        return ipV6Mode;
+    }
+
+    /**
+     * Changes JsonNode alocPools to a collection of the alocPools.
+     *
+     * @param allocationPools the allocationPools JsonNode
+     * @return a collection of allocationPools
+     */
+    public Iterable<AllocationPool> jsonNodeToAllocationPools(JsonNode allocationPools) {
+        checkNotNull(allocationPools, JSON_NOT_NULL);
+        ConcurrentMap<Integer, AllocationPool> alocplMaps = Maps
+                .newConcurrentMap();
+        Integer i = 0;
+        for (JsonNode node : allocationPools) {
+            IpAddress startIp = IpAddress.valueOf(node.get("start").asText());
+            IpAddress endIp = IpAddress.valueOf(node.get("end").asText());
+            AllocationPool alocPls = new DefaultAllocationPool(startIp, endIp);
+            alocplMaps.putIfAbsent(i, alocPls);
+            i++;
+        }
+        return Collections.unmodifiableCollection(alocplMaps.values());
+    }
+
+    /**
+     * Changes hostRoutes JsonNode to a collection of the hostRoutes.
+     *
+     * @param hostRoutes the hostRoutes json node
+     * @return a collection of hostRoutes
+     */
+    public Iterable<HostRoute> jsonNodeToHostRoutes(JsonNode hostRoutes) {
+        checkNotNull(hostRoutes, JSON_NOT_NULL);
+        ConcurrentMap<Integer, HostRoute> hostRouteMaps = Maps
+                .newConcurrentMap();
+        Integer i = 0;
+        for (JsonNode node : hostRoutes) {
+            IpAddress nexthop = IpAddress.valueOf(node.get("nexthop").asText());
+            IpPrefix destination = IpPrefix.valueOf(node.get("destination")
+                    .asText());
+            HostRoute hostRoute = new DefaultHostRoute(nexthop, destination);
+            hostRouteMaps.putIfAbsent(i, hostRoute);
+            i++;
+        }
+        return Collections.unmodifiableCollection(hostRouteMaps.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/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
index 6ab1b14..092ea89 100644
--- a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
@@ -1,368 +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;
-    }
-}
+/*
+ * 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.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.DefaultTenantNetwork;
+import org.onosproject.vtnrsc.PhysicalNetwork;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.TenantNetwork.State;
+import org.onosproject.vtnrsc.TenantNetwork.Type;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.web.TenantNetworkCodec;
+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/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
index 6d7d9f4..b851a0f 100644
--- a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
@@ -1,399 +1,407 @@
-/*
- * 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.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-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.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.HostId;
-import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.app.vtnrsc.AllowedAddressPair;
-import org.onosproject.app.vtnrsc.DefaultVirtualPort;
-import org.onosproject.app.vtnrsc.FixedIp;
-import org.onosproject.app.vtnrsc.SecurityGroup;
-import org.onosproject.app.vtnrsc.SubnetId;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.VirtualPort;
-import org.onosproject.app.vtnrsc.VirtualPortId;
-import org.onosproject.app.vtnrsc.VirtualPort.State;
-import org.onosproject.app.vtnrsc.virtualport.VirtualPortService;
-import org.onosproject.app.vtnrsc.web.VirtualPortCodec;
-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 infrastructure
- * virtualPort.
- */
-@Path("ports")
-public class VirtualPortWebResource extends AbstractWebResource {
-    public static final String VPORT_NOT_FOUND = "VirtualPort is not found";
-    public static final String VPORT_ID_EXIST = "VirtualPort id is exist";
-    public static final String VPORT_ID_NOT_EXIST = "VirtualPort id is not exist";
-    public static final String JSON_NOT_NULL = "JsonNode can not be null";
-    protected static final Logger log = LoggerFactory
-            .getLogger(VirtualPortService.class);
-
-    @GET
-    @Produces({ MediaType.APPLICATION_JSON })
-    public Response getPorts() {
-        Iterable<VirtualPort> virtualPorts = get(VirtualPortService.class)
-                .getPorts();
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("ports", new VirtualPortCodec().encode(virtualPorts, this));
-        return ok(result.toString()).build();
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces({ MediaType.APPLICATION_JSON })
-    public Response getportsById(@PathParam("id") String id) {
-
-        if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
-            return ok("the virtualPort does not exists").build();
-        }
-        VirtualPort virtualPort = nullIsNotFound(get(VirtualPortService.class)
-                .getPort(VirtualPortId.portId(id)), VPORT_NOT_FOUND);
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("ports", new VirtualPortCodec().encode(virtualPort, this));
-        return ok(result.toString()).build();
-    }
-
-    @POST
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response createPorts(InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
-            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
-                    .createPorts(vPorts), VPORT_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(VPORT_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Creates VirtualPort failed because of exception {}",
-                      e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @Path("{portUUID}")
-    @DELETE
-    public Response deletePorts(@PathParam("portUUID") String id) {
-        Set<VirtualPortId> vPortIds = new HashSet<VirtualPortId>();
-        try {
-            if (id != null) {
-                vPortIds.add(VirtualPortId.portId(id));
-            }
-            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
-                    .removePorts(vPortIds), VPORT_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(VPORT_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Deletes VirtualPort failed because of exception {}",
-                      e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @PUT
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response updatePorts(@PathParam("id") String id, InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
-            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
-                    .updatePorts(vPorts), VPORT_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(VPORT_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Updates failed because of exception {}", e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    /**
-     * Returns a Object of the currently known infrastructure virtualPort.
-     *
-     * @param vPortNode the virtualPort json node
-     * @return a collection of virtualPorts
-     */
-    public Iterable<VirtualPort> createOrUpdateByInputStream(JsonNode vPortNode) {
-        checkNotNull(vPortNode, JSON_NOT_NULL);
-        JsonNode vPortNodes = vPortNode.get("ports");
-        if (vPortNodes == null) {
-            vPortNodes = vPortNode.get("port");
-        }
-        if (vPortNodes.isArray()) {
-            return changeJsonToPorts(vPortNodes);
-        } else {
-            return changeJsonToPort(vPortNodes);
-        }
-    }
-
-    /**
-     * Returns the iterable collection of virtualports from subnetNodes.
-     *
-     * @param vPortNodes the virtualPort json node
-     * @return virtualPorts a collection of virtualPorts
-     */
-    public Iterable<VirtualPort> changeJsonToPorts(JsonNode vPortNodes) {
-        checkNotNull(vPortNodes, JSON_NOT_NULL);
-        Map<VirtualPortId, VirtualPort> portMap = new HashMap<VirtualPortId, VirtualPort>();
-        Map<String, String> strMap = new HashMap<String, String>();
-        for (JsonNode vPortnode : vPortNodes) {
-            VirtualPortId id = VirtualPortId.portId(vPortnode.get("id")
-                    .asText());
-            String name = vPortnode.get("name").asText();
-            TenantId tenantId = TenantId.tenantId(vPortnode.get("tenant_id")
-                    .asText());
-            TenantNetworkId networkId = TenantNetworkId.networkId(vPortnode
-                    .get("network_id").asText());
-            Boolean adminStateUp = vPortnode.get("admin_state_up").asBoolean();
-            String state = vPortnode.get("status").asText();
-            MacAddress macAddress = MacAddress.valueOf(vPortnode
-                    .get("mac_address").asText());
-            DeviceId deviceId = DeviceId.deviceId(vPortnode.get("device_id")
-                    .asText());
-            String deviceOwner = vPortnode.get("device_owner").asText();
-            JsonNode fixedIpNode = vPortnode.get("fixed_ips");
-            FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
-            HostId bindingHostId = HostId.hostId(MacAddress.valueOf(vPortnode
-                    .get("binding:host_id").asText()));
-            String bindingVnicType = vPortnode.get("binding:vnic_type")
-                    .asText();
-            String bindingVifType = vPortnode.get("binding:vif_type").asText();
-            String bindingVifDetails = vPortnode.get("binding:vif_details")
-                    .asText();
-            JsonNode allowedAddressPairJsonNode = vPortnode
-                    .get("allowed_address_pairs");
-            Collection<AllowedAddressPair> allowedAddressPairs =
-                    jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
-            JsonNode securityGroupNode = vPortnode.get("security_groups");
-            Collection<SecurityGroup> securityGroups =
-                    jsonNodeToSecurityGroup(securityGroupNode);
-            strMap.putIfAbsent("name", name);
-            strMap.putIfAbsent("deviceOwner", deviceOwner);
-            strMap.putIfAbsent("bindingVnicType", bindingVnicType);
-            strMap.putIfAbsent("bindingVifType", bindingVifType);
-            strMap.putIfAbsent("bindingVifDetails", bindingVifDetails);
-            VirtualPort vPort = new DefaultVirtualPort(id, networkId,
-                                                       adminStateUp, strMap,
-                                                       isState(state),
-                                                       macAddress, tenantId,
-                                                       deviceId, fixedIp,
-                                                       bindingHostId,
-                                                       allowedAddressPairs,
-                                                       securityGroups);
-            portMap.put(id, vPort);
-        }
-        return Collections.unmodifiableCollection(portMap.values());
-    }
-
-    /**
-     * Returns a collection of virtualPorts from subnetNodes.
-     *
-     * @param vPortNodes the virtualPort json node
-     * @return virtualPorts a collection of virtualPorts
-     */
-    public Iterable<VirtualPort> changeJsonToPort(JsonNode vPortNodes) {
-        checkNotNull(vPortNodes, JSON_NOT_NULL);
-        Map<VirtualPortId, VirtualPort> vportMap = new HashMap<VirtualPortId, VirtualPort>();
-        Map<String, String> strMap = new HashMap<String, String>();
-        VirtualPortId id = VirtualPortId.portId(vPortNodes.get("id").asText());
-        String name = vPortNodes.get("name").asText();
-        TenantId tenantId = TenantId.tenantId(vPortNodes.get("tenant_id")
-                .asText());
-        TenantNetworkId networkId = TenantNetworkId.networkId(vPortNodes
-                .get("network_id").asText());
-        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
-        String state = vPortNodes.get("status").asText();
-        MacAddress macAddress = MacAddress.valueOf(vPortNodes
-                .get("mac_address").asText());
-        DeviceId deviceId = DeviceId.deviceId(vPortNodes.get("device_id")
-                .asText());
-        String deviceOwner = vPortNodes.get("device_owner").asText();
-        JsonNode fixedIpNode = vPortNodes.get("fixed_ips");
-        FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
-        HostId bindingHostId = HostId.hostId(MacAddress.valueOf(vPortNodes
-                .get("binding:host_id").asText()));
-        String bindingVnicType = vPortNodes.get("binding:vnic_type").asText();
-        String bindingVifType = vPortNodes.get("binding:vif_type").asText();
-        String bindingVifDetails = vPortNodes.get("binding:vif_details")
-                .asText();
-        JsonNode allowedAddressPairJsonNode = vPortNodes
-                .get("allowed_address_pairs");
-        Collection<AllowedAddressPair> allowedAddressPairs =
-                jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
-        JsonNode securityGroupNode = vPortNodes.get("security_groups");
-        Collection<SecurityGroup> securityGroups =
-                jsonNodeToSecurityGroup(securityGroupNode);
-        strMap.putIfAbsent("name", name);
-        strMap.putIfAbsent("deviceOwner", deviceOwner);
-        strMap.putIfAbsent("bindingVnicType", bindingVnicType);
-        strMap.putIfAbsent("bindingVifType", bindingVifType);
-        strMap.putIfAbsent("bindingVifDetails", bindingVifDetails);
-        VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
-                                                   strMap, isState(state),
-                                                   macAddress, tenantId,
-                                                   deviceId, fixedIp,
-                                                   bindingHostId,
-                                                   allowedAddressPairs,
-                                                   securityGroups);
-        vportMap.put(id, vPort);
-
-        return Collections.unmodifiableCollection(vportMap.values());
-    }
-
-    /**
-     * Returns a Object of the currently known infrastructure virtualPort.
-     *
-     * @param allowedAddressPairs the allowedAddressPairs json node
-     * @return a collection of allowedAddressPair
-     */
-    public Collection<AllowedAddressPair> jsonNodeToAllowedAddressPair(JsonNode allowedAddressPairs) {
-        checkNotNull(allowedAddressPairs, JSON_NOT_NULL);
-        ConcurrentMap<Integer, AllowedAddressPair> allowMaps = Maps
-                .newConcurrentMap();
-        int i = 0;
-        for (JsonNode node : allowedAddressPairs) {
-            IpAddress ip = IpAddress.valueOf(node.get("ip_address").asText());
-            MacAddress mac = MacAddress.valueOf(node.get("mac_address")
-                    .asText());
-            AllowedAddressPair allows = AllowedAddressPair
-                    .allowedAddressPair(ip, mac);
-            allowMaps.put(i, allows);
-            i++;
-        }
-        log.debug("The jsonNode of allowedAddressPairallow is {}"
-                + allowedAddressPairs.toString());
-        return Collections.unmodifiableCollection(allowMaps.values());
-    }
-
-    /**
-     * Returns a collection of virtualPorts.
-     *
-     * @param securityGroups the virtualPort jsonnode
-     * @return a collection of securityGroups
-     */
-    public Collection<SecurityGroup> jsonNodeToSecurityGroup(JsonNode securityGroups) {
-        checkNotNull(securityGroups, JSON_NOT_NULL);
-        ConcurrentMap<Integer, SecurityGroup> securMaps = Maps
-                .newConcurrentMap();
-        int i = 0;
-        for (JsonNode node : securityGroups) {
-            SecurityGroup securityGroup = SecurityGroup.securityGroup(node
-                    .get("security_group").asText());
-            securMaps.put(i, securityGroup);
-            i++;
-        }
-        return Collections.unmodifiableCollection(securMaps.values());
-    }
-
-    /**
-     * Returns a collection of fixedIps.
-     *
-     * @param fixedIpNode the fixedIp jsonnode
-     * @return a collection of SecurityGroup
-     */
-    public FixedIp jsonNodeToFixedIps(JsonNode fixedIpNode) {
-        SubnetId subnetId = SubnetId.subnetId(fixedIpNode.get("subnet_id")
-                .asText());
-        IpAddress ipAddress = IpAddress.valueOf(fixedIpNode.get("ip_address")
-                .asText());
-        FixedIp fixedIps = FixedIp.fixedIp(subnetId, ipAddress);
-        return fixedIps;
-    }
-
-    /**
-     * Returns VirtualPort State.
-     *
-     * @param state the virtualport state
-     * @return the virtualPort state
-     */
-    private State isState(String state) {
-        if (state.equals("ACTIVE")) {
-            return VirtualPort.State.ACTIVE;
-        } else {
-            return VirtualPort.State.DOWN;
-        }
-
-    }
-
-    /**
-     * 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;
-    }
-}
+/*
+ * 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.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+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.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.net.DeviceId;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultVirtualPort;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.VirtualPort.State;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.onosproject.vtnrsc.web.VirtualPortCodec;
+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 infrastructure
+ * virtualPort.
+ */
+@Path("ports")
+public class VirtualPortWebResource extends AbstractWebResource {
+    public static final String VPORT_NOT_FOUND = "VirtualPort is not found";
+    public static final String VPORT_ID_EXIST = "VirtualPort id is exist";
+    public static final String VPORT_ID_NOT_EXIST = "VirtualPort id is not exist";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+    protected static final Logger log = LoggerFactory
+            .getLogger(VirtualPortService.class);
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getPorts() {
+        Iterable<VirtualPort> virtualPorts = get(VirtualPortService.class)
+                .getPorts();
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("ports", new VirtualPortCodec().encode(virtualPorts, this));
+        return ok(result.toString()).build();
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getportsById(@PathParam("id") String id) {
+
+        if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
+            return ok("the virtualPort does not exists").build();
+        }
+        VirtualPort virtualPort = nullIsNotFound(get(VirtualPortService.class)
+                .getPort(VirtualPortId.portId(id)), VPORT_NOT_FOUND);
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("ports", new VirtualPortCodec().encode(virtualPort, this));
+        return ok(result.toString()).build();
+    }
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createPorts(InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
+            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
+                    .createPorts(vPorts), VPORT_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(VPORT_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Creates VirtualPort failed because of exception {}",
+                      e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @Path("{portUUID}")
+    @DELETE
+    public Response deletePorts(@PathParam("portUUID") String id) {
+        Set<VirtualPortId> vPortIds = new HashSet<VirtualPortId>();
+        try {
+            if (id != null) {
+                vPortIds.add(VirtualPortId.portId(id));
+            }
+            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
+                    .removePorts(vPortIds), VPORT_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(VPORT_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Deletes VirtualPort failed because of exception {}",
+                      e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response updatePorts(@PathParam("id") String id, InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
+            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
+                    .updatePorts(vPorts), VPORT_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(VPORT_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Updates failed because of exception {}", e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    /**
+     * Returns a Object of the currently known infrastructure virtualPort.
+     *
+     * @param vPortNode the virtualPort json node
+     * @return a collection of virtualPorts
+     */
+    public Iterable<VirtualPort> createOrUpdateByInputStream(JsonNode vPortNode) {
+        checkNotNull(vPortNode, JSON_NOT_NULL);
+        JsonNode vPortNodes = vPortNode.get("ports");
+        if (vPortNodes == null) {
+            vPortNodes = vPortNode.get("port");
+        }
+        if (vPortNodes.isArray()) {
+            return changeJsonToPorts(vPortNodes);
+        } else {
+            return changeJsonToPort(vPortNodes);
+        }
+    }
+
+    /**
+     * Returns the iterable collection of virtualports from subnetNodes.
+     *
+     * @param vPortNodes the virtualPort json node
+     * @return virtualPorts a collection of virtualPorts
+     */
+    public Iterable<VirtualPort> changeJsonToPorts(JsonNode vPortNodes) {
+        checkNotNull(vPortNodes, JSON_NOT_NULL);
+        Map<VirtualPortId, VirtualPort> portMap = new HashMap<VirtualPortId, VirtualPort>();
+        Map<String, String> strMap = new HashMap<String, String>();
+        for (JsonNode vPortnode : vPortNodes) {
+            VirtualPortId id = VirtualPortId.portId(vPortnode.get("id")
+                    .asText());
+            String name = vPortnode.get("name").asText();
+            TenantId tenantId = TenantId.tenantId(vPortnode.get("tenant_id")
+                    .asText());
+            TenantNetworkId networkId = TenantNetworkId.networkId(vPortnode
+                    .get("network_id").asText());
+            Boolean adminStateUp = vPortnode.get("admin_state_up").asBoolean();
+            String state = vPortnode.get("status").asText();
+            MacAddress macAddress = MacAddress.valueOf(vPortnode
+                    .get("mac_address").asText());
+            DeviceId deviceId = DeviceId.deviceId(vPortnode.get("device_id")
+                    .asText());
+            String deviceOwner = vPortnode.get("device_owner").asText();
+            JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
+            Set<FixedIp> fixedIps = new HashSet<FixedIp>();
+            for (JsonNode fixedIpNode : fixedIpNodes) {
+                FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
+                fixedIps.add(fixedIp);
+            }
+
+            BindingHostId bindingHostId = BindingHostId
+                    .bindingHostId(vPortnode.get("binding:host_id").asText());
+            String bindingVnicType = vPortnode.get("binding:vnic_type")
+                    .asText();
+            String bindingVifType = vPortnode.get("binding:vif_type").asText();
+            String bindingVifDetails = vPortnode.get("binding:vif_details")
+                    .asText();
+            JsonNode allowedAddressPairJsonNode = vPortnode
+                    .get("allowed_address_pairs");
+            Collection<AllowedAddressPair> allowedAddressPairs =
+                    jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
+            JsonNode securityGroupNode = vPortnode.get("security_groups");
+            Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
+            strMap.put("name", name);
+            strMap.put("deviceOwner", deviceOwner);
+            strMap.put("bindingVnicType", bindingVnicType);
+            strMap.put("bindingVifType", bindingVifType);
+            strMap.put("bindingVifDetails", bindingVifDetails);
+            VirtualPort vPort = new DefaultVirtualPort(id, networkId,
+                                                       adminStateUp, strMap,
+                                                       isState(state),
+                                                       macAddress, tenantId,
+                                                       deviceId, fixedIps,
+                                                       bindingHostId,
+                                                       allowedAddressPairs,
+                                                       securityGroups);
+            portMap.put(id, vPort);
+        }
+        return Collections.unmodifiableCollection(portMap.values());
+    }
+
+    /**
+     * Returns a collection of virtualPorts from subnetNodes.
+     *
+     * @param vPortNodes the virtualPort json node
+     * @return virtualPorts a collection of virtualPorts
+     */
+    public Iterable<VirtualPort> changeJsonToPort(JsonNode vPortNodes) {
+        checkNotNull(vPortNodes, JSON_NOT_NULL);
+        Map<VirtualPortId, VirtualPort> vportMap = new HashMap<VirtualPortId, VirtualPort>();
+        Map<String, String> strMap = new HashMap<String, String>();
+        VirtualPortId id = VirtualPortId.portId(vPortNodes.get("id").asText());
+        String name = vPortNodes.get("name").asText();
+        TenantId tenantId = TenantId.tenantId(vPortNodes.get("tenant_id")
+                .asText());
+        TenantNetworkId networkId = TenantNetworkId.networkId(vPortNodes
+                .get("network_id").asText());
+        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
+        String state = vPortNodes.get("status").asText();
+        MacAddress macAddress = MacAddress.valueOf(vPortNodes
+                .get("mac_address").asText());
+        DeviceId deviceId = DeviceId.deviceId(vPortNodes.get("device_id")
+                .asText());
+        String deviceOwner = vPortNodes.get("device_owner").asText();
+        JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
+        Set<FixedIp> fixedIps = new HashSet<FixedIp>();
+        for (JsonNode fixedIpNode : fixedIpNodes) {
+            FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
+            fixedIps.add(fixedIp);
+        }
+
+        BindingHostId bindingHostId = BindingHostId
+                .bindingHostId(vPortNodes.get("binding:host_id").asText());
+        String bindingVnicType = vPortNodes.get("binding:vnic_type").asText();
+        String bindingVifType = vPortNodes.get("binding:vif_type").asText();
+        String bindingVifDetails = vPortNodes.get("binding:vif_details")
+                .asText();
+        JsonNode allowedAddressPairJsonNode = vPortNodes
+                .get("allowed_address_pairs");
+        Collection<AllowedAddressPair> allowedAddressPairs =
+                jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
+        JsonNode securityGroupNode = vPortNodes.get("security_groups");
+        Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
+        strMap.put("name", name);
+        strMap.put("deviceOwner", deviceOwner);
+        strMap.put("bindingVnicType", bindingVnicType);
+        strMap.put("bindingVifType", bindingVifType);
+        strMap.put("bindingVifDetails", bindingVifDetails);
+        VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
+                                                   strMap, isState(state),
+                                                   macAddress, tenantId,
+                                                   deviceId, fixedIps,
+                                                   bindingHostId,
+                                                   allowedAddressPairs,
+                                                   securityGroups);
+        vportMap.put(id, vPort);
+
+        return Collections.unmodifiableCollection(vportMap.values());
+    }
+
+    /**
+     * Returns a Object of the currently known infrastructure virtualPort.
+     *
+     * @param allowedAddressPairs the allowedAddressPairs json node
+     * @return a collection of allowedAddressPair
+     */
+    public Collection<AllowedAddressPair> jsonNodeToAllowedAddressPair(JsonNode allowedAddressPairs) {
+        checkNotNull(allowedAddressPairs, JSON_NOT_NULL);
+        ConcurrentMap<Integer, AllowedAddressPair> allowMaps = Maps
+                .newConcurrentMap();
+        int i = 0;
+        for (JsonNode node : allowedAddressPairs) {
+            IpAddress ip = IpAddress.valueOf(node.get("ip_address").asText());
+            MacAddress mac = MacAddress.valueOf(node.get("mac_address")
+                    .asText());
+            AllowedAddressPair allows = AllowedAddressPair
+                    .allowedAddressPair(ip, mac);
+            allowMaps.put(i, allows);
+            i++;
+        }
+        log.debug("The jsonNode of allowedAddressPairallow is {}"
+                + allowedAddressPairs.toString());
+        return Collections.unmodifiableCollection(allowMaps.values());
+    }
+
+    /**
+     * Returns a collection of virtualPorts.
+     *
+     * @param securityGroups the virtualPort jsonnode
+     * @return a collection of securityGroups
+     */
+    public Collection<SecurityGroup> jsonNodeToSecurityGroup(JsonNode securityGroups) {
+        checkNotNull(securityGroups, JSON_NOT_NULL);
+        ConcurrentMap<Integer, SecurityGroup> securMaps = Maps
+                .newConcurrentMap();
+        int i = 0;
+        for (JsonNode node : securityGroups) {
+            SecurityGroup securityGroup = SecurityGroup
+                    .securityGroup(node.asText());
+            securMaps.put(i, securityGroup);
+            i++;
+        }
+        return Collections.unmodifiableCollection(securMaps.values());
+    }
+
+    /**
+     * Returns a collection of fixedIps.
+     *
+     * @param fixedIpNode the fixedIp jsonnode
+     * @return a collection of SecurityGroup
+     */
+    public FixedIp jsonNodeToFixedIps(JsonNode fixedIpNode) {
+        SubnetId subnetId = SubnetId.subnetId(fixedIpNode.get("subnet_id")
+                .asText());
+        IpAddress ipAddress = IpAddress.valueOf(fixedIpNode.get("ip_address")
+                .asText());
+        FixedIp fixedIps = FixedIp.fixedIp(subnetId, ipAddress);
+        return fixedIps;
+    }
+
+    /**
+     * Returns VirtualPort State.
+     *
+     * @param state the virtualport state
+     * @return the virtualPort state
+     */
+    private State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return VirtualPort.State.ACTIVE;
+        } else {
+            return VirtualPort.State.DOWN;
+        }
+
+    }
+
+    /**
+     * 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;
+    }
+}
