Refactor: resolve code smells of openstacknetworking impl pkgs #2

Change-Id: I788d328cf0f5a3673d8cad01416f5926e1ab055c
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java
index f4fbf52..c7a47faa 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DistributedSecurityGroupStore.java
@@ -159,21 +159,19 @@
             switch (event.type()) {
                 case INSERT:
                     log.debug("OpenStack security group created {}", event.newValue());
-                    eventExecutor.execute(() ->
-                            notifyDelegate(new OpenstackSecurityGroupEvent(
+                    eventExecutor.execute(() -> notifyDelegate(new OpenstackSecurityGroupEvent(
                                     OPENSTACK_SECURITY_GROUP_CREATED,
                                     event.newValue().value())));
                     break;
                 case UPDATE:
                     log.debug("OpenStack security group updated {}", event.newValue());
                     eventExecutor.execute(() -> processUpdate(
-                            event.oldValue().value(),
-                            event.newValue().value()));
+                                    event.oldValue().value(),
+                                    event.newValue().value()));
                     break;
                 case REMOVE:
                     log.debug("OpenStack security group removed {}", event.oldValue());
-                    eventExecutor.execute(() ->
-                            notifyDelegate(new OpenstackSecurityGroupEvent(
+                    eventExecutor.execute(() -> notifyDelegate(new OpenstackSecurityGroupEvent(
                                     OPENSTACK_SECURITY_GROUP_REMOVED,
                                     event.oldValue().value())));
                     break;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
index 8263f63..f04071f 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/InstancePortManager.java
@@ -307,80 +307,89 @@
                     updateInstancePort(instPort);
                     break;
                 case HOST_ADDED:
-                    InstancePort existingPort = instancePort(instPort.portId());
-                    if (existingPort == null) {
-                        // first time to add instance
-                        createInstancePort(instPort);
-                    } else {
-                        if (existingPort.state() == INACTIVE) {
-
-                            if (instPort.deviceId().equals(existingPort.deviceId())) {
-
-                                // VM RESTART case
-                                // if the ID of switch where VM is attached to is
-                                // identical, we can assume that the VM was
-                                // restarted in the same location;
-                                // note that the switch port number where VM is
-                                // attached can be varied per each restart
-                                updateInstancePort(instPort);
-                            } else {
-
-                                // VM COLD MIGRATION case
-                                // if the ID of switch where VM is attached to is
-                                // varied, we can assume that the VM was migrated
-                                // to a new location
-                                updateInstancePort(instPort.updateState(MIGRATING));
-                                InstancePort updated = instPort.updateState(MIGRATED);
-                                updateInstancePort(updated.updatePrevLocation(
-                                        existingPort.deviceId(), existingPort.portNumber()));
-                            }
-                        }
-                    }
+                    processHostAddition(instPort);
                     break;
                 case HOST_REMOVED:
-
-                    // in case the instance port cannot be found in the store,
-                    // this indicates that the instance port was removed due to
-                    // the removal of openstack port; in some cases, openstack
-                    // port removal message arrives before ovs port removal message
-                    if (instancePortStore.instancePort(instPort.portId()) == null) {
-                        log.debug("instance port was removed before ovs port removal");
-                        break;
-                    }
-
-                    // we will remove instance port from persistent store,
-                    // only if we receive port removal signal from neutron.
-                    // by default, we update the instance port state to INACTIVE
-                    // to indicate the instance is terminated
-                    updateInstancePort(instPort.updateState(INACTIVE));
+                    processHostRemoval(instPort);
                     break;
                 case HOST_MOVED:
-                    Host oldHost = event.prevSubject();
-                    Host currHost = event.subject();
-
-                    // in the middle of VM migration
-                    if (oldHost.locations().size() < currHost.locations().size()) {
-                        updateInstancePort(instPort.updateState(MIGRATING));
-                    }
-
-                    // finish of VM migration
-                    if (oldHost.locations().size() > currHost.locations().size()) {
-                        Set<HostLocation> diff =
-                                Sets.difference(oldHost.locations(), currHost.locations());
-                        HostLocation location = diff.stream().findFirst().orElse(null);
-
-                        if (location != null) {
-                            InstancePort updated = instPort.updateState(MIGRATED);
-                            updateInstancePort(updated.updatePrevLocation(
-                                        location.deviceId(), location.port()));
-                        }
-                    }
+                    processHostMove(event, instPort);
                     break;
                 default:
                     break;
             }
         }
 
+        private void processHostAddition(InstancePort instPort) {
+            InstancePort existingPort = instancePort(instPort.portId());
+            if (existingPort == null) {
+                // first time to add instance
+                createInstancePort(instPort);
+            } else {
+                if (existingPort.state() == INACTIVE) {
+
+                    if (instPort.deviceId().equals(existingPort.deviceId())) {
+                        // VM RESTART case
+                        // if the ID of switch where VM is attached to is
+                        // identical, we can assume that the VM was
+                        // restarted in the same location;
+                        // note that the switch port number where VM is
+                        // attached can be varied per each restart
+                        updateInstancePort(instPort);
+                    } else {
+                        // VM COLD MIGRATION case
+                        // if the ID of switch where VM is attached to is
+                        // varied, we can assume that the VM was migrated
+                        // to a new location
+                        updateInstancePort(instPort.updateState(MIGRATING));
+                        InstancePort updated = instPort.updateState(MIGRATED);
+                        updateInstancePort(updated.updatePrevLocation(
+                                existingPort.deviceId(), existingPort.portNumber()));
+                    }
+                }
+            }
+        }
+
+        private void processHostRemoval(InstancePort instPort) {
+            /* in case the instance port cannot be found in the store,
+               this indicates that the instance port was removed due to
+               the removal of openstack port; in some cases, openstack
+               port removal message arrives before ovs port removal message */
+            if (instancePortStore.instancePort(instPort.portId()) == null) {
+                log.debug("instance port was removed before ovs port removal");
+                return;
+            }
+
+            /* we will remove instance port from persistent store,
+               only if we receive port removal signal from neutron.
+               by default, we update the instance port state to INACTIVE
+               to indicate the instance is terminated */
+            updateInstancePort(instPort.updateState(INACTIVE));
+        }
+
+        private void processHostMove(HostEvent event, InstancePort instPort) {
+            Host oldHost = event.prevSubject();
+            Host currHost = event.subject();
+
+            // in the middle of VM migration
+            if (oldHost.locations().size() < currHost.locations().size()) {
+                updateInstancePort(instPort.updateState(MIGRATING));
+            }
+
+            // finish of VM migration
+            if (oldHost.locations().size() > currHost.locations().size()) {
+                Set<HostLocation> diff =
+                        Sets.difference(oldHost.locations(), currHost.locations());
+                HostLocation location = diff.stream().findFirst().orElse(null);
+
+                if (location != null) {
+                    InstancePort updated = instPort.updateState(MIGRATED);
+                    updateInstancePort(updated.updatePrevLocation(
+                            location.deviceId(), location.port()));
+                }
+            }
+        }
+
         private boolean isValidHost(Host host) {
             return !host.ipAddresses().isEmpty() &&
                     host.annotations().value(ANNOTATION_NETWORK_ID) != null &&
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java
index 642b686..382c054 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenStackSwitchingDirectPortProvider.java
@@ -62,7 +62,7 @@
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
 
 @Component(immediate = true)
-public final class OpenStackSwitchingDirectPortProvider {
+public class OpenStackSwitchingDirectPortProvider {
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private static final String UNBOUND = "unbound";
@@ -102,7 +102,7 @@
     private ApplicationId appId;
 
     @Activate
-    void activate() {
+    protected void activate() {
         appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
         localNodeId = clusterService.getLocalNode().id();
         leadershipService.runForLeadership(appId.name());
@@ -113,7 +113,7 @@
     }
 
     @Deactivate
-    void deactivate() {
+    protected void deactivate() {
         leadershipService.withdraw(appId.name());
         osNetworkService.removeListener(openstackNetworkListener);
         osNodeService.removeListener(internalNodeListener);
@@ -131,44 +131,41 @@
         public void event(OpenstackNetworkEvent event) {
             switch (event.type()) {
                 case OPENSTACK_PORT_UPDATED:
-
-                    executor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        if (event.port().getState() == State.DOWN) {
-                            processPortRemoved(event.port());
-                        } else {
-                            processPortAdded(event.port());
-                        }
-                    });
-
+                    executor.execute(() -> processPortUpdate(event));
                     break;
                 case OPENSTACK_PORT_REMOVED:
-
-                    executor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        processPortRemoved(event.port());
-                    });
-
+                    executor.execute(() -> processPortRemoval(event));
                     break;
                 default:
                     break;
-
             }
         }
 
-        private void processPortAdded(Port port) {
+        private void processPortUpdate(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            if (event.port().getState() == State.DOWN) {
+                removePort(event.port());
+            } else {
+                addPort(event.port());
+            }
+        }
+
+        private void processPortRemoval(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            removePort(event.port());
+        }
+
+        private void addPort(Port port) {
             if (!port.getvNicType().equals(DIRECT)) {
                 return;
             } else if (!port.isAdminStateUp() || port.getVifType().equals(UNBOUND)) {
-                log.trace("processPortAdded skipped because of status: {}, adminStateUp: {}, vifType: {}",
+                log.trace("AddPort skipped because of status: {}, adminStateUp: {}, vifType: {}",
                         port.getState(), port.isAdminStateUp(), port.getVifType());
                 return;
             } else {
@@ -176,7 +173,7 @@
                         .filter(node -> node.hostname().equals(port.getHostId()))
                         .findAny();
                 if (!osNode.isPresent()) {
-                    log.error("processPortAdded failed because openstackNode doesn't exist that matches hostname {}",
+                    log.error("AddPort failed because openstackNode doesn't exist that matches hostname {}",
                             port.getHostId());
                     return;
                 }
@@ -184,7 +181,7 @@
 
                 String intfName = getIntfNameFromPciAddress(port);
                 if (intfName == null) {
-                    log.error("Failed to execute processPortAdded because of null interface name");
+                    log.error("Failed to execute AddPort because of null interface name");
                     return;
                 } else if (intfName.equals(UNSUPPORTED_VENDOR)) {
                     return;
@@ -211,11 +208,11 @@
             }
         }
 
-        private void processPortRemoved(Port port) {
+        private void removePort(Port port) {
             if (!port.getvNicType().equals(DIRECT)) {
                 return;
             } else if (instancePortService.instancePort(port.getId()) == null) {
-                log.trace("processPortRemoved skipped because no instance port exist for portId: {}", port.getId());
+                log.trace("RemovePort skipped because no instance port exist for portId: {}", port.getId());
                 return;
             } else {
                 InstancePort instancePort = instancePortService.instancePort(port.getId());
@@ -236,14 +233,14 @@
                         .findAny();
 
                 if (!removedPort.isPresent()) {
-                    log.error("Failed to execute processPortAdded because port number doesn't exist");
+                    log.error("Failed to execute RemovePort because port number doesn't exist");
                     return;
                 }
 
                 String intfName = removedPort.get().annotations().value(PORT_NAME);
 
                 if (intfName == null) {
-                    log.error("Failed to execute processPortAdded because of null interface name");
+                    log.error("Failed to execute RemovePort because of null interface name");
                     return;
                 }
                 log.trace("Retrieved interface name: {}", intfName);
@@ -276,29 +273,27 @@
 
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    log.info("COMPLETE node {} is detected", osNode.hostname());
-
-                    executor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        processComputeState(event.subject());
-                    });
-
+                    executor.execute(() -> processNodeCompletion(event, osNode));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
                 case OPENSTACK_NODE_CREATED:
                 case OPENSTACK_NODE_UPDATED:
                 case OPENSTACK_NODE_REMOVED:
-                    // not reacts to the events other than complete and incomplete states
-                    break;
                 default:
                     break;
             }
         }
 
+        private void processNodeCompletion(OpenstackNodeEvent event,
+                                           OpenstackNode osNode) {
+            log.info("COMPLETE node {} is detected", osNode.hostname());
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            processComputeState(event.subject());
+        }
+
         private void processComputeState(OpenstackNode node) {
             List<Port> ports = osNetworkService.ports().stream()
                     .filter(port -> port.getvNicType().equals(DIRECT))
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackMetadataProxyHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackMetadataProxyHandler.java
index 9446976..66250e0 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackMetadataProxyHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackMetadataProxyHandler.java
@@ -454,9 +454,6 @@
             log.info("Sending HTTP {} request to metadata endpoint {}...", method, url);
 
             switch (method) {
-                case HTTP_GET_METHOD:
-                    request = new HttpGet(url);
-                    break;
                 case HTTP_POST_METHOD:
                     request = new HttpPost(url);
                     HttpEntityEnclosingRequest postRequest =
@@ -472,6 +469,7 @@
                 case HTTP_DELETE_METHOD:
                     request = new HttpDelete(url);
                     break;
+                case HTTP_GET_METHOD:
                 default:
                     request = new HttpGet(url);
                     break;
@@ -532,6 +530,17 @@
                     ByteBuffer.wrap(ethReply.serialize())));
             context.block();
         }
+
+        private String metadataSecret() {
+            OpenstackNode controller = osNodeService.completeNodes(CONTROLLER)
+                    .stream().findFirst().orElse(null);
+
+            if (controller != null && controller.neutronConfig() != null) {
+                return controller.neutronConfig().metadataProxySecret();
+            }
+
+            return null;
+        }
     }
 
     private class InternalNodeEventListener implements OpenstackNodeListener {
@@ -550,28 +559,10 @@
             OpenstackNode osNode = event.subject();
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setMetadataRule(osNode, true);
-                    });
-
+                    eventExecutor.execute(() -> processNodeCompletion(osNode));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
-
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setMetadataRule(osNode, false);
-                    });
-
+                    eventExecutor.execute(() -> processNodeIncompletion(osNode));
                     break;
                 case OPENSTACK_NODE_CREATED:
                 case OPENSTACK_NODE_UPDATED:
@@ -581,6 +572,22 @@
             }
         }
 
+        private void processNodeCompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setMetadataRule(osNode, true);
+        }
+
+        private void processNodeIncompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setMetadataRule(osNode, false);
+        }
+
         /**
          * Installs metadata rule for receiving all metadata request packets.
          *
@@ -622,17 +629,6 @@
         return false;
     }
 
-    private String metadataSecret() {
-        OpenstackNode controller = osNodeService.completeNodes(CONTROLLER)
-                .stream().findFirst().orElse(null);
-
-        if (controller != null && controller.neutronConfig() != null) {
-            return controller.neutronConfig().metadataProxySecret();
-        }
-
-        return null;
-    }
-
     /**
      * Implements Http packet format.
      */
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index 3491450..c028331 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -99,7 +99,6 @@
 
     private static final String ERR_NULL_NETWORK  = "OpenStack network cannot be null";
     private static final String ERR_NULL_NETWORK_ID  = "OpenStack network ID cannot be null";
-    private static final String ERR_NULL_NETWORK_NAME  = "OpenStack network name cannot be null";
     private static final String ERR_NULL_SUBNET = "OpenStack subnet cannot be null";
     private static final String ERR_NULL_SUBNET_ID = "OpenStack subnet ID cannot be null";
     private static final String ERR_NULL_SUBNET_NET_ID = "OpenStack subnet network ID cannot be null";
@@ -108,9 +107,7 @@
     private static final String ERR_NULL_PORT_ID = "OpenStack port ID cannot be null";
     private static final String ERR_NULL_PORT_NET_ID = "OpenStack port network ID cannot be null";
 
-    private static final String ERR_NOT_FOUND = " does not exist";
     private static final String ERR_IN_USE = " still in use";
-    private static final String ERR_DUPLICATE = " already exists";
 
     private static final int PREFIX_LENGTH = 32;
 
@@ -331,7 +328,6 @@
                             .filter(p -> p.getId().contains(portName.substring(3)))
                             .findFirst();
                     return osPort.orElse(null);
-
                 case DIRECT:
                     //Additional prefixes will be added
                     osPort = osNetworkStore.ports()
@@ -340,7 +336,6 @@
                             .filter(p -> Objects.requireNonNull(getIntfNameFromPciAddress(p)).equals(portName))
                             .findFirst();
                     return osPort.orElse(null);
-
                 default:
                     return null;
             }
@@ -532,11 +527,10 @@
             log.info("Updated external peer router map {}",
                     externalPeerRouterMap.get(ipAddress.toString()).value().toString());
         } catch (Exception e) {
-            log.error("Exception occurred because of {}", e.toString());
+            log.error("Exception occurred because of {}", e);
         }
     }
 
-
     @Override
     public void updateExternalPeerRouter(IpAddress ipAddress, MacAddress macAddress, VlanId vlanId) {
         try {
@@ -548,7 +542,7 @@
                             .build());
 
         } catch (Exception e) {
-            log.error("Exception occurred because of {}", e.toString());
+            log.error("Exception occurred because of {}", e);
         }
     }
 
@@ -577,7 +571,7 @@
                             .vlanId(vlanId).build());
 
         } catch (Exception e) {
-            log.error("Exception occurred because of {}", e.toString());
+            log.error("Exception occurred because of {}", e);
         }
     }
 
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
index 75db5a6..5b60976 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
@@ -193,30 +193,32 @@
             OpenstackNode osNode = event.subject();
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setIcmpReplyRules(osNode.intgBridge(), true);
-                    });
+                    eventExecutor.execute(() -> processNodeCompletion(osNode));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setIcmpReplyRules(osNode.intgBridge(), false);
-                    });
+                    eventExecutor.execute(() -> processNodeInCompletion(osNode));
                     break;
                 default:
                     break;
             }
         }
 
+        private void processNodeCompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setIcmpReplyRules(osNode.intgBridge(), true);
+        }
+
+        private void processNodeInCompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setIcmpReplyRules(osNode.intgBridge(), false);
+        }
+
         private void setIcmpReplyRules(DeviceId deviceId, boolean install) {
             // Sends ICMP response to controller for SNATing ingress traffic
             TrafficSelector selector = DefaultTrafficSelector.builder()
@@ -289,9 +291,7 @@
             switch (icmp.getIcmpType()) {
                 case TYPE_ECHO_REQUEST:
                     if (handleEchoRequest(context.inPacket().receivedFrom().deviceId(),
-                            ethernet.getSourceMAC(),
-                            ipPacket,
-                            icmp)) {
+                            ethernet.getSourceMAC(), ipPacket, icmp)) {
                         context.block();
                     }
                     break;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index 6203740..1d76063 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -92,6 +92,7 @@
     private static final long TIME_OUT_SNAT_PORT_MS = 120L * 1000L;
     private static final int TP_PORT_MINIMUM_NUM = 65000;
     private static final int TP_PORT_MAXIMUM_NUM = 65535;
+    private static final int VM_PREFIX = 32;
 
     private static final KryoNamespace.Builder NUMBER_SERIALIZER = KryoNamespace.newBuilder()
             .register(KryoNamespaces.API);
@@ -258,8 +259,8 @@
         TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPProtocol(iPacket.getProtocol())
-                .matchIPDst(IpPrefix.valueOf(externalIp.getIp4Address(), 32))
-                .matchIPSrc(IpPrefix.valueOf(iPacket.getDestinationAddress(), 32));
+                .matchIPDst(IpPrefix.valueOf(externalIp.getIp4Address(), VM_PREFIX))
+                .matchIPSrc(IpPrefix.valueOf(iPacket.getDestinationAddress(), VM_PREFIX));
 
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
                 .setEthDst(packetIn.parsed().getSourceMAC())
@@ -304,36 +305,45 @@
 
         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,
-                            gNode.intgBridge(),
-                            srcNode.dataIp().getIp4Address()), gNode.intgBridge())
-                            .setOutput(gNode.tunnelPortNum());
-                    break;
-                case VLAN:
-                    tmpBuilder.setOutput(gNode.vlanPortNum());
-                    break;
-                default:
-                    final String error = String.format("%s %s",
-                            ERR_UNSUPPORTED_NET_TYPE, networkType.toString());
-                    throw new IllegalStateException(error);
-            }
-
+            TrafficTreatment treatment =
+                    getDownStreamTreatment(networkType, tBuilder, gNode, srcNode);
             osFlowRuleService.setRule(
                     appId,
                     gNode.intgBridge(),
                     sBuilder.build(),
-                    tmpBuilder.build(),
+                    treatment,
                     PRIORITY_SNAT_RULE,
                     GW_COMMON_TABLE,
                     true);
         });
     }
 
+    private TrafficTreatment getDownStreamTreatment(NetworkType networkType,
+                                                    TrafficTreatment.Builder tBuilder,
+                                                    OpenstackNode gNode,
+                                                    OpenstackNode srcNode) {
+        TrafficTreatment.Builder tmpBuilder =
+                DefaultTrafficTreatment.builder(tBuilder.build());
+        switch (networkType) {
+            case VXLAN:
+                tmpBuilder.extension(RulePopulatorUtil.buildExtension(
+                        deviceService,
+                        gNode.intgBridge(),
+                        srcNode.dataIp().getIp4Address()), gNode.intgBridge())
+                        .setOutput(gNode.tunnelPortNum());
+                break;
+            case VLAN:
+                tmpBuilder.setOutput(gNode.vlanPortNum());
+                break;
+            default:
+                final String error = String.format("%s %s",
+                        ERR_UNSUPPORTED_NET_TYPE, networkType.toString());
+                throw new IllegalStateException(error);
+        }
+
+        return tmpBuilder.build();
+    }
+
     private void setUpstreamRules(String segmentId, NetworkType networkType,
                                   IpAddress externalIp, ExternalPeerRouter externalPeerRouter,
                                   TpPort patPort,
@@ -343,8 +353,8 @@
         TrafficSelector.Builder sBuilder =  DefaultTrafficSelector.builder()
                 .matchEthType(Ethernet.TYPE_IPV4)
                 .matchIPProtocol(iPacket.getProtocol())
-                .matchIPSrc(IpPrefix.valueOf(iPacket.getSourceAddress(), 32))
-                .matchIPDst(IpPrefix.valueOf(iPacket.getDestinationAddress(), 32));
+                .matchIPSrc(IpPrefix.valueOf(iPacket.getSourceAddress(), VM_PREFIX))
+                .matchIPDst(IpPrefix.valueOf(iPacket.getDestinationAddress(), VM_PREFIX));
 
         TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
 
@@ -367,15 +377,13 @@
                 TCP tcpPacket = (TCP) iPacket.getPayload();
                 sBuilder.matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort()))
                         .matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));
-                tBuilder.setTcpSrc(patPort)
-                        .setEthDst(externalPeerRouter.macAddress());
+                tBuilder.setTcpSrc(patPort).setEthDst(externalPeerRouter.macAddress());
                 break;
             case IPv4.PROTOCOL_UDP:
                 UDP udpPacket = (UDP) iPacket.getPayload();
                 sBuilder.matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort()))
                         .matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));
-                tBuilder.setUdpSrc(patPort)
-                        .setEthDst(externalPeerRouter.macAddress());
+                tBuilder.setUdpSrc(patPort).setEthDst(externalPeerRouter.macAddress());
                 break;
             default:
                 log.debug("Unsupported IPv4 protocol {}");
@@ -408,18 +416,10 @@
         IPv4 iPacket = (IPv4) ethPacketIn.getPayload();
         switch (iPacket.getProtocol()) {
             case IPv4.PROTOCOL_TCP:
-                TCP tcpPacket = (TCP) iPacket.getPayload();
-                tcpPacket.setSourcePort(patPort);
-                tcpPacket.resetChecksum();
-                tcpPacket.setParent(iPacket);
-                iPacket.setPayload(tcpPacket);
+                iPacket.setPayload(buildPacketOutTcp(iPacket, patPort));
                 break;
             case IPv4.PROTOCOL_UDP:
-                UDP udpPacket = (UDP) iPacket.getPayload();
-                udpPacket.setSourcePort(patPort);
-                udpPacket.resetChecksum();
-                udpPacket.setParent(iPacket);
-                iPacket.setPayload(udpPacket);
+                iPacket.setPayload(buildPacketOutUdp(iPacket, patPort));
                 break;
             default:
                 log.trace("Temporally, this method can process UDP and TCP protocol.");
@@ -454,6 +454,24 @@
                 ByteBuffer.wrap(ethPacketIn.serialize())));
     }
 
+    private TCP buildPacketOutTcp(IPv4 iPacket, int patPort) {
+        TCP tcpPacket = (TCP) iPacket.getPayload();
+        tcpPacket.setSourcePort(patPort);
+        tcpPacket.resetChecksum();
+        tcpPacket.setParent(iPacket);
+
+        return tcpPacket;
+    }
+
+    private UDP buildPacketOutUdp(IPv4 iPacket, int patPort) {
+        UDP udpPacket = (UDP) iPacket.getPayload();
+        udpPacket.setSourcePort(patPort);
+        udpPacket.resetChecksum();
+        udpPacket.setParent(iPacket);
+
+        return udpPacket;
+    }
+
     private int getPortNum() {
         if (unUsedPortNumSet.isEmpty()) {
             clearPortNumMap();
@@ -502,16 +520,13 @@
                     UDP udpPacket = (UDP) iPacket.getPayload();
                     if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT &&
                             udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) {
-                        // don't process DHCP
-                        break;
+                        break; // don't process DHCP
                     }
                 default:
                     eventExecutor.execute(() -> {
-
                         if (!isRelevantHelper(context)) {
                             return;
                         }
-
                         processSnatPacket(context, eth);
                     });
                     break;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
index d6b0adc..ae91613 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingArpHandler.java
@@ -101,42 +101,42 @@
     immediate = true,
     property = {
         GATEWAY_MAC + "=" + GATEWAY_MAC_DEFAULT,
-        ARP_MODE + "=" + ARP_MODE_DEFAULT,
+        ARP_MODE + "=" + ARP_MODE_DEFAULT
     }
 )
-public final class OpenstackSwitchingArpHandler {
+public class OpenstackSwitchingArpHandler {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    CoreService coreService;
+    protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    PacketService packetService;
+    protected PacketService packetService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    OpenstackFlowRuleService osFlowRuleService;
+    protected OpenstackFlowRuleService osFlowRuleService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    ComponentConfigService configService;
+    protected ComponentConfigService configService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    ClusterService clusterService;
+    protected ClusterService clusterService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    LeadershipService leadershipService;
+    protected LeadershipService leadershipService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    DeviceService deviceService;
+    protected DeviceService deviceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    MastershipService mastershipService;
+    protected MastershipService mastershipService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    InstancePortService instancePortService;
+    protected InstancePortService instancePortService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    OpenstackNetworkService osNetworkService;
+    protected OpenstackNetworkService osNetworkService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected OpenstackNodeService osNodeService;
@@ -713,26 +713,10 @@
             switch (event.type()) {
                 case OPENSTACK_SUBNET_CREATED:
                 case OPENSTACK_SUBNET_UPDATED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setFakeGatewayArpRule(event.subnet(), event.subject(),
-                                true, null);
-                    });
+                    eventExecutor.execute(() -> processSubnetCreation(event));
                     break;
                 case OPENSTACK_SUBNET_REMOVED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setFakeGatewayArpRule(event.subnet(), event.subject(),
-                                false, null);
-                    });
+                    eventExecutor.execute(() -> processSubnetRemoval(event));
                     break;
                 case OPENSTACK_NETWORK_CREATED:
                 case OPENSTACK_NETWORK_UPDATED:
@@ -745,6 +729,24 @@
                     break;
             }
         }
+
+        private void processSubnetCreation(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setFakeGatewayArpRule(event.subnet(), event.subject(),
+                    true, null);
+        }
+
+        private void processSubnetRemoval(OpenstackNetworkEvent event) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setFakeGatewayArpRule(event.subnet(), event.subject(),
+                    false, null);
+        }
     }
 
     /**
@@ -767,32 +769,34 @@
             OpenstackNode osNode = event.subject();
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setDefaultArpRule(osNode, true);
-                        setAllArpRules(osNode, true);
-                    });
+                    eventExecutor.execute(() -> processNodeCompletion(osNode));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setDefaultArpRule(osNode, false);
-                        setAllArpRules(osNode, false);
-                    });
+                    eventExecutor.execute(() -> processNodeIncompletion(osNode));
                     break;
                 default:
                     break;
             }
         }
 
+        private void processNodeCompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setDefaultArpRule(osNode, true);
+            setAllArpRules(osNode, true);
+        }
+
+        private void processNodeIncompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+
+            setDefaultArpRule(osNode, false);
+            setAllArpRules(osNode, false);
+        }
+
         private void setDefaultArpRule(OpenstackNode osNode, boolean install) {
 
             if (getArpMode() == null) {
@@ -804,20 +808,7 @@
                     setDefaultArpRuleForProxyMode(osNode, install);
                     break;
                 case ARP_BROADCAST_MODE:
-                    setDefaultArpRuleForBroadcastMode(osNode, install);
-
-                    // we do not add fake gateway ARP rules for FLAT network
-                    // ARP packets generated by FLAT typed VM should not be
-                    // delegated to switch to handle
-                    osNetworkService.subnets().stream().filter(subnet ->
-                        osNetworkService.network(subnet.getNetworkId()) != null &&
-                            osNetworkService.network(subnet.getNetworkId())
-                                    .getNetworkType() != NetworkType.FLAT)
-                                    .forEach(subnet -> {
-                                        String netId = subnet.getNetworkId();
-                                        Network net = osNetworkService.network(netId);
-                                        setFakeGatewayArpRule(subnet, net, install, osNode);
-                                    });
+                    processDefaultArpRuleForBroadcastMode(osNode, install);
                     break;
                 default:
                     log.warn("Invalid ARP mode {}. Please use either " +
@@ -826,6 +817,24 @@
             }
         }
 
+        private void processDefaultArpRuleForBroadcastMode(OpenstackNode osNode,
+                                                           boolean install) {
+            setDefaultArpRuleForBroadcastMode(osNode, install);
+
+            // we do not add fake gateway ARP rules for FLAT network
+            // ARP packets generated by FLAT typed VM should not be
+            // delegated to switch to handle
+            osNetworkService.subnets().stream().filter(subnet ->
+                    osNetworkService.network(subnet.getNetworkId()) != null &&
+                            osNetworkService.network(subnet.getNetworkId())
+                                    .getNetworkType() != NetworkType.FLAT)
+                    .forEach(subnet -> {
+                        String netId = subnet.getNetworkId();
+                        Network net = osNetworkService.network(netId);
+                        setFakeGatewayArpRule(subnet, net, install, osNode);
+                    });
+        }
+
         private void setDefaultArpRuleForProxyMode(OpenstackNode osNode, boolean install) {
             TrafficSelector selector = DefaultTrafficSelector.builder()
                     .matchEthType(EthType.EtherType.ARP.ethType().toShort())
@@ -904,41 +913,44 @@
                 case OPENSTACK_INSTANCE_PORT_DETECTED:
                 case OPENSTACK_INSTANCE_PORT_UPDATED:
                 case OPENSTACK_INSTANCE_MIGRATION_STARTED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        setArpRequestRule(event.subject(), true);
-                        setArpReplyRule(event.subject(), true);
-                    });
+                    eventExecutor.execute(() -> processInstanceMigrationStart(event));
                     break;
                 case OPENSTACK_INSTANCE_PORT_VANISHED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        setArpRequestRule(event.subject(), false);
-                        setArpReplyRule(event.subject(), false);
-                    });
+                    eventExecutor.execute(() -> processInstanceRemoval(event));
                     break;
                 case OPENSTACK_INSTANCE_MIGRATION_ENDED:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        InstancePort revisedInstPort = swapStaleLocation(event.subject());
-                        setArpRequestRule(revisedInstPort, false);
-                    });
+                    eventExecutor.execute(() -> processInstanceMigrationEnd(event));
                     break;
                 default:
                     break;
             }
         }
+
+        private void processInstanceMigrationStart(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            setArpRequestRule(event.subject(), true);
+            setArpReplyRule(event.subject(), true);
+        }
+
+        private void processInstanceMigrationEnd(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            InstancePort revisedInstPort = swapStaleLocation(event.subject());
+            setArpRequestRule(revisedInstPort, false);
+        }
+
+        private void processInstanceRemoval(InstancePortEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            setArpRequestRule(event.subject(), false);
+            setArpReplyRule(event.subject(), false);
+        }
     }
 }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
index 9785c3c..6111395 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
@@ -113,8 +113,7 @@
     private static final byte DHCP_OPTION_MTU = (byte) 26;
     private static final byte[] DHCP_DATA_LEASE_INFINITE =
             ByteBuffer.allocate(4).putInt(-1).array();
-    // we are using 1450 as a default DHCP MTU value
-    private static final int DHCP_DATA_MTU_DEFAULT = 1450;
+
     private static final int OCTET_BIT_LENGTH = 8;
     private static final int V4_BYTE_SIZE = 4;
     private static final int V4_CIDR_LOWER_BOUND = -1;
@@ -151,8 +150,6 @@
     /** Fake MAC address for virtual network subnet gateway. */
     private String dhcpServerMac = DHCP_SERVER_MAC_DEFAULT;
 
-    private int dhcpDataMtu = DHCP_DATA_MTU_DEFAULT;
-
     private final PacketProcessor packetProcessor = new InternalPacketProcessor();
     private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
 
@@ -247,24 +244,10 @@
             Ethernet ethPacket = context.inPacket().parsed();
             switch (inPacketType) {
                 case DHCPDISCOVER:
-                    log.trace("DHCP DISCOVER received from {}", clientMac);
-                    Ethernet discoverReply = buildReply(
-                            ethPacket,
-                            (byte) DHCPOFFER.getValue(),
-                            reqInstPort);
-                    sendReply(context, discoverReply);
-                    log.trace("DHCP OFFER({}) is sent for {}",
-                            reqInstPort.ipAddress(), clientMac);
+                    processDhcpDiscover(context, clientMac, reqInstPort, ethPacket);
                     break;
                 case DHCPREQUEST:
-                    log.trace("DHCP REQUEST received from {}", clientMac);
-                    Ethernet requestReply = buildReply(
-                            ethPacket,
-                            (byte) DHCPACK.getValue(),
-                            reqInstPort);
-                    sendReply(context, requestReply);
-                    log.trace("DHCP ACK({}) is sent for {}",
-                            reqInstPort.ipAddress(), clientMac);
+                    processDhcpRequest(context, clientMac, reqInstPort, ethPacket);
                     break;
                 case DHCPRELEASE:
                     log.trace("DHCP RELEASE received from {}", clientMac);
@@ -275,6 +258,26 @@
             }
         }
 
+        private void processDhcpDiscover(PacketContext context, MacAddress clientMac,
+                                         InstancePort instPort, Ethernet ethPacket) {
+            log.trace("DHCP DISCOVER received from {}", clientMac);
+            Ethernet discoverReply = buildReply(ethPacket,
+                                                (byte) DHCPOFFER.getValue(),
+                                                instPort);
+            sendReply(context, discoverReply);
+            log.trace("DHCP OFFER({}) is sent for {}", instPort.ipAddress(), clientMac);
+        }
+
+        private void processDhcpRequest(PacketContext context, MacAddress clientMac,
+                                        InstancePort instPort, Ethernet ethPacket) {
+            log.trace("DHCP REQUEST received from {}", clientMac);
+            Ethernet requestReply = buildReply(ethPacket,
+                                                (byte) DHCPACK.getValue(),
+                                                instPort);
+            sendReply(context, requestReply);
+            log.trace("DHCP ACK({}) is sent for {}", instPort.ipAddress(), clientMac);
+        }
+
         private DHCP.MsgType getPacketType(DHCP dhcpPacket) {
             DhcpOption optType = dhcpPacket.getOption(OptionCode_MessageType);
             if (optType == null) {
@@ -366,46 +369,92 @@
             dhcpReply.setClientHardwareAddress(request.getClientHardwareAddress());
 
             List<DhcpOption> options = Lists.newArrayList();
+
             // message type
+            options.add(doMsgType(msgType));
+
+            // server identifier
+            options.add(doServerId(gatewayIp));
+
+            // lease time
+            options.add(doLeaseTime());
+
+            // subnet mask
+            options.add(doSubnetMask(subnetPrefixLen));
+
+            // broadcast address
+            options.add(doBroadcastAddr(yourIp, subnetPrefixLen));
+
+            // domain server
+            options.add(doDomainServer(osSubnet));
+
+            // mtu
+            options.add(doMtu(osSubnet));
+
+            // classless static route
+            if (!osSubnet.getHostRoutes().isEmpty()) {
+                options.add(doClasslessSr(osSubnet));
+            }
+
+            // Sets the default router address up.
+            // Performs only if the gateway is set in subnet.
+            if (!Strings.isNullOrEmpty(osSubnet.getGateway())) {
+                options.add(doRouterAddr(osSubnet));
+            }
+
+            // end option
+            options.add(doEnd());
+
+            dhcpReply.setOptions(options);
+            return dhcpReply;
+        }
+
+
+        private DhcpOption doMsgType(byte msgType) {
             DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_MessageType.getValue());
             option.setLength((byte) 1);
             byte[] optionData = {msgType};
             option.setData(optionData);
-            options.add(option);
+            return option;
+        }
 
-            // server identifier
-            option = new DhcpOption();
+        private DhcpOption doServerId(IpAddress gatewayIp) {
+            DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_DHCPServerIp.getValue());
             option.setLength((byte) 4);
             option.setData(gatewayIp.toOctets());
-            options.add(option);
+            return option;
+        }
 
-            // lease time
-            option = new DhcpOption();
+        private DhcpOption doLeaseTime() {
+            DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_LeaseTime.getValue());
             option.setLength((byte) 4);
             option.setData(DHCP_DATA_LEASE_INFINITE);
-            options.add(option);
+            return option;
+        }
 
-            // subnet mask
+        private DhcpOption doSubnetMask(int subnetPrefixLen) {
             Ip4Address subnetMask = Ip4Address.makeMaskPrefix(subnetPrefixLen);
-            option = new DhcpOption();
+            DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_SubnetMask.getValue());
             option.setLength((byte) 4);
             option.setData(subnetMask.toOctets());
-            options.add(option);
+            return option;
+        }
 
-            // broadcast address
+        private DhcpOption doBroadcastAddr(Ip4Address yourIp, int subnetPrefixLen) {
             Ip4Address broadcast = Ip4Address.makeMaskedAddress(yourIp, subnetPrefixLen);
-            option = new DhcpOption();
+            DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_BroadcastAddress.getValue());
             option.setLength((byte) 4);
             option.setData(broadcast.toOctets());
-            options.add(option);
+            return option;
+        }
 
-            // domain server
-            option = new DhcpOption();
+        private DhcpOption doDomainServer(Subnet osSubnet) {
+            DhcpOption option = new DhcpOption();
 
             List<String> dnsServers = osSubnet.getDnsNames();
             option.setCode(OptionCode_DomainServer.getValue());
@@ -424,15 +473,17 @@
 
                 ByteBuffer dnsByteBuf = ByteBuffer.allocate(8);
 
-                for (int i = 0; i < dnsServers.size(); i++) {
-                    dnsByteBuf.put(IpAddress.valueOf(dnsServers.get(i)).toOctets());
+                for (String dnsServer : dnsServers) {
+                    dnsByteBuf.put(IpAddress.valueOf(dnsServer).toOctets());
                 }
                 option.setData(dnsByteBuf.array());
             }
 
-            options.add(option);
+            return option;
+        }
 
-            option = new DhcpOption();
+        private DhcpOption doMtu(Subnet osSubnet) {
+            DhcpOption option = new DhcpOption();
             option.setCode(DHCP_OPTION_MTU);
             option.setLength((byte) 2);
             Network osNetwork = osNetworkService.network(osSubnet.getNetworkId());
@@ -440,56 +491,51 @@
             checkNotNull(osNetwork.getMTU());
 
             option.setData(ByteBuffer.allocate(2).putShort(osNetwork.getMTU().shortValue()).array());
-            options.add(option);
 
-            // classless static route
-            if (!osSubnet.getHostRoutes().isEmpty()) {
-                option = new DhcpOption();
-                option.setCode(OptionCode_Classless_Static_Route.getValue());
+            return option;
+        }
 
-                int hostRoutesSize = hostRoutesSize(ImmutableList.copyOf(osSubnet.getHostRoutes()));
-                if (hostRoutesSize == 0) {
-                    throw new IllegalArgumentException("Illegal CIDR hostRoutesSize value!");
-                }
+        private DhcpOption doClasslessSr(Subnet osSubnet) {
+            DhcpOption option = new DhcpOption();
+            option.setCode(OptionCode_Classless_Static_Route.getValue());
 
-                log.trace("hostRouteSize: {}", hostRoutesSize);
-
-                option.setLength((byte) hostRoutesSize);
-                ByteBuffer hostRouteByteBuf = ByteBuffer.allocate(hostRoutesSize);
-
-                osSubnet.getHostRoutes().forEach(h -> {
-                    log.debug("processing host route information: {}", h.toString());
-
-                    IpPrefix ipPrefix = IpPrefix.valueOf(h.getDestination());
-
-                    hostRouteByteBuf.put(bytesDestinationDescriptor(ipPrefix));
-
-                    hostRouteByteBuf.put(Ip4Address.valueOf(h.getNexthop()).toOctets());
-                });
-
-                option.setData(hostRouteByteBuf.array());
-
-                options.add(option);
+            int hostRoutesSize = hostRoutesSize(ImmutableList.copyOf(osSubnet.getHostRoutes()));
+            if (hostRoutesSize == 0) {
+                throw new IllegalArgumentException("Illegal CIDR hostRoutesSize value!");
             }
 
-            // Sets the default router address up.
-            // Performs only if the gateway is set in subnet.
-            if (!Strings.isNullOrEmpty(osSubnet.getGateway())) {
-                option = new DhcpOption();
-                option.setCode(OptionCode_RouterAddress.getValue());
-                option.setLength((byte) 4);
-                option.setData(Ip4Address.valueOf(osSubnet.getGateway()).toOctets());
-                options.add(option);
-            }
+            log.trace("hostRouteSize: {}", hostRoutesSize);
 
-            // end option
-            option = new DhcpOption();
+            option.setLength((byte) hostRoutesSize);
+            ByteBuffer hostRouteByteBuf = ByteBuffer.allocate(hostRoutesSize);
+
+            osSubnet.getHostRoutes().forEach(h -> {
+                log.debug("processing host route information: {}", h.toString());
+
+                IpPrefix ipPrefix = IpPrefix.valueOf(h.getDestination());
+
+                hostRouteByteBuf.put(Objects.requireNonNull(bytesDestinationDescriptor(ipPrefix)));
+
+                hostRouteByteBuf.put(Ip4Address.valueOf(h.getNexthop()).toOctets());
+            });
+
+            option.setData(hostRouteByteBuf.array());
+            return option;
+        }
+
+        private DhcpOption doRouterAddr(Subnet osSubnet) {
+            DhcpOption option = new DhcpOption();
+            option.setCode(OptionCode_RouterAddress.getValue());
+            option.setLength((byte) 4);
+            option.setData(Ip4Address.valueOf(osSubnet.getGateway()).toOctets());
+            return option;
+        }
+
+        private DhcpOption doEnd() {
+            DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_END.getValue());
             option.setLength((byte) 1);
-            options.add(option);
-
-            dhcpReply.setOptions(options);
-            return dhcpReply;
+            return option;
         }
 
         private int hostRoutesSize(List<HostRoute> hostRoutes) {
@@ -560,24 +606,10 @@
             OpenstackNode osNode = event.subject();
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setDhcpRule(osNode, true);
-                    });
+                    eventExecutor.execute(() -> processNodeCompletion(osNode));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
-                    eventExecutor.execute(() -> {
-
-                        if (!isRelevantHelper()) {
-                            return;
-                        }
-
-                        setDhcpRule(osNode, false);
-                    });
+                    eventExecutor.execute(() -> processNodeIncompletion(osNode));
                     break;
                 case OPENSTACK_NODE_CREATED:
                 case OPENSTACK_NODE_UPDATED:
@@ -587,6 +619,20 @@
             }
         }
 
+        private void processNodeCompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+            setDhcpRule(osNode, true);
+        }
+
+        private void processNodeIncompletion(OpenstackNode osNode) {
+            if (!isRelevantHelper()) {
+                return;
+            }
+            setDhcpRule(osNode, false);
+        }
+
         private void setDhcpRule(OpenstackNode openstackNode, boolean install) {
             TrafficSelector selector = DefaultTrafficSelector.builder()
                     .matchEthType(Ethernet.TYPE_IPV4)
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
index 4dd5ea7..c4ab10c 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProvider.java
@@ -76,7 +76,7 @@
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
 
 @Component(immediate = true, service = HostProvider.class)
-public final class OpenstackSwitchingHostProvider
+public class OpenstackSwitchingHostProvider
         extends AbstractProvider implements HostProvider {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -122,7 +122,7 @@
     }
 
     @Activate
-    void activate() {
+    protected void activate() {
         coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
         deviceService.addListener(internalDeviceListener);
         osNodeService.addListener(internalNodeListener);
@@ -132,7 +132,7 @@
     }
 
     @Deactivate
-    void deactivate() {
+    protected void deactivate() {
         hostProviderRegistry.unregister(this);
         osNodeService.removeListener(internalNodeListener);
         deviceService.removeListener(internalDeviceListener);
@@ -153,7 +153,7 @@
      *
      * @param event device event
      */
-    protected void portAddedHelper(DeviceEvent event) {
+    void portAddedHelper(DeviceEvent event) {
         log.debug("Instance port {} is detected from {}",
                 event.port().annotations().value(PORT_NAME),
                 event.subject().id());
@@ -166,7 +166,7 @@
      *
      * @param event device event
      */
-    protected void portRemovedHelper(DeviceEvent event) {
+    void portRemovedHelper(DeviceEvent event) {
         log.debug("Instance port {} is removed from {}",
                 event.port().annotations().value(PORT_NAME),
                 event.subject().id());
@@ -181,7 +181,7 @@
      *
      * @param port port object used in ONOS
      */
-    protected void processPortAdded(Port port) {
+    void processPortAdded(Port port) {
         // TODO check the node state is COMPLETE
         org.openstack4j.model.network.Port osPort = osNetworkService.port(port);
         if (osPort == null) {
@@ -204,9 +204,9 @@
         MacAddress mac = MacAddress.valueOf(osPort.getMacAddress());
         HostId hostId = HostId.hostId(mac);
 
-        // typically one openstack port should only be bound to one fix IP address;
-        // however, openstack4j binds multiple fixed IPs to one port, this might
-        // be a defect of openstack4j implementation
+        /* typically one openstack port should only be bound to one fix IP address;
+           however, openstack4j binds multiple fixed IPs to one port, this might
+           be a defect of openstack4j implementation */
 
         // TODO: we need to find a way to bind multiple ports from multiple
         // openstack networks into one host sooner or later
@@ -250,7 +250,7 @@
 
             // newly added location is not in the existing location list,
             // therefore, we simply add this into the location list
-            if (locations.size() == 0) {
+            if (locations.isEmpty()) {
                 hostProviderService.addLocationToHost(hostId,
                         new HostLocation(connectPoint, createTime));
             }
@@ -273,7 +273,7 @@
      *
      * @param port ONOS port
      */
-    protected void processPortRemoved(Port port) {
+    private void processPortRemoved(Port port) {
         ConnectPoint connectPoint = new ConnectPoint(port.element().id(), port.number());
 
         Set<Host> hosts = hostService.getConnectedHosts(connectPoint);
@@ -330,43 +330,46 @@
             log.info("Device event occurred with type {}", event.type());
             switch (event.type()) {
                 case PORT_UPDATED:
-                    executor.execute(() -> {
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        if (!event.port().isEnabled()) {
-                            portRemovedHelper(event);
-                        } else if (event.port().isEnabled()) {
-                            portAddedHelper(event);
-                        }
-                    });
-
+                    executor.execute(() -> processPortUpdate(event));
                     break;
                 case PORT_ADDED:
-                    executor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        portAddedHelper(event);
-                    });
+                    executor.execute(() -> processPortAddition(event));
                     break;
                 case PORT_REMOVED:
-                    executor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        portRemovedHelper(event);
-                    });
+                    executor.execute(() -> processPortRemoval(event));
                     break;
                 default:
                     break;
             }
         }
+
+        private void processPortUpdate(DeviceEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            if (!event.port().isEnabled()) {
+                portRemovedHelper(event);
+            } else if (event.port().isEnabled()) {
+                portAddedHelper(event);
+            }
+        }
+
+        private void processPortAddition(DeviceEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            portAddedHelper(event);
+        }
+
+        private void processPortRemoval(DeviceEvent event) {
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            portRemovedHelper(event);
+        }
     }
 
     private class InternalOpenstackNodeListener implements OpenstackNodeListener {
@@ -391,15 +394,7 @@
 
             switch (event.type()) {
                 case OPENSTACK_NODE_COMPLETE:
-                    log.info("COMPLETE node {} is detected", osNode.hostname());
-                    executor.execute(() -> {
-
-                        if (!isRelevantHelper(event)) {
-                            return;
-                        }
-
-                        processCompleteNode(event.subject());
-                    });
+                    executor.execute(() -> processCompleteNode(event, event.subject()));
                     break;
                 case OPENSTACK_NODE_INCOMPLETE:
                     log.warn("{} is changed to INCOMPLETE state", osNode);
@@ -407,14 +402,20 @@
                 case OPENSTACK_NODE_CREATED:
                 case OPENSTACK_NODE_UPDATED:
                 case OPENSTACK_NODE_REMOVED:
-                    // not reacts to the events other than complete and incomplete states
-                    break;
                 default:
                     break;
             }
         }
 
-        private void processCompleteNode(OpenstackNode osNode) {
+        private void processCompleteNode(OpenstackNodeEvent event,
+                                         OpenstackNode osNode) {
+
+            if (!isRelevantHelper(event)) {
+                return;
+            }
+
+            log.info("COMPLETE node {} is detected", osNode.hostname());
+
             deviceService.getPorts(osNode.intgBridge()).stream()
                     .filter(port -> vnicType(port.annotations().value(PORT_NAME))
                                     .equals(Constants.VnicType.NORMAL) ||