[SDFAB-355] Revisit MeterService and north abstractions
Change-Id: I685cb90d53f8aa61017ecda9fa7ff842e58e2940
diff --git a/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java b/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java
index 805009d..9b786e5 100644
--- a/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java
+++ b/core/net/src/main/java/org/onosproject/net/meter/impl/MeterManager.java
@@ -34,7 +34,7 @@
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.meter.DefaultMeter;
import org.onosproject.net.meter.Meter;
-import org.onosproject.net.meter.MeterCellId.MeterCellType;
+import org.onosproject.net.meter.MeterCellId;
import org.onosproject.net.meter.MeterEvent;
import org.onosproject.net.meter.MeterFailReason;
import org.onosproject.net.meter.MeterFeatures;
@@ -46,6 +46,7 @@
import org.onosproject.net.meter.MeterProviderRegistry;
import org.onosproject.net.meter.MeterProviderService;
import org.onosproject.net.meter.MeterRequest;
+import org.onosproject.net.meter.MeterScope;
import org.onosproject.net.meter.MeterService;
import org.onosproject.net.meter.MeterState;
import org.onosproject.net.meter.MeterStore;
@@ -53,6 +54,8 @@
import org.onosproject.net.meter.MeterStoreResult;
import org.onosproject.net.provider.AbstractListenerProviderRegistry;
import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.pi.model.PiMeterId;
+import org.onosproject.net.pi.runtime.PiMeterCellId;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
@@ -252,13 +255,24 @@
@Override
public Meter submit(MeterRequest request) {
checkNotNull(request, "request cannot be null.");
- // Allocate an id and then submit the request
- MeterId id = allocateMeterId(request.deviceId());
+ MeterCellId cellId;
+ if (request.index().isPresent()) {
+ // User provides index
+ if (request.scope().isGlobal()) {
+ cellId = MeterId.meterId(request.index().get());
+ } else {
+ cellId = PiMeterCellId.ofIndirect(
+ PiMeterId.of(request.scope().id()), request.index().get());
+ }
+ } else {
+ // Allocate an id
+ cellId = allocateMeterId(request.deviceId(), request.scope());
+ }
Meter.Builder mBuilder = DefaultMeter.builder()
.forDevice(request.deviceId())
.fromApp(request.appId())
.withBands(request.bands())
- .withCellId(id)
+ .withCellId(cellId)
.withUnit(request.unit());
if (request.isBurst()) {
mBuilder.burst();
@@ -277,12 +291,17 @@
@Override
public void withdraw(MeterRequest request, MeterId meterId) {
+ withdraw(request, (MeterCellId) meterId);
+ }
+
+ @Override
+ public void withdraw(MeterRequest request, MeterCellId meterCellId) {
checkNotNull(request, "request cannot be null.");
Meter.Builder mBuilder = DefaultMeter.builder()
.forDevice(request.deviceId())
.fromApp(request.appId())
.withBands(request.bands())
- .withCellId(meterId)
+ .withCellId(meterCellId)
.withUnit(request.unit());
if (request.isBurst()) {
@@ -299,6 +318,11 @@
@Override
public Meter getMeter(DeviceId deviceId, MeterId id) {
+ return getMeter(deviceId, (MeterCellId) id);
+ }
+
+ @Override
+ public Meter getMeter(DeviceId deviceId, MeterCellId id) {
MeterKey key = MeterKey.key(deviceId, id);
return store.getMeter(key);
}
@@ -320,6 +344,10 @@
return store.allocateMeterId(deviceId);
}
+ private MeterCellId allocateMeterId(DeviceId deviceId, MeterScope scope) {
+ return store.allocateMeterId(deviceId, scope);
+ }
+
@Override
public void freeMeterId(DeviceId deviceId, MeterId meterId) {
// We delegate directly to the store
@@ -361,14 +389,14 @@
// Each update on the store is reflected on this collection
Collection<Meter> allMeters = store.getAllMeters(deviceId);
- Map<MeterId, Meter> meterEntriesMap = meterEntries.stream()
- .collect(Collectors.toMap(Meter::id, Meter -> Meter));
+ Map<MeterCellId, Meter> meterEntriesMap = meterEntries.stream()
+ .collect(Collectors.toMap(Meter::meterCellId, Meter -> Meter));
// Look for meters defined in onos and missing in the device (restore)
allMeters.stream().forEach(m -> {
if ((m.state().equals(MeterState.PENDING_ADD) ||
m.state().equals(MeterState.ADDED)) &&
- !meterEntriesMap.containsKey(m.id())) {
+ !meterEntriesMap.containsKey(m.meterCellId())) {
// The meter is missing in the device. Reinstall!
log.debug("Adding meter missing in device {} {}", deviceId, m);
// offload the task to avoid the overloading of the sb threads
@@ -378,27 +406,21 @@
// Look for meters defined in the device and not in onos (remove)
meterEntriesMap.entrySet().stream()
- .filter(md -> !allMeters.stream().anyMatch(m -> m.id().equals(md.getKey())))
+ .filter(md -> !allMeters.stream().anyMatch(m -> m.meterCellId().equals(md.getKey())))
.forEach(mio -> {
Meter meter = mio.getValue();
- // FIXME: Removing a meter is meaningful for OpenFlow, but not for P4Runtime.
- // In P4Runtime meter cells cannot be removed. For the
- // moment, we make the distinction between OpenFlow and
- // P4Runtime by looking at the MeterCellType (always
- // INDEX for OpenFlow).
- if (meter.meterCellId().type() == MeterCellType.INDEX) {
- // The meter is missing in onos. Uninstall!
- log.debug("Remove meter in device not in onos {} {}", deviceId, mio.getKey());
- // offload the task to avoid the overloading of the sb threads
- meterInstallers.execute(new MeterInstaller(deviceId, meter, MeterOperation.Type.REMOVE));
- }
+ // The meter is missing in onos. Uninstall!
+ log.debug("Remove meter in device not in onos {} {}", deviceId, mio.getKey());
+ // offload the task to avoid the overloading of the sb threads
+ meterInstallers.execute(new MeterInstaller(deviceId, meter, MeterOperation.Type.REMOVE));
});
// Update the meter stats in the store (first time move the state from pending to added)
Collection<Meter> addedMeters = Sets.newHashSet();
meterEntries.stream()
.filter(m -> allMeters.stream()
- .anyMatch(sm -> sm.deviceId().equals(deviceId) && sm.id().equals(m.id())))
+ .anyMatch(sm -> sm.deviceId().equals(deviceId) &&
+ sm.meterCellId().equals(m.meterCellId())))
.forEach(m -> {
Meter updatedMeter = store.updateMeterState(m);
if (updatedMeter != null && updatedMeter.state() == MeterState.ADDED) {
@@ -409,20 +431,13 @@
newAllMeters.removeAll(addedMeters);
newAllMeters.forEach(m -> {
- // FIXME: Installing a meter is meaningful for OpenFlow, but not for P4Runtime.
- // It looks like this flow is used only for p4runtime to emulate the installation
- // since meters are already instantiated - we need just modify the params.
- if (m.state() == MeterState.PENDING_ADD && m.meterCellId().type() != MeterCellType.INDEX) {
- // offload the task to avoid the overloading of the sb threads
- log.debug("Modify meter {} in device {}", m.id(), deviceId);
- meterInstallers.execute(new MeterInstaller(m.deviceId(), m, MeterOperation.Type.MODIFY));
// Remove workflow. Regarding OpenFlow, meters have been removed from
// the device but they are still in the store, we will purge them definitely.
// Instead, P4Runtime devices will not remove the meter. The first workaround
// for P4Runtime will avoid to send a remove op. Then, we reach this point
// and we purge the meter from the store
- } else if (m.state() == MeterState.PENDING_REMOVE) {
- log.debug("Delete meter {} now in store", m.id());
+ if (m.state() == MeterState.PENDING_REMOVE) {
+ log.debug("Delete meter {} now in store", m.meterCellId());
store.purgeMeter(m);
}
});
@@ -498,7 +513,7 @@
NodeId master = mastershipService.getMasterFor(meter.deviceId());
if (!Objects.equals(local, master)) {
log.trace("Not the master of device {}, skipping installation of the meter {}",
- meter.deviceId(), meter.id());
+ meter.deviceId(), meter.meterCellId());
return;
}
MeterProvider p = getProvider(this.deviceId);
@@ -511,7 +526,7 @@
@Override
public int hint() {
- return meter.id().hashCode();
+ return meter.meterCellId().hashCode();
}
}