[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);