[ONOS-2159]Add to query devices by type api in DeviceService and
DeviceStore interfaces
Change-Id: Ifa7e94e08eb150fb4d71248a50a390832d1549df
diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceService.java b/core/api/src/main/java/org/onosproject/net/device/DeviceService.java
index 5ce4d16..ab6dba5 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DeviceService.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DeviceService.java
@@ -44,6 +44,15 @@
Iterable<Device> getDevices();
/**
+ * Returns a collection of the currently known infrastructure
+ * devices by device type.
+ *
+ * @param type device type
+ * @return collection of devices
+ */
+ Iterable<Device> getDevices(Device.Type type);
+
+ /**
* Returns an iterable collection of all devices
* currently available to the system.
*
@@ -52,6 +61,14 @@
Iterable<Device> getAvailableDevices();
/**
+ * Returns an iterable collection of all devices currently available to the system by device type.
+ *
+ * @param type device type
+ * @return device collection
+ */
+ Iterable<Device> getAvailableDevices(Device.Type type);
+
+ /**
* Returns the device with the specified identifier.
*
* @param deviceId device identifier
diff --git a/core/api/src/test/java/org/onosproject/net/device/DeviceServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/device/DeviceServiceAdapter.java
index 88c2f94..539fd5f 100644
--- a/core/api/src/test/java/org/onosproject/net/device/DeviceServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/device/DeviceServiceAdapter.java
@@ -19,6 +19,7 @@
import com.google.common.collect.FluentIterable;
import org.onosproject.net.Device;
+import org.onosproject.net.Device.Type;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
@@ -91,4 +92,14 @@
public void removeListener(DeviceListener listener) {
}
+ @Override
+ public Iterable<Device> getDevices(Type type) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Iterable<Device> getAvailableDevices(Type type) {
+ return Collections.emptyList();
+ }
+
}
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 dfd8f29..c0ee516 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
@@ -15,7 +15,25 @@
*/
package org.onosproject.net.device.impl;
-import com.google.common.collect.Lists;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.MastershipRole.MASTER;
+import static org.onosproject.net.MastershipRole.NONE;
+import static org.onosproject.net.MastershipRole.STANDBY;
+import static org.onosproject.security.AppGuard.checkPermission;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -25,14 +43,15 @@
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.Permission;
-import org.onosproject.event.ListenerRegistry;
import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.ListenerRegistry;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
import org.onosproject.mastership.MastershipTerm;
import org.onosproject.mastership.MastershipTermService;
import org.onosproject.net.Device;
+import org.onosproject.net.Device.Type;
import org.onosproject.net.DeviceId;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.Port;
@@ -56,21 +75,7 @@
import org.onosproject.net.provider.AbstractProviderService;
import org.slf4j.Logger;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.MastershipRole.*;
-import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.security.AppGuard.checkPermission;
-
+import com.google.common.collect.Lists;
/**
* Provides implementation of the device SB & NB APIs.
@@ -88,8 +93,7 @@
private final Logger log = getLogger(getClass());
- protected final ListenerRegistry<DeviceEvent, DeviceListener> listenerRegistry =
- new ListenerRegistry<>();
+ protected final ListenerRegistry<DeviceEvent, DeviceListener> listenerRegistry = new ListenerRegistry<>();
private final DeviceStoreDelegate delegate = new InternalStoreDelegate();
@@ -118,7 +122,8 @@
@Activate
public void activate() {
- backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos/device", "manager-background"));
+ backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos/device",
+ "manager-background"));
localNodeId = clusterService.getLocalNode().id();
store.setDelegate(delegate);
@@ -258,8 +263,7 @@
}
@Override
- protected DeviceProviderService createProviderService(
- DeviceProvider provider) {
+ protected DeviceProviderService createProviderService(DeviceProvider provider) {
return new InternalDeviceProviderService(provider);
}
@@ -280,7 +284,8 @@
continue;
}
- log.info("{} is reachable but did not have a valid role, reasserting", deviceId);
+ log.info("{} is reachable but did not have a valid role, reasserting",
+ deviceId);
// isReachable but was not MASTER or STANDBY, get a role and apply
// Note: NONE triggers request to MastershipService
@@ -300,20 +305,21 @@
/**
* Apply role in reaction to provider event.
*
- * @param deviceId device identifier
- * @param newRole new role to apply to the device
+ * @param deviceId device identifier
+ * @param newRole new role to apply to the device
* @return true if the request was sent to provider
*/
private boolean applyRole(DeviceId deviceId, MastershipRole newRole) {
if (newRole.equals(MastershipRole.NONE)) {
- //no-op
+ // no-op
return true;
}
DeviceProvider provider = provider();
if (provider == null) {
- log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole);
+ log.warn("Provider for {} was not found. Cannot apply role {}",
+ deviceId, newRole);
return false;
}
provider.roleChanged(deviceId, newRole);
@@ -322,7 +328,6 @@
return true;
}
-
@Override
public void deviceConnected(DeviceId deviceId,
DeviceDescription deviceDescription) {
@@ -332,14 +337,16 @@
log.info("Device {} connected", deviceId);
// check my Role
- CompletableFuture<MastershipRole> role = mastershipService.requestRoleFor(deviceId);
+ CompletableFuture<MastershipRole> role = mastershipService
+ .requestRoleFor(deviceId);
try {
// Device subsystem must wait for role assignment
// to avoid losing Device information.
// (This node could be the only Node connected to the Device.)
role.get();
} catch (InterruptedException e) {
- log.warn("Interrupted while waiting role-assignment for {}", deviceId);
+ log.warn("Interrupted while waiting role-assignment for {}",
+ deviceId);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
log.error("Exception thrown while waiting role-assignment for {}",
@@ -358,7 +365,8 @@
}
DeviceEvent event = store.createOrUpdateDevice(provider().id(),
- deviceId, deviceDescription);
+ deviceId,
+ deviceDescription);
if (event != null) {
log.trace("event: {} {}", event.type(), event);
@@ -375,10 +383,8 @@
List<Port> ports = store.getPorts(deviceId);
List<PortDescription> descs = Lists.newArrayList();
- ports.forEach(port ->
- descs.add(new DefaultPortDescription(port.number(),
- false, port.type(),
- port.portSpeed())));
+ ports.forEach(port -> descs.add(new DefaultPortDescription(port
+ .number(), false, port.type(), port.portSpeed())));
store.updatePorts(this.provider().id(), deviceId, descs);
try {
if (mastershipService.getLocalRole(deviceId) == MASTER) {
@@ -387,37 +393,49 @@
} catch (IllegalStateException e) {
log.warn("Failed to mark {} offline", deviceId);
// only the MASTER should be marking off-line in normal cases,
- // but if I was the last STANDBY connection, etc. and no one else
- // was there to mark the device offline, this instance may need to
+ // but if I was the last STANDBY connection, etc. and no one
+ // else
+ // was there to mark the device offline, this instance may need
+ // to
// temporarily request for Master Role and mark offline.
- //there are times when this node will correctly have mastership, BUT
- //that isn't reflected in the ClockManager before the device disconnects.
- //we want to let go of the device anyways, so make sure this happens.
+ // there are times when this node will correctly have
+ // mastership, BUT
+ // that isn't reflected in the ClockManager before the device
+ // disconnects.
+ // we want to let go of the device anyways, so make sure this
+ // happens.
// FIXME: Store semantics leaking out as IllegalStateException.
- // Consider revising store API to handle this scenario.
- CompletableFuture<MastershipRole> roleFuture = mastershipService.requestRoleFor(deviceId);
+ // Consider revising store API to handle this scenario.
+ CompletableFuture<MastershipRole> roleFuture = mastershipService
+ .requestRoleFor(deviceId);
roleFuture.whenComplete((role, error) -> {
- MastershipTerm term = termService.getMastershipTerm(deviceId);
- // TODO: Move this type of check inside device clock manager, etc.
- if (term != null && localNodeId.equals(term.master())) {
- log.info("Retry marking {} offline", deviceId);
- deviceClockProviderService.setMastershipTerm(deviceId, term);
- post(store.markOffline(deviceId));
- } else {
- log.info("Failed again marking {} offline. {}", deviceId, role);
- }
- });
+ MastershipTerm term = termService
+ .getMastershipTerm(deviceId);
+ // TODO: Move this type of check inside device clock
+ // manager, etc.
+ if (term != null && localNodeId.equals(term.master())) {
+ log.info("Retry marking {} offline", deviceId);
+ deviceClockProviderService
+ .setMastershipTerm(deviceId, term);
+ post(store.markOffline(deviceId));
+ } else {
+ log.info("Failed again marking {} offline. {}",
+ deviceId, role);
+ }
+ });
} finally {
try {
- //relinquish master role and ability to be backup.
+ // relinquish master role and ability to be backup.
mastershipService.relinquishMastership(deviceId).get();
} catch (InterruptedException e) {
- log.warn("Interrupted while reliquishing role for {}", deviceId);
+ log.warn("Interrupted while reliquishing role for {}",
+ deviceId);
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
- log.error("Exception thrown while relinquishing role for {}", deviceId, e);
+ log.error("Exception thrown while relinquishing role for {}",
+ deviceId, e);
}
}
}
@@ -432,12 +450,14 @@
if (!deviceClockProviderService.isTimestampAvailable(deviceId)) {
// Never been a master for this device
// any update will be ignored.
- log.trace("Ignoring {} port updates on standby node. {}", deviceId, portDescriptions);
+ log.trace("Ignoring {} port updates on standby node. {}",
+ deviceId, portDescriptions);
return;
}
List<DeviceEvent> events = store.updatePorts(this.provider().id(),
- deviceId, portDescriptions);
+ deviceId,
+ portDescriptions);
for (DeviceEvent event : events) {
post(event);
}
@@ -453,12 +473,13 @@
if (!deviceClockProviderService.isTimestampAvailable(deviceId)) {
// Never been a master for this device
// any update will be ignored.
- log.trace("Ignoring {} port update on standby node. {}", deviceId, portDescription);
+ log.trace("Ignoring {} port update on standby node. {}",
+ deviceId, portDescription);
return;
}
- final DeviceEvent event = store.updatePortStatus(this.provider().id(),
- deviceId, portDescription);
+ final DeviceEvent event = store.updatePortStatus(this.provider()
+ .id(), deviceId, portDescription);
if (event != null) {
log.info("Device {} port {} status changed", deviceId, event
.port().number());
@@ -467,7 +488,8 @@
}
@Override
- public void receivedRoleReply(DeviceId deviceId, MastershipRole requested,
+ public void receivedRoleReply(DeviceId deviceId,
+ MastershipRole requested,
MastershipRole response) {
// Several things can happen here:
// 1. request and response match
@@ -480,43 +502,50 @@
// FIXME: implement response to this notification
log.debug("got reply to a role request for {}: asked for {}, and got {}",
- deviceId, requested, response);
+ deviceId, requested, response);
if (requested == null && response == null) {
- // something was off with DeviceProvider, maybe check channel too?
- log.warn("Failed to assert role [{}] onto Device {}", requested, deviceId);
+ // something was off with DeviceProvider, maybe check channel
+ // too?
+ log.warn("Failed to assert role [{}] onto Device {}",
+ requested, deviceId);
mastershipService.relinquishMastership(deviceId);
return;
}
if (Objects.equals(requested, response)) {
- if (Objects.equals(requested, mastershipService.getLocalRole(deviceId))) {
+ if (Objects.equals(requested,
+ mastershipService.getLocalRole(deviceId))) {
return;
} else {
return;
- // FIXME roleManager got the device to comply, but doesn't agree with
+ // FIXME roleManager got the device to comply, but doesn't
+ // agree with
// the store; use the store's view, then try to reassert.
}
} else {
// we didn't get back what we asked for. Reelect someone else.
- log.warn("Failed to assert role [{}] onto Device {}", response, deviceId);
+ log.warn("Failed to assert role [{}] onto Device {}", response,
+ deviceId);
if (response == MastershipRole.MASTER) {
mastershipService.relinquishMastership(deviceId);
// TODO: Shouldn't we be triggering event?
- //final Device device = getDevice(deviceId);
- //post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device));
+ // final Device device = getDevice(deviceId);
+ // post(new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device));
}
}
}
@Override
- public void updatePortStatistics(DeviceId deviceId, Collection<PortStatistics> portStatistics) {
+ public void updatePortStatistics(DeviceId deviceId,
+ Collection<PortStatistics> portStatistics) {
checkNotNull(deviceId, DEVICE_ID_NULL);
checkNotNull(portStatistics, "Port statistics list cannot be null");
checkValidity();
- DeviceEvent event = store.updatePortStatistics(this.provider().id(),
- deviceId, portStatistics);
+ DeviceEvent event = store
+ .updatePortStatistics(this.provider().id(), deviceId,
+ portStatistics);
post(event);
}
}
@@ -532,19 +561,20 @@
/**
* Apply role to device and send probe if MASTER.
*
- * @param deviceId device identifier
- * @param newRole new role to apply to the device
+ * @param deviceId device identifier
+ * @param newRole new role to apply to the device
* @return true if the request was sent to provider
*/
private boolean applyRoleAndProbe(DeviceId deviceId, MastershipRole newRole) {
if (newRole.equals(MastershipRole.NONE)) {
- //no-op
+ // no-op
return true;
}
DeviceProvider provider = getProvider(deviceId);
if (provider == null) {
- log.warn("Provider for {} was not found. Cannot apply role {}", deviceId, newRole);
+ log.warn("Provider for {} was not found. Cannot apply role {}",
+ deviceId, newRole);
return false;
}
provider.roleChanged(deviceId, newRole);
@@ -559,12 +589,11 @@
/**
* Reaasert role for specified device connected to this node.
*
- * @param did device identifier
- * @param nextRole role to apply. If NONE is specified,
- * it will ask mastership service for a role and apply it.
+ * @param did device identifier
+ * @param nextRole role to apply. If NONE is specified, it will ask
+ * mastership service for a role and apply it.
*/
- private void reassertRole(final DeviceId did,
- final MastershipRole nextRole) {
+ private void reassertRole(final DeviceId did, final MastershipRole nextRole) {
MastershipRole myNextRole = nextRole;
if (myNextRole == NONE) {
@@ -581,18 +610,17 @@
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);
+ // 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);
}
// TODO: should apply role only if there is mismatch
@@ -634,7 +662,8 @@
if (localNodeId.equals(event.roleInfo().master())) {
// confirm latest info
MastershipTerm term = termService.getMastershipTerm(did);
- final boolean iHaveControl = term != null && localNodeId.equals(term.master());
+ final boolean iHaveControl = term != null
+ && localNodeId.equals(term.master());
if (iHaveControl) {
deviceClockProviderService.setMastershipTerm(did, term);
myNextRole = MASTER;
@@ -647,15 +676,13 @@
myNextRole = NONE;
}
-
final boolean isReachable = isReachable(did);
if (!isReachable) {
// device is not connected to this node
if (myNextRole != NONE) {
log.warn("Node was instructed to be {} role for {}, "
+ "but this node cannot reach the device. "
- + "Relinquishing role. ",
- myNextRole, did);
+ + "Relinquishing role. ", myNextRole, did);
mastershipService.relinquishMastership(did);
}
return;
@@ -691,4 +718,34 @@
post(event);
}
}
+
+ @Override
+ public Iterable<Device> getDevices(Type type) {
+ checkPermission(Permission.DEVICE_READ);
+ Set<Device> results = new HashSet<>();
+ Iterable<Device> devices = store.getDevices();
+ if (devices != null) {
+ devices.forEach(d -> {
+ if (type.equals(d.type())) {
+ results.add(d);
+ }
+ });
+ }
+ return results;
+ }
+
+ @Override
+ public Iterable<Device> getAvailableDevices(Type type) {
+ checkPermission(Permission.DEVICE_READ);
+ Set<Device> results = new HashSet<>();
+ Iterable<Device> availableDevices = store.getAvailableDevices();
+ if (availableDevices != null) {
+ availableDevices.forEach(d -> {
+ if (type.equals(d.type())) {
+ results.add(d);
+ }
+ });
+ }
+ return results;
+ }
}