[CORD-313] Handles uncaught exceptions when device is not configured

Includes following minor changes
    - Move DeviceConfiguration and DeviceProperties to config package
    - Create DeviceConfigNotFoundException

Change-Id: I32455d88c712bb65cd7f71dab9472ae003303de2
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
index 36563f0..96c85ba 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
@@ -31,6 +31,8 @@
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.HostId;
 import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -140,9 +142,16 @@
      * @param inPort in-port
      */
     public void sendArpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
+        byte[] senderMacAddress;
+        byte[] senderIpAddress;
 
-        byte[] senderMacAddress = config.getDeviceMac(deviceId).toBytes();
-        byte[] senderIpAddress = config.getRouterIp(deviceId).toOctets();
+        try {
+            senderMacAddress = config.getDeviceMac(deviceId).toBytes();
+            senderIpAddress = config.getRouterIp(deviceId).toOctets();
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting sendArpRequest.");
+            return;
+        }
 
         ARP arpRequest = new ARP();
         arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
index c4a91c7..a737339 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
@@ -23,6 +23,8 @@
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -449,7 +451,20 @@
 
         // If both target switch and dest switch are edge routers, then set IP
         // rule for both subnet and router IP.
-        if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) {
+        boolean targetIsEdge;
+        boolean destIsEdge;
+        Ip4Address destRouterIp;
+
+        try {
+            targetIsEdge = config.isEdgeDevice(targetSw);
+            destIsEdge = config.isEdgeDevice(destSw);
+            destRouterIp = config.getRouterIp(destSw);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateEcmpRoutingRulePartial.");
+            return false;
+        }
+
+        if (targetIsEdge && destIsEdge) {
             Set<Ip4Prefix> subnets = config.getSubnets(destSw);
             log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}",
                     targetSw, destSw, subnets);
@@ -461,7 +476,7 @@
                 return false;
             }
 
-            Ip4Address routerIp = config.getRouterIp(destSw);
+            Ip4Address routerIp = destRouterIp;
             IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
             log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}",
                     targetSw, destSw, routerIpPrefix);
@@ -471,8 +486,8 @@
             }
 
         // If the target switch is an edge router, then set IP rules for the router IP.
-        } else if (config.isEdgeDevice(targetSw)) {
-            Ip4Address routerIp = config.getRouterIp(destSw);
+        } else if (targetIsEdge) {
+            Ip4Address routerIp = destRouterIp;
             IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
             log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}",
                     targetSw, destSw, routerIpPrefix);
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
index b3916b0..c4267eb 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -28,6 +28,8 @@
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,7 +73,13 @@
         Ip4Address destinationAddress =
                 Ip4Address.valueOf(ipv4.getDestinationAddress());
         Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
-        Ip4Address routerIp = config.getRouterIp(deviceId);
+        Ip4Address routerIp;
+        try {
+            routerIp = config.getRouterIp(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting processPacketIn.");
+            return;
+        }
         IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
         Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
index 14ce679..b1682e7 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
@@ -26,6 +26,8 @@
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -127,13 +129,19 @@
 
         for (IPv4 ipPacket : ipPacketQueue.get(destIpAddress)) {
             Ip4Address destAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
-            if (ipPacket != null && config.inSameSubnet(deviceId, destAddress)) {
+            if (config.inSameSubnet(deviceId, destAddress)) {
                 ipPacket.setTtl((byte) (ipPacket.getTtl() - 1));
                 ipPacket.setChecksum((short) 0);
                 for (Host dest: srManager.hostService.getHostsByIp(destIpAddress)) {
                     Ethernet eth = new Ethernet();
                     eth.setDestinationMACAddress(dest.mac());
-                    eth.setSourceMACAddress(config.getDeviceMac(deviceId));
+                    try {
+                        eth.setSourceMACAddress(config.getDeviceMac(deviceId));
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage()
+                                + " Skipping forwardPackets for this destination.");
+                        continue;
+                    }
                     eth.setEtherType(Ethernet.TYPE_IPV4);
                     eth.setPayload(ipPacket);
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java
index 83cb7e8..0a4c26d 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java
@@ -27,6 +27,7 @@
 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.slf4j.Logger;
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index d46028e..f827403 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -22,6 +22,8 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
@@ -103,6 +105,14 @@
      */
     public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
                                       MacAddress hostMac, PortNumber outPort) {
+        MacAddress deviceMac;
+        try {
+            deviceMac = config.getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateIpRuleForHost.");
+            return;
+        }
+
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
 
@@ -111,7 +121,7 @@
 
         tbuilder.deferred()
                 .setEthDst(hostMac)
-                .setEthSrc(config.getDeviceMac(deviceId))
+                .setEthSrc(deviceMac)
                 .setOutput(outPort);
 
         TrafficTreatment treatment = tbuilder.build();
@@ -167,6 +177,13 @@
     public boolean populateIpRuleForRouter(DeviceId deviceId,
                                            IpPrefix ipPrefix, DeviceId destSw,
                                            Set<DeviceId> nextHops) {
+        int segmentId;
+        try {
+            segmentId = config.getSegmentId(destSw);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateIpRuleForRouter.");
+            return false;
+        }
 
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
@@ -183,7 +200,7 @@
             ns = new NeighborSet(nextHops);
         } else {
             tbuilder.deferred().copyTtlOut();
-            ns = new NeighborSet(nextHops, config.getSegmentId(destSw));
+            ns = new NeighborSet(nextHops, segmentId);
         }
 
         TrafficTreatment treatment = tbuilder.build();
@@ -227,19 +244,26 @@
      */
     public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId,
                                     Set<DeviceId> nextHops) {
+        int segmentId;
+        try {
+            segmentId = config.getSegmentId(destSwId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateMplsRule.");
+            return false;
+        }
 
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
         List<ForwardingObjective.Builder> fwdObjBuilders = new ArrayList<>();
 
         // TODO Handle the case of Bos == false
-        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId)));
+        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId));
         sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
 
         // If the next hop is the destination router, do PHP
         if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
             log.debug("populateMplsRule: Installing MPLS forwarding objective for "
                     + "label {} in switch {} with PHP",
-                    config.getSegmentId(destSwId),
+                    segmentId,
                     deviceId);
 
             ForwardingObjective.Builder fwdObjBosBuilder =
@@ -264,7 +288,7 @@
         } else {
             log.debug("Installing MPLS forwarding objective for "
                     + "label {} in switch {} without PHP",
-                    config.getSegmentId(destSwId),
+                    segmentId,
                     deviceId);
 
             ForwardingObjective.Builder fwdObjBosBuilder =
@@ -310,9 +334,21 @@
                                                                    Set<DeviceId> nextHops,
                                                                    boolean phpRequired,
                                                                    boolean isBos) {
-
         ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
                 .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
+        DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
+
+        boolean isEdge;
+        MacAddress srcMac;
+        MacAddress dstMac;
+        try {
+            isEdge = config.isEdgeDevice(deviceId);
+            srcMac = config.getDeviceMac(deviceId);
+            dstMac = config.getDeviceMac(nextHop);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting getMplsForwardingObjective");
+            return null;
+        }
 
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
 
@@ -329,16 +365,15 @@
             tbuilder.deferred().decMplsTtl();
         }
 
-        if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) {
+        if (!isECMPSupportedInTransitRouter() && !isEdge) {
             PortNumber port = selectOnePort(deviceId, nextHops);
-            DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
             if (port == null) {
                 log.warn("No link from {} to {}", deviceId, nextHops);
                 return null;
             }
             tbuilder.deferred()
-                    .setEthSrc(config.getDeviceMac(deviceId))
-                    .setEthDst(config.getDeviceMac(nextHop))
+                    .setEthSrc(srcMac)
+                    .setEthDst(dstMac)
                     .setOutput(port);
             fwdBuilder.withTreatment(tbuilder.build());
         } else {
@@ -372,15 +407,27 @@
     public void populateRouterMacVlanFilters(DeviceId deviceId) {
         log.debug("Installing per-port filtering objective for untagged "
                 + "packets in device {}", deviceId);
+
+        MacAddress deviceMac;
+        try {
+            deviceMac = config.getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateRouterMacVlanFilters.");
+            return;
+        }
+
         for (Port port : srManager.deviceService.getPorts(deviceId)) {
             if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
                 Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number());
                 VlanId assignedVlan = (portSubnet == null)
                         ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)
                         : srManager.getSubnetAssignedVlanId(deviceId, portSubnet);
+
+
+
                 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
                 fob.withKey(Criteria.matchInPort(port.number()))
-                .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId)))
+                .addCondition(Criteria.matchEthDst(deviceMac))
                 .addCondition(Criteria.matchVlanId(VlanId.NONE));
                 // vlan assignment is valid only if this instance is master
                 if (srManager.mastershipService.isLocalMaster(deviceId)) {
@@ -405,6 +452,14 @@
      * @param deviceId the switch dpid for the router
      */
     public void populateRouterIpPunts(DeviceId deviceId) {
+        Ip4Address routerIp;
+        try {
+            routerIp = config.getRouterIp(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateRouterIpPunts.");
+            return;
+        }
+
         if (!srManager.mastershipService.isLocalMaster(deviceId)) {
             log.debug("Not installing port-IP punts - not the master for dev:{} ",
                       deviceId);
@@ -412,7 +467,7 @@
         }
         ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
         Set<Ip4Address> allIps = new HashSet<Ip4Address>(config.getPortIPs(deviceId));
-        allIps.add(config.getRouterIp(deviceId));
+        allIps.add(routerIp);
         for (Ip4Address ipaddr : allIps) {
             TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
             TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index b82752d..787f934 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -38,6 +38,8 @@
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
@@ -553,7 +555,10 @@
 
     private void processLinkAdded(Link link) {
         log.debug("A new link {} was added", link.toString());
-
+        if (!deviceConfiguration.isConfigured(link.src().deviceId())) {
+            log.warn("Source device of this link is not configured.");
+            return;
+        }
         //Irrespective whether the local is a MASTER or not for this device,
         //create group handler instance and push default TTP flow rules.
         //Because in a multi-instance setup, instances can initiate
@@ -596,7 +601,7 @@
 
     private void processDeviceAdded(Device device) {
         log.debug("A new device with ID {} was added", device.id());
-        if (deviceConfiguration == null) {
+        if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
             log.warn("Device configuration uploading. Device {} will be "
                     + "processed after config completes.", device.id());
             return;
@@ -608,14 +613,20 @@
         // to the switch). To handle this, a default-group-handler instance is necessary
         // per switch.
         if (groupHandlerMap.get(device.id()) == null) {
-            DefaultGroupHandler groupHandler = DefaultGroupHandler.
-                    createGroupHandler(device.id(),
-                                       appId,
-                                       deviceConfiguration,
-                                       linkService,
-                                       flowObjectiveService,
-                                       nsNextObjStore,
-                                       subnetNextObjStore);
+            DefaultGroupHandler groupHandler;
+            try {
+                groupHandler = DefaultGroupHandler.
+                        createGroupHandler(device.id(),
+                                           appId,
+                                           deviceConfiguration,
+                                           linkService,
+                                           flowObjectiveService,
+                                           nsNextObjStore,
+                                           subnetNextObjStore);
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn(e.getMessage() + " Aborting processDeviceAdded.");
+                return;
+            }
             groupHandlerMap.put(device.id(), groupHandler);
             // Also, in some cases, drivers may need extra
             // information to process rules (eg. Router IP/MAC); and so, we send
@@ -667,12 +678,20 @@
                 // to the switch). To handle this, a default-group-handler instance is necessary
                 // per switch.
                 if (groupHandlerMap.get(device.id()) == null) {
-                    DefaultGroupHandler groupHandler = DefaultGroupHandler
-                            .createGroupHandler(device.id(), appId,
-                                                deviceConfiguration, linkService,
-                                                flowObjectiveService,
-                                                nsNextObjStore,
-                                                subnetNextObjStore);
+                    DefaultGroupHandler groupHandler;
+                    try {
+                        groupHandler = DefaultGroupHandler.
+                                createGroupHandler(device.id(),
+                                                   appId,
+                                                   deviceConfiguration,
+                                                   linkService,
+                                                   flowObjectiveService,
+                                                   nsNextObjStore,
+                                                   subnetNextObjStore);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage() + " Aborting configureNetwork.");
+                        return;
+                    }
                     groupHandlerMap.put(device.id(), groupHandler);
 
                     // Also, in some cases, drivers may need extra
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
index 820bb40..7d025c7 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
@@ -18,6 +18,7 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
 import org.onosproject.store.service.EventuallyConsistentMap;
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java
new file mode 100644
index 0000000..ae156e6
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+/**
+ * Signals that an error occurred during reading device configuration.
+ */
+public class DeviceConfigNotFoundException extends Exception {
+
+    /**
+     * Creates a new ConfigNotFoundException with the given message.
+     *
+     * @param message exception message
+     */
+    public DeviceConfigNotFoundException(String message) {
+        super(message);
+    }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
similarity index 87%
rename from apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
rename to apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
index 828c51c..0ad0067 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.segmentrouting;
+package org.onosproject.segmentrouting.config;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
@@ -26,9 +26,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
 import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid;
-import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.slf4j.Logger;
@@ -126,23 +124,20 @@
         });
     }
 
-    /**
-     * Returns the Node segment id of a segment router.
-     *
-     * @param deviceId device identifier
-     * @return segment id
-     */
     @Override
-    public int getSegmentId(DeviceId deviceId) {
+    public boolean isConfigured(DeviceId deviceId) {
+        return deviceConfigMap.get(deviceId) != null;
+    }
+
+    @Override
+    public int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid);
             return srinfo.nodeSid;
         } else {
-            log.warn("getSegmentId for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "getSegmentId fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
@@ -180,71 +175,42 @@
         return -1;
     }
 
-    /**
-     * Returns the router mac of a segment router.
-     *
-     * @param deviceId device identifier
-     * @return router mac address
-     */
     @Override
-    public MacAddress getDeviceMac(DeviceId deviceId) {
+    public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac);
             return srinfo.mac;
         } else {
-            log.warn("getDeviceMac for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "getDeviceMac fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
-    /**
-     * Returns the router ip address of a segment router.
-     *
-     * @param deviceId device identifier
-     * @return router ip address
-     */
-    public Ip4Address getRouterIp(DeviceId deviceId) {
+    @Override
+    public Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip);
             return srinfo.ip;
         } else {
-            log.warn("getRouterIp for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "getRouterIp fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
-    /**
-     * Indicates if the segment router is a edge router or
-     * a core/backbone router.
-     *
-     * @param deviceId device identifier
-     * @return boolean
-     */
     @Override
-    public boolean isEdgeDevice(DeviceId deviceId) {
+    public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge);
             return srinfo.isEdge;
         } else {
-            log.warn("isEdgeDevice for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "isEdgeDevice fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
-    /**
-     * Returns the node segment ids of all configured segment routers.
-     *
-     * @return list of node segment ids
-     */
     @Override
     public List<Integer> getAllDeviceSegmentIds() {
         return allSegmentIds;
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
similarity index 65%
rename from apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java
rename to apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
index d28d38d..a39c956 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
@@ -13,11 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.segmentrouting.grouphandler;
+package org.onosproject.segmentrouting.config;
 
 import java.util.List;
 import java.util.Map;
 
+import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.DeviceId;
@@ -30,28 +31,48 @@
  */
 public interface DeviceProperties {
     /**
+     * Checks if the device is configured.
+     *
+     * @param deviceId device identifier
+     * @return true if the device is configured
+     */
+    boolean isConfigured(DeviceId deviceId);
+
+    /**
      * Returns the segment id of a device to be used in group creation.
      *
      * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return segment id of a device
      */
-    int getSegmentId(DeviceId deviceId);
+    int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
      * Returns the Mac address of a device to be used in group creation.
      *
      * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return mac address of a device
      */
-    MacAddress getDeviceMac(DeviceId deviceId);
+    MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns the router ip address of a segment router.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return router ip address
+     */
+    Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
      * Indicates whether a device is edge device or transit/core device.
      *
      * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return boolean
      */
-    boolean isEdgeDevice(DeviceId deviceId);
+    boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
      * Returns all segment IDs to be considered in building auto
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
index a5c1090..33496bd 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
@@ -24,6 +24,7 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.store.service.EventuallyConsistentMap;
 
 /**
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
index 69a0d86..1af72a8 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -48,6 +48,8 @@
 import org.onosproject.net.group.DefaultGroupKey;
 import org.onosproject.net.group.GroupKey;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.slf4j.Logger;
 
@@ -63,9 +65,9 @@
     protected final ApplicationId appId;
     protected final DeviceProperties deviceConfig;
     protected final List<Integer> allSegmentIds;
-    protected final int nodeSegmentId;
-    protected final boolean isEdgeRouter;
-    protected final MacAddress nodeMacAddr;
+    protected int nodeSegmentId = -1;
+    protected boolean isEdgeRouter = false;
+    protected MacAddress nodeMacAddr = null;
     protected LinkService linkService;
     protected FlowObjectiveService flowObjectiveService;
 
@@ -99,10 +101,15 @@
         this.appId = checkNotNull(appId);
         this.deviceConfig = checkNotNull(config);
         this.linkService = checkNotNull(linkService);
-        allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
-        nodeSegmentId = config.getSegmentId(deviceId);
-        isEdgeRouter = config.isEdgeDevice(deviceId);
-        nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
+        this.allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
+        try {
+            this.nodeSegmentId = config.getSegmentId(deviceId);
+            this.isEdgeRouter = config.isEdgeDevice(deviceId);
+            this.nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage()
+                    + " Skipping value assignment in DefaultGroupHandler");
+        }
         this.flowObjectiveService = flowObjService;
         this.nsNextObjStore = nsNextObjStore;
         this.subnetNextObjStore = subnetNextObjStore;
@@ -122,6 +129,7 @@
      * @param flowObjService flow objective service object
      * @param nsNextObjStore NeighborSet next objective store map
      * @param subnetNextObjStore subnet next objective store map
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return default group handler type
      */
     public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
@@ -133,7 +141,9 @@
                                                                  NeighborSetNextObjectiveStoreKey,
                                                                  Integer> nsNextObjStore,
                                                          EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
-                                                                 Integer> subnetNextObjStore) {
+                                                                 Integer> subnetNextObjStore)
+                                                         throws DeviceConfigNotFoundException {
+        // handle possible exception in the caller
         if (config.isEdgeDevice(deviceId)) {
             return new DefaultEdgeGroupHandler(deviceId, appId, config,
                                                linkService,
@@ -176,6 +186,14 @@
             return;
         }
 
+        MacAddress dstMac;
+        try {
+            dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId());
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting linkUp.");
+            return;
+        }
+
         log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId,
                   newLink.src().port(), newLink.dst().deviceId());
         addNeighborAtPort(newLink.dst().deviceId(),
@@ -202,8 +220,7 @@
             TrafficTreatment.Builder tBuilder =
                     DefaultTrafficTreatment.builder();
             tBuilder.setOutput(newLink.src().port())
-                    .setEthDst(deviceConfig.getDeviceMac(
-                          newLink.dst().deviceId()))
+                    .setEthDst(dstMac)
                     .setEthSrc(nodeMacAddr);
             if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
                 tBuilder.pushMpls()
@@ -242,6 +259,15 @@
             log.warn("portDown: unknown port");
             return;
         }
+
+        MacAddress dstMac;
+        try {
+            dstMac = deviceConfig.getDeviceMac(portDeviceMap.get(port));
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting portDown.");
+            return;
+        }
+
         log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
                   portDeviceMap.get(port));
         /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap
@@ -263,8 +289,8 @@
             TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
                     .builder();
             tBuilder.setOutput(port)
-                    .setEthDst(deviceConfig.getDeviceMac(portDeviceMap
-                                       .get(port))).setEthSrc(nodeMacAddr);
+                    .setEthDst(dstMac)
+                    .setEthSrc(nodeMacAddr);
             if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
                 tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
                                                     .getEdgeLabel()));
@@ -432,7 +458,15 @@
     }
 
     private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) {
-        return (deviceConfig.getSegmentId(deviceId) == sId);
+        int segmentId;
+        try {
+            segmentId = deviceConfig.getSegmentId(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting isSegmentIdSameAsNodeSegmentId.");
+            return false;
+        }
+
+        return segmentId == sId;
     }
 
     protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(Set<DeviceId> neighbors) {
@@ -487,11 +521,19 @@
                     return;
                 }
 
+                MacAddress deviceMac;
+                try {
+                    deviceMac = deviceConfig.getDeviceMac(d);
+                } catch (DeviceConfigNotFoundException e) {
+                    log.warn(e.getMessage() + " Aborting createGroupsFromNeighborsets.");
+                    return;
+                }
+
                 for (PortNumber sp : devicePortMap.get(d)) {
                     TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
                             .builder();
                     tBuilder.setOutput(sp)
-                            .setEthDst(deviceConfig.getDeviceMac(d))
+                            .setEthDst(deviceMac)
                             .setEthSrc(nodeMacAddr);
                     if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
                         tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
index b009e86..8e1b6a8 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
@@ -23,6 +23,8 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.store.service.EventuallyConsistentMap;
 
 /**
@@ -171,7 +173,15 @@
             if (deviceSubSet.size() > 1) {
                 boolean avoidEdgeRouterPairing = true;
                 for (DeviceId device : deviceSubSet) {
-                    if (!deviceConfig.isEdgeDevice(device)) {
+                    boolean isEdge;
+                    try {
+                        isEdge = deviceConfig.isEdgeDevice(device);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage() + " Skipping filterEdgeRouterOnlyPairings on this device.");
+                        continue;
+                    }
+
+                    if (!isEdge) {
                         avoidEdgeRouterPairing = false;
                         break;
                     }
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
index e47a662..5514207 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
@@ -24,8 +24,11 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.onlab.packet.MacAddress;
 import org.onlab.packet.MplsLabel;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.onosproject.net.DeviceId;
@@ -105,11 +108,19 @@
                                     PolicyGroupIdentifier(id,
                                                           Collections.singletonList(param),
                                                           Collections.singletonList(bucketId));
+                            MacAddress neighborEthDst;
+                            try {
+                                neighborEthDst = deviceConfig.getDeviceMac(neighbor);
+                            } catch (DeviceConfigNotFoundException e) {
+                                log.warn(e.getMessage()
+                                        + " Skipping createPolicyGroupChain for this label.");
+                                continue;
+                            }
+
                             TrafficTreatment.Builder tBuilder =
                                     DefaultTrafficTreatment.builder();
                             tBuilder.setOutput(sp)
-                                    .setEthDst(deviceConfig.
-                                               getDeviceMac(neighbor))
+                                    .setEthDst(neighborEthDst)
                                     .setEthSrc(nodeMacAddr)
                                     .pushMpls()
                                     .setMpls(MplsLabel.mplsLabel(label));
@@ -168,14 +179,23 @@
 
             if (fullyResolved) {
                 List<GroupBucket> outBuckets = new ArrayList<>();
-                for (GroupBucketIdentifier bucketId:bucketIds) {
+                for (GroupBucketIdentifier bucketId : bucketIds) {
                     DeviceId neighbor = portDeviceMap.
                             get(bucketId.outPort());
+
+                    MacAddress neighborEthDst;
+                    try {
+                        neighborEthDst = deviceConfig.getDeviceMac(neighbor);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage()
+                                + " Skipping createPolicyGroupChain for this bucketId.");
+                        continue;
+                    }
+
                     TrafficTreatment.Builder tBuilder =
                             DefaultTrafficTreatment.builder();
                     tBuilder.setOutput(bucketId.outPort())
-                            .setEthDst(deviceConfig.
-                                       getDeviceMac(neighbor))
+                            .setEthDst(neighborEthDst)
                             .setEthSrc(nodeMacAddr);
                     if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) {
                         tBuilder.pushMpls()