use of org.onosproject.net.device.PortDescription in project onos by opennetworkinglab.
the class GossipDeviceStore method updatePorts.
@Override
public synchronized List<DeviceEvent> updatePorts(ProviderId providerId, DeviceId deviceId, List<PortDescription> portDescriptions) {
NodeId localNode = clusterService.getLocalNode().id();
// TODO: It might be negligible, but this will have negative impact to topology discovery performance,
// since it will trigger distributed store read.
// Also, it'll probably be better if side-way communication happened on ConfigurationProvider, etc.
// outside Device subsystem. so that we don't have to modify both Device and Link stores.
// If we don't care much about topology performance, then it might be OK.
NodeId deviceNode = mastershipService.getMasterFor(deviceId);
// Process port update only if we're the master of the device,
// otherwise signal the actual master.
List<DeviceEvent> deviceEvents = null;
if (localNode.equals(deviceNode)) {
final Timestamp newTimestamp;
try {
newTimestamp = deviceClockService.getTimestamp(deviceId);
} catch (IllegalStateException e) {
log.info("Timestamp was not available for device {}", deviceId);
log.debug(" discarding {}", portDescriptions);
return Collections.emptyList();
}
log.debug("timestamp for {} {}", deviceId, newTimestamp);
final Timestamped<List<PortDescription>> timestampedInput = new Timestamped<>(portDescriptions, newTimestamp);
final Timestamped<List<PortDescription>> merged;
final Map<ProviderId, DeviceDescriptions> device = getOrCreateDeviceDescriptionsMap(deviceId);
synchronized (device) {
deviceEvents = updatePortsInternal(providerId, deviceId, timestampedInput);
final DeviceDescriptions descs = device.get(providerId);
List<PortDescription> mergedList = FluentIterable.from(portDescriptions).transform(input -> descs.getPortDesc(input.portNumber()).value()).toList();
merged = new Timestamped<>(mergedList, newTimestamp);
}
if (!deviceEvents.isEmpty()) {
log.debug("Notifying peers of a ports update topology event for providerId: {} and deviceId: {}", providerId, deviceId);
notifyPeers(new InternalPortEvent(providerId, deviceId, merged));
}
} else {
return Collections.emptyList();
}
return deviceEvents;
}
use of org.onosproject.net.device.PortDescription in project onos by opennetworkinglab.
the class GossipDeviceStore method updatePortStatusInternal.
private DeviceEvent updatePortStatusInternal(ProviderId providerId, DeviceId deviceId, Timestamped<PortDescription> deltaDesc) {
Device device = devices.get(deviceId);
checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
Map<ProviderId, DeviceDescriptions> descsMap = deviceDescs.get(deviceId);
checkArgument(descsMap != null, DEVICE_NOT_FOUND, deviceId);
synchronized (descsMap) {
if (isDeviceRemoved(deviceId, deltaDesc.timestamp())) {
log.debug("Ignoring outdated event: {}", deltaDesc);
return null;
}
DeviceDescriptions descs = descsMap.get(providerId);
// assuming all providers must to give DeviceDescription
verify(descs != null, "Device description for Device ID %s from Provider %s was not found", deviceId, providerId);
ConcurrentMap<PortNumber, Port> ports = getPortMap(deviceId);
final PortNumber number = deltaDesc.value().portNumber();
final Port oldPort = ports.get(number);
final Port newPort;
final Timestamped<PortDescription> existingPortDesc = descs.getPortDesc(number);
boolean toDelete;
if (existingPortDesc == null || deltaDesc.isNewer(existingPortDesc)) {
// on new port or valid update
// update description
descs.putPortDesc(deltaDesc);
newPort = composePort(device, number, descsMap);
toDelete = deltaDesc.value().isRemoved();
} else {
// same or outdated event, ignored.
log.trace("ignore same or outdated {} >= {}", existingPortDesc, deltaDesc);
return null;
}
if (!toDelete) {
return oldPort == null ? createPort(device, newPort, ports) : updatePort(device, oldPort, newPort, ports);
} else {
return removePort(deviceId, number, providerId, descsMap);
}
}
}
use of org.onosproject.net.device.PortDescription in project onos by opennetworkinglab.
the class DeviceDescriptions method putPortDesc.
/**
* Puts PortDescription, merging annotations as necessary.
*
* @param newDesc new PortDescription
*/
public void putPortDesc(Timestamped<PortDescription> newDesc) {
Timestamped<PortDescription> oldOne = portDescs.get(newDesc.value().portNumber());
Timestamped<PortDescription> newOne = newDesc;
if (oldOne != null) {
SparseAnnotations merged = union(oldOne.value().annotations(), newDesc.value().annotations());
newOne = new Timestamped<>(DefaultPortDescription.builder(newDesc.value()).annotations(merged).build(), newDesc.timestamp());
}
portDescs.put(newOne.value().portNumber(), newOne);
}
use of org.onosproject.net.device.PortDescription in project onos by opennetworkinglab.
the class GossipDeviceStore method handlePortStatusEvent.
private void handlePortStatusEvent(InternalPortStatusEvent event) {
ProviderId providerId = event.providerId();
DeviceId deviceId = event.deviceId();
Timestamped<PortDescription> portDescription = event.portDescription();
if (getDevice(deviceId) == null) {
log.debug("{} not found on this node yet, ignoring.", deviceId);
// Note: dropped information will be recovered by anti-entropy
return;
}
try {
notifyDelegateIfNotNull(updatePortStatusInternal(providerId, deviceId, portDescription));
} catch (Exception e) {
log.warn("Exception thrown handling port update", e);
}
}
use of org.onosproject.net.device.PortDescription in project onos by opennetworkinglab.
the class GossipDeviceStore method updatePortsInternal.
private List<DeviceEvent> updatePortsInternal(ProviderId providerId, DeviceId deviceId, Timestamped<List<PortDescription>> portDescriptions) {
Device device = devices.get(deviceId);
if (device == null) {
log.debug("Device is no longer valid: {}", deviceId);
return Collections.emptyList();
}
Map<ProviderId, DeviceDescriptions> descsMap = deviceDescs.get(deviceId);
checkArgument(descsMap != null, DEVICE_NOT_FOUND, deviceId);
List<DeviceEvent> events = new ArrayList<>();
synchronized (descsMap) {
if (isDeviceRemoved(deviceId, portDescriptions.timestamp())) {
log.debug("Ignoring outdated events: {}", portDescriptions);
return Collections.emptyList();
}
DeviceDescriptions descs = descsMap.get(providerId);
// every provider must provide DeviceDescription.
checkArgument(descs != null, "Device description for Device ID %s from Provider %s was not found", deviceId, providerId);
Map<PortNumber, Port> ports = getPortMap(deviceId);
final Timestamp newTimestamp = portDescriptions.timestamp();
// Add new ports
Set<PortNumber> processed = new HashSet<>();
for (PortDescription portDescription : portDescriptions.value()) {
final PortNumber number = portDescription.portNumber();
processed.add(number);
final Port oldPort = ports.get(number);
final Port newPort;
boolean isRemoved = portDescription.isRemoved();
final Timestamped<PortDescription> existingPortDesc = descs.getPortDesc(number);
if (existingPortDesc == null || newTimestamp.compareTo(existingPortDesc.timestamp()) >= 0) {
// on new port or valid update
// update description
descs.putPortDesc(new Timestamped<>(portDescription, portDescriptions.timestamp()));
newPort = composePort(device, number, descsMap);
} else {
// outdated event, ignored.
continue;
}
if (isRemoved && oldPort != null) {
events.add(removePort(deviceId, oldPort.number(), providerId, descsMap));
} else if (!isRemoved) {
events.add(oldPort == null ? createPort(device, newPort, ports) : updatePort(device, oldPort, newPort, ports));
}
}
events.addAll(pruneOldPorts(device, ports, processed));
}
return FluentIterable.from(events).filter(notNull()).toList();
}
Aggregations