[AETHER-76] Impelentation of a new Trellis Troubleshoot Tool (T3) for offline mode

- For the performance improvement, T3 offline mode uses snapshots of the network states
called Network Information Base (NIB) instead of runtime interactions with ONOS core
during troubleshooting a Trellis system.
- Partially tested with some mininet topos for trellis
(https://github.com/opennetworkinglab/routing/tree/master/trellis).
- Usage instruction docs (https://docs.trellisfabric.org/troubleshooting.html).

Change-Id: Ice608f77aa96bfbcadfff34991c4a1b6d93125b6
(cherry picked from commit eaa6329aba67c2577fdca7d3ddf230611e82f9f7)
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/DeviceNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/DeviceNib.java
new file mode 100644
index 0000000..618724a
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/DeviceNib.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents Network Information Base (NIB) for devices
+ * and supports alternative functions to
+ * {@link org.onosproject.net.device.DeviceService} for offline data.
+ */
+public class DeviceNib {
+
+    private Map<Device, Set<Port>> devicePortMap;
+
+    // use the singleton helper to create the instance
+    protected DeviceNib() {
+    }
+
+    /**
+     * Sets a map of device : ports of the device.
+     *
+     * @param devicePortMap device-ports map
+     */
+    public void setDevicePortMap(Map<Device, Set<Port>> devicePortMap) {
+        this.devicePortMap = devicePortMap;
+    }
+
+    /**
+     * Returns the device-ports map.
+     *
+     * @return device-ports map
+     */
+    public Map<Device, Set<Port>> getDevicePortMap() {
+        return ImmutableMap.copyOf(devicePortMap);
+    }
+
+    /**
+     * Returns the device with the specified identifier.
+     *
+     * @param deviceId device identifier
+     * @return device or null if one with the given identifier is not known
+     */
+    public Device getDevice(DeviceId deviceId) {
+        return devicePortMap.keySet().stream()
+                .filter(device -> device.id().equals(deviceId))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Returns the port with the specified connect point.
+     *
+     * @param cp connect point
+     * @return device port
+     */
+    public Port getPort(ConnectPoint cp) {
+        return devicePortMap.get(getDevice(cp.deviceId())).stream()
+                .filter(port -> port.number().equals(cp.port()))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Returns the list of ports associated with the device.
+     *
+     * @param deviceId device identifier
+     * @return list of ports
+     */
+    public List<Port> getPorts(DeviceId deviceId) {
+        return ImmutableList.copyOf(devicePortMap.get(getDevice(deviceId)));
+    }
+
+    /**
+     * Indicates whether or not the device is presently online and available.
+     * Availability, unlike reachability, denotes whether ANY node in the
+     * cluster can discover that this device is in an operational state,
+     * this does not necessarily mean that there exists a node that can
+     * control this device.
+     *
+     * @param deviceId device identifier
+     * @return true if the device is available
+     */
+    public boolean isAvailable(DeviceId deviceId) {
+        Device device = getDevice(deviceId);
+        // TODO: may need an extra REST API to get availableDevices from DeviceService, not from device annotations
+        return device.annotations().value("available").equals("true") ? true : false;
+    }
+
+    /**
+     * Returns the singleton instance of devices NIB.
+     *
+     * @return instance of devices NIB
+     */
+    public static DeviceNib getInstance() {
+        return DeviceNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final DeviceNib INSTANCE = new DeviceNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/DriverNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/DriverNib.java
new file mode 100644
index 0000000..4c88a20
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/DriverNib.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.DeviceId;
+
+import java.util.Map;
+
+/**
+ * Represents Network Information Base (NIB) for drivers
+ * and supports alternative functions to
+ * {@link org.onosproject.net.driver.DriverService} for offline data.
+ */
+public class DriverNib {
+
+    private Map<DeviceId, String> deviceDriverMap;
+
+    // use the singleton helper to create the instance
+    protected DriverNib() {
+    }
+
+    /**
+     * Sets a map of device id : driver name.
+     *
+     * @param deviceDriverMap device-driver map
+     */
+    public void setDeviceDriverMap(Map<DeviceId, String> deviceDriverMap) {
+        this.deviceDriverMap = deviceDriverMap;
+    }
+
+    /**
+     * Returns the device-driver map.
+     *
+     * @return device-driver map
+     */
+    public Map<DeviceId, String> getDeviceDriverMap() {
+        return ImmutableMap.copyOf(deviceDriverMap);
+    }
+
+    /**
+     * Returns a driver name of the given device.
+     *
+     * @param deviceId the device id
+     * @return the driver name
+     */
+    public String getDriverName(DeviceId deviceId) {
+        return deviceDriverMap.get(deviceId);
+    }
+
+    /**
+     * Returns the singleton instance of drivers NIB.
+     *
+     * @return instance of drivers NIB
+     */
+    public static DriverNib getInstance() {
+        return DriverNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final DriverNib INSTANCE = new DriverNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/EdgePortNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/EdgePortNib.java
new file mode 100644
index 0000000..f24668f
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/EdgePortNib.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents Network Information Base (NIB) for edge ports
+ * and supports alternative functions to
+ * {@link org.onosproject.net.edge.EdgePortService} for offline data.
+ */
+public class EdgePortNib {
+
+    private Map<DeviceId, Set<ConnectPoint>> edgePorts;
+
+    // use the singleton helper to create the instance
+    protected EdgePortNib() {
+    }
+
+    /**
+     * Sets a map of device id : edge ports of the device.
+     *
+     * @param edgePorts device-edge ports map
+     */
+    public void setEdgePorts(Map<DeviceId, Set<ConnectPoint>> edgePorts) {
+        this.edgePorts = edgePorts;
+    }
+
+    /**
+     * Returns the device-edge ports map.
+     * @return device-edge ports map
+     */
+    public Map<DeviceId, Set<ConnectPoint>> getEdgePorts() {
+        return ImmutableMap.copyOf(edgePorts);
+    }
+
+    /**
+     * Indicates whether or not the specified connection point is an edge point.
+     *
+     * @param point connection point
+     * @return true if edge point
+     */
+    public boolean isEdgePoint(ConnectPoint point) {
+        Set<ConnectPoint> connectPoints = edgePorts.get(point.deviceId());
+        return connectPoints != null && connectPoints.contains(point);
+    }
+
+    /**
+     * Returns the singleton instance of edge ports NIB.
+     *
+     * @return instance of edge ports NIB
+     */
+    public static EdgePortNib getInstance() {
+        return EdgePortNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final EdgePortNib INSTANCE = new EdgePortNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/FlowNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/FlowNib.java
new file mode 100644
index 0000000..aecb57c
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/FlowNib.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.FlowEntry;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Represents Network Information Base (NIB) for flows
+ * and supports alternative functions to
+ * {@link org.onosproject.net.flow.FlowRuleService} for offline data.
+ */
+public class FlowNib {
+
+    // TODO with method optimization, store into subdivided structures at the first load
+    private Set<FlowEntry> flows;
+
+    // use the singleton helper to create the instance
+    protected FlowNib() {
+    }
+
+    /**
+     * Sets a set of flows.
+     *
+     * @param flows flow set
+     */
+    public void setFlows(Set<FlowEntry> flows) {
+        this.flows = flows;
+    }
+
+    /**
+     * Returns the set of flows.
+     *
+     * @return flow set
+     */
+    public Set<FlowEntry> getFlows() {
+        return ImmutableSet.copyOf(flows);
+    }
+
+    /**
+     * Returns a list of rules filtered by device id and flow state.
+     *
+     * @param deviceId the device id to lookup
+     * @param flowState the flow state to lookup
+     * @return collection of flow entries
+     */
+    public Iterable<FlowEntry> getFlowEntriesByState(DeviceId deviceId, FlowEntry.FlowEntryState flowState) {
+        Set<FlowEntry> flowsFiltered = flows.stream()
+                .filter(flow -> flow.state() == flowState
+                        && flow.deviceId().equals(deviceId))
+                .collect(Collectors.toSet());
+        return flowsFiltered != null ? ImmutableSet.copyOf(flowsFiltered) : ImmutableSet.of();
+    }
+
+    /**
+     * Returns the singleton instance of flows NIB.
+     *
+     * @return instance of flows NIB
+     */
+    public static FlowNib getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final FlowNib INSTANCE = new FlowNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/GroupNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/GroupNib.java
new file mode 100644
index 0000000..64d6575
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/GroupNib.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.Group;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Represents Network Information Base (NIB) for groups
+ * and supports alternative functions to
+ * {@link org.onosproject.net.group.GroupService} for offline data.
+ */
+public class GroupNib {
+
+    // TODO with method optimization, store into subdivided structures at the first load
+    private Set<Group> groups;
+
+    // use the singleton helper to create the instance
+    protected GroupNib() {
+    }
+
+    /**
+     * Sets a set of groups.
+     *
+     * @param groups group set
+     */
+    public void setGroups(Set<Group> groups) {
+        this.groups = groups;
+    }
+
+    /**
+     * Returns the set of groups.
+     *
+     * @return group set
+     */
+    public Set<Group> getGroups() {
+        return ImmutableSet.copyOf(groups);
+    }
+
+    /**
+     * Returns all groups associated with the given device.
+     *
+     * @param deviceId device ID to get groups for
+     * @return iterable of device's groups
+     */
+    public Iterable<Group> getGroups(DeviceId deviceId) {
+        Set<Group> groupsFiltered = groups.stream()
+                .filter(g -> g.deviceId().equals(deviceId))
+                .collect(Collectors.toSet());
+        return groupsFiltered != null ? ImmutableSet.copyOf(groupsFiltered) : ImmutableSet.of();
+    }
+
+    /**
+     * Returns the singleton instance of groups NIB.
+     *
+     * @return instance of groups NIB
+     */
+    public static GroupNib getInstance() {
+        return GroupNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final GroupNib INSTANCE = new GroupNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/HostNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/HostNib.java
new file mode 100644
index 0000000..5b5eab2
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/HostNib.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Represents Network Information Base (NIB) for hosts
+ * and supports alternative functions to
+ * {@link org.onosproject.net.host.HostService} for offline data.
+ */
+public class HostNib {
+
+    // TODO with method optimization, store into subdivided structures at the first load
+    private Set<Host> hosts;
+
+    // use the singleton helper to create the instance
+    protected HostNib() {
+    }
+
+    /**
+     * Sets a set of hosts.
+     *
+     * @param hosts host set
+     */
+    public void setHosts(Set<Host> hosts) {
+        this.hosts = hosts;
+    }
+
+    /**
+     * Returns the set of hosts.
+     *
+     * @return host set
+     */
+    public Set<Host> getHosts() {
+        return ImmutableSet.copyOf(hosts);
+    }
+
+    /**
+     * Returns the host with the specified identifier.
+     *
+     * @param hostId host identifier
+     * @return host or null if one with the given identifier is not known
+     */
+    public Host getHost(HostId hostId) {
+        return hosts.stream()
+                .filter(host -> host.id().equals(hostId))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Returns the set of hosts whose most recent location is the specified
+     * connection point.
+     *
+     * @param connectPoint connection point
+     * @return set of hosts connected to the connection point
+     */
+    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+        // TODO extend this method to support matching on auxLocations as well
+        Set<Host> connectedHosts = hosts.stream()
+                .filter(host -> host.locations().contains(connectPoint))
+                .collect(Collectors.toSet());
+        return connectedHosts != null ? ImmutableSet.copyOf(connectedHosts) : ImmutableSet.of();
+    }
+
+    /**
+     * Returns the set of hosts that have the specified IP address.
+     *
+     * @param ip ip address
+     * @return set of hosts with the given IP
+     */
+    public Set<Host> getHostsByIp(IpAddress ip) {
+        Set<Host> hostsByIp = hosts.stream()
+                .filter(host -> host.ipAddresses().contains(ip))
+                .collect(Collectors.toSet());
+        return hostsByIp != null ? ImmutableSet.copyOf(hostsByIp) : ImmutableSet.of();
+    }
+
+    /**
+     * Returns the set of hosts that have the specified MAC address.
+     *
+     * @param mac mac address
+     * @return set of hosts with the given mac
+     */
+    public Set<Host> getHostsByMac(MacAddress mac) {
+        Set<Host> hostsByMac = hosts.stream()
+                .filter(host -> host.mac().equals(mac))
+                .collect(Collectors.toSet());
+        return hostsByMac != null ? ImmutableSet.copyOf(hostsByMac) : ImmutableSet.of();
+    }
+
+    /**
+     * Returns the singleton instance of hosts NIB.
+     *
+     * @return instance of hosts NIB
+     */
+    public static HostNib getInstance() {
+        return HostNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final HostNib INSTANCE = new HostNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/LinkNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/LinkNib.java
new file mode 100644
index 0000000..02acb54
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/LinkNib.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Link;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Represents Network Information Base (NIB) for links
+ * and supports alternative functions to
+ * {@link org.onosproject.net.link.LinkService} for offline data.
+ */
+public class LinkNib {
+
+    // TODO with method optimization, store into subdivided structures at the first load
+    private Set<Link> links;
+
+    // use the singleton helper to create the instance
+    protected LinkNib() {
+    }
+
+    /**
+     * Sets a set of links.
+     *
+     * @param links link set
+     */
+    public void setLinks(Set<Link> links) {
+        this.links = links;
+    }
+
+    /**
+     * Returns the set of links.
+     *
+     * @return link set
+     */
+    public Set<Link> getLinks() {
+        return ImmutableSet.copyOf(links);
+    }
+
+    /**
+     * Returns set of all infrastructure links leading from the specified
+     * connection point.
+     *
+     * @param connectPoint connection point
+     * @return set of device egress links
+     */
+    public Set<Link> getEgressLinks(ConnectPoint connectPoint) {
+        Set<Link> egressLinks = links.stream()
+                .filter(link -> connectPoint.equals(link.src()))
+                .collect(Collectors.toSet());
+        return egressLinks != null ? ImmutableSet.copyOf(egressLinks) : ImmutableSet.of();
+    }
+
+    /**
+     * Returns the singleton instance of links NIB.
+     *
+     * @return instance of links NIB
+     */
+    public static LinkNib getInstance() {
+        return LinkNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final LinkNib INSTANCE = new LinkNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/MastershipNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/MastershipNib.java
new file mode 100644
index 0000000..5101d52
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/MastershipNib.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.net.DeviceId;
+
+import java.util.Map;
+
+/**
+ * Represents Network Information Base (NIB) for mastership
+ * and supports alternative functions to
+ * {@link org.onosproject.mastership.MastershipService} for offline data.
+ */
+public class MastershipNib {
+
+    private Map<DeviceId, NodeId> deviceMasterMap;
+
+    // use the singleton helper to create the instance
+    protected MastershipNib() {
+    }
+
+    /**
+     * Sets a map of device id : master node id.
+     *
+     * @param deviceMasterMap device-master map
+     */
+    public void setDeviceMasterMap(Map<DeviceId, NodeId> deviceMasterMap) {
+        this.deviceMasterMap = deviceMasterMap;
+    }
+
+    /**
+     * Returns the device-master map.
+     *
+     * @return device-master map
+     */
+    public Map<DeviceId, NodeId> getDeviceMasterMap() {
+        return ImmutableMap.copyOf(deviceMasterMap);
+    }
+
+    /**
+     * Returns the current master for a given device.
+     *
+     * @param deviceId the identifier of the device
+     * @return the ID of the master controller for the device
+     */
+    public NodeId getMasterFor(DeviceId deviceId) {
+        return deviceMasterMap.get(deviceId);
+    }
+
+    /**
+     * Returns the singleton instance of mastership NIB.
+     *
+     * @return instance of mastership NIB
+     */
+    public static MastershipNib getInstance() {
+        return MastershipNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final MastershipNib INSTANCE = new MastershipNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/MulticastRouteNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/MulticastRouteNib.java
new file mode 100644
index 0000000..b9d106d
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/MulticastRouteNib.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.mcast.api.McastRoute;
+import org.onosproject.mcast.api.McastRouteData;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents Network Information Base (NIB) for multicast routes
+ * and supports alternative functions to
+ * {@link org.onosproject.mcast.api.MulticastRouteService} for offline data.
+ */
+public class MulticastRouteNib {
+
+    private Map<McastRoute, McastRouteData> mcastRoutes;
+
+    // use the singleton helper to create the instance
+    protected MulticastRouteNib() {
+    }
+
+    public void setMcastRoutes(Map<McastRoute, McastRouteData> mcastRoutes) {
+        this.mcastRoutes = mcastRoutes;
+    }
+
+    public Map<McastRoute, McastRouteData> getMcastRoutes() {
+        return ImmutableMap.copyOf(mcastRoutes);
+    }
+
+    /**
+     * Gets all Multicast routes in the system.
+     *
+     * @return set of Multicast routes
+     */
+    public Set<McastRoute> getRoutes() {
+        return ImmutableSet.copyOf(mcastRoutes.keySet());
+    }
+
+    /**
+     * Return the Multicast data for this route.
+     *
+     * @param route route
+     * @return the mcast route data
+     */
+    public McastRouteData routeData(McastRoute route) {
+        return mcastRoutes.get(route);
+    }
+
+    /**
+     * Returns the singleton instance of multicast routes NIB.
+     *
+     * @return instance of multicast routes NIB
+     */
+    public static MulticastRouteNib getInstance() {
+        return MulticastRouteNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final MulticastRouteNib INSTANCE = new MulticastRouteNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/NetworkConfigNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/NetworkConfigNib.java
new file mode 100644
index 0000000..9624fb7
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/NetworkConfigNib.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.basics.InterfaceConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+import org.slf4j.Logger;
+
+import java.util.Map;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Represents Network Information Base (NIB) for network configurations
+ * and supports alternative functions to
+ * {@link org.onosproject.net.config.NetworkConfigService} for offline data.
+ */
+public class NetworkConfigNib {
+
+    private static final Logger log = getLogger(NetworkConfigNib.class);
+
+    // Map of str ConnectPoint : InterfaceConfig
+    private Map<String, Config> portConfigMap;
+    // Map of str DeviceId : SegmentRoutingDeviceConfig
+    private Map<String, Config> deviceConfigMap;
+
+    // use the singleton helper to create the instance
+    protected NetworkConfigNib() {
+    }
+
+    /**
+     * Sets a map of port : configuration to the port.
+     *
+     * @param portConfigMap port-config map
+     */
+    public void setPortConfigMap(Map<String, Config> portConfigMap) {
+         this.portConfigMap = portConfigMap;
+    }
+
+    /**
+     * Sets a map of device : configuration to the device.
+     *
+     * @param deviceConfigMap device-config map
+     */
+    public void setDeviceConfigMap(Map<String, Config> deviceConfigMap) {
+        this.deviceConfigMap = deviceConfigMap;
+    }
+
+    /**
+     * Returns the port-config map.
+     *
+     * @return port-config map
+     */
+    public Map<Object, Object> getPortConfigMap() {
+        return ImmutableMap.copyOf(portConfigMap);
+    }
+
+    /**
+     * Returns the device-config map.
+     *
+     * @return device-config map
+     */
+    public Map<Object, Object> getDeviceConfigMap() {
+        return ImmutableMap.copyOf(deviceConfigMap);
+    }
+
+    /**
+     * Returns the configuration for the specified subject and configuration
+     * class if one is available; null otherwise.
+     *
+     * @param subject     configuration subject
+     * @param configClass configuration class
+     * @param <S>         type of subject
+     * @param <C>         type of configuration
+     * @return configuration or null if one is not available
+     */
+    public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+        if (configClass.equals(InterfaceConfig.class)) {
+            return (C) portConfigMap.get(subject.toString());
+        } else if (configClass.equals(SegmentRoutingDeviceConfig.class)) {
+            return (C) deviceConfigMap.get(subject.toString());
+        } else {
+            log.warn("Given configuration {} is not supported", configClass.toString());
+            return null;
+        }
+    }
+
+    /**
+     * Returns the singleton instance of multicast routes NIB.
+     *
+     * @return instance of multicast routes NIB
+     */
+    public static NetworkConfigNib getInstance() {
+        return NetworkConfigNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final NetworkConfigNib INSTANCE = new NetworkConfigNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/RouteNib.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/RouteNib.java
new file mode 100644
index 0000000..3edabd3
--- /dev/null
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/RouteNib.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.t3.api;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.routeservice.ResolvedRoute;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Represents Network Information Base (NIB) for routes
+ * and supports alternative functions to
+ * {@link org.onosproject.routeservice.RouteService} for offline data.
+ */
+public class RouteNib {
+
+    // TODO with method optimization, store into subdivided structures at the first load
+    // unresolved Route is treated as ResolvedRoute with nextHopMac null
+    Set<ResolvedRoute> routes;
+
+    // use the singleton helper to create the instance
+    protected RouteNib() {
+    }
+
+    /**
+     * Sets a set of routes.
+     *
+     * @param routes route set
+     */
+    public void setRoutes(Set<ResolvedRoute> routes) {
+        this.routes = routes;
+    }
+
+    /**
+     * Returns the set of routes.
+     *
+     * @return route set
+     */
+    public Set<ResolvedRoute> getRoutes() {
+        return routes;
+    }
+
+    /**
+     * Performs a longest prefix lookup on the given IP address.
+     *
+     * @param ip IP address to look up
+     * @return most specific matching route, if one exists
+     */
+    public Optional<ResolvedRoute> longestPrefixLookup(IpAddress ip) {
+        return routes.stream()
+                .filter(r -> r.prefix().contains(ip))
+                .max(Comparator.comparing(r -> r.prefix().prefixLength()));
+    }
+
+    /**
+     * Returns all resolved routes stored for the given prefix, including the
+     * best selected route.
+     *
+     * @param prefix IP prefix to look up routes for
+     * @return all stored resolved routes for this prefix
+     */
+    public Collection<ResolvedRoute> getAllResolvedRoutes(IpPrefix prefix) {
+        return routes.stream()
+                .filter(r -> r.prefix().contains(prefix)
+                        && r.nextHopMac() != null
+                        && r.nextHopVlan() != null)
+                .collect(Collectors.toCollection(ArrayList::new));
+    }
+
+    /**
+     * Returns the singleton instance of multicast routes NIB.
+     *
+     * @return instance of multicast routes NIB
+     */
+    public static RouteNib getInstance() {
+        return RouteNib.SingletonHelper.INSTANCE;
+    }
+
+    private static class SingletonHelper {
+        private static final RouteNib INSTANCE = new RouteNib();
+    }
+
+}
diff --git a/apps/t3/app/src/main/java/org/onosproject/t3/api/TroubleshootService.java b/apps/t3/app/src/main/java/org/onosproject/t3/api/TroubleshootService.java
index a21baf5..9838e04 100644
--- a/apps/t3/app/src/main/java/org/onosproject/t3/api/TroubleshootService.java
+++ b/apps/t3/app/src/main/java/org/onosproject/t3/api/TroubleshootService.java
@@ -83,4 +83,17 @@
      * @return a list of trace result
      */
     List<Set<StaticPacketTrace>> getMulitcastTrace(VlanId vlanId);
+
+    /**
+     * Checks the availability of all NIBs of the manager.
+     *
+     * @return true if any NIB objects is unavailable
+     */
+    boolean checkNibsUnavailable();
+
+    /**
+     * Applies created NIBs to the manager.
+     */
+    void applyNibs();
+
 }