Naoki Shiota
Committed by Gerrit Code Review

bug fix: ResourceManager#unregisterResources only unregisters given resources an…

…d didn't unregister descendants (ONOS-3827).

Change-Id: I48956234553053e2a54834129b5f10357ca116ea
......@@ -41,10 +41,13 @@ import org.onosproject.net.newresource.ResourceAdminService;
import org.onosproject.net.newresource.BandwidthCapacity;
import org.onosproject.net.newresource.Resource;
import org.onosproject.net.newresource.Resources;
import org.onosproject.net.newresource.ResourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
......@@ -60,6 +63,7 @@ final class ResourceDeviceListener implements DeviceListener {
private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
private final ResourceAdminService adminService;
private final ResourceService resourceService;
private final DeviceService deviceService;
private final DriverService driverService;
private final NetworkConfigService netcfgService;
......@@ -75,9 +79,11 @@ final class ResourceDeviceListener implements DeviceListener {
* @param netcfgService {@link NetworkConfigService} to be used.
* @param executor executor used for processing resource registration
*/
ResourceDeviceListener(ResourceAdminService adminService, DeviceService deviceService, DriverService driverService,
ResourceDeviceListener(ResourceAdminService adminService, ResourceService resourceService,
DeviceService deviceService, DriverService driverService,
NetworkConfigService netcfgService, ExecutorService executor) {
this.adminService = checkNotNull(adminService);
this.resourceService = checkNotNull(resourceService);
this.deviceService = checkNotNull(deviceService);
this.driverService = checkNotNull(driverService);
this.netcfgService = checkNotNull(netcfgService);
......@@ -123,7 +129,11 @@ final class ResourceDeviceListener implements DeviceListener {
}
private void unregisterDeviceResource(Device device) {
executor.submit(() -> adminService.unregisterResources(Resources.discrete(device.id()).resource()));
executor.submit(() -> {
Resource devResource = Resources.discrete(device.id()).resource();
List<Resource> allResources = getDescendantResources(devResource);
adminService.unregisterResources(allResources);
});
}
private void registerPortResource(Device device, Port port) {
......@@ -175,8 +185,30 @@ final class ResourceDeviceListener implements DeviceListener {
}
private void unregisterPortResource(Device device, Port port) {
Resource resource = Resources.discrete(device.id(), port.number()).resource();
executor.submit(() -> adminService.unregisterResources(resource));
executor.submit(() -> {
Resource portResource = Resources.discrete(device.id(), port.number()).resource();
List<Resource> allResources = getDescendantResources(portResource);
adminService.unregisterResources(allResources);
});
}
// Returns list of all descendant resources of given resource, including itself.
private List<Resource> getDescendantResources(Resource parent) {
LinkedList<Resource> allResources = new LinkedList<>();
allResources.add(parent);
Set<Resource> nextResources = resourceService.getRegisteredResources(parent);
while (!nextResources.isEmpty()) {
Set<Resource> currentResources = nextResources;
// resource list should be ordered from leaf to root
allResources.addAll(0, currentResources);
nextResources = currentResources.stream()
.flatMap(r -> resourceService.getRegisteredResources(r).stream())
.collect(Collectors.toSet());
}
return allResources;
}
/**
......
......@@ -32,6 +32,7 @@ import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.newresource.BandwidthCapacity;
import org.onosproject.net.newresource.ResourceAdminService;
import org.onosproject.net.newresource.ResourceService;
import org.slf4j.Logger;
import java.util.List;
......@@ -53,6 +54,9 @@ public final class ResourceRegistrar {
protected ResourceAdminService adminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ResourceService resourceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DriverService driverService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -87,7 +91,8 @@ public final class ResourceRegistrar {
cfgListener = new ResourceNetworkConfigListener(adminService, cfgRegistry, executor);
cfgRegistry.addListener(cfgListener);
deviceListener = new ResourceDeviceListener(adminService, deviceService, driverService, cfgRegistry, executor);
deviceListener = new ResourceDeviceListener(adminService, resourceService,
deviceService, driverService, cfgRegistry, executor);
deviceService.addListener(deviceListener);
// TODO Attempt initial registration of existing resources?
......