[ONOS-4681] Enables device registration in GossipDeviceStore,
exposes availability, and polls NETCONF device reachability.

Change-Id: I5492c7b6109c3431d71555a9104c7e97fc6e75be
diff --git a/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java b/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
index 72ec4ab..91ce5af 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
@@ -38,6 +38,7 @@
     private final String swVersion;
     private final String serialNumber;
     private final ChassisId chassisId;
+    private final boolean defaultAvailable;
 
     /**
      * Creates a device description using the supplied information.
@@ -55,6 +56,28 @@
                                     String hwVersion, String swVersion,
                                     String serialNumber, ChassisId chassis,
                                     SparseAnnotations... annotations) {
+        this(uri, type, manufacturer, hwVersion, swVersion, serialNumber,
+             chassis, true, annotations);
+    }
+
+    /**
+     * Creates a device description using the supplied information.
+     *
+     * @param uri            device URI
+     * @param type           device type
+     * @param manufacturer   device manufacturer
+     * @param hwVersion      device HW version
+     * @param swVersion      device SW version
+     * @param serialNumber   device serial number
+     * @param chassis        chassis id
+     * @param defaultAvailable optional whether device is by default available
+     * @param annotations    optional key/value annotations map
+     */
+    public DefaultDeviceDescription(URI uri, Type type, String manufacturer,
+                                    String hwVersion, String swVersion,
+                                    String serialNumber, ChassisId chassis,
+                                    boolean defaultAvailable,
+                                    SparseAnnotations... annotations) {
         super(annotations);
         this.uri = checkNotNull(uri, "Device URI cannot be null");
         this.type = checkNotNull(type, "Device type cannot be null");
@@ -63,6 +86,7 @@
         this.swVersion = swVersion;
         this.serialNumber = serialNumber;
         this.chassisId = chassis;
+        this.defaultAvailable = defaultAvailable;
     }
 
     /**
@@ -74,7 +98,7 @@
                                     SparseAnnotations... annotations) {
         this(base.deviceUri(), base.type(), base.manufacturer(),
              base.hwVersion(), base.swVersion(), base.serialNumber(),
-             base.chassisId(), annotations);
+             base.chassisId(), base.isDefaultAvailable(), annotations);
     }
 
     /**
@@ -83,10 +107,26 @@
      * @param type device type
      * @param annotations Annotations to use.
      */
-    public DefaultDeviceDescription(DeviceDescription base, Type type, SparseAnnotations... annotations) {
+    public DefaultDeviceDescription(DeviceDescription base, Type type,
+                                    SparseAnnotations... annotations) {
         this(base.deviceUri(), type, base.manufacturer(),
                 base.hwVersion(), base.swVersion(), base.serialNumber(),
-                base.chassisId(), annotations);
+                base.chassisId(), base.isDefaultAvailable(), annotations);
+    }
+
+    /**
+     * Creates a device description using the supplied information.
+     *
+     * @param base DeviceDescription to basic information (except for defaultAvailable)
+     * @param defaultAvailable whether device should be made available by default
+     * @param annotations Annotations to use.
+     */
+    public DefaultDeviceDescription(DeviceDescription base,
+                                    boolean defaultAvailable,
+                                    SparseAnnotations... annotations) {
+        this(base.deviceUri(), base.type(), base.manufacturer(),
+             base.hwVersion(), base.swVersion(), base.serialNumber(),
+             base.chassisId(), defaultAvailable, annotations);
     }
 
     @Override
@@ -125,6 +165,11 @@
     }
 
     @Override
+    public boolean isDefaultAvailable() {
+        return defaultAvailable;
+    }
+
+    @Override
     public String toString() {
         return toStringHelper(this)
                 .add("uri", uri).add("type", type).add("mfr", manufacturer)
@@ -137,7 +182,8 @@
     @Override
     public int hashCode() {
         return Objects.hashCode(super.hashCode(), uri, type, manufacturer,
-                                hwVersion, swVersion, serialNumber, chassisId);
+                                hwVersion, swVersion, serialNumber, chassisId,
+                                defaultAvailable);
     }
 
     @Override
@@ -153,7 +199,8 @@
                     && Objects.equal(this.hwVersion, that.hwVersion)
                     && Objects.equal(this.swVersion, that.swVersion)
                     && Objects.equal(this.serialNumber, that.serialNumber)
-                    && Objects.equal(this.chassisId, that.chassisId);
+                    && Objects.equal(this.chassisId, that.chassisId)
+                    && Objects.equal(this.defaultAvailable, that.defaultAvailable);
         }
         return false;
     }
@@ -167,5 +214,6 @@
         this.swVersion = null;
         this.serialNumber = null;
         this.chassisId = null;
+        this.defaultAvailable = true;
     }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java b/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java
index b796f29..848fc6d 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java
@@ -77,4 +77,11 @@
      */
     ChassisId chassisId();
 
+    /**
+     * Return whether device should be made available by default.
+     *
+     * @return default availability
+     */
+    boolean isDefaultAvailable();
+
 }
diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java b/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java
index cfc9626..e010202 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DeviceStore.java
@@ -52,8 +52,6 @@
      */
     Iterable<Device> getAvailableDevices();
 
-
-
     /**
      * Returns the device with the specified identifier.
      *
@@ -74,6 +72,7 @@
     DeviceEvent createOrUpdateDevice(ProviderId providerId, DeviceId deviceId,
                                      DeviceDescription deviceDescription);
 
+
     // TODO: We may need to enforce that ancillary cannot interfere this state
     /**
      * Removes the specified infrastructure device.
@@ -84,6 +83,14 @@
     DeviceEvent markOffline(DeviceId deviceId);
 
     /**
+     * Marks the device as available.
+     *
+     * @param deviceId device identifier
+     * @return true if availability change request was accepted and changed the state
+     */
+    boolean markOnline(DeviceId deviceId);
+
+    /**
      * Updates the ports of the specified infrastructure device using the given
      * list of port descriptions. The list is assumed to be comprehensive.
      *
diff --git a/core/api/src/test/java/org/onosproject/net/device/DeviceStoreAdapter.java b/core/api/src/test/java/org/onosproject/net/device/DeviceStoreAdapter.java
index d13da6a..9859892 100644
--- a/core/api/src/test/java/org/onosproject/net/device/DeviceStoreAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/device/DeviceStoreAdapter.java
@@ -57,6 +57,11 @@
     }
 
     @Override
+    public boolean markOnline(DeviceId deviceId) {
+        return false;
+    }
+
+    @Override
     public DeviceEvent markOffline(DeviceId deviceId) {
         return null;
     }
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java
index 31b4292..b51a1d1 100644
--- a/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java
@@ -245,6 +245,13 @@
         }
     }
 
+    // implement differently if desired
+    @Override
+    public boolean markOnline(DeviceId deviceId) {
+        log.warn("Mark online not supported");
+        return false;
+    }
+
     @Override
     public List<DeviceEvent> updatePorts(ProviderId providerId,
                                          DeviceId deviceId,
diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java b/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
index 4d94f3d..ede33a5 100644
--- a/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
+++ b/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
@@ -79,7 +79,8 @@
         SparseAnnotations sa = combine(bdc, descr.annotations());
         return new DefaultDeviceDescription(descr.deviceUri(), type, manufacturer,
                                             hwVersion, swVersion,
-                                            serial, descr.chassisId(), sa);
+                                            serial, descr.chassisId(),
+                                            descr.isDefaultAvailable(), sa);
     }
 
     /**
diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
index 2bf4ee8..c350a41 100644
--- a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
@@ -64,7 +64,6 @@
 import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.config.basics.BasicDeviceConfig;
 import org.onosproject.net.config.basics.OpticalPortConfig;
-import org.onosproject.net.device.DefaultDeviceDescription;
 import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.device.DeviceAdminService;
 import org.onosproject.net.device.DeviceDescription;
@@ -288,6 +287,19 @@
             log.trace("Checking device {}", deviceId);
 
             if (!isReachable(deviceId)) {
+                if (mastershipService.getLocalRole(deviceId) != NONE) {
+                    // can't be master if device is not reachable
+                    try {
+                        post(store.markOffline(deviceId));
+                        //relinquish master role and ability to be backup.
+                        mastershipService.relinquishMastership(deviceId).get();
+                    } catch (InterruptedException e) {
+                        log.warn("Interrupted while reliquishing role for {}", deviceId);
+                        Thread.currentThread().interrupt();
+                    } catch (ExecutionException e) {
+                        log.error("Exception thrown while relinquishing role for {}", deviceId, e);
+                    }
+                }
                 continue;
             }
 
@@ -334,7 +346,6 @@
             }
             provider.roleChanged(deviceId, newRole);
             // not triggering probe when triggered by provider service event
-
             return true;
         }
 
@@ -360,12 +371,15 @@
 
             DeviceEvent event = store.createOrUpdateDevice(provider().id(), deviceId,
                                                            deviceDescription);
-            log.info("Device {} connected", deviceId);
+            if (deviceDescription.isDefaultAvailable()) {
+                log.info("Device {} connected", deviceId);
+            } else {
+                log.info("Device {} registered", deviceId);
+            }
             if (event != null) {
                 log.trace("event: {} {}", event.type(), event);
                 post(event);
             }
-
         }
 
         private PortDescription ensurePortEnabledState(PortDescription desc, boolean enabled) {
@@ -684,19 +698,7 @@
             case MASTER:
                 final Device device = getDevice(did);
                 if ((device != null) && !isAvailable(did)) {
-                    //flag the device as online. Is there a better way to do this?
-                    DefaultDeviceDescription deviceDescription
-                            = new DefaultDeviceDescription(did.uri(),
-                                                           device.type(),
-                                                           device.manufacturer(),
-                                                           device.hwVersion(),
-                                                           device.swVersion(),
-                                                           device.serialNumber(),
-                                                           device.chassisId());
-                    DeviceEvent devEvent =
-                            store.createOrUpdateDevice(device.providerId(), did,
-                                                       deviceDescription);
-                    post(devEvent);
+                    store.markOnline(did);
                 }
                 // TODO: should apply role only if there is mismatch
                 log.debug("Applying role {} to {}", myNextRole, did);
diff --git a/core/store/dist/src/main/java/org/onosproject/store/device/impl/ECDeviceStore.java b/core/store/dist/src/main/java/org/onosproject/store/device/impl/ECDeviceStore.java
index 725e3ca..c291b4b 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/device/impl/ECDeviceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/device/impl/ECDeviceStore.java
@@ -275,6 +275,7 @@
         return devices.get(deviceId);
     }
 
+    // FIXME handle deviceDescription.isDefaultAvailable()=false case properly.
     @Override
     public DeviceEvent createOrUpdateDevice(ProviderId providerId,
             DeviceId deviceId,
@@ -392,8 +393,13 @@
         return null;
     }
 
-    private boolean markOnline(DeviceId deviceId) {
-        return availableDevices.add(deviceId);
+    // FIXME publicization of markOnline -- trigger some action independently?
+    public boolean markOnline(DeviceId deviceId) {
+        if (devices.containsKey(deviceId)) {
+            return availableDevices.add(deviceId);
+        }
+        log.warn("Device {} does not exist in store", deviceId);
+        return false;
     }
 
     @Override
diff --git a/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java b/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
index 49c8534..52d0c3c 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
@@ -341,7 +341,7 @@
 
             if (deviceEvent != null) {
                 log.debug("Notifying peers of a device update topology event for providerId: {} and deviceId: {}",
-                         providerId, deviceId);
+                          providerId, deviceId);
                 notifyPeers(new InternalDeviceEvent(providerId, deviceId, mergedDesc));
             }
 
@@ -406,11 +406,16 @@
                 return null;
             }
             if (oldDevice == null) {
+                // REGISTER
+                if (!deltaDesc.value().isDefaultAvailable()) {
+                    return registerDevice(providerId, newDevice);
+                }
                 // ADD
                 return createDevice(providerId, newDevice, deltaDesc.timestamp());
             } else {
                 // UPDATE or ignore (no change or stale)
-                return updateDevice(providerId, oldDevice, newDevice, deltaDesc.timestamp());
+                return updateDevice(providerId, oldDevice, newDevice, deltaDesc.timestamp(),
+                                    deltaDesc.value().isDefaultAvailable());
             }
         }
     }
@@ -437,7 +442,8 @@
     // Guarded by deviceDescs value (=Device lock)
     private DeviceEvent updateDevice(ProviderId providerId,
                                      Device oldDevice,
-                                     Device newDevice, Timestamp newTimestamp) {
+                                     Device newDevice, Timestamp newTimestamp,
+                                     boolean forceAvailable) {
         // We allow only certain attributes to trigger update
         boolean propertiesChanged =
                 !Objects.equals(oldDevice.hwVersion(), newDevice.hwVersion()) ||
@@ -461,7 +467,7 @@
             event = new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, newDevice, null);
         }
 
-        if (!providerId.isAncillary()) {
+        if (!providerId.isAncillary() && forceAvailable) {
             boolean wasOnline = availableDevices.contains(newDevice.id());
             markOnline(newDevice.id(), newTimestamp);
             if (!wasOnline) {
@@ -471,6 +477,20 @@
         return event;
     }
 
+    private DeviceEvent registerDevice(ProviderId providerId, Device newDevice) {
+        // update composed device cache
+        Device oldDevice = devices.putIfAbsent(newDevice.id(), newDevice);
+        verify(oldDevice == null,
+               "Unexpected Device in cache. PID:%s [old=%s, new=%s]",
+               providerId, oldDevice, newDevice);
+
+        if (!providerId.isAncillary()) {
+            markOffline(newDevice.id());
+        }
+
+        return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, newDevice, null);
+    }
+
     @Override
     public DeviceEvent markOffline(DeviceId deviceId) {
         final Timestamp timestamp = deviceClockService.getTimestamp(deviceId);
@@ -514,6 +534,24 @@
         }
     }
 
+    public boolean markOnline(DeviceId deviceId) {
+        if (devices.containsKey(deviceId)) {
+            final Timestamp timestamp = deviceClockService.getTimestamp(deviceId);
+            Map<?, ?> deviceLock = getOrCreateDeviceDescriptionsMap(deviceId);
+            synchronized (deviceLock) {
+                if (markOnline(deviceId, timestamp)) {
+                    notifyDelegate(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, getDevice(deviceId), null));
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        }
+        log.warn("Device {} does not exist in store", deviceId);
+        return false;
+
+    }
+
     /**
      * Marks the device as available if the given timestamp is not outdated,
      * compared to the time the device has been marked offline.
@@ -1576,7 +1614,8 @@
             Timestamped<DeviceDescription> deviceDescription = event.deviceDescription();
 
             try {
-                notifyDelegateIfNotNull(createOrUpdateDeviceInternal(providerId, deviceId, deviceDescription));
+                notifyDelegateIfNotNull(createOrUpdateDeviceInternal(providerId, deviceId,
+                                                                     deviceDescription));
             } catch (Exception e) {
                 log.warn("Exception thrown handling device update", e);
             }
diff --git a/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java b/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java
index b95e752..744f956 100644
--- a/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java
+++ b/incubator/rpc-grpc/src/test/java/org/onosproject/incubator/rpc/grpc/GrpcRemoteServiceTest.java
@@ -450,7 +450,6 @@
             deviceConnected.countDown();
         }
 
-
         final CountDownLatch updatePorts = new CountDownLatch(1);
         DeviceId updatePortsDid;
         List<PortDescription> updatePortsDescs;
diff --git a/providers/isis/topology/src/test/java/org/onosproject/provider/isis/topology/impl/IsisTopologyProviderTest.java b/providers/isis/topology/src/test/java/org/onosproject/provider/isis/topology/impl/IsisTopologyProviderTest.java
index fb3acd1..0905ec7 100755
--- a/providers/isis/topology/src/test/java/org/onosproject/provider/isis/topology/impl/IsisTopologyProviderTest.java
+++ b/providers/isis/topology/src/test/java/org/onosproject/provider/isis/topology/impl/IsisTopologyProviderTest.java
@@ -258,7 +258,6 @@
 
             }
 
-
             @Override
             public void deviceDisconnected(DeviceId deviceId) {
 
diff --git a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
index 4970296..eec8b29 100644
--- a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
+++ b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
@@ -67,6 +67,9 @@
 import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
@@ -114,17 +117,21 @@
     private static final String IPADDRESS = "ipaddress";
     private static final String NETCONF = "netconf";
     private static final String PORT = "port";
+    private static final int CORE_POOL_SIZE = 10;
     //FIXME eventually a property
     private static final int ISREACHABLE_TIMEOUT = 2000;
+    private static final int DEFAULT_POLL_FREQUENCY_SECONDS = 30;
 
     private final ExecutorService executor =
             Executors.newFixedThreadPool(5, groupedThreads("onos/netconfdeviceprovider",
                                                            "device-installer-%d", log));
+    protected ScheduledExecutorService connectionExecutor = Executors.newScheduledThreadPool(CORE_POOL_SIZE);
 
     private DeviceProviderService providerService;
     private NetconfDeviceListener innerNodeListener = new InnerNetconfDeviceListener();
     private InternalDeviceListener deviceListener = new InternalDeviceListener();
     private NodeId localNodeId;
+    private ScheduledFuture<?> scheduledTask;
 
     private final ConfigFactory factory =
             new ConfigFactory<ApplicationId, NetconfProviderConfig>(APP_SUBJECT_FACTORY,
@@ -152,6 +159,7 @@
         deviceService.addListener(deviceListener);
         executor.execute(NetconfDeviceProvider.this::connectDevices);
         localNodeId = clusterService.getLocalNode().id();
+        scheduledTask = schedulePolling();
         log.info("Started");
     }
 
@@ -169,6 +177,7 @@
         providerRegistry.unregister(this);
         providerService = null;
         cfgService.unregisterConfigFactory(factory);
+        scheduledTask.cancel(true);
         executor.shutdown();
         log.info("Stopped");
     }
@@ -177,6 +186,15 @@
         super(new ProviderId(SCHEME_NAME, DEVICE_PROVIDER_PACKAGE));
     }
 
+    // Checks connection to devices in the config file
+    // every DEFAULT_POLL_FREQUENCY_SECONDS seconds.
+    private ScheduledFuture schedulePolling() {
+        return connectionExecutor.scheduleAtFixedRate(this::checkAndUpdateDevices,
+                                                      DEFAULT_POLL_FREQUENCY_SECONDS / 10,
+                                                      DEFAULT_POLL_FREQUENCY_SECONDS,
+                                                      TimeUnit.SECONDS);
+    }
+
     @Override
     public void triggerProbe(DeviceId deviceId) {
         // TODO: This will be implemented later.
@@ -270,8 +288,14 @@
         @Override
         public void deviceRemoved(DeviceId deviceId) {
             Preconditions.checkNotNull(deviceId, ISNULL);
-            log.debug("Netconf device {} removed from Netconf subController", deviceId);
-            providerService.deviceDisconnected(deviceId);
+
+            if (deviceService.getDevice(deviceId) != null) {
+                providerService.deviceDisconnected(deviceId);
+                log.debug("Netconf device {} removed from Netconf subController", deviceId);
+            } else {
+                log.warn("Netconf device {} does not exist in the store, " +
+                         "it may already have been removed", deviceId);
+            }
         }
     }
 
@@ -295,13 +319,67 @@
                             Device.Type.SWITCH,
                             UNKNOWN, UNKNOWN,
                             UNKNOWN, UNKNOWN,
-                            cid,
+                            cid, false,
                             annotations);
                     deviceKeyAdminService.addKey(
                             DeviceKey.createDeviceKeyUsingUsernamePassword(
                                     DeviceKeyId.deviceKeyId(deviceId.toString()),
                                     null, addr.name(), addr.password()));
-                    providerService.deviceConnected(deviceId, deviceDescription);
+                    if (deviceService.getDevice(deviceId) == null) {
+                        providerService.deviceConnected(deviceId, deviceDescription);
+                    }
+                    checkAndUpdateDevice(deviceId, deviceDescription);
+                });
+            } catch (ConfigException e) {
+                log.error("Cannot read config error " + e);
+            }
+        }
+    }
+
+    private void checkAndUpdateDevice(DeviceId deviceId, DeviceDescription deviceDescription) {
+        if (deviceService.getDevice(deviceId) == null) {
+            log.warn("Device {} has not been added to store, " +
+                             "maybe due to a problem in connectivity", deviceId);
+        } else {
+            boolean isReachable = isReachable(deviceId);
+            if (isReachable && !deviceService.isAvailable(deviceId)) {
+                providerService.deviceConnected(
+                        deviceId, new DefaultDeviceDescription(
+                                deviceDescription, true, deviceDescription.annotations()));
+            } else if (!isReachable && deviceService.isAvailable(deviceId)) {
+                providerService.deviceDisconnected(deviceId);
+            }
+        }
+    }
+
+    private void checkAndUpdateDevices() {
+        NetconfProviderConfig cfg = cfgService.getConfig(appId, NetconfProviderConfig.class);
+        if (cfg != null) {
+            log.info("Checking connection to devices in configuration");
+            try {
+                cfg.getDevicesAddresses().stream().forEach(addr -> {
+                    DeviceId deviceId = getDeviceId(addr.ip().toString(), addr.port());
+                    Preconditions.checkNotNull(deviceId, ISNULL);
+                    //Netconf configuration object
+                    ChassisId cid = new ChassisId();
+                    String ipAddress = addr.ip().toString();
+                    SparseAnnotations annotations = DefaultAnnotations.builder()
+                            .set(IPADDRESS, ipAddress)
+                            .set(PORT, String.valueOf(addr.port()))
+                            .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase())
+                            .build();
+                    DeviceDescription deviceDescription = new DefaultDeviceDescription(
+                            deviceId.uri(),
+                            Device.Type.SWITCH,
+                            UNKNOWN, UNKNOWN,
+                            UNKNOWN, UNKNOWN,
+                            cid, false,
+                            annotations);
+                    deviceKeyAdminService.addKey(
+                            DeviceKey.createDeviceKeyUsingUsernamePassword(
+                                    DeviceKeyId.deviceKeyId(deviceId.toString()),
+                                    null, addr.name(), addr.password()));
+                    checkAndUpdateDevice(deviceId, deviceDescription);
                 });
             } catch (ConfigException e) {
                 log.error("Cannot read config error " + e);