ONOS-6742 Refactored OpenstackNode

- Removed gateway node uplink interface configuration steps
- Added checking group states
- Refactored interface, store, manager and handler

Change-Id: I9149edbec6481b15377848c8f24bdc5c6c73adc4
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
index 4f7ead7..8b93115 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackFlowRuleManager.java
@@ -36,10 +36,10 @@
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.openstacknetworking.api.Constants;
 import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
-import org.onosproject.openstacknode.OpenstackNode;
-import org.onosproject.openstacknode.OpenstackNodeEvent;
-import org.onosproject.openstacknode.OpenstackNodeListener;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.slf4j.Logger;
 
 import java.util.concurrent.ExecutorService;
@@ -73,7 +73,7 @@
 
     private final ExecutorService deviceEventExecutor =
             Executors.newSingleThreadExecutor(groupedThreads("openstacknetworking", "device-event"));
-    private final InternalOpenstackNodeListener internalNodeListener = new InternalOpenstackNodeListener();
+    private final OpenstackNodeListener internalNodeListener = new InternalOpenstackNodeListener();
 
     private ApplicationId appId;
 
@@ -228,25 +228,25 @@
             // TODO check leadership of the node and make only the leader process
 
             switch (event.type()) {
-                case COMPLETE:
+                case OPENSTACK_NODE_COMPLETE:
                     deviceEventExecutor.execute(() -> {
                         log.info("COMPLETE node {} is detected", osNode.hostname());
                         processCompleteNode(event.subject());
                     });
                     break;
-                case INCOMPLETE:
-                    log.warn("{} is changed to INCOMPLETE state", osNode);
-                    break;
-                case INIT:
-                case DEVICE_CREATED:
+                case OPENSTACK_NODE_CREATED:
+                case OPENSTACK_NODE_UPDATED:
+                case OPENSTACK_NODE_REMOVED:
+                case OPENSTACK_NODE_INCOMPLETE:
                 default:
+                    // do nothing
                     break;
             }
         }
 
         private void processCompleteNode(OpenstackNode osNode) {
-            if (osNode.type().equals(OpenstackNodeService.NodeType.COMPUTE)) {
-                initializePipeline(osNode.intBridge());
+            if (osNode.type().equals(OpenstackNode.NodeType.COMPUTE)) {
+                initializePipeline(osNode.intgBridge());
             }
         }
     }
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index f99d2ae..fce18a0 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -25,6 +25,7 @@
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.packet.DefaultOutboundPacket;
@@ -34,15 +35,19 @@
 import org.onosproject.net.packet.PacketService;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
 import org.onosproject.openstacknetworking.api.Constants;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.slf4j.Logger;
 
 import java.nio.ByteBuffer;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
 
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -68,7 +73,7 @@
     private final ExecutorService eventExecutor = newSingleThreadExecutor(
             groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
 
-    private final InternalPacketProcessor packetProcessor = new InternalPacketProcessor();
+    private final PacketProcessor packetProcessor = new InternalPacketProcessor();
 
     @Activate
     protected void activate() {
@@ -123,8 +128,13 @@
         public void process(PacketContext context) {
             if (context.isHandled()) {
                 return;
-            } else if (!osNodeService.gatewayDeviceIds().contains(
-                    context.inPacket().receivedFrom().deviceId())) {
+            }
+
+            Set<DeviceId> gateways = osNodeService.completeNodes(GATEWAY)
+                    .stream().map(OpenstackNode::intgBridge)
+                    .collect(Collectors.toSet());
+
+            if (!gateways.contains(context.inPacket().receivedFrom().deviceId())) {
                 // return if the packet is not from gateway nodes
                 return;
             }
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index f1fdf29..50110a2 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -44,9 +44,10 @@
 import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
 import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
 import org.onosproject.openstacknetworking.api.OpenstackRouterService;
-import org.onosproject.openstacknode.OpenstackNodeEvent;
-import org.onosproject.openstacknode.OpenstackNodeListener;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.openstack4j.model.network.NetFloatingIP;
 import org.openstack4j.model.network.Network;
 import org.openstack4j.model.network.NetworkType;
@@ -55,7 +56,6 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.Objects;
-import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
@@ -65,7 +65,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLOATING_EXTERNAL;
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_FLOATING_INTERNAL;
 import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
-import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 
 /**
  * Handles OpenStack floating IP events.
@@ -107,7 +107,7 @@
 
     private final ExecutorService eventExecutor = newSingleThreadExecutor(
             groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
-    private final OpenstackRouterListener floatingIpLisener = new InternalFloatingIpLisener();
+    private final OpenstackRouterListener floatingIpLisener = new InternalFloatingIpListener();
     private final OpenstackNodeListener osNodeListener = new InternalNodeListener();
 
     private ApplicationId appId;
@@ -158,11 +158,21 @@
 
     private void setDownstreamRules(NetFloatingIP floatingIp, Network osNet,
                                     InstancePort instPort, boolean install) {
-        Optional<IpAddress> dataIp = osNodeService.dataIp(instPort.deviceId());
-        if (!dataIp.isPresent()) {
-            log.warn(ERR_FLOW + "compute node {} is not ready",
-                    floatingIp, instPort.deviceId());
-            return;
+        OpenstackNode cNode = osNodeService.node(instPort.deviceId());
+        if (cNode == null) {
+            final String error = String.format("Cannot find openstack node for device %s",
+                    instPort.deviceId());
+            throw new IllegalStateException(error);
+        }
+        if (osNet.getNetworkType() == NetworkType.VXLAN && cNode.dataIp() == null) {
+            final String error = String.format(ERR_FLOW +
+                    "VXLAN mode is not ready for %s", floatingIp, cNode.hostname());
+            throw new IllegalStateException(error);
+        }
+        if (osNet.getNetworkType() == NetworkType.VLAN && cNode.vlanIntf() == null) {
+            final String error = String.format(ERR_FLOW +
+                    "VLAN mode is not ready for %s", floatingIp, cNode.hostname());
+            throw new IllegalStateException(error);
         }
 
         IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
@@ -171,7 +181,7 @@
                 .matchIPDst(floating.toIpPrefix())
                 .build();
 
-        osNodeService.gatewayDeviceIds().forEach(gnodeId -> {
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
             TrafficTreatment.Builder externalBuilder = DefaultTrafficTreatment.builder()
                     .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
                     .setEthDst(instPort.macAddress())
@@ -182,37 +192,36 @@
                     externalBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID()))
                             .extension(buildExtension(
                                     deviceService,
-                                    gnodeId,
-                                    dataIp.get().getIp4Address()),
-                                    gnodeId)
-                            .setOutput(osNodeService.tunnelPort(gnodeId).get());
+                                    gNode.intgBridge(),
+                                    cNode.dataIp().getIp4Address()),
+                                    gNode.intgBridge())
+                            .setOutput(gNode.tunnelPortNum());
                     break;
                 case VLAN:
                     externalBuilder.pushVlan()
                             .setVlanId(VlanId.vlanId(osNet.getProviderSegID()))
-                            .setOutput(osNodeService.vlanPort(gnodeId).get());
+                            .setOutput(gNode.vlanPortNum());
                     break;
                 default:
-                    final String error = String.format(
-                            ERR_UNSUPPORTED_NET_TYPE + "%s",
-                            osNet.getNetworkType().toString());
+                    final String error = String.format(ERR_UNSUPPORTED_NET_TYPE + "%s",
+                            osNet.getNetworkType());
                     throw new IllegalStateException(error);
             }
 
             osFlowRuleService.setRule(
                     appId,
-                    gnodeId,
+                    gNode.intgBridge(),
                     externalSelector,
                     externalBuilder.build(),
                     PRIORITY_FLOATING_EXTERNAL,
                     GW_COMMON_TABLE,
                     install);
 
-            // access from one VM to the other via floating IP
+            // access from one VM to the others via floating IP
             TrafficSelector internalSelector = DefaultTrafficSelector.builder()
                     .matchEthType(Ethernet.TYPE_IPV4)
                     .matchIPDst(floating.toIpPrefix())
-                    .matchInPort(osNodeService.tunnelPort(gnodeId).get())
+                    .matchInPort(gNode.tunnelPortNum())
                     .build();
 
             TrafficTreatment.Builder internalBuilder = DefaultTrafficTreatment.builder()
@@ -225,9 +234,9 @@
                     internalBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID()))
                             .extension(buildExtension(
                                     deviceService,
-                                    gnodeId,
-                                    dataIp.get().getIp4Address()),
-                                    gnodeId)
+                                    gNode.intgBridge(),
+                                    cNode.dataIp().getIp4Address()),
+                                    gNode.intgBridge())
                             .setOutput(PortNumber.IN_PORT);
                     break;
                 case VLAN:
@@ -236,15 +245,14 @@
                             .setOutput(PortNumber.IN_PORT);
                     break;
                 default:
-                    final String error = String.format(
-                            ERR_UNSUPPORTED_NET_TYPE + "%s",
-                            osNet.getNetworkType().toString());
+                    final String error = String.format(ERR_UNSUPPORTED_NET_TYPE + "%s",
+                            osNet.getNetworkType());
                     throw new IllegalStateException(error);
             }
 
             osFlowRuleService.setRule(
                     appId,
-                    gnodeId,
+                    gNode.intgBridge(),
                     internalSelector,
                     internalBuilder.build(),
                     PRIORITY_FLOATING_INTERNAL,
@@ -256,7 +264,6 @@
     private void setUpstreamRules(NetFloatingIP floatingIp, Network osNet,
                                   InstancePort instPort, boolean install) {
         IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
-
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPSrc(instPort.ipAddress().toIpPrefix());
@@ -269,13 +276,12 @@
                 sBuilder.matchVlanId(VlanId.vlanId(osNet.getProviderSegID()));
                 break;
             default:
-                final String error = String.format(
-                        ERR_UNSUPPORTED_NET_TYPE + "%s",
-                        osNet.getNetworkType().toString());
+                final String error = String.format(ERR_UNSUPPORTED_NET_TYPE + "%s",
+                        osNet.getNetworkType());
                 throw new IllegalStateException(error);
         }
 
-        osNodeService.gatewayDeviceIds().forEach(gnodeId -> {
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
             TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
                     .setIpSrc(floating.getIp4Address())
                     .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
@@ -287,16 +293,16 @@
 
             osFlowRuleService.setRule(
                     appId,
-                    gnodeId,
+                    gNode.intgBridge(),
                     sBuilder.build(),
-                    tBuilder.setOutput(osNodeService.externalPort(gnodeId).get()).build(),
+                    tBuilder.setOutput(gNode.patchPortNum()).build(),
                     PRIORITY_FLOATING_EXTERNAL,
                     GW_COMMON_TABLE,
                     install);
         });
     }
 
-    private class InternalFloatingIpLisener implements OpenstackRouterListener {
+    private class InternalFloatingIpListener implements OpenstackRouterListener {
 
         @Override
         public boolean isRelevant(OpenstackRouterEvent event) {
@@ -401,7 +407,7 @@
         public void event(OpenstackNodeEvent event) {
 
             switch (event.type()) {
-                case COMPLETE:
+                case OPENSTACK_NODE_COMPLETE:
                     eventExecutor.execute(() -> {
                         for (NetFloatingIP fip : osRouterService.floatingIps()) {
                             if (Strings.isNullOrEmpty(fip.getPortId())) {
@@ -416,10 +422,12 @@
                         }
                     });
                     break;
-                case INIT:
-                case DEVICE_CREATED:
-                case INCOMPLETE:
+                case OPENSTACK_NODE_CREATED:
+                case OPENSTACK_NODE_UPDATED:
+                case OPENSTACK_NODE_REMOVED:
+                case OPENSTACK_NODE_INCOMPLETE:
                 default:
+                    // do nothing
                     break;
             }
         }
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index e0b5ccb..084f1b8 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -26,7 +26,6 @@
 import org.onlab.packet.IPv4;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 import org.onosproject.cluster.ClusterService;
 import org.onosproject.cluster.LeadershipService;
@@ -36,7 +35,6 @@
 import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
@@ -47,11 +45,11 @@
 import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
 import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
 import org.onosproject.openstacknetworking.api.OpenstackRouterService;
-import org.onosproject.openstacknode.OpenstackNode;
-import org.onosproject.openstacknode.OpenstackNodeEvent;
-import org.onosproject.openstacknode.OpenstackNodeListener;
-import org.onosproject.openstacknode.OpenstackNodeService;
-import org.onosproject.openstacknode.OpenstackNodeService.NetworkMode;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNode.NetworkMode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.openstack4j.model.network.ExternalGateway;
 import org.openstack4j.model.network.Network;
 import org.openstack4j.model.network.NetworkType;
@@ -68,16 +66,9 @@
 
 import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
 import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.AnnotationKeys.PORT_MAC;
-import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.openstacknetworking.api.Constants.FORWARDING_TABLE;
-import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
-import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_EXTERNAL_ROUTING_RULE;
-import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_ICMP_RULE;
-import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_INTERNAL_ROUTING_RULE;
-import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SWITCHING_RULE;
-import static org.onosproject.openstacknetworking.api.Constants.ROUTING_TABLE;
-import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.COMPUTE;
+import static org.onosproject.openstacknetworking.api.Constants.*;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 
 /**
  * Handles OpenStack router events.
@@ -111,9 +102,6 @@
     protected OpenstackRouterService osRouterService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected OpenstackFlowRuleService osFlowRuleService;
 
     private final ExecutorService eventExecutor = newSingleThreadScheduledExecutor(
@@ -173,7 +161,6 @@
         if (exGateway != null && exGateway.isEnableSnat()) {
             setSourceNat(osRouterIface, true);
         }
-
         log.info("Connected subnet({}) to {}", osSubnet.getCidr(), osRouter.getName());
     }
 
@@ -193,7 +180,6 @@
         if (exGateway != null && exGateway.isEnableSnat()) {
             setSourceNat(osRouterIface, false);
         }
-
         log.info("Disconnected subnet({}) from {}", osSubnet.getCidr(), osRouter.getName());
     }
 
@@ -201,22 +187,21 @@
         Subnet osSubnet = osNetworkService.subnet(routerIface.getSubnetId());
         Network osNet = osNetworkService.network(osSubnet.getNetworkId());
 
-        osNodeService.completeNodes().stream()
-                .filter(osNode -> osNode.type() == COMPUTE)
-                .forEach(osNode -> {
-                        setRulesToGateway(osNode.intBridge(), osNet.getProviderSegID(),
-                                IpPrefix.valueOf(osSubnet.getCidr()), osNet.getNetworkType(),
-                                install);
-                });
+        osNodeService.completeNodes(COMPUTE).forEach(cNode -> {
+            setRulesToGateway(cNode, osNet.getProviderSegID(),
+                    IpPrefix.valueOf(osSubnet.getCidr()), osNet.getNetworkType(),
+                    install);
+        });
 
         // take the first outgoing packet to controller for source NAT
-        osNodeService.gatewayDeviceIds()
-                .forEach(gwDeviceId -> setRulesToController(
-                        gwDeviceId,
-                        osNet.getProviderSegID(),
-                        IpPrefix.valueOf(osSubnet.getCidr()),
-                        osNet.getNetworkType(),
-                        install));
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
+            setRulesToController(
+                    gNode,
+                    osNet.getProviderSegID(),
+                    IpPrefix.valueOf(osSubnet.getCidr()),
+                    osNet.getNetworkType(),
+                    install);
+        });
 
         final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
         log.info(updateStr + "external access for subnet({})", osSubnet.getCidr());
@@ -232,24 +217,22 @@
         Network network = osNetworkService.network(osSubnet.getNetworkId());
         switch (network.getNetworkType()) {
             case VXLAN:
-                osNodeService.completeNodes().stream()
-                        .filter(osNode -> osNode.type() == COMPUTE)
-                        .filter(osNode -> osNode.dataIp().isPresent())
-                        .forEach(osNode -> setRulesToGatewayWithDstIp(
-                                osNode.intBridge(),
-                                osNodeService.gatewayGroupId(osNode.intBridge(), NetworkMode.VXLAN),
+                osNodeService.completeNodes(COMPUTE).stream()
+                        .filter(cNode -> cNode.dataIp() != null)
+                        .forEach(cNode -> setRulesToGatewayWithDstIp(
+                                cNode,
+                                cNode.gatewayGroupId(NetworkMode.VXLAN),
                                 network.getProviderSegID(),
                                 IpAddress.valueOf(osSubnet.getGateway()),
                                 NetworkMode.VXLAN,
                                 install));
                 break;
             case VLAN:
-                osNodeService.completeNodes().stream()
-                        .filter(osNode -> osNode.type() == COMPUTE)
-                        .filter(osNode -> osNode.vlanPort().isPresent())
-                        .forEach(osNode -> setRulesToGatewayWithDstIp(
-                                osNode.intBridge(),
-                                osNodeService.gatewayGroupId(osNode.intBridge(), NetworkMode.VLAN),
+                osNodeService.completeNodes(COMPUTE).stream()
+                        .filter(cNode -> cNode.vlanPortNum() != null)
+                        .forEach(cNode -> setRulesToGatewayWithDstIp(
+                                cNode,
+                                cNode.gatewayGroupId(NetworkMode.VLAN),
                                 network.getProviderSegID(),
                                 IpAddress.valueOf(osSubnet.getGateway()),
                                 NetworkMode.VLAN,
@@ -263,12 +246,13 @@
         }
 
         IpAddress gatewayIp = IpAddress.valueOf(osSubnet.getGateway());
-        osNodeService.gatewayDeviceIds()
-                .forEach(gwDeviceId -> setGatewayIcmpRule(
-                        gatewayIp,
-                        gwDeviceId,
-                        install
-                ));
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
+            setGatewayIcmpRule(
+                    gatewayIp,
+                    gNode.intgBridge(),
+                    install
+            );
+        });
 
         final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
         log.debug(updateStr + "ICMP to {}", osSubnet.getGateway());
@@ -281,40 +265,38 @@
 
         // installs rule from/to my subnet intentionally to fix ICMP failure
         // to my subnet gateway if no external gateway added to the router
-        osNodeService.completeNodes().stream()
-                .filter(osNode -> osNode.type() == COMPUTE)
-                .forEach(osNode -> {
-                    setInternalRouterRules(
-                            osNode.intBridge(),
-                            updatedSegmendId,
-                            updatedSegmendId,
-                            IpPrefix.valueOf(updatedSubnet.getCidr()),
-                            IpPrefix.valueOf(updatedSubnet.getCidr()),
-                            updatedNetwork.getNetworkType(),
-                            install
-                    );
+        osNodeService.completeNodes(COMPUTE).forEach(cNode -> {
+            setInternalRouterRules(
+                    cNode.intgBridge(),
+                    updatedSegmendId,
+                    updatedSegmendId,
+                    IpPrefix.valueOf(updatedSubnet.getCidr()),
+                    IpPrefix.valueOf(updatedSubnet.getCidr()),
+                    updatedNetwork.getNetworkType(),
+                    install
+            );
 
-                    routableSubnets.forEach(subnet -> {
-                        setInternalRouterRules(
-                                osNode.intBridge(),
-                                updatedSegmendId,
-                                getSegmentId(subnet),
-                                IpPrefix.valueOf(updatedSubnet.getCidr()),
-                                IpPrefix.valueOf(subnet.getCidr()),
-                                updatedNetwork.getNetworkType(),
-                                install
-                        );
-                        setInternalRouterRules(
-                                osNode.intBridge(),
-                                getSegmentId(subnet),
-                                updatedSegmendId,
-                                IpPrefix.valueOf(subnet.getCidr()),
-                                IpPrefix.valueOf(updatedSubnet.getCidr()),
-                                updatedNetwork.getNetworkType(),
-                                install
-                        );
-                    });
-                });
+            routableSubnets.forEach(subnet -> {
+                setInternalRouterRules(
+                        cNode.intgBridge(),
+                        updatedSegmendId,
+                        getSegmentId(subnet),
+                        IpPrefix.valueOf(updatedSubnet.getCidr()),
+                        IpPrefix.valueOf(subnet.getCidr()),
+                        updatedNetwork.getNetworkType(),
+                        install
+                );
+                setInternalRouterRules(
+                        cNode.intgBridge(),
+                        getSegmentId(subnet),
+                        updatedSegmendId,
+                        IpPrefix.valueOf(subnet.getCidr()),
+                        IpPrefix.valueOf(updatedSubnet.getCidr()),
+                        updatedNetwork.getNetworkType(),
+                        install
+                );
+            });
+        });
 
 
         final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
@@ -341,7 +323,7 @@
         TrafficSelector selector = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
-                .matchIPDst(gatewayIp.toIpPrefix())
+                .matchIPDst(gatewayIp.getIp4Address().toIpPrefix())
                 .build();
 
         TrafficTreatment treatment = DefaultTrafficTreatment.builder()
@@ -368,8 +350,8 @@
                 selector = DefaultTrafficSelector.builder()
                         .matchEthType(Ethernet.TYPE_IPV4)
                         .matchTunnelId(Long.parseLong(srcSegmentId))
-                        .matchIPSrc(srcSubnet)
-                        .matchIPDst(dstSubnet)
+                        .matchIPSrc(srcSubnet.getIp4Prefix())
+                        .matchIPDst(dstSubnet.getIp4Prefix())
                         .build();
 
                 treatment = DefaultTrafficTreatment.builder()
@@ -389,8 +371,8 @@
                 selector = DefaultTrafficSelector.builder()
                         .matchEthType(Ethernet.TYPE_IPV4)
                         .matchTunnelId(Long.parseLong(dstSegmentId))
-                        .matchIPSrc(srcSubnet)
-                        .matchIPDst(dstSubnet)
+                        .matchIPSrc(srcSubnet.getIp4Prefix())
+                        .matchIPDst(dstSubnet.getIp4Prefix())
                         .build();
 
                 treatment = DefaultTrafficTreatment.builder()
@@ -411,8 +393,8 @@
                 selector = DefaultTrafficSelector.builder()
                         .matchEthType(Ethernet.TYPE_IPV4)
                         .matchVlanId(VlanId.vlanId(srcSegmentId))
-                        .matchIPSrc(srcSubnet)
-                        .matchIPDst(dstSubnet)
+                        .matchIPSrc(srcSubnet.getIp4Prefix())
+                        .matchIPDst(dstSubnet.getIp4Prefix())
                         .build();
 
                 treatment = DefaultTrafficTreatment.builder()
@@ -432,8 +414,8 @@
                 selector = DefaultTrafficSelector.builder()
                         .matchEthType(Ethernet.TYPE_IPV4)
                         .matchVlanId(VlanId.vlanId(dstSegmentId))
-                        .matchIPSrc(srcSubnet)
-                        .matchIPDst(dstSubnet)
+                        .matchIPSrc(srcSubnet.getIp4Prefix())
+                        .matchIPDst(dstSubnet.getIp4Prefix())
                         .build();
 
                 treatment = DefaultTrafficTreatment.builder()
@@ -459,26 +441,24 @@
 
     }
 
-    private void setRulesToGateway(DeviceId deviceId, String segmentId, IpPrefix srcSubnet,
+    private void setRulesToGateway(OpenstackNode osNode, String segmentId, IpPrefix srcSubnet,
                                    NetworkType networkType, boolean install) {
         TrafficTreatment treatment;
         GroupId groupId;
 
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPSrc(srcSubnet)
+                .matchIPSrc(srcSubnet.getIp4Prefix())
                 .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
 
         switch (networkType) {
             case VXLAN:
                 sBuilder.matchTunnelId(Long.parseLong(segmentId));
-
-                groupId = osNodeService.gatewayGroupId(deviceId, NetworkMode.VXLAN);
+                groupId = osNode.gatewayGroupId(NetworkMode.VXLAN);
                 break;
             case VLAN:
                 sBuilder.matchVlanId(VlanId.vlanId(segmentId));
-
-                groupId = osNodeService.gatewayGroupId(deviceId, NetworkMode.VLAN);
+                groupId = osNode.gatewayGroupId(NetworkMode.VLAN);
                 break;
             default:
                 final String error = String.format(
@@ -493,7 +473,7 @@
 
         osFlowRuleService.setRule(
                 appId,
-                deviceId,
+                osNode.intgBridge(),
                 sBuilder.build(),
                 treatment,
                 PRIORITY_EXTERNAL_ROUTING_RULE,
@@ -501,11 +481,16 @@
                 install);
     }
 
-    private void setRulesToController(DeviceId deviceId, String segmentId, IpPrefix srcSubnet,
+    private void setRulesToController(OpenstackNode osNode, String segmentId,
+                                      IpPrefix srcSubnet,
                                       NetworkType networkType, boolean install) {
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPSrc(srcSubnet);
+                .matchIPSrc(srcSubnet.getIp4Prefix());
+
+        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+                .setEthDst(Constants.DEFAULT_GATEWAY_MAC)
+                .setOutput(PortNumber.CONTROLLER);
 
         switch (networkType) {
             case VXLAN:
@@ -514,27 +499,18 @@
                 break;
             case VLAN:
                 sBuilder.matchVlanId(VlanId.vlanId(segmentId))
-                        .matchEthDst(MacAddress.valueOf(vlanPortMac(deviceId)));
+                        .matchEthDst(osNode.vlanPortMac());
+                tBuilder.popVlan();
                 break;
             default:
-                final String error = String.format(
-                        ERR_UNSUPPORTED_NET_TYPE + "%s",
+                final String error = String.format(ERR_UNSUPPORTED_NET_TYPE + "%s",
                         networkType.toString());
                 throw new IllegalStateException(error);
         }
 
-        TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
-                .setEthDst(Constants.DEFAULT_GATEWAY_MAC);
-
-        if (networkType.equals(NetworkType.VLAN)) {
-            tBuilder.popVlan();
-        }
-
-        tBuilder.setOutput(PortNumber.CONTROLLER);
-
         osFlowRuleService.setRule(
                 appId,
-                deviceId,
+                osNode.intgBridge(),
                 sBuilder.build(),
                 tBuilder.build(),
                 PRIORITY_EXTERNAL_ROUTING_RULE,
@@ -542,27 +518,21 @@
                 install);
     }
 
-    private String vlanPortMac(DeviceId deviceId) {
-        return deviceService.getPorts(deviceId).stream()
-                .filter(p -> p.annotations()
-                        .value(PORT_NAME).equals(osNodeService.gatewayNode(deviceId).vlanPort().get()) && p.isEnabled())
-                .findFirst().get().annotations().value(PORT_MAC);
-    }
-
-    private void setRulesToGatewayWithDstIp(DeviceId deviceId, GroupId groupId, String segmentId,
-                                            IpAddress dstIp, NetworkMode networkMode, boolean install) {
+    private void setRulesToGatewayWithDstIp(OpenstackNode osNode, GroupId groupId,
+                                            String segmentId, IpAddress dstIp,
+                                            NetworkMode networkMode, boolean install) {
         TrafficSelector selector;
         if (networkMode.equals(NetworkMode.VXLAN)) {
             selector = DefaultTrafficSelector.builder()
                     .matchEthType(Ethernet.TYPE_IPV4)
                     .matchTunnelId(Long.valueOf(segmentId))
-                    .matchIPDst(dstIp.toIpPrefix())
+                    .matchIPDst(dstIp.getIp4Address().toIpPrefix())
                     .build();
         } else {
             selector = DefaultTrafficSelector.builder()
                     .matchEthType(Ethernet.TYPE_IPV4)
                     .matchVlanId(VlanId.vlanId(segmentId))
-                    .matchIPDst(dstIp.toIpPrefix())
+                    .matchIPDst(dstIp.getIp4Address().toIpPrefix())
                     .build();
         }
 
@@ -572,7 +542,7 @@
 
         osFlowRuleService.setRule(
                 appId,
-                deviceId,
+                osNode.intgBridge(),
                 selector,
                 treatment,
                 PRIORITY_SWITCHING_RULE,
@@ -659,15 +629,16 @@
             OpenstackNode osNode = event.subject();
 
             switch (event.type()) {
-                case COMPLETE:
-                case INCOMPLETE:
+                case OPENSTACK_NODE_COMPLETE:
+                case OPENSTACK_NODE_INCOMPLETE:
                     eventExecutor.execute(() -> {
                         log.info("Reconfigure routers for {}", osNode.hostname());
                         reconfigureRouters();
                     });
                     break;
-                case INIT:
-                case DEVICE_CREATED:
+                case OPENSTACK_NODE_CREATED:
+                case OPENSTACK_NODE_UPDATED:
+                case OPENSTACK_NODE_REMOVED:
                 default:
                     break;
             }
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
index ea716db..a6f0a39 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
@@ -47,10 +47,10 @@
 import org.onosproject.openstacknetworking.api.InstancePortService;
 import org.onosproject.openstacknetworking.api.OpenstackRouterService;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
-import org.onosproject.openstacknode.OpenstackNode;
-import org.onosproject.openstacknode.OpenstackNodeEvent;
-import org.onosproject.openstacknode.OpenstackNodeListener;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.openstack4j.model.network.ExternalGateway;
 import org.openstack4j.model.network.IP;
 import org.openstack4j.model.network.Port;
@@ -70,7 +70,7 @@
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.openstacknetworking.api.Constants.*;
-import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.slf4j.LoggerFactory.getLogger;
 
 
@@ -111,8 +111,8 @@
 
     private final ExecutorService eventExecutor = newSingleThreadExecutor(
             groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
-    private final InternalPacketProcessor packetProcessor = new InternalPacketProcessor();
-    private final InternalNodeListener nodeListener = new InternalNodeListener();
+    private final PacketProcessor packetProcessor = new InternalPacketProcessor();
+    private final OpenstackNodeListener osNodeListener = new InternalNodeListener();
     private final Map<String, InstancePort> icmpInfoMap = Maps.newHashMap();
 
     private ApplicationId appId;
@@ -121,7 +121,7 @@
     protected void activate() {
         appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
         packetService.addProcessor(packetProcessor, PacketProcessor.director(1));
-        osNodeService.addListener(nodeListener);
+        osNodeService.addListener(osNodeListener);
         requestPacket(appId);
 
         log.info("Started");
@@ -130,7 +130,7 @@
     @Deactivate
     protected void deactivate() {
         packetService.removeProcessor(packetProcessor);
-        osNodeService.removeListener(nodeListener);
+        osNodeService.removeListener(osNodeListener);
         eventExecutor.shutdown();
 
         log.info("Stopped");
@@ -142,13 +142,13 @@
                 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
                 .build();
 
-        osNodeService.gatewayDeviceIds().forEach(gateway -> {
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
             packetService.requestPackets(
                     icmpSelector,
                     PacketPriority.CONTROL,
                     appId,
-                    Optional.of(gateway));
-            log.debug("Requested ICMP packet to {}", gateway);
+                    Optional.of(gNode.intgBridge()));
+            log.debug("Requested ICMP packet to {}", gNode.intgBridge());
         });
     }
 
@@ -210,9 +210,7 @@
             if (externalIp == null) {
                 return;
             }
-            log.debug("1");
             sendRequestForExternal(ipPacket, srcDevice, externalIp);
-            log.debug("2");
             String icmpInfoKey = String.valueOf(getIcmpId(icmp))
                     .concat(String.valueOf(externalIp.getIp4Address().toInt()))
                     .concat(String.valueOf(ipPacket.getDestinationAddress()));
@@ -329,8 +327,14 @@
                 .setDestinationMACAddress(DEFAULT_EXTERNAL_ROUTER_MAC)
                 .setPayload(ipPacket);
 
+        OpenstackNode osNode = osNodeService.node(srcDevice);
+        if (osNode == null) {
+            final String error = String.format("Cannot find openstack node for %s",
+                    srcDevice);
+            throw new IllegalStateException(error);
+        }
         TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setOutput(osNodeService.externalPort(srcDevice).get())
+                .setOutput(osNode.patchPortNum())
                 .build();
 
         OutboundPacket packet = new DefaultOutboundPacket(
@@ -379,10 +383,13 @@
 
         @Override
         public void process(PacketContext context) {
+            Set<DeviceId> gateways = osNodeService.completeNodes(GATEWAY)
+                    .stream().map(OpenstackNode::intgBridge)
+                    .collect(Collectors.toSet());
+
             if (context.isHandled()) {
                 return;
-            } else if (!osNodeService.gatewayDeviceIds().contains(
-                    context.inPacket().receivedFrom().deviceId())) {
+            } else if (!gateways.contains(context.inPacket().receivedFrom().deviceId())) {
                 // return if the packet is not from gateway nodes
                 return;
             }
@@ -406,7 +413,7 @@
         public boolean isRelevant(OpenstackNodeEvent event) {
             // do not proceed without mastership
             OpenstackNode osNode = event.subject();
-            return mastershipService.isLocalMaster(osNode.intBridge());
+            return mastershipService.isLocalMaster(osNode.intgBridge());
         }
 
         @Override
@@ -414,7 +421,7 @@
             OpenstackNode osNode = event.subject();
 
             switch (event.type()) {
-                case COMPLETE:
+                case OPENSTACK_NODE_COMPLETE:
                     if (osNode.type() == GATEWAY) {
                         log.info("GATEWAY node {} detected", osNode.hostname());
                         eventExecutor.execute(() -> {
@@ -422,10 +429,12 @@
                         });
                     }
                     break;
-                case INIT:
-                case DEVICE_CREATED:
-                case INCOMPLETE:
+                case OPENSTACK_NODE_CREATED:
+                case OPENSTACK_NODE_UPDATED:
+                case OPENSTACK_NODE_REMOVED:
+                case OPENSTACK_NODE_INCOMPLETE:
                 default:
+                    // do nothing
                     break;
             }
         }
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index 9d62a34..1300188 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -47,7 +47,8 @@
 import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
 import org.onosproject.openstacknetworking.api.OpenstackRouterService;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.DistributedSet;
@@ -65,15 +66,14 @@
 
 import java.nio.ByteBuffer;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
 
 import static java.util.concurrent.Executors.newSingleThreadExecutor;
 import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_EXTERNAL_ROUTER_MAC;
-import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_GATEWAY_MAC;
-import static org.onosproject.openstacknetworking.api.Constants.GW_COMMON_TABLE;
-import static org.onosproject.openstacknetworking.api.Constants.OPENSTACK_NETWORKING_APP_ID;
-import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_SNAT_RULE;
+import static org.onosproject.openstacknetworking.api.Constants.*;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -122,7 +122,7 @@
 
     private final ExecutorService eventExecutor = newSingleThreadExecutor(
             groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
-    private final InternalPacketProcessor packetProcessor = new InternalPacketProcessor();
+    private final PacketProcessor packetProcessor = new InternalPacketProcessor();
 
     private ConsistentMap<Integer, Long> allocatedPortNumMap;
     private DistributedSet<Integer> unUsedPortNumSet;
@@ -273,7 +273,8 @@
                 packetIn);
     }
 
-    private void setDownstreamRules(InstancePort srcInstPort, String segmentId, NetworkType networkType,
+    private void setDownstreamRules(InstancePort srcInstPort, String segmentId,
+                                    NetworkType networkType,
                                     IpAddress externalIp, TpPort patPort,
                                     InboundPacket packetIn) {
         IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
@@ -282,7 +283,7 @@
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPProtocol(iPacket.getProtocol())
-                .matchIPDst(IpPrefix.valueOf(externalIp, 32))
+                .matchIPDst(IpPrefix.valueOf(externalIp.getIp4Address(), 32))
                 .matchIPSrc(IpPrefix.valueOf(iPacket.getDestinationAddress(), 32));
 
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
@@ -323,31 +324,30 @@
                 break;
         }
 
-        osNodeService.gatewayDeviceIds().forEach(deviceId -> {
-            DeviceId srcDeviceId = srcInstPort.deviceId();
+        OpenstackNode srcNode = osNodeService.node(srcInstPort.deviceId());
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
             TrafficTreatment.Builder tmpBuilder =
                     DefaultTrafficTreatment.builder(tBuilder.build());
             switch (networkType) {
                 case VXLAN:
                     tmpBuilder.extension(RulePopulatorUtil.buildExtension(
                             deviceService,
-                            deviceId,
-                            osNodeService.dataIp(srcDeviceId).get().getIp4Address()), deviceId)
-                            .setOutput(osNodeService.tunnelPort(deviceId).get());
+                            gNode.intgBridge(),
+                            srcNode.dataIp().getIp4Address()), gNode.intgBridge())
+                            .setOutput(gNode.tunnelPortNum());
                     break;
                 case VLAN:
-                    tmpBuilder.setOutput(osNodeService.vlanPort(deviceId).get());
+                    tmpBuilder.setOutput(gNode.vlanPortNum());
                     break;
                 default:
-                    final String error = String.format(
-                            ERR_UNSUPPORTED_NET_TYPE + "%s",
+                    final String error = String.format(ERR_UNSUPPORTED_NET_TYPE + "%s",
                             networkType.toString());
                     throw new IllegalStateException(error);
             }
 
             osFlowRuleService.setRule(
                     appId,
-                    deviceId,
+                    gNode.intgBridge(),
                     sBuilder.build(),
                     tmpBuilder.build(),
                     PRIORITY_SNAT_RULE,
@@ -356,7 +356,8 @@
         });
     }
 
-    private void setUpstreamRules(String segmentId, NetworkType networkType, IpAddress externalIp, TpPort patPort,
+    private void setUpstreamRules(String segmentId, NetworkType networkType,
+                                  IpAddress externalIp, TpPort patPort,
                                   InboundPacket packetIn) {
         IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
 
@@ -377,8 +378,7 @@
                 tBuilder.popVlan();
                 break;
             default:
-                final String error = String.format(
-                        ERR_UNSUPPORTED_NET_TYPE + "%s",
+                final String error = String.format(ERR_UNSUPPORTED_NET_TYPE + "%s",
                         networkType.toString());
                 throw new IllegalStateException(error);
         }
@@ -397,7 +397,6 @@
                         .matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));
                 tBuilder.setUdpSrc(patPort)
                         .setEthDst(DEFAULT_EXTERNAL_ROUTER_MAC);
-
                 break;
             default:
                 log.debug("Unsupported IPv4 protocol {}");
@@ -405,14 +404,14 @@
         }
 
         tBuilder.setIpSrc(externalIp);
-        osNodeService.gatewayDeviceIds().forEach(deviceId -> {
+        osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
             TrafficTreatment.Builder tmpBuilder =
                     DefaultTrafficTreatment.builder(tBuilder.build());
-            tmpBuilder.setOutput(osNodeService.externalPort(deviceId).get());
+            tmpBuilder.setOutput(gNode.patchPortNum());
 
             osFlowRuleService.setRule(
                     appId,
-                    deviceId,
+                    gNode.intgBridge(),
                     sBuilder.build(),
                     tmpBuilder.build(),
                     PRIORITY_SNAT_RULE,
@@ -424,7 +423,6 @@
     private void packetOut(Ethernet ethPacketIn, DeviceId srcDevice, int patPort,
                            IpAddress externalIp) {
         IPv4 iPacket = (IPv4) ethPacketIn.getPayload();
-
         switch (iPacket.getProtocol()) {
             case IPv4.PROTOCOL_TCP:
                 TCP tcpPacket = (TCP) iPacket.getPayload();
@@ -452,9 +450,15 @@
         ethPacketIn.setPayload(iPacket);
         ethPacketIn.resetChecksum();
 
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
-                .setOutput(osNodeService.externalPort(srcDevice).get()).build();
+        OpenstackNode srcNode = osNodeService.node(srcDevice);
+        if (srcNode == null) {
+            final String error = String.format("Cannot find openstack node for %s",
+                    srcDevice);
+            throw new IllegalStateException(error);
+        }
 
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(srcNode.patchPortNum()).build();
         packetService.emit(new DefaultOutboundPacket(
                 srcDevice,
                 treatment,
@@ -465,13 +469,11 @@
         if (unUsedPortNumSet.isEmpty()) {
             clearPortNumMap();
         }
-
         int portNum = findUnusedPortNum();
         if (portNum != 0) {
             unUsedPortNumSet.remove(portNum);
             allocatedPortNumMap.put(portNum, System.currentTimeMillis());
         }
-
         return portNum;
     }
 
@@ -492,10 +494,12 @@
 
         @Override
         public void process(PacketContext context) {
+            Set<DeviceId> gateways = osNodeService.completeNodes(OpenstackNode.NodeType.GATEWAY)
+                    .stream().map(OpenstackNode::intgBridge)
+                    .collect(Collectors.toSet());
             if (context.isHandled()) {
                 return;
-            } else if (!osNodeService.gatewayDeviceIds().contains(
-                    context.inPacket().receivedFrom().deviceId())) {
+            } else if (!gateways.contains(context.inPacket().receivedFrom().deviceId())) {
                 // return if the packet is not from gateway nodes
                 return;
             }
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
index 10b1776..0ec6ccc 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHandler.java
@@ -38,7 +38,8 @@
 import org.onosproject.openstacknetworking.api.InstancePortService;
 import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.openstack4j.model.network.Network;
 import org.slf4j.Logger;
 
@@ -53,7 +54,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
 import static org.onosproject.openstacknetworking.api.Constants.SRC_VNI_TABLE;
 import static org.onosproject.openstacknetworking.impl.RulePopulatorUtil.buildExtension;
-import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.COMPUTE;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.slf4j.LoggerFactory.getLogger;
 
 
@@ -148,22 +149,27 @@
                 install);
 
         // switching rules for the instPorts in the remote node
-        osNodeService.completeNodes().stream()
-                .filter(osNode -> osNode.type() == COMPUTE)
-                .filter(osNode -> !osNode.intBridge().equals(instPort.deviceId()))
-                .forEach(osNode -> {
+        OpenstackNode localNode = osNodeService.node(instPort.deviceId());
+        if (localNode == null) {
+            final String error = String.format("Cannot find openstack node for %s",
+                    instPort.deviceId());
+            throw new IllegalStateException(error);
+        }
+        osNodeService.completeNodes(COMPUTE).stream()
+                .filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
+                .forEach(remoteNode -> {
                     TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
                             .extension(buildExtension(
                                     deviceService,
-                                    osNode.intBridge(),
-                                    osNodeService.dataIp(instPort.deviceId()).get().getIp4Address()),
-                                    osNode.intBridge())
-                            .setOutput(osNodeService.tunnelPort(osNode.intBridge()).get())
+                                    remoteNode.intgBridge(),
+                                    localNode.dataIp().getIp4Address()),
+                                    remoteNode.intgBridge())
+                            .setOutput(remoteNode.tunnelPortNum())
                             .build();
 
                     osFlowRuleService.setRule(
                             appId,
-                            osNode.intBridge(),
+                            remoteNode.intgBridge(),
                             selector,
                             treatmentToRemote,
                             PRIORITY_SWITCHING_RULE,
@@ -196,25 +202,23 @@
                 install);
 
         // switching rules for the instPorts in the remote node
-        osNodeService.completeNodes().stream()
-                .filter(osNode -> osNode.type() == COMPUTE)
-                .filter(osNode -> !osNode.intBridge().equals(instPort.deviceId()))
-                .filter(osNode -> osNode.vlanPort().isPresent())
-                .forEach(osNode -> {
+        osNodeService.completeNodes(COMPUTE).stream()
+                .filter(remoteNode -> !remoteNode.intgBridge().equals(instPort.deviceId()) &&
+                        remoteNode.vlanIntf() != null)
+                .forEach(remoteNode -> {
                     TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
-                                    .setOutput(osNodeService.vlanPort(osNode.intBridge()).get())
+                                    .setOutput(remoteNode.vlanPortNum())
                                     .build();
 
                     osFlowRuleService.setRule(
                             appId,
-                            osNode.intBridge(),
+                            remoteNode.intgBridge(),
                             selector,
                             treatmentToRemote,
                             PRIORITY_SWITCHING_RULE,
                             FORWARDING_TABLE,
                             install);
                 });
-
     }
 
     private void setTunnelTagFlowRules(InstancePort instPort, boolean install) {
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
index 5f776b3..c5de792 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
@@ -47,10 +47,10 @@
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
-import org.onosproject.openstacknode.OpenstackNode;
-import org.onosproject.openstacknode.OpenstackNodeEvent;
-import org.onosproject.openstacknode.OpenstackNodeListener;
-import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
 import org.openstack4j.model.network.Network;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -260,24 +260,25 @@
             // TODO check leadership of the node and make only the leader process
 
             switch (event.type()) {
-                case COMPLETE:
+                case OPENSTACK_NODE_COMPLETE:
                     deviceEventExecutor.execute(() -> {
                         log.info("COMPLETE node {} is detected", osNode.hostname());
                         processCompleteNode(event.subject());
                     });
                     break;
-                case INCOMPLETE:
+                case OPENSTACK_NODE_INCOMPLETE:
                     log.warn("{} is changed to INCOMPLETE state", osNode);
                     break;
-                case INIT:
-                case DEVICE_CREATED:
+                case OPENSTACK_NODE_CREATED:
+                case OPENSTACK_NODE_UPDATED:
+                case OPENSTACK_NODE_REMOVED:
                 default:
                     break;
             }
         }
 
         private void processCompleteNode(OpenstackNode osNode) {
-            deviceService.getPorts(osNode.intBridge()).stream()
+            deviceService.getPorts(osNode.intgBridge()).stream()
                     .filter(port -> port.annotations().value(PORT_NAME)
                             .startsWith(PORT_NAME_PREFIX_VM) &&
                             port.isEnabled())