Implement an option in CPRM to reprogram the flows when device reconnecting
Also remove unused AsyncDeviceFetcher in FibInstaller
Change-Id: I52e778a51854efd6bfe47c56569efa5c27d7c7fb
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/Router.java b/apps/routing-api/src/main/java/org/onosproject/routing/Router.java
index 97fee88..855084e 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/Router.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/Router.java
@@ -53,9 +53,9 @@
private InterfaceService interfaceService;
private InterfaceListener listener = new InternalInterfaceListener();
- private AsyncDeviceFetcher asyncDeviceFetcher;
+ private DeviceService deviceService;
- private volatile boolean deviceAvailable = false;
+ private AsyncDeviceFetcher asyncDeviceFetcher;
/**
* Creates a new router interface manager.
@@ -65,27 +65,26 @@
* @param deviceService device service
* @param provisioner consumer that will provision new interfaces
* @param unprovisioner consumer that will unprovision old interfaces
+ * @param forceUnprovision force unprovision when the device goes offline
*/
public Router(RouterInfo info,
InterfaceService interfaceService,
DeviceService deviceService,
Consumer<InterfaceProvisionRequest> provisioner,
- Consumer<InterfaceProvisionRequest> unprovisioner) {
+ Consumer<InterfaceProvisionRequest> unprovisioner,
+ boolean forceUnprovision) {
this.info = checkNotNull(info);
this.provisioner = checkNotNull(provisioner);
this.unprovisioner = checkNotNull(unprovisioner);
this.interfaceService = checkNotNull(interfaceService);
+ this.deviceService = checkNotNull(deviceService);
this.asyncDeviceFetcher = AsyncDeviceFetcher.create(deviceService);
- asyncDeviceFetcher.getDevice(info.deviceId())
- .thenAccept(deviceId1 -> {
- deviceAvailable = true;
- provision();
- }).whenComplete((v, t) -> {
- if (t != null) {
- log.error("Error provisioning: ", t);
- }
- });
+ if (forceUnprovision) {
+ asyncDeviceFetcher.registerCallback(info.deviceId(), this::provision, this::forceUnprovision);
+ } else {
+ asyncDeviceFetcher.registerCallback(info.deviceId(), this::provision, null);
+ }
interfaceService.addListener(listener);
}
@@ -94,6 +93,8 @@
* Cleans up the router and unprovisions all interfaces.
*/
public void cleanup() {
+ asyncDeviceFetcher.shutdown();
+
interfaceService.removeListener(listener);
unprovision();
@@ -112,8 +113,15 @@
* Changes the router configuration.
*
* @param newConfig new configuration
+ * @param forceUnprovision true if we want to force unprovision the device when it goes offline
*/
- public void changeConfiguration(RouterInfo newConfig) {
+ public void changeConfiguration(RouterInfo newConfig, boolean forceUnprovision) {
+ if (forceUnprovision) {
+ asyncDeviceFetcher.registerCallback(info.deviceId(), this::provision, this::forceUnprovision);
+ } else {
+ asyncDeviceFetcher.registerCallback(info.deviceId(), this::provision, null);
+ }
+
Set<String> oldConfiguredInterfaces = info.interfaces();
info = newConfig;
Set<String> newConfiguredInterfaces = info.interfaces();
@@ -153,18 +161,21 @@
private void provision() {
getInterfacesForDevice(info.deviceId())
- .filter(this::shouldProvision)
.forEach(this::provision);
}
private void unprovision() {
getInterfacesForDevice(info.deviceId())
- .filter(this::shouldProvision)
.forEach(this::unprovision);
}
+ private void forceUnprovision() {
+ getInterfacesForDevice(info.deviceId())
+ .forEach(this::forceUnprovision);
+ }
+
private void provision(Interface intf) {
- if (!provisioned.contains(intf) && shouldProvision(intf)) {
+ if (!provisioned.contains(intf) && deviceAvailable(intf) && shouldProvision(intf)) {
log.info("Provisioning interface {}", intf);
provisioner.accept(InterfaceProvisionRequest.of(info, intf));
provisioned.add(intf);
@@ -172,16 +183,28 @@
}
private void unprovision(Interface intf) {
- if (provisioned.contains(intf)) {
+ if (provisioned.contains(intf) && deviceAvailable(intf) && shouldProvision(intf)) {
log.info("Unprovisioning interface {}", intf);
unprovisioner.accept(InterfaceProvisionRequest.of(info, intf));
provisioned.remove(intf);
}
}
+ private void forceUnprovision(Interface intf) {
+ // Skip availability check when force unprovisioning an interface
+ if (provisioned.contains(intf) && shouldProvision(intf)) {
+ log.info("Unprovisioning interface {}", intf);
+ unprovisioner.accept(InterfaceProvisionRequest.of(info, intf));
+ provisioned.remove(intf);
+ }
+ }
+
+ private boolean deviceAvailable(Interface intf) {
+ return deviceService.isAvailable(intf.connectPoint().deviceId());
+ }
+
private boolean shouldProvision(Interface intf) {
- return deviceAvailable &&
- (info.interfaces().isEmpty() || info.interfaces().contains(intf.name()));
+ return info.interfaces().isEmpty() || info.interfaces().contains(intf.name());
}
private Stream<Interface> getInterfacesForDevice(DeviceId deviceId) {