ONOS-6825: added OFAgent tracer

Change-Id: Ib04184b5fe108c636f8fb9c4b721a1004b72c0a7
diff --git a/apps/ofagent/README.md b/apps/ofagent/README.md
new file mode 100644
index 0000000..011cc11
--- /dev/null
+++ b/apps/ofagent/README.md
@@ -0,0 +1,51 @@
+OFAgent : OpenFlow agent for virtual subsystem
+====================================
+
+### What is OFAgent?
+OFAgent is an OpenFlow agent which exposes virtual network to the external OpenFlow controllers.
+
+### Top-Level Features
+
+* *TODO*: add features.
+
+## OFAgent Tracer how-to
+
+Builtin OFAgent tracer enables filtering of OFAgent logs per specific OFAgent tenant. Tracer is not enabled by default. Steps required for its activation are:
+
+1. Create Karaf alias ofagent_tracer by executing CLI command:
+`onos>ofagent_tracer = { log:display | grep "OFAGENT_tenantId:" | grep "$1" }`
+
+2. Use `ofagent_tracer` in form:
+`onos>ofagent_tracer <tenant_id>`
+
+Default log level is `INFO`. Optionally, OFAgent log level can be changed with CLI command:
+``log:set <log_level> org.onosproject.ofagent``
+where ``<log_level>`` can be `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`.
+
+_Note 1.:_ Useful Karaf CLI commands for changing log configuration are (reference: [Apache Karaf Container 3.x - Documentation](http://karaf.apache.org/manual/latest-3.0.x/#_log)):
+ 
+* `log:clear` - clear the log entries
+
+* `log:display` -  displays the log entries of the rootLogger
+
+* `log:tail` -  exactly the same as `log:display` but it continuously displays the log entries
+
+* `log:display <logger>` -  displays the log entries of the `<logger>`
+
+* `log:exception-display` - displays the last occurred exception
+
+* `log:get` - shows the current log level of a ROOT logger
+
+* `log:get ALL` - shows the current log level of all loggers
+
+* `log:get <logger>` - show the current log level of a `<logger>`
+
+* `log:set <log_level>` - sets `<log_level>` for ROOT logger
+
+* `log:set <log_level> <logger>` - sets `<log_level>` for `<logger>` 
+
+_Note 2.:_ Karaf log4j configuration is in file $ONOS_INSTALL_DIR/apache-karaf-3.0.8/etc/org.ops4j.pax.logging.cfg and it can be changed on the fly.  
+ 
+
+More documentation is available in vBrigade [wiki](https://wiki.onosproject.org/display/ONOS/Virtualization+brigade) and [vBrigade weekly scrum notes](https://docs.google.com/document/d/1PNtZyjVcZ1jr4Yw12ngDsAx-nkry03lvAkRlc1OcHUg).
+   
\ No newline at end of file
diff --git a/apps/ofagent/src/main/java/org/onosproject/ofagent/api/OFAgent.java b/apps/ofagent/src/main/java/org/onosproject/ofagent/api/OFAgent.java
index ed1b2be..4602185 100644
--- a/apps/ofagent/src/main/java/org/onosproject/ofagent/api/OFAgent.java
+++ b/apps/ofagent/src/main/java/org/onosproject/ofagent/api/OFAgent.java
@@ -16,6 +16,7 @@
 package org.onosproject.ofagent.api;
 
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 
 import java.util.Set;
 
@@ -25,6 +26,8 @@
  */
 public interface OFAgent {
 
+    String TRACER_LOG_TENANT_ID_PREFIX = "OFAGENT_tenantId:";
+
     enum State {
 
         /**
@@ -46,6 +49,13 @@
     NetworkId networkId();
 
     /**
+     * Returns the identifier of the tenant which owns virtual network this agent cares for.
+     *
+     * @return id of the tenant
+     */
+    TenantId tenantId();
+
+    /**
      * Returns the external OpenFlow controllers of the virtual network.
      *
      * @return set of openflow controllers
@@ -89,6 +99,14 @@
         Builder networkId(NetworkId networkId);
 
         /**
+         * Returns OF agent builder with the supplied tenant ID.
+         *
+         * @param tenantId id of the virtual network
+         * @return of agent builder
+         */
+        Builder tenantId(TenantId tenantId);
+
+        /**
          * Returns OF agent builder with the supplied controllers.
          *
          * @param controllers set of openflow controllers
diff --git a/apps/ofagent/src/main/java/org/onosproject/ofagent/cli/OFAgentCreateCommand.java b/apps/ofagent/src/main/java/org/onosproject/ofagent/cli/OFAgentCreateCommand.java
index 101a1ff..b70d191 100644
--- a/apps/ofagent/src/main/java/org/onosproject/ofagent/cli/OFAgentCreateCommand.java
+++ b/apps/ofagent/src/main/java/org/onosproject/ofagent/cli/OFAgentCreateCommand.java
@@ -22,6 +22,8 @@
 import org.onlab.packet.TpPort;
 import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetworkService;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFAgentAdminService;
 import org.onosproject.ofagent.api.OFController;
@@ -30,6 +32,8 @@
 
 import java.util.Set;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * Creates a new OFAagent.
  */
@@ -60,14 +64,18 @@
                     TpPort.tpPort(Integer.valueOf(temp[1]))));
         }
 
+        VirtualNetworkService virtualNetworkService = get(VirtualNetworkService.class);
+        TenantId tenantId = virtualNetworkService.getTenantId(NetworkId.networkId(networkId));
+        checkNotNull(tenantId, "Virtual network %s does not have tenant.", networkId);
         OFAgentAdminService adminService = get(OFAgentAdminService.class);
         OFAgent ofAgent = DefaultOFAgent.builder()
                 .networkId(NetworkId.networkId(networkId))
+                .tenantId(tenantId)
                 .controllers(ctrls)
                 .state(OFAgent.State.STOPPED)
                 .build();
         adminService.createAgent(ofAgent);
-        print("Successfully created OFAgent for network %s", networkId);
+        print("Successfully created OFAgent for network %s, tenant %s", networkId, tenantId);
     }
 
     private boolean isValidController(String ctrl) {
diff --git a/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFAgent.java b/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFAgent.java
index c82dc94..d87e474 100644
--- a/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFAgent.java
+++ b/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFAgent.java
@@ -19,6 +19,7 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFController;
 
@@ -33,13 +34,16 @@
 public final class DefaultOFAgent implements OFAgent {
 
     private final NetworkId networkId;
+    private final TenantId tenantId;
+
     private final Set<OFController> controllers;
     private final State state;
 
-    private DefaultOFAgent(NetworkId networkId,
+    private DefaultOFAgent(NetworkId networkId, TenantId tenantId,
                            Set<OFController> controllers,
                            State state) {
         this.networkId = networkId;
+        this.tenantId = tenantId;
         this.controllers = controllers;
         this.state = state;
     }
@@ -50,6 +54,11 @@
     }
 
     @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
     public Set<OFController> controllers() {
         return controllers;
     }
@@ -83,6 +92,7 @@
     public String toString() {
         return MoreObjects.toStringHelper(this)
                 .add("networkId", this.networkId)
+                .add("tenantId", this.tenantId)
                 .add("controllers", this.controllers)
                 .add("state", this.state)
                 .toString();
@@ -100,6 +110,7 @@
     public static final class Builder implements OFAgent.Builder {
 
         private NetworkId networkId;
+        private TenantId tenantId;
         private Set<OFController> controllers = Sets.newHashSet();
         private State state;
 
@@ -109,15 +120,17 @@
         @Override
         public OFAgent build() {
             checkNotNull(networkId, "Network ID cannot be null");
+            checkNotNull(tenantId, "Tenant ID cannot be null");
             checkNotNull(state, "State cannot be null");
             controllers = controllers == null ? ImmutableSet.of() : controllers;
 
-            return new DefaultOFAgent(networkId, controllers, state);
+            return new DefaultOFAgent(networkId, tenantId, controllers, state);
         }
 
         @Override
         public Builder from(OFAgent ofAgent) {
             this.networkId = ofAgent.networkId();
+            this.tenantId = ofAgent.tenantId();
             this.controllers = Sets.newHashSet(ofAgent.controllers());
             this.state = ofAgent.state();
             return this;
@@ -130,6 +143,12 @@
         }
 
         @Override
+        public Builder tenantId(TenantId tenantId) {
+            this.tenantId = tenantId;
+            return this;
+        }
+
+        @Override
         public Builder controllers(Set<OFController> controllers) {
             this.controllers = controllers;
             return this;
diff --git a/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFSwitch.java b/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFSwitch.java
index 3c04364..1fbd561 100644
--- a/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFSwitch.java
+++ b/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DefaultOFSwitch.java
@@ -49,6 +49,7 @@
 import org.onosproject.net.meter.MeterRequest;
 import org.onosproject.net.meter.MeterService;
 import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFSwitch;
 import org.onosproject.ofagent.api.OFSwitchCapabilities;
 import org.onosproject.ofagent.api.OFSwitchService;
@@ -176,7 +177,9 @@
         this.flowRuleService = virtualNetworkService.get(networkId, FlowRuleService.class);
         this.groupService = virtualNetworkService.get(networkId, GroupService.class);
         this.meterService = virtualNetworkService.get(networkId, MeterService.class);
-        log = LoggerFactory.getLogger(getClass().getName() + " : " + dpid);
+
+        log = LoggerFactory.getLogger(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + virtualNetworkService.getTenantId(networkId)
+                                              + " " + getClass().getSimpleName() + " : " + dpid);
     }
 
     public static DefaultOFSwitch of(DatapathId dpid, OFSwitchCapabilities capabilities,
diff --git a/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DistributedOFAgentStore.java b/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DistributedOFAgentStore.java
index e405c14..7e41243 100644
--- a/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DistributedOFAgentStore.java
+++ b/apps/ofagent/src/main/java/org/onosproject/ofagent/impl/DistributedOFAgentStore.java
@@ -26,6 +26,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFAgentEvent;
 import org.onosproject.ofagent.api.OFAgentEvent.Type;
@@ -72,6 +73,7 @@
             .register(OFAgent.class)
             .register(OFAgent.State.class)
             .register(NetworkId.class)
+            .register(TenantId.class)
             .register(DefaultOFAgent.class)
             .register(OFController.class)
             .register(DefaultOFController.class)
@@ -155,7 +157,8 @@
             switch (event.type()) {
                 case INSERT:
                     eventExecutor.execute(() -> {
-                        log.debug("OFAgent for network {} created", event.key());
+                        log.debug(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + event.newValue().value().tenantId()
+                                          + " OFAgent for network {} created", event.key());
                         notifyDelegate(new OFAgentEvent(
                                 Type.OFAGENT_CREATED,
                                 event.newValue().value()));
@@ -163,13 +166,15 @@
                     break;
                 case UPDATE:
                     eventExecutor.execute(() -> {
-                        log.debug("OFAgent for network {} updated", event.key());
+                        log.debug(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + event.newValue().value().tenantId()
+                                          + " OFAgent for network {} updated", event.key());
                         processUpdated(event.oldValue().value(), event.newValue().value());
                     });
                     break;
                 case REMOVE:
                     eventExecutor.execute(() -> {
-                        log.debug("OFAgent for network {} removed", event.key());
+                        log.debug(OFAgent.TRACER_LOG_TENANT_ID_PREFIX + event.oldValue().value().tenantId()
+                                          + " OFAgent for network {} removed", event.key());
                         notifyDelegate(new OFAgentEvent(
                                 Type.OFAGENT_REMOVED,
                                 event.oldValue().value()));
diff --git a/apps/ofagent/src/main/java/org/onosproject/ofagent/rest/OFAgentCodec.java b/apps/ofagent/src/main/java/org/onosproject/ofagent/rest/OFAgentCodec.java
index aae3614..4b8683c 100644
--- a/apps/ofagent/src/main/java/org/onosproject/ofagent/rest/OFAgentCodec.java
+++ b/apps/ofagent/src/main/java/org/onosproject/ofagent/rest/OFAgentCodec.java
@@ -23,6 +23,7 @@
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFController;
 import org.onosproject.ofagent.impl.DefaultOFAgent;
@@ -45,6 +46,7 @@
         ObjectNode ofAgentNode = mapper.createObjectNode();
         ofAgentNode
                 .put("networkId", ofAgent.networkId().toString())
+                .put("tenantId", ofAgent.tenantId().toString())
                 .put("state", ofAgent.state().toString());
 
         ArrayNode controllers = mapper.createArrayNode();
@@ -59,6 +61,9 @@
         JsonNode networkId = json.get("networkId");
         checkNotNull(networkId);
 
+        JsonNode tenantId = json.get("tenantId");
+        checkNotNull(tenantId);
+
         checkNotNull(json.get("controllers"));
         checkState(json.get("controllers").isArray());
         Set<OFController> controllers = Sets.newHashSet();
@@ -67,6 +72,7 @@
 
         return DefaultOFAgent.builder()
                 .networkId(NetworkId.networkId(networkId.asLong()))
+                .tenantId(TenantId.tenantId(tenantId.asText()))
                 .controllers(controllers)
                 .state(OFAgent.State.STOPPED)
                 .build();
diff --git a/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java
index 6e537b4..0028fc1 100644
--- a/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java
+++ b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/DefaultOFAgentTest.java
@@ -21,6 +21,7 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.TpPort;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFController;
 
@@ -51,26 +52,33 @@
     private static final NetworkId NETWORK_1 = NetworkId.networkId(1);
     private static final NetworkId NETWORK_2 = NetworkId.networkId(2);
 
+    private static final TenantId TENANT_1 = TenantId.tenantId("Tenant_1");
+    private static final TenantId TENANT_2 = TenantId.tenantId("Tenant_2");
+
     private static final OFAgent OFAGENT = DefaultOFAgent.builder()
             .networkId(NETWORK_1)
+            .tenantId(TENANT_1)
             .controllers(CONTROLLER_1)
             .state(STOPPED)
             .build();
 
     private static final OFAgent SAME_AS_OFAGENT_1 = DefaultOFAgent.builder()
             .networkId(NETWORK_1)
+            .tenantId(TENANT_1)
             .controllers(CONTROLLER_2)
             .state(STOPPED)
             .build();
 
     private static final OFAgent SAME_AS_OFAGENT_2 = DefaultOFAgent.builder()
             .networkId(NETWORK_1)
+            .tenantId(TENANT_1)
             .controllers(CONTROLLER_1)
             .state(STARTED)
             .build();
 
     private static final OFAgent ANOTHER_OFAGENT = DefaultOFAgent.builder()
             .networkId(NETWORK_2)
+            .tenantId(TENANT_2)
             .controllers(CONTROLLER_1)
             .state(STOPPED)
             .build();
diff --git a/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java
index 2a7c941..90ba30d 100644
--- a/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java
+++ b/apps/ofagent/src/test/java/org/onosproject/ofagent/impl/OFAgentManagerTest.java
@@ -34,6 +34,7 @@
 import org.onosproject.core.DefaultApplicationId;
 import org.onosproject.event.Event;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 import org.onosproject.incubator.net.virtual.VirtualNetworkService;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFAgentEvent;
@@ -76,25 +77,32 @@
     private static final NetworkId NETWORK_1 = NetworkId.networkId(1);
     private static final NetworkId NETWORK_2 = NetworkId.networkId(2);
 
+    private static final TenantId TENANT_1 = TenantId.tenantId("Tenant_1");
+    private static final TenantId TENANT_2 = TenantId.tenantId("Tenant_2");
+
     private static final OFAgent OFAGENT_1 = DefaultOFAgent.builder()
             .networkId(NETWORK_1)
+            .tenantId(TENANT_1)
             .state(STOPPED)
             .build();
 
     private static final OFAgent OFAGENT_1_CTRL_1 = DefaultOFAgent.builder()
             .networkId(NETWORK_1)
+            .tenantId(TENANT_1)
             .controllers(CONTROLLER_1)
             .state(STOPPED)
             .build();
 
     private static final OFAgent OFAGENT_1_CTRL_2 = DefaultOFAgent.builder()
             .networkId(NETWORK_1)
+            .tenantId(TENANT_1)
             .controllers(CONTROLLER_2)
             .state(STOPPED)
             .build();
 
     private static final OFAgent OFAGENT_2 = DefaultOFAgent.builder()
             .networkId(NETWORK_2)
+            .tenantId(TENANT_2)
             .state(STOPPED)
             .build();
 
diff --git a/apps/ofagent/src/test/java/org/onosproject/ofagent/rest/OFAgentWebResourceTest.java b/apps/ofagent/src/test/java/org/onosproject/ofagent/rest/OFAgentWebResourceTest.java
index dee4ba6..74e2c4a 100644
--- a/apps/ofagent/src/test/java/org/onosproject/ofagent/rest/OFAgentWebResourceTest.java
+++ b/apps/ofagent/src/test/java/org/onosproject/ofagent/rest/OFAgentWebResourceTest.java
@@ -29,6 +29,7 @@
 import org.onlab.packet.TpPort;
 import org.onlab.rest.BaseResource;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
 import org.onosproject.ofagent.api.OFAgent;
 import org.onosproject.ofagent.api.OFAgentAdminService;
 import org.onosproject.ofagent.api.OFAgentService;
@@ -94,19 +95,27 @@
     private static final NetworkId NETWORK_2 = NetworkId.networkId(2);
     private static final NetworkId NETWORK = NetworkId.networkId(3);
 
+
+    private static final TenantId TENANT_1 = TenantId.tenantId("Tenant_1");
+    private static final TenantId TENANT_2 = TenantId.tenantId("Tenant_2");
+    private static final TenantId TENANT = TenantId.tenantId("Tenant");
+
     private static final OFAgent OF_AGENT = DefaultOFAgent.builder()
             .networkId(NETWORK)
+            .tenantId(TENANT)
             .controllers(CONTROLLER_SET)
             .state(STOPPED)
             .build();
 
     private Set<OFAgent> agents = Sets.newHashSet(DefaultOFAgent.builder()
                                                   .networkId(NETWORK_1)
+                                                  .tenantId(TENANT_1)
                                                   .controllers(CONTROLLER_SET_1)
                                                   .state(STOPPED)
                                                   .build(),
                                           DefaultOFAgent.builder()
                                                   .networkId(NETWORK_2)
+                                                  .tenantId(TENANT_2)
                                                   .controllers(CONTROLLER_SET_2)
                                                   .state(STOPPED)
                                                   .build(),
@@ -166,6 +175,9 @@
             String expectedJsonStringNetworkId = "\"networkId\":\"" + ofAgent.networkId().id() + "\"";
             assertThat(response, containsString(expectedJsonStringNetworkId));
 
+            String expectedJsonStringTenantId = "\"tenantId\":\"" + ofAgent.tenantId().id() + "\"";
+            assertThat(response, containsString(expectedJsonStringTenantId));
+
             String expectedJsonStringState = "\"state\":\"" + ofAgent.state() + "\"";
             assertThat(response, containsString(expectedJsonStringState));
 
@@ -219,8 +231,9 @@
         final Response response = wt.path("service/ofagent/" + NETWORK).request().get();
         final JsonObject result = Json.parse(response.readEntity(String.class)).asObject();
         assertThat(result, notNullValue());
-        assertThat(result.names(), hasSize(3));
+        assertThat(result.names(), hasSize(4));
         assertThat(result.get("networkId").asString(), is(NETWORK.id().toString()));
+        assertThat(result.get("tenantId").asString(), is(TENANT.id()));
         assertThat(result.get("state").asString(), is(STOPPED.toString()));
 
         verify(mockOFAgentService);
diff --git a/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/post-ofagent-create.json b/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/post-ofagent-create.json
index 7632bbf..492ef7a 100644
--- a/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/post-ofagent-create.json
+++ b/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/post-ofagent-create.json
@@ -1,5 +1,6 @@
 {
   "networkId": "3",
+  "tenantId": "Tenant_3",
   "controllers": [
     {
       "ip": "147.91.1.27",
diff --git a/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-non-existent-ofagent-update.json b/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-non-existent-ofagent-update.json
index 86d1b21..a420183 100644
--- a/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-non-existent-ofagent-update.json
+++ b/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-non-existent-ofagent-update.json
@@ -1,5 +1,6 @@
 {
   "networkId": "3",
+  "tenantId": "Tenant_2",
   "controllers": [
     {
       "ip": "147.91.1.27",
diff --git a/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-ofagent-update.json b/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-ofagent-update.json
index 1a36150..1910339 100644
--- a/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-ofagent-update.json
+++ b/apps/ofagent/src/test/resources/org/onosproject/ofagent/rest/put-ofagent-update.json
@@ -1,5 +1,6 @@
 {
   "networkId": "3",
+  "tenantId": "Tenant_3",
   "controllers": [
     {
       "ip": "147.91.1.27",
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
index 2e208e8..aa513ec 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/virtual/VirtualNetworkService.java
@@ -46,6 +46,24 @@
     Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId);
 
     /**
+     * Returns the virtual network matching the network identifier.
+     *
+     * @param networkId virtual network identifier
+     * @return virtual network instance
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    VirtualNetwork getVirtualNetwork(NetworkId networkId);
+
+    /**
+     * Returns {@code tenantId} for specified virtual network id.
+     *
+     * @param networkId virtual network identifier
+     * @return tenantId tenant identifier
+     * @throws org.onlab.util.ItemNotFoundException if no such network found
+     */
+    TenantId getTenantId(NetworkId networkId);
+
+    /**
      * Returns a collection of all virtual devices in the specified network.
      *
      * @param networkId network identifier
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
index 26145cc..0e10de6 100644
--- a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/VirtualNetworkAdminServiceAdapter.java
@@ -112,4 +112,14 @@
     public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, PortNumber portNumber) {
 
     }
+
+    @Override
+    public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+        return null;
+    }
+
+    @Override
+    public TenantId getTenantId(NetworkId networkId) {
+        return null;
+    }
 }
diff --git a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java
index 16369e0..ac4ce41 100644
--- a/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java
+++ b/incubator/api/src/test/java/org/onosproject/incubator/net/virtual/event/AbstractVirtualListenerManagerTest.java
@@ -28,6 +28,8 @@
 import org.onosproject.event.EventListener;
 import org.onosproject.event.EventSink;
 import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
 import org.onosproject.incubator.net.virtual.VirtualNetworkService;
 import org.onosproject.incubator.net.virtual.VirtualNetworkServiceAdapter;
 
@@ -254,6 +256,16 @@
         }
 
         @Override
+        public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
+        public TenantId getTenantId(NetworkId networkId) {
+            return null;
+        }
+
+        @Override
         public ServiceDirectory getServiceDirectory() {
             return serviceDirectory;
         }
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
index a5bd412..2343b3e 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManager.java
@@ -320,18 +320,20 @@
         return store.getNetworks(tenantId);
     }
 
-    /**
-     * Returns the virtual network matching the network identifier.
-     *
-     * @param networkId network identifier
-     * @return virtual network
-     */
-    private VirtualNetwork getVirtualNetwork(NetworkId networkId) {
+    @Override
+    public VirtualNetwork getVirtualNetwork(NetworkId networkId) {
         checkNotNull(networkId, NETWORK_NULL);
         return store.getNetwork(networkId);
     }
 
     @Override
+    public TenantId getTenantId(NetworkId networkId) {
+        VirtualNetwork virtualNetwork = getVirtualNetwork(networkId);
+        checkNotNull(virtualNetwork, "The network does not exist.");
+        return virtualNetwork.tenantId();
+    }
+
+    @Override
     public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
         checkNotNull(networkId, NETWORK_NULL);
         return store.getDevices(networkId);
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
index 1f1624e..d0e20e2 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkManagerTest.java
@@ -88,6 +88,7 @@
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
+import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.*;
 import static org.onosproject.net.NetTestTools.APP_ID;
 
@@ -174,6 +175,43 @@
     }
 
     /**
+     * Test method {@code getTenantId()} for registered virtual network.
+     */
+    @Test
+    public void testGetTenantIdForRegisteredVirtualNetwork() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+        TenantId tenantId = manager.getTenantId(virtualNetwork.id());
+
+        assertThat(tenantId.toString(), is(tenantIdValue1));
+    }
+
+    /**
+     * Test method {@code getTenantId()} for null virtual network id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetTenantIdForNullVirtualNetwork() {
+        manager.getTenantId(null);
+    }
+
+    /**
+     * Test method {@code getVirtualNetwork()} for registered virtual network.
+     */
+    @Test
+    public void testGetVirtualNetworkForRegisteredNetwork() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
+
+        assertNotNull("Registered virtual network is null", manager.getVirtualNetwork(virtualNetwork.id()));
+    }
+
+    /**
+     * Test method {@code getVirtualNetwork()} for null virtual network id.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testGetVirtualForNullVirtualNetworkId() {
+        manager.getVirtualNetwork(null);
+    }
+
+    /**
      * Tests adding a null virtual network.
      */
     @Test(expected = NullPointerException.class)
@@ -745,12 +783,12 @@
 
 
     /**
-     * Method to create the virtual network for further testing.
+     * Method to create the virtual network for {@code tenantIdValue} for further testing.
      **/
-    private VirtualNetwork setupVirtualNetworkTopology() {
-        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+    private VirtualNetwork setupVirtualNetworkTopology(String tenantIdValue) {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue));
         VirtualNetwork virtualNetwork =
-                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+                manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue));
 
         VirtualDevice virtualDevice1 =
                 manager.createVirtualDevice(virtualNetwork.id(), DID1);
@@ -829,7 +867,7 @@
      */
     @Test
     public void testTopologyChanged() {
-        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology(tenantIdValue1);
         VirtualNetworkProviderService providerService =
                 manager.createProviderService(topologyProvider);