Trigger pipeconf deploy right after registration
Without waiting for the next pipeconf watchdog periodic probe.
To support this, this patch extends the PiPipeconfService to advertise
pipeconf registration events.
Change-Id: Ib44f1813bd37083c666a5e7980de320ce469c2d2
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java
index 3070d66..8fdbfc8 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfManager.java
@@ -23,6 +23,7 @@
import org.onlab.util.HexString;
import org.onlab.util.ItemNotFoundException;
import org.onlab.util.SharedExecutors;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.basics.BasicDeviceConfig;
@@ -36,6 +37,8 @@
import org.onosproject.net.driver.DriverProvider;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipeconfId;
+import org.onosproject.net.pi.service.PiPipeconfEvent;
+import org.onosproject.net.pi.service.PiPipeconfListener;
import org.onosproject.net.pi.service.PiPipeconfMappingStore;
import org.onosproject.net.pi.service.PiPipeconfService;
import org.osgi.service.component.annotations.Activate;
@@ -68,7 +71,9 @@
*/
@Component(immediate = true, service = PiPipeconfService.class)
@Beta
-public class PiPipeconfManager implements PiPipeconfService {
+public class PiPipeconfManager
+ extends AbstractListenerManager<PiPipeconfEvent, PiPipeconfListener>
+ implements PiPipeconfService {
private final Logger log = getLogger(getClass());
@@ -100,6 +105,7 @@
@Activate
public void activate() {
driverAdminService.addListener(driverListener);
+ eventDispatcher.addSink(PiPipeconfEvent.class, listenerRegistry);
checkMissingMergedDrivers();
if (!missingMergedDrivers.isEmpty()) {
// Missing drivers should be created upon detecting registration
@@ -114,6 +120,7 @@
@Deactivate
public void deactivate() {
+ eventDispatcher.removeSink(PiPipeconfEvent.class);
executor.shutdown();
driverAdminService.removeListener(driverListener);
pipeconfs.clear();
@@ -133,10 +140,11 @@
log.info("New pipeconf registered: {} (fingerprint={})",
pipeconf.id(), HexString.toHexString(pipeconf.fingerprint()));
executor.execute(() -> attemptMergeAll(pipeconf.id()));
+ post(new PiPipeconfEvent(PiPipeconfEvent.Type.REGISTERED, pipeconf));
}
@Override
- public void remove(PiPipeconfId pipeconfId) throws IllegalStateException {
+ public void unregister(PiPipeconfId pipeconfId) throws IllegalStateException {
checkNotNull(pipeconfId);
// TODO add mechanism to remove from device.
if (!pipeconfs.containsKey(pipeconfId)) {
@@ -147,6 +155,7 @@
final PiPipeconf pipeconf = pipeconfs.remove(pipeconfId);
log.info("Unregistered pipeconf: {} (fingerprint={})",
pipeconfId, HexString.toHexString(pipeconf.fingerprint()));
+ post(new PiPipeconfEvent(PiPipeconfEvent.Type.UNREGISTERED, pipeconfId));
}
@Override
diff --git a/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfWatchdogManager.java b/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfWatchdogManager.java
index e76d673..21df778 100644
--- a/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfWatchdogManager.java
+++ b/core/net/src/main/java/org/onosproject/net/pi/impl/PiPipeconfWatchdogManager.java
@@ -35,6 +35,8 @@
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipeconfId;
+import org.onosproject.net.pi.service.PiPipeconfEvent;
+import org.onosproject.net.pi.service.PiPipeconfListener;
import org.onosproject.net.pi.service.PiPipeconfMappingStore;
import org.onosproject.net.pi.service.PiPipeconfService;
import org.onosproject.net.pi.service.PiPipeconfWatchdogEvent;
@@ -57,6 +59,7 @@
import java.util.Dictionary;
import java.util.Map;
+import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
@@ -75,11 +78,11 @@
* pipeline.
*/
@Component(
- immediate = true,
- service = PiPipeconfWatchdogService.class,
- property = {
- PWM_PROBE_INTERVAL + ":Integer=" + PWM_PROBE_INTERVAL_DEFAULT
- }
+ immediate = true,
+ service = PiPipeconfWatchdogService.class,
+ property = {
+ PWM_PROBE_INTERVAL + ":Integer=" + PWM_PROBE_INTERVAL_DEFAULT
+ }
)
public class PiPipeconfWatchdogManager
extends AbstractListenerManager<PiPipeconfWatchdogEvent, PiPipeconfWatchdogListener>
@@ -107,13 +110,16 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
private ComponentConfigService componentConfigService;
- /** Configure interval in seconds for device pipeconf probing. */
+ /**
+ * Configure interval in seconds for device pipeconf probing.
+ */
private int probeInterval = PWM_PROBE_INTERVAL_DEFAULT;
protected ExecutorService executor = Executors.newFixedThreadPool(
30, groupedThreads("onos/pipeconf-watchdog", "%d", log));
- private final InternalDeviceListener deviceListener = new InternalDeviceListener();
+ private final DeviceListener deviceListener = new InternalDeviceListener();
+ private final PiPipeconfListener pipeconfListener = new InternalPipeconfListener();
private Timer timer;
private TimerTask task;
@@ -141,8 +147,9 @@
// Start periodic watchdog task.
timer = new Timer();
startProbeTask();
- // Add device listener.
+ // Add listeners.
deviceService.addListener(deviceListener);
+ pipeconfService.addListener(pipeconfListener);
log.info("Started");
}
@@ -167,6 +174,7 @@
@Deactivate
public void deactivate() {
eventDispatcher.removeSink(PiPipeconfWatchdogEvent.class);
+ pipeconfService.removeListener(pipeconfListener);
deviceService.removeListener(deviceListener);
stopProbeTask();
timer = null;
@@ -205,7 +213,8 @@
}
if (!pipeconfService.getPipeconf(pipeconfId).isPresent()) {
- log.error("Pipeconf {} is not registered", pipeconfId);
+ log.warn("Pipeconf {} is not registered, skipping probe for {}",
+ pipeconfId, device.id());
return;
}
@@ -356,6 +365,19 @@
}
}
+ private class InternalPipeconfListener implements PiPipeconfListener {
+ @Override
+ public void event(PiPipeconfEvent event) {
+ pipeconfMappingStore.getDevices(event.subject())
+ .forEach(PiPipeconfWatchdogManager.this::triggerProbe);
+ }
+
+ @Override
+ public boolean isRelevant(PiPipeconfEvent event) {
+ return Objects.equals(event.type(), PiPipeconfEvent.Type.REGISTERED);
+ }
+ }
+
private class StatusMapListener
implements EventuallyConsistentMapListener<DeviceId, PipelineStatus> {
diff --git a/core/net/src/test/java/org/onosproject/net/pi/impl/PiPipeconfManagerTest.java b/core/net/src/test/java/org/onosproject/net/pi/impl/PiPipeconfManagerTest.java
index 6dd861d..5cab502 100644
--- a/core/net/src/test/java/org/onosproject/net/pi/impl/PiPipeconfManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/pi/impl/PiPipeconfManagerTest.java
@@ -24,6 +24,7 @@
import org.junit.Before;
import org.junit.Test;
import org.onlab.util.ItemNotFoundException;
+import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.ConfigApplyDelegate;
@@ -55,7 +56,9 @@
import java.util.Set;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
import static org.onosproject.pipelines.basic.PipeconfLoader.BASIC_PIPECONF;
@@ -82,49 +85,50 @@
//Services
- private PiPipeconfManager piPipeconfService;
- private PiPipeconf piPipeconf;
+ private PiPipeconfManager mgr;
+ private PiPipeconf pipeconf;
@Before
public void setUp() throws IOException {
- piPipeconfService = new PiPipeconfManager();
- piPipeconf = BASIC_PIPECONF;
- piPipeconfService.cfgService = cfgService;
- piPipeconfService.driverAdminService = driverAdminService;
+ mgr = new PiPipeconfManager();
+ pipeconf = BASIC_PIPECONF;
+ mgr.cfgService = cfgService;
+ mgr.driverAdminService = driverAdminService;
+ injectEventDispatcher(mgr, new TestEventDispatcher());
ObjectMapper mapper = new ObjectMapper();
ConfigApplyDelegate delegate = new MockDelegate();
String keyBasic = "basic";
JsonNode jsonNodeBasic = mapper.readTree(jsonStreamBasic);
basicDeviceConfig.init(DEVICE_ID, keyBasic, jsonNodeBasic, mapper, delegate);
- piPipeconfService.activate();
+ mgr.activate();
}
@Test
public void activate() {
- assertEquals("Incorrect driver admin service", driverAdminService, piPipeconfService.driverAdminService);
- assertEquals("Incorrect driverAdminService service", driverAdminService, piPipeconfService.driverAdminService);
- assertEquals("Incorrect configuration service", cfgService, piPipeconfService.cfgService);
+ assertEquals("Incorrect driver admin service", driverAdminService, mgr.driverAdminService);
+ assertEquals("Incorrect driverAdminService service", driverAdminService, mgr.driverAdminService);
+ assertEquals("Incorrect configuration service", cfgService, mgr.cfgService);
}
@Test
public void deactivate() {
- piPipeconfService.deactivate();
- assertEquals("Incorrect driver admin service", null, piPipeconfService.driverAdminService);
- assertEquals("Incorrect driverAdminService service", null, piPipeconfService.driverAdminService);
- assertEquals("Incorrect configuration service", null, piPipeconfService.cfgService);
+ mgr.deactivate();
+ assertNull("Incorrect driver admin service", mgr.driverAdminService);
+ assertNull("Incorrect driverAdminService service", mgr.driverAdminService);
+ assertNull("Incorrect configuration service", mgr.cfgService);
}
@Test
public void register() {
- piPipeconfService.register(piPipeconf);
- assertTrue("PiPipeconf should be registered", piPipeconfService.pipeconfs.containsValue(piPipeconf));
+ mgr.register(pipeconf);
+ assertTrue("PiPipeconf should be registered", mgr.pipeconfs.containsValue(pipeconf));
}
@Test
public void getPipeconf() {
- piPipeconfService.register(piPipeconf);
- assertEquals("Returned PiPipeconf is not correct", piPipeconf,
- piPipeconfService.getPipeconf(piPipeconf.id()).get());
+ mgr.register(pipeconf);
+ assertEquals("Returned PiPipeconf is not correct", pipeconf,
+ mgr.getPipeconf(pipeconf.id()).get());
}
@@ -132,29 +136,29 @@
public void mergeDriver() {
PiPipeconfId piPipeconfId = new PiPipeconfId(cfgService.getConfig(
DEVICE_ID, BasicDeviceConfig.class).pipeconf());
- assertEquals(piPipeconf.id(), piPipeconfId);
+ assertEquals(pipeconf.id(), piPipeconfId);
String baseDriverName = cfgService.getConfig(DEVICE_ID, BasicDeviceConfig.class).driver();
assertEquals(BASE_DRIVER, baseDriverName);
- piPipeconfService.register(piPipeconf);
- assertEquals("Returned PiPipeconf is not correct", piPipeconf,
- piPipeconfService.getPipeconf(piPipeconf.id()).get());
+ mgr.register(pipeconf);
+ assertEquals("Returned PiPipeconf is not correct", pipeconf,
+ mgr.getPipeconf(pipeconf.id()).get());
- String mergedDriverName = piPipeconfService.getMergedDriver(DEVICE_ID, piPipeconfId);
+ String mergedDriverName = mgr.getMergedDriver(DEVICE_ID, piPipeconfId);
String expectedName = BASE_DRIVER + ":" + piPipeconfId.id();
assertEquals(expectedName, mergedDriverName);
//we assume that the provider is 1 and that it contains 1 driver
//we also assume that everything after driverAdminService.registerProvider(provider); has been tested.
- assertTrue("Provider should be registered", providers.size() == 1);
+ assertEquals("Provider should be registered", 1, providers.size());
assertTrue("Merged driver name should be valid",
mergedDriverName != null && !mergedDriverName.isEmpty());
DriverProvider provider = providers.iterator().next();
- assertTrue("Provider should contain one driver", provider.getDrivers().size() == 1);
+ assertEquals("Provider should contain one driver", 1, provider.getDrivers().size());
Driver driver = provider.getDrivers().iterator().next();