diff --git a/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java b/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java
index 1fa6f79..4d45a30 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java
@@ -47,7 +47,9 @@
                 FlowObjectiveWebResource.class,
                 MulticastRouteWebResource.class,
                 DeviceKeyWebResource.class,
-                RegionsWebResource.class
+                RegionsWebResource.class,
+                TenantWebResource.class,
+                VirtualNetworkWebResource.class
         );
     }
 }
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/TenantWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/TenantWebResource.java
new file mode 100755
index 0000000..4ba8d44
--- /dev/null
+++ b/web/api/src/main/java/org/onosproject/rest/resources/TenantWebResource.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2016 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.rest.resources;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Query and manage tenants of virtual networks.
+ */
+@Path("tenants")
+public class TenantWebResource extends AbstractWebResource {
+
+    private static final String MISSING_TENANTID = "Missing tenant identifier";
+    private static final String TENANTID_NOT_FOUND = "Tenant identifier not found";
+    private static final String INVALID_TENANTID = "Invalid tenant identifier ";
+
+    @Context
+    UriInfo uriInfo;
+
+    private final VirtualNetworkAdminService vnetAdminService = get(VirtualNetworkAdminService.class);
+
+    /**
+     * Returns all tenants.
+     *
+     * @return 200 OK
+     * @onos.rsModel TenantIds
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getVirtualNetworkTenants() {
+        Iterable<TenantId> tenantIds = vnetAdminService.getTenantIds();
+        return ok(encodeArray(TenantId.class, "tenants", tenantIds)).build();
+    }
+
+    /**
+     * Creates a tenant with the given tenant identifier.
+     *
+     * @param stream TenantId JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel TenantId
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response addTenantId(InputStream stream) {
+        try {
+            final TenantId tid = getTenantIdFromJsonStream(stream);
+            vnetAdminService.registerTenantId(tid);
+            final TenantId resultTid = getExistingTenantId(vnetAdminService, tid);
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("tenants")
+                    .path(resultTid.id());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the specified tenant with the specified tenant identifier.
+     *
+     * @param tenantId tenant identifier
+     * @return 200 OK, 404 not found
+     */
+    @DELETE
+    @Path("{tenantId}")
+    public Response removeTenantId(@PathParam("tenantId") String tenantId) {
+        final TenantId tid = TenantId.tenantId(tenantId);
+        final TenantId existingTid = getExistingTenantId(vnetAdminService, tid);
+        vnetAdminService.unregisterTenantId(existingTid);
+        return Response.ok().build();
+    }
+
+    /**
+     * Removes the specified tenant with the specified tenant identifier.
+     *
+     * @param stream deviceIds JSON stream
+     * @return 200 OK, 404 not found
+     * @onos.rsModel TenantId
+     */
+    @DELETE
+    public Response removeTenantId(InputStream stream) {
+        try {
+            final TenantId tid = getTenantIdFromJsonStream(stream);
+            vnetAdminService.unregisterTenantId(tid);
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+        return Response.ok().build();
+    }
+
+    /**
+     * Get the tenant identifier from the JSON stream.
+     *
+     * @param stream TenantId JSON stream
+     * @return TenantId
+     * @throws IOException
+     */
+    private TenantId getTenantIdFromJsonStream(InputStream stream) throws IOException {
+        ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+        JsonNode specifiedTenantId = jsonTree.get("id");
+
+        if (specifiedTenantId == null) {
+            throw new IllegalArgumentException(MISSING_TENANTID);
+        }
+        return TenantId.tenantId(specifiedTenantId.asText());
+    }
+
+    /**
+     * Get the matching tenant identifier from existing tenant identifiers in system.
+     *
+     * @param vnetAdminSvc
+     * @param tidIn tenant identifier
+     * @return TenantId
+     */
+    private static TenantId getExistingTenantId(VirtualNetworkAdminService vnetAdminSvc,
+                                               TenantId tidIn) {
+        final TenantId resultTid = vnetAdminSvc
+                .getTenantIds()
+                .stream()
+                .filter(tenantId -> tenantId.equals(tidIn))
+                .findFirst()
+                .orElseThrow(() -> new ItemNotFoundException(TENANTID_NOT_FOUND));
+        return resultTid;
+    }
+}
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/VirtualNetworkWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/VirtualNetworkWebResource.java
new file mode 100755
index 0000000..62ec090
--- /dev/null
+++ b/web/api/src/main/java/org/onosproject/rest/resources/VirtualNetworkWebResource.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2016 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.rest.resources;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.rest.AbstractWebResource;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Query and Manage Virtual Network elements.
+ */
+@Path("vnets")
+public class VirtualNetworkWebResource extends AbstractWebResource {
+
+    private static final String MISSING_FIELD = "Missing ";
+    private static final String INVALID_FIELD = "Invalid ";
+
+    private final VirtualNetworkAdminService vnetAdminService = get(VirtualNetworkAdminService.class);
+    private final VirtualNetworkService vnetService = get(VirtualNetworkService.class);
+
+    @Context
+    UriInfo uriInfo;
+
+    // VirtualNetwork
+    // TODO Query vnets by tenant
+
+    /**
+     * Returns all virtual networks.
+     *
+     * @return 200 OK
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getVirtualNetworks() {
+        Set<TenantId> tenantIds = vnetAdminService.getTenantIds();
+        List<VirtualNetwork> allVnets = tenantIds.stream()
+                .map(tenantId -> vnetService.getVirtualNetworks(tenantId))
+                .flatMap(Collection::stream)
+                .collect(Collectors.toList());
+        return ok(encodeArray(VirtualNetwork.class, "vnets", allVnets)).build();
+    }
+
+    /**
+     * Creates a virtual network from the JSON input stream.
+     *
+     * @param stream TenantId JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel TenantId
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createVirtualNetwork(InputStream stream) {
+        try {
+            final TenantId tid = TenantId.tenantId(getFromJsonStream(stream, "id").asText());
+            VirtualNetwork newVnet = vnetAdminService.createVirtualNetwork(tid);
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets")
+                    .path(newVnet.id().toString());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network with the specified network identifier.
+     *
+     * @param networkId network identifier
+     * @return 200 OK, 404 not found
+     */
+    @DELETE
+    @Path("{networkId}")
+    public Response removeVirtualNetwork(@PathParam("networkId") long networkId) {
+        final NetworkId nid = NetworkId.networkId(networkId);
+        vnetAdminService.removeVirtualNetwork(nid);
+        return Response.ok().build();
+    }
+
+    // VirtualDevice
+
+    /**
+     * Returns all virtual network devices in a virtual network.
+     *
+     * @param networkId network identifier
+     * @return 200 OK
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/devices")
+    public Response getVirtualDevices(@PathParam("networkId") long networkId) {
+        final NetworkId nid = NetworkId.networkId(networkId);
+        Set<VirtualDevice> vdevs  = vnetService.getVirtualDevices(nid);
+        return ok(encodeArray(VirtualDevice.class, "devices", vdevs)).build();
+    }
+
+    /**
+     * Creates a virtual device from the JSON input stream.
+     *
+     * @param networkId network identifier
+     * @param stream Virtual device JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel VirtualDevice
+     */
+    @POST
+    @Path("{networkId}/devices/")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createVirtualDevice(@PathParam("networkId") long networkId,
+                                        InputStream stream) {
+        try {
+            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+            final VirtualDevice vdevReq = codec(VirtualDevice.class).decode(jsonTree, this);
+            JsonNode specifiedRegionId = jsonTree.get("networkId");
+            if (specifiedRegionId != null &&
+                    specifiedRegionId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            final VirtualDevice vdevRes = vnetAdminService.createVirtualDevice(vdevReq.networkId(),
+                                                                               vdevReq.id());
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets").path(specifiedRegionId.asText())
+                    .path("devices").path(vdevRes.id().toString());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network device from the virtual network.
+     *
+     * @param networkId network identifier
+     * @param deviceId device identifier
+     * @return 200 OK, 404 not found
+     */
+    @DELETE
+    @Path("{networkId}/devices/{deviceId}")
+    public Response removeVirtualDevice(@PathParam("networkId") long networkId,
+            @PathParam("deviceId") String deviceId) {
+        final NetworkId nid = NetworkId.networkId(networkId);
+        final DeviceId did = DeviceId.deviceId(deviceId);
+        vnetAdminService.removeVirtualDevice(nid, did);
+        return Response.ok().build();
+    }
+
+    // VirtualPort
+
+    /**
+     * Returns all virtual network ports in a virtual device in a virtual network.
+     *
+     * @param networkId network identifier
+     * @param deviceId virtual device identifier
+     * @return 200 OK
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/devices/{deviceId}/ports")
+    public Response getVirtualPorts(@PathParam("networkId") long networkId,
+            @PathParam("deviceId") String deviceId) {
+        final NetworkId nid = NetworkId.networkId(networkId);
+        Iterable<VirtualPort> vports  = vnetService.getVirtualPorts(nid, DeviceId.deviceId(deviceId));
+        return ok(encodeArray(VirtualPort.class, "ports", vports)).build();
+    }
+
+    /**
+     * Creates a virtual network port in a virtual device in a virtual network.
+     *
+     * @param networkId network identifier
+     * @param virtDeviceId virtual device identifier
+     * @param stream Virtual device JSON stream
+     * @return status of the request - CREATED if the JSON is correct,
+     * BAD_REQUEST if the JSON is invalid
+     * @onos.rsModel VirtualPort
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("{networkId}/devices/{deviceId}/ports")
+    public Response createVirtualPort(@PathParam("networkId") long networkId,
+            @PathParam("deviceId") String virtDeviceId,
+            InputStream stream) {
+        try {
+            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+//            final VirtualPort vportReq = codec(VirtualPort.class).decode(jsonTree, this);
+            JsonNode specifiedNetworkId = jsonTree.get("networkId");
+            JsonNode specifiedDeviceId = jsonTree.get("deviceId");
+            if (specifiedNetworkId != null &&
+                    specifiedNetworkId.asLong() != (networkId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "networkId");
+            }
+            if (specifiedDeviceId != null &&
+                    !specifiedDeviceId.asText().equals(virtDeviceId)) {
+                throw new IllegalArgumentException(INVALID_FIELD + "deviceId");
+            }
+            JsonNode specifiedPortNum = jsonTree.get("portNum");
+            JsonNode specifiedPhysDeviceId = jsonTree.get("physDeviceId");
+            JsonNode specifiedPhysPortNum = jsonTree.get("physPortNum");
+            final NetworkId nid = NetworkId.networkId(networkId);
+            DeviceId vdevId = DeviceId.deviceId(virtDeviceId);
+            DefaultAnnotations annotations = DefaultAnnotations.builder().build();
+            Device physDevice = new DefaultDevice(null, DeviceId.deviceId(specifiedPhysDeviceId.asText()),
+                    null, null, null, null, null, null, annotations);
+            Port realizedBy = new DefaultPort(physDevice,
+                    PortNumber.portNumber(specifiedPhysPortNum.asText()), true);
+            VirtualPort vport = vnetAdminService.createVirtualPort(nid, vdevId,
+                    PortNumber.portNumber(specifiedPortNum.asText()), realizedBy);
+            UriBuilder locationBuilder = uriInfo.getBaseUriBuilder()
+                    .path("vnets").path(specifiedNetworkId.asText())
+                    .path("devices").path(specifiedDeviceId.asText())
+                    .path("ports").path(vport.number().toString());
+            return Response
+                    .created(locationBuilder.build())
+                    .build();
+        } catch (IOException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Removes the virtual network port from the virtual device in a virtual network.
+     *
+     * @param networkId network identifier
+     * @param deviceId virtual device identifier
+     * @param portNum virtual port number
+     * @return 200 OK, 404 not found
+     */
+    @DELETE
+    @Path("{networkId}/devices/{deviceId}/ports/{portNum}")
+    public Response removeVirtualPort(@PathParam("networkId") long networkId,
+            @PathParam("deviceId") String deviceId,
+            @PathParam("portNum") long portNum) {
+        final NetworkId nid = NetworkId.networkId(networkId);
+        vnetAdminService.removeVirtualPort(nid, DeviceId.deviceId(deviceId),
+                PortNumber.portNumber(portNum));
+        return Response.ok().build();
+    }
+
+    // TODO VirtualLink
+
+    /**
+     * Get the tenant identifier from the JSON stream.
+     *
+     * @param stream TenantId JSON stream
+     * @param jsonFieldName field name
+     * @return JsonNode
+     * @throws IOException
+     */
+    private JsonNode getFromJsonStream(InputStream stream, String jsonFieldName) throws IOException {
+        ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+        JsonNode jsonNode = jsonTree.get(jsonFieldName);
+
+        if (jsonNode == null) {
+            throw new IllegalArgumentException(MISSING_FIELD + jsonFieldName);
+        }
+        return jsonNode;
+    }
+}
diff --git a/web/api/src/main/resources/definitions/TenantId.json b/web/api/src/main/resources/definitions/TenantId.json
new file mode 100644
index 0000000..23981e8
--- /dev/null
+++ b/web/api/src/main/resources/definitions/TenantId.json
@@ -0,0 +1,13 @@
+{
+  "type": "object",
+  "title": "TenantId",
+  "required": [
+    "id"
+  ],
+  "properties": {
+    "id": {
+      "type": "String",
+      "example": "Tenant unique identifier"
+    }
+  }
+}
diff --git a/web/api/src/main/resources/definitions/TenantIds.json b/web/api/src/main/resources/definitions/TenantIds.json
new file mode 100644
index 0000000..91e104b
--- /dev/null
+++ b/web/api/src/main/resources/definitions/TenantIds.json
@@ -0,0 +1,29 @@
+{
+  "type": "object",
+  "title": "tenants",
+  "required": [
+    "tenants"
+  ],
+  "properties": {
+    "tenants": {
+      "type": "array",
+      "xml": {
+        "name": "tenants",
+        "wrapped": true
+      },
+      "items": {
+        "type": "object",
+        "title": "tenant",
+        "required": [
+          "id"
+        ],
+        "properties": {
+          "id": {
+            "type": "String",
+            "example": "Tenant unique identifier"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/web/api/src/main/resources/definitions/VirtualDevice.json b/web/api/src/main/resources/definitions/VirtualDevice.json
new file mode 100644
index 0000000..858c49d
--- /dev/null
+++ b/web/api/src/main/resources/definitions/VirtualDevice.json
@@ -0,0 +1,18 @@
+{
+  "type": "object",
+  "title": "vdev",
+  "required": [
+    "networkId",
+    "deviceId"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "String",
+      "example": "Network identifier"
+    },
+    "deviceId": {
+      "type": "String",
+      "example": "Device identifier"
+    }
+  }
+}
diff --git a/web/api/src/main/resources/definitions/VirtualPort.json b/web/api/src/main/resources/definitions/VirtualPort.json
new file mode 100644
index 0000000..89cb6c1
--- /dev/null
+++ b/web/api/src/main/resources/definitions/VirtualPort.json
@@ -0,0 +1,33 @@
+{
+  "type": "object",
+  "title": "vport",
+  "required": [
+    "networkId",
+    "deviceId",
+    "portNum",
+    "physDeviceId",
+    "physPortNum"
+  ],
+  "properties": {
+    "networkId": {
+      "type": "String",
+      "example": "Network identifier"
+    },
+    "deviceId": {
+      "type": "String",
+      "example": "Virtual device identifier"
+    },
+    "portNum": {
+      "type": "String",
+      "example": "Virtual device port number"
+    },
+    "physDeviceId": {
+      "type": "String",
+      "example": "Physical device identifier"
+    },
+    "physPortNum": {
+      "type": "String",
+      "example": "Physical device port number"
+    }
+  }
+}
diff --git a/web/api/src/test/java/org/onosproject/rest/resources/TenantWebResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/TenantWebResourceTest.java
new file mode 100644
index 0000000..03b6e4e
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/resources/TenantWebResourceTest.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2016 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.rest.resources;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableSet;
+import org.glassfish.jersey.client.ClientProperties;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for tenant REST APIs.
+ */
+public class TenantWebResourceTest extends ResourceTest {
+
+    private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
+
+    final HashSet<TenantId> tenantIdSet = new HashSet<>();
+
+    private static final String ID = "id";
+
+    private final TenantId tenantId1 = TenantId.tenantId("TenantId1");
+    private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
+    private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
+    private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Register the services needed for the test
+        CodecManager codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(VirtualNetworkAdminService.class, mockVnetAdminService)
+                        .add(CodecService.class, codecService);
+
+        BaseResource.setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Hamcrest matcher to check that a tenant id representation in JSON matches
+     * the actual tenant id.
+     */
+    public static class TenantIdJsonMatcher extends TypeSafeMatcher<JsonObject> {
+        private final TenantId tenantId;
+        private String reason = "";
+
+        public TenantIdJsonMatcher(TenantId tenantIdValue) {
+            tenantId = tenantIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            // Check the tenant id
+            final String jsonId = jsonHost.get(ID).asString();
+            if (!jsonId.equals(tenantId.id())) {
+                reason = ID + " " + tenantId.id();
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a tenant id array matcher.
+     *
+     * @param tenantId tenant id object we are looking for
+     * @return matcher
+     */
+    private static TenantIdJsonMatcher matchesTenantId(TenantId tenantId) {
+        return new TenantIdJsonMatcher(tenantId);
+    }
+
+    /**
+     * Hamcrest matcher to check that a tenant id is represented properly in a JSON
+     * array of tenant ids.
+     */
+    public static class TenantIdJsonArrayMatcher extends TypeSafeMatcher<JsonArray> {
+        private final TenantId tenantId;
+        private String reason = "";
+
+        public TenantIdJsonArrayMatcher(TenantId tenantIdValue) {
+            tenantId = tenantIdValue;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean tenantIdFound = false;
+            final int expectedAttributes = 1;
+            for (int tenantIdIndex = 0; tenantIdIndex < json.size();
+                 tenantIdIndex++) {
+
+                final JsonObject jsonHost = json.get(tenantIdIndex).asObject();
+
+                // Only 1 attribute - ID.
+                if (jsonHost.names().size() < expectedAttributes) {
+                    reason = "Found a tenant id with the wrong number of attributes";
+                    return false;
+                }
+
+                final String jsonDeviceKeyId = jsonHost.get(ID).asString();
+                if (jsonDeviceKeyId.equals(tenantId.id())) {
+                    tenantIdFound = true;
+
+                    //  We found the correct tenant id, check the tenant id attribute values
+                    assertThat(jsonHost, matchesTenantId(tenantId));
+                }
+            }
+            if (!tenantIdFound) {
+                reason = "Tenant id " + tenantId.id() + " was not found";
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a tenant id array matcher.
+     *
+     * @param tenantId tenant id object we are looking for
+     * @return matcher
+     */
+    private static TenantIdJsonArrayMatcher hasTenantId(TenantId tenantId) {
+        return new TenantIdJsonArrayMatcher(tenantId);
+    }
+
+    /**
+     * Tests the result of the REST API GET when there are no tenant ids.
+     */
+    @Test
+    public void testGetTenantsEmptyArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        String response = wt.path("tenants").request().get(String.class);
+        assertThat(response, is("{\"tenants\":[]}"));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when tenant ids are defined.
+     */
+    @Test
+    public void testGetTenantIdsArray() {
+        tenantIdSet.add(tenantId1);
+        tenantIdSet.add(tenantId2);
+        tenantIdSet.add(tenantId3);
+        tenantIdSet.add(tenantId4);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(tenantIdSet).anyTimes();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        String response = wt.path("tenants").request().get(String.class);
+        assertThat(response, containsString("{\"tenants\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("tenants"));
+
+        final JsonArray tenantIds = result.get("tenants").asArray();
+        assertThat(tenantIds, notNullValue());
+        assertEquals("Device keys array is not the correct size.",
+                     tenantIdSet.size(), tenantIds.size());
+
+        tenantIdSet.forEach(tenantId -> assertThat(tenantIds, hasTenantId(tenantId)));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of new tenant id using POST via JSON stream.
+     */
+    @Test
+    public void testPost() {
+        mockVnetAdminService.registerTenantId(anyObject());
+        tenantIdSet.add(tenantId2);
+        expect(mockVnetAdminService.getTenantIds()).andReturn(tenantIdSet).anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+
+        Response response = wt.path("tenants").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/tenants/" + tenantId2));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null tenant id using POST via JSON stream.
+     */
+    @Test
+    public void testPostNullTenantId() {
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String response = wt.path("tenants")
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null tenant id did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a tenant id with DELETE request.
+     */
+    @Test
+    public void testDelete() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of(tenantId2)).anyTimes();
+        mockVnetAdminService.unregisterTenantId(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        Response response = wt.path("tenants/" + tenantId2)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a tenant id with DELETE request via JSON stream.
+     */
+    @Test
+    public void testDeleteViaJson() {
+        mockVnetAdminService.unregisterTenantId(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+        Response response = wt.request().method("DELETE", Entity.json(jsonStream));
+
+//        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+//        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests that a DELETE of a non-existent tenant id throws an exception.
+     */
+    @Test
+    public void testDeleteNonExistentDeviceKey() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of())
+                .anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("tenants/" + "NON_EXISTENT_TENANT_ID")
+                    .request()
+                    .delete(String.class);
+            fail("Delete of a non-existent tenant did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+}
diff --git a/web/api/src/test/java/org/onosproject/rest/resources/VirtualNetworkWebResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/VirtualNetworkWebResourceTest.java
new file mode 100644
index 0000000..9581e3a
--- /dev/null
+++ b/web/api/src/test/java/org/onosproject/rest/resources/VirtualNetworkWebResourceTest.java
@@ -0,0 +1,760 @@
+/*
+ * Copyright 2016 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.rest.resources;
+
+import com.eclipsesource.json.Json;
+import com.eclipsesource.json.JsonArray;
+import com.eclipsesource.json.JsonObject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.glassfish.jersey.client.ClientProperties;
+import org.hamcrest.Description;
+import org.hamcrest.Matchers;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onlab.rest.BaseResource;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.NotFoundException;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Unit tests for virtual network REST APIs.
+ */
+public class VirtualNetworkWebResourceTest extends ResourceTest {
+
+    private final VirtualNetworkAdminService mockVnetAdminService = createMock(VirtualNetworkAdminService.class);
+    private final VirtualNetworkService mockVnetService = createMock(VirtualNetworkService.class);
+    private CodecManager codecService;
+
+    final HashSet<TenantId> tenantIdSet = new HashSet<>();
+    final HashSet<VirtualNetwork> vnetSet = new HashSet<>();
+    final HashSet<VirtualDevice> vdevSet = new HashSet<>();
+    final HashSet<VirtualPort> vportSet = new HashSet<>();
+
+    private static final String ID = "networkId";
+    private static final String TENANT_ID = "tenantId";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String PORT_NUM = "portNum";
+    private static final String PHYS_DEVICE_ID = "physDeviceId";
+    private static final String PHYS_PORT_NUM = "physPortNum";
+
+    private final TenantId tenantId1 = TenantId.tenantId("TenantId1");
+    private final TenantId tenantId2 = TenantId.tenantId("TenantId2");
+    private final TenantId tenantId3 = TenantId.tenantId("TenantId3");
+    private final TenantId tenantId4 = TenantId.tenantId("TenantId4");
+
+    private final NetworkId networkId1 = NetworkId.networkId(1);
+    private final NetworkId networkId2 = NetworkId.networkId(2);
+    private final NetworkId networkId3 = NetworkId.networkId(3);
+    private final NetworkId networkId4 = NetworkId.networkId(4);
+
+    private final VirtualNetwork vnet1 = new DefaultVirtualNetwork(networkId1, tenantId3);
+    private final VirtualNetwork vnet2 = new DefaultVirtualNetwork(networkId2, tenantId3);
+    private final VirtualNetwork vnet3 = new DefaultVirtualNetwork(networkId3, tenantId3);
+    private final VirtualNetwork vnet4 = new DefaultVirtualNetwork(networkId4, tenantId3);
+
+    private final DeviceId devId1 = DeviceId.deviceId("devId1");
+    private final DeviceId devId2 = DeviceId.deviceId("devId2");
+    private final DeviceId devId22 = DeviceId.deviceId("dev22");
+
+    private final VirtualDevice vdev1 = new DefaultVirtualDevice(networkId3, devId1);
+    private final VirtualDevice vdev2 = new DefaultVirtualDevice(networkId3, devId2);
+
+    private final Device dev1 = NetTestTools.device("dev1");
+    private final Device dev2 = NetTestTools.device("dev2");
+    private final Device dev22 = NetTestTools.device("dev22");
+
+    Port port1 = new DefaultPort(dev1, portNumber(1), true);
+    Port port2 = new DefaultPort(dev2, portNumber(2), true);
+
+    private final VirtualPort vport22 = new DefaultVirtualPort(networkId3,
+                                                              dev22, portNumber(22), port1);
+    private final VirtualPort vport23 = new DefaultVirtualPort(networkId3,
+                                                              dev22, portNumber(23), port2);
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        // Register the services needed for the test
+        codecService = new CodecManager();
+        codecService.activate();
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(VirtualNetworkAdminService.class, mockVnetAdminService)
+                        .add(VirtualNetworkService.class, mockVnetService)
+                        .add(CodecService.class, codecService);
+
+        BaseResource.setServiceDirectory(testDirectory);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual network entity representation in JSON matches
+     * the actual virtual network entity.
+     */
+    public static class JsonObjectMatcher<T> extends TypeSafeMatcher<JsonObject> {
+        private final T vnetEntity;
+        private List<String> jsonFieldNames;
+        private String reason = "";
+        private BiFunction<T, String, String> getValue; // get vnetEntity's value
+
+        public JsonObjectMatcher(T vnetEntityValue,
+                                 List<String> jsonFieldNames1,
+                                 BiFunction<T, String, String> getValue1) {
+            vnetEntity = vnetEntityValue;
+            jsonFieldNames = jsonFieldNames1;
+            getValue = getValue1;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonObject jsonHost) {
+            return jsonFieldNames
+                    .stream()
+                    .allMatch(s -> checkField(jsonHost, s, getValue.apply(vnetEntity, s)));
+        }
+
+        private boolean checkField(JsonObject jsonHost, String jsonFieldName,
+                                   String objectValue) {
+            final String jsonValue = jsonHost.get(jsonFieldName).asString();
+            if (!jsonValue.equals(objectValue)) {
+                reason = jsonFieldName + " " + objectValue;
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual network id array matcher.
+     *
+     * @param obj virtual network id object we are looking for
+     * @return matcher
+     */
+    /**
+     * Factory to allocate a virtual network entity matcher.
+     *
+     * @param obj virtual network object we are looking for
+     * @param jsonFieldNames JSON field names to check against
+     * @param getValue function to retrieve value from virtual network object
+     * @param <T>
+     * @return JsonObjectMatcher
+     */
+    private static <T> JsonObjectMatcher matchesVnetEntity(T obj, List<String> jsonFieldNames,
+                                                    BiFunction<T, String, String> getValue) {
+        return new JsonObjectMatcher(obj, jsonFieldNames, getValue);
+    }
+
+    /**
+     * Hamcrest matcher to check that a virtual network entity is represented properly in a JSON
+     * array of virtual network entities.
+     */
+    public static class JsonArrayMatcher<T> extends TypeSafeMatcher<JsonArray> {
+        private final T vnetEntity;
+        private String reason = "";
+        private Function<T, String> getKey; // gets vnetEntity's key
+        private BiPredicate<T, JsonObject> checkKey; // check vnetEntity's key with JSON rep'n
+        private List<String> jsonFieldNames; // field/property names
+        private BiFunction<T, String, String> getValue; // get vnetEntity's value
+
+        public JsonArrayMatcher(T vnetEntityValue, Function<T, String> getKey1,
+                                BiPredicate<T, JsonObject> checkKey1,
+                                List<String> jsonFieldNames1,
+                                BiFunction<T, String, String> getValue1) {
+            vnetEntity = vnetEntityValue;
+            getKey = getKey1;
+            checkKey = checkKey1;
+            jsonFieldNames = jsonFieldNames1;
+            getValue = getValue1;
+        }
+
+        @Override
+        public boolean matchesSafely(JsonArray json) {
+            boolean itemFound = false;
+            final int expectedAttributes = jsonFieldNames.size();
+            for (int jsonArrayIndex = 0; jsonArrayIndex < json.size();
+                 jsonArrayIndex++) {
+
+                final JsonObject jsonHost = json.get(jsonArrayIndex).asObject();
+
+                if (jsonHost.names().size() < expectedAttributes) {
+                    reason = "Found a virtual network with the wrong number of attributes";
+                    return false;
+                }
+
+                if (checkKey != null && checkKey.test(vnetEntity, jsonHost)) {
+                    itemFound = true;
+                    assertThat(jsonHost, matchesVnetEntity(vnetEntity, jsonFieldNames, getValue));
+                }
+            }
+            if (!itemFound) {
+                reason = getKey.apply(vnetEntity) + " was not found";
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(Description description) {
+            description.appendText(reason);
+        }
+    }
+
+    /**
+     * Array matcher for VirtualNetwork.
+     */
+    public static class VnetJsonArrayMatcher extends JsonArrayMatcher<VirtualNetwork> {
+
+        public VnetJsonArrayMatcher(VirtualNetwork vnetIn) {
+            super(vnetIn,
+                  vnet -> "Virtual network " + vnet.id().toString(),
+                  (vnet, jsonObject) -> {
+                      return jsonObject.get(ID).asString().equals(vnet.id().toString()); },
+                  ImmutableList.of(ID, TENANT_ID),
+                  (vnet, s) -> {
+                      return s.equals(ID) ? vnet.id().toString()
+                              : s.equals(TENANT_ID) ? vnet.tenantId().toString()
+                              : null;
+                      }
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual network array matcher.
+     *
+     * @param vnet virtual network object we are looking for
+     * @return matcher
+     */
+    private VnetJsonArrayMatcher hasVnet(VirtualNetwork vnet) {
+        return new VnetJsonArrayMatcher(vnet);
+    }
+
+    // Tests for Virtual Networks
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual networks.
+     */
+    @Test
+    public void testGetVirtualNetworksEmptyArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetAdminService);
+        expect(mockVnetService.getVirtualNetworks(tenantId4)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets").request().get(String.class);
+        assertThat(response, is("{\"vnets\":[]}"));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual networks are defined.
+     */
+    @Test
+    public void testGetVirtualNetworksArray() {
+        expect(mockVnetAdminService.getTenantIds()).andReturn(ImmutableSet.of(tenantId3)).anyTimes();
+        replay(mockVnetAdminService);
+        vnetSet.add(vnet1);
+        vnetSet.add(vnet2);
+        vnetSet.add(vnet3);
+        vnetSet.add(vnet4);
+        expect(mockVnetService.getVirtualNetworks(tenantId3)).andReturn(vnetSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String response = wt.path("vnets").request().get(String.class);
+        assertThat(response, containsString("{\"vnets\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("vnets"));
+
+        final JsonArray vnetJsonArray = result.get("vnets").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual networks array is not the correct size.",
+                     vnetSet.size(), vnetJsonArray.size());
+
+        vnetSet.forEach(vnet -> assertThat(vnetJsonArray, hasVnet(vnet)));
+
+        verify(mockVnetService);
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of new virtual network using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualNetwork() {
+        expect(mockVnetAdminService.createVirtualNetwork(tenantId2)).andReturn(vnet1);
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = TenantWebResourceTest.class
+                .getResourceAsStream("post-tenant.json");
+
+        Response response = wt.path("vnets").request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/vnets/" + vnet1.id().toString()));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual network using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualNetworkNullTenantId() {
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String response = wt.path("vnets")
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual network did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual network with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualNetwork() {
+        mockVnetAdminService.removeVirtualNetwork(anyObject());
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        Response response = wt.path("vnets/" + "2")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests that a DELETE of a non-existent virtual network throws an exception.
+     */
+    @Test
+    public void testDeleteNetworkNonExistentNetworkId() {
+        expect(mockVnetAdminService.getTenantIds())
+                .andReturn(ImmutableSet.of())
+                .anyTimes();
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+
+        try {
+            wt.path("vnets/" + "NON_EXISTENT_NETWORK_ID")
+                    .request()
+                    .delete(String.class);
+            fail("Delete of a non-existent virtual network did not throw an exception");
+        } catch (NotFoundException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 404 Not Found"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Device
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual devices.
+     */
+    @Test
+    public void testGetVirtualDevicesEmptyArray() {
+        NetworkId networkId = networkId4;
+        expect(mockVnetService.getVirtualDevices(networkId)).andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/devices";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"devices\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual devices are defined.
+     */
+    @Test
+    public void testGetVirtualDevicesArray() {
+        NetworkId networkId = networkId3;
+        vdevSet.add(vdev1);
+        vdevSet.add(vdev2);
+        expect(mockVnetService.getVirtualDevices(networkId)).andReturn(vdevSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString() + "/devices";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"devices\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("devices"));
+
+        final JsonArray vnetJsonArray = result.get("devices").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual devices array is not the correct size.",
+                     vdevSet.size(), vnetJsonArray.size());
+
+        vdevSet.forEach(vdev -> assertThat(vnetJsonArray, hasVdev(vdev)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Array matcher for VirtualDevice.
+     */
+    public static class VdevJsonArrayMatcher extends JsonArrayMatcher<VirtualDevice> {
+
+        public VdevJsonArrayMatcher(VirtualDevice vdevIn) {
+            super(vdevIn,
+                  vdev -> "Virtual device " + vdev.networkId().toString()
+                          + " " + vdev.id().toString(),
+                  (vdev, jsonObject) -> {
+                      return jsonObject.get(ID).asString().equals(vdev.networkId().toString())
+                              && jsonObject.get(DEVICE_ID).asString().equals(vdev.id().toString()); },
+                  ImmutableList.of(ID, DEVICE_ID),
+                  (vdev, s) -> {
+                      return s.equals(ID) ? vdev.networkId().toString()
+                              : s.equals(DEVICE_ID) ? vdev.id().toString()
+                              : null;
+                  }
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual device array matcher.
+     *
+     * @param vdev virtual device object we are looking for
+     * @return matcher
+     */
+    private VdevJsonArrayMatcher hasVdev(VirtualDevice vdev) {
+        return new VdevJsonArrayMatcher(vdev);
+    }
+    /**
+     * Tests adding of new virtual device using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualDevice() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        expect(mockVnetAdminService.createVirtualDevice(networkId, deviceId)).andReturn(vdev2);
+        expectLastCall();
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-device.json");
+        String reqLocation = "vnets/" + networkId.toString() + "/devices";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        String location = response.getLocation().getPath();
+        assertThat(location, Matchers.startsWith("/" + reqLocation + "/" + vdev2.id().toString()));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual device using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualDeviceNullJsonStream() {
+        NetworkId networkId = networkId3;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString() + "/devices";
+            String response = wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual device did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual device with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualDevice() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        mockVnetAdminService.removeVirtualDevice(networkId, deviceId);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        String reqLocation = "vnets/" + networkId.toString() + "/devices/" + deviceId.toString();
+        Response response = wt.path(reqLocation)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+        verify(mockVnetAdminService);
+    }
+
+    // Tests for Virtual Ports
+
+    /**
+     * Tests the result of the REST API GET when there are no virtual ports.
+     */
+    @Test
+    public void testGetVirtualPortsEmptyArray() {
+        NetworkId networkId = networkId4;
+        DeviceId deviceId = devId2;
+        expect(mockVnetService.getVirtualPorts(networkId, deviceId))
+                .andReturn(ImmutableSet.of()).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, is("{\"ports\":[]}"));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Tests the result of the REST API GET when virtual ports are defined.
+     */
+    @Test
+    public void testGetVirtualPortsArray() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = dev22.id();
+        vportSet.add(vport23);
+        vportSet.add(vport22);
+        expect(mockVnetService.getVirtualPorts(networkId, deviceId)).andReturn(vportSet).anyTimes();
+        replay(mockVnetService);
+
+        WebTarget wt = target();
+        String location = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        String response = wt.path(location).request().get(String.class);
+        assertThat(response, containsString("{\"ports\":["));
+
+        final JsonObject result = Json.parse(response).asObject();
+        assertThat(result, notNullValue());
+
+        assertThat(result.names(), hasSize(1));
+        assertThat(result.names().get(0), is("ports"));
+
+        final JsonArray vnetJsonArray = result.get("ports").asArray();
+        assertThat(vnetJsonArray, notNullValue());
+        assertEquals("Virtual ports array is not the correct size.",
+                vportSet.size(), vnetJsonArray.size());
+
+        vportSet.forEach(vport -> assertThat(vnetJsonArray, hasVport(vport)));
+
+        verify(mockVnetService);
+    }
+
+    /**
+     * Array matcher for VirtualPort.
+     */
+    public static class VportJsonArrayMatcher extends JsonArrayMatcher<VirtualPort> {
+
+        public VportJsonArrayMatcher(VirtualPort vportIn) {
+            super(vportIn,
+                  vport -> "Virtual port " + vport.networkId().toString() + " "
+                    + vport.element().id().toString() + " " + vport.number().toString(),
+                  (vport, jsonObject) -> {
+                      return jsonObject.get(ID).asString().equals(vport.networkId().toString())
+                              && jsonObject.get(PORT_NUM).asString().equals(vport.number().toString())
+                              && jsonObject.get(DEVICE_ID).asString().equals(vport.element().id().toString()); },
+                  ImmutableList.of(ID, DEVICE_ID, PORT_NUM, PHYS_DEVICE_ID, PHYS_PORT_NUM),
+                  (vport, s) -> {
+                      return s.equals(ID) ? vport.networkId().toString()
+                              : s.equals(DEVICE_ID) ? vport.element().id().toString()
+                              : s.equals(PORT_NUM) ? vport.number().toString()
+                              : s.equals(PHYS_DEVICE_ID) ? vport.realizedBy().element().id().toString()
+                              : s.equals(PHYS_PORT_NUM) ? vport.realizedBy().number().toString()
+                              : null;
+                  }
+            );
+        }
+    }
+
+    /**
+     * Factory to allocate a virtual port array matcher.
+     *
+     * @param vport virtual port object we are looking for
+     * @return matcher
+     */
+    private VportJsonArrayMatcher hasVport(VirtualPort vport) {
+        return new VportJsonArrayMatcher(vport);
+    }
+
+    /**
+     * Tests adding of new virtual port using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualPort() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId22;
+        DefaultAnnotations annotations = DefaultAnnotations.builder().build();
+        Device physDevice = new DefaultDevice(null, DeviceId.deviceId("dev1"),
+                null, null, null, null, null, null, annotations);
+        Port port1 = new DefaultPort(physDevice, portNumber(1), true);
+        expect(mockVnetAdminService.createVirtualPort(networkId, deviceId, portNumber(22), port1))
+                .andReturn(vport22);
+
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        InputStream jsonStream = VirtualNetworkWebResourceTest.class
+                .getResourceAsStream("post-virtual-port.json");
+        String reqLocation = "vnets/" + networkId.toString()
+                + "/devices/" + deviceId.toString() + "/ports";
+        Response response = wt.path(reqLocation).request(MediaType.APPLICATION_JSON_TYPE)
+                .post(Entity.json(jsonStream));
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED));
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests adding of a null virtual port using POST via JSON stream.
+     */
+    @Test
+    public void testPostVirtualPortNullJsonStream() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target();
+        try {
+            String reqLocation = "vnets/" + networkId.toString()
+                    + "/devices/" + deviceId.toString() + "/ports";
+            String response = wt.path(reqLocation)
+                    .request(MediaType.APPLICATION_JSON_TYPE)
+                    .post(Entity.json(null), String.class);
+            fail("POST of null virtual port did not throw an exception");
+        } catch (BadRequestException ex) {
+            assertThat(ex.getMessage(), containsString("HTTP 400 Bad Request"));
+        }
+
+        verify(mockVnetAdminService);
+    }
+
+    /**
+     * Tests removing a virtual port with DELETE request.
+     */
+    @Test
+    public void testDeleteVirtualPort() {
+        NetworkId networkId = networkId3;
+        DeviceId deviceId = devId2;
+        PortNumber portNum = portNumber(2);
+        mockVnetAdminService.removeVirtualPort(networkId, deviceId, portNum);
+        expectLastCall();
+        replay(mockVnetAdminService);
+
+        WebTarget wt = target()
+                .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true);
+        String reqLocation = "vnets/" + networkId.toString()
+            + "/devices/" + deviceId.toString() + "/ports/" + portNum.toLong();
+        Response response = wt.path(reqLocation)
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+
+        assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
+
+        verify(mockVnetAdminService);
+    }
+
+    // TODO Tests for Virtual Links
+}
diff --git a/web/api/src/test/resources/org/onosproject/rest/resources/post-tenant.json b/web/api/src/test/resources/org/onosproject/rest/resources/post-tenant.json
new file mode 100644
index 0000000..407f9a2
--- /dev/null
+++ b/web/api/src/test/resources/org/onosproject/rest/resources/post-tenant.json
@@ -0,0 +1,3 @@
+{
+  "id": "TenantId2"
+}
diff --git a/web/api/src/test/resources/org/onosproject/rest/resources/post-virtual-device.json b/web/api/src/test/resources/org/onosproject/rest/resources/post-virtual-device.json
new file mode 100644
index 0000000..fbd129c
--- /dev/null
+++ b/web/api/src/test/resources/org/onosproject/rest/resources/post-virtual-device.json
@@ -0,0 +1,4 @@
+{
+  "networkId": "3",
+  "deviceId": "devId2"
+}
diff --git a/web/api/src/test/resources/org/onosproject/rest/resources/post-virtual-port.json b/web/api/src/test/resources/org/onosproject/rest/resources/post-virtual-port.json
new file mode 100644
index 0000000..1d60842
--- /dev/null
+++ b/web/api/src/test/resources/org/onosproject/rest/resources/post-virtual-port.json
@@ -0,0 +1,7 @@
+{
+  "networkId": "3",
+  "deviceId": "dev22",
+  "portNum": "22",
+  "physDeviceId": "dev1",
+  "physPortNum": "1"
+}
