[SDFAB-352][SDFAB-353] Retrieve MeterFeatures from the P4RT southbound, Extend MeterProviderService and revisit MeterStore
Change-Id: If0dae53643988cb551ff5020abd792cb6d33ff6b
diff --git a/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterFeatures.java b/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterFeatures.java
index bd5d998..3806250 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterFeatures.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/DefaultMeterFeatures.java
@@ -22,6 +22,7 @@
import java.util.HashSet;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
@@ -29,7 +30,8 @@
*/
public final class DefaultMeterFeatures implements MeterFeatures {
private DeviceId deviceId;
- private long maxMeter;
+ private long startIndex;
+ private long endIndex;
private Set<Band.Type> bandTypes;
private Set<Meter.Unit> units;
private boolean burst;
@@ -37,13 +39,16 @@
private short maxBands;
private short maxColor;
private Set<MeterFeaturesFlag> features;
+ private MeterScope scope;
- private DefaultMeterFeatures(DeviceId did, long maxMeter,
+ private DefaultMeterFeatures(DeviceId did, long startIndex, long endIndex,
Set<Band.Type> bandTypes, Set<Meter.Unit> units,
boolean burst, boolean stats,
- short maxBands, short maxColor, Set<MeterFeaturesFlag> flag) {
+ short maxBands, short maxColor, Set<MeterFeaturesFlag> flag,
+ MeterScope scope) {
this.deviceId = did;
- this.maxMeter = maxMeter;
+ this.startIndex = startIndex;
+ this.endIndex = endIndex;
this.bandTypes = bandTypes;
this.burst = burst;
this.stats = stats;
@@ -51,6 +56,7 @@
this.maxBands = maxBands;
this.maxColor = maxColor;
this.features = flag;
+ this.scope = scope;
}
@Override
@@ -60,7 +66,18 @@
@Override
public long maxMeter() {
- return maxMeter;
+ // For OpenFlow meter, return end index as maxMeter
+ return scope.isGlobal() ? endIndex + 1 : endIndex - startIndex + 1;
+ }
+
+ @Override
+ public long startIndex() {
+ return startIndex;
+ }
+
+ @Override
+ public long endIndex() {
+ return endIndex;
}
@Override
@@ -98,6 +115,11 @@
return features;
}
+ @Override
+ public MeterScope scope() {
+ return scope;
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -111,13 +133,15 @@
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("deviceId", deviceId())
- .add("maxMeter", maxMeter())
+ .add("startIndex", startIndex())
+ .add("endIndex", endIndex())
.add("maxBands", maxBands())
.add("maxColor", maxColor())
.add("bands", bandTypes())
.add("burst", isBurstSupported())
.add("stats", isStatsSupported())
.add("units", unitTypes())
+ .add("scope", scope())
.toString();
}
@@ -127,6 +151,8 @@
public static final class Builder implements MeterFeatures.Builder {
private DeviceId did;
private long mmeter = 0L;
+ private long starti = -1L;
+ private long endi = -1L;
private short mbands = 0;
private short mcolors = 0;
private Set<Band.Type> bandTypes = new HashSet<>();
@@ -134,6 +160,7 @@
private boolean burst = false;
private boolean stats = false;
private Set<MeterFeaturesFlag> features = Sets.newHashSet();
+ private MeterScope mscope = MeterScope.globalScope();
@Override
public MeterFeatures.Builder forDevice(DeviceId deviceId) {
@@ -148,6 +175,18 @@
}
@Override
+ public MeterFeatures.Builder withStartIndex(long startIndex) {
+ starti = startIndex;
+ return this;
+ }
+
+ @Override
+ public MeterFeatures.Builder withEndIndex(long endIndex) {
+ endi = endIndex;
+ return this;
+ }
+
+ @Override
public MeterFeatures.Builder withMaxBands(short maxBands) {
mbands = maxBands;
return this;
@@ -190,9 +229,33 @@
}
@Override
+ public MeterFeatures.Builder withScope(MeterScope scope) {
+ mscope = scope;
+ return this;
+ }
+
+ @Override
public MeterFeatures build() {
+ // In case some functions are using maxMeter
+ // and both indexes are not set
+ // Start index will be
+ // 1, if it is global scope (An OpenFlow meter)
+ // 0, for the rest (A P4RT meter)
+ if (mmeter != 0L && starti == -1L && endi == -1L) {
+ starti = mscope.isGlobal() ? 1 : 0;
+ endi = mmeter - 1;
+ }
+ // If one of the index is unset/unvalid value, treated as no meter features
+ if (starti <= -1 || endi <= -1) {
+ starti = -1;
+ endi = -1;
+ }
+
checkNotNull(did, "Must specify a device");
- return new DefaultMeterFeatures(did, mmeter, bandTypes, units1, burst, stats, mbands, mcolors, features);
+ checkArgument(starti <= endi, "Start index must be less than or equal to end index");
+
+ return new DefaultMeterFeatures(did, starti, endi, bandTypes, units1, burst,
+ stats, mbands, mcolors, features, mscope);
}
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterFeatures.java b/core/api/src/main/java/org/onosproject/net/meter/MeterFeatures.java
index 2749687..ff846eb 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterFeatures.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterFeatures.java
@@ -35,10 +35,26 @@
* Returns the maximum number of meters accepted by the device.
*
* @return the maximum meter value.
+ * @deprecated in onos-2.5 replaced by {@link #startIndex()} and {@link #endIndex()}
*/
+ @Deprecated
long maxMeter();
/**
+ * Returns the start index (inclusive) of the meters.
+ *
+ * @return the start index
+ */
+ long startIndex();
+
+ /**
+ * Returns the end index (inclusive) of the meters.
+ *
+ * @return the end index
+ */
+ long endIndex();
+
+ /**
* Returns band types supported.
*
* @return the band types supported.
@@ -89,6 +105,13 @@
Set<MeterFeaturesFlag> features();
/**
+ * Returns Meter Scope.
+ *
+ * @return meter scope
+ */
+ MeterScope scope();
+
+ /**
* A meter features builder.
*/
interface Builder {
@@ -105,10 +128,28 @@
*
* @param maxMeter the maximum meters available
* @return this builder
+ * @deprecated in onos-2.5 replaced by {@link #withStartIndex(long)} and {@link #withEndIndex(long)}
*/
+ @Deprecated
Builder withMaxMeters(long maxMeter);
/**
+ * Assigns the start index (inclusive) for this meter features.
+ *
+ * @param startIndex the start index
+ * @return this builder
+ */
+ Builder withStartIndex(long startIndex);
+
+ /**
+ * Assigns the end index (inclusive) for this meter features.
+ *
+ * @param endIndex the end index
+ * @return this builder
+ */
+ Builder withEndIndex(long endIndex);
+
+ /**
* Assigns the max bands value for this meter features.
*
* @param maxBands the maximum bands available.
@@ -165,6 +206,14 @@
Builder withFeatures(Set<MeterFeaturesFlag> featureFlags);
/**
+ * Assigns the meter scope.
+ *
+ * @param scope the scope
+ * @return this builder
+ */
+ Builder withScope(MeterScope scope);
+
+ /**
* Builds the Meter Features based on the specified parameters.
*
* @return the meter features
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterFeaturesKey.java b/core/api/src/main/java/org/onosproject/net/meter/MeterFeaturesKey.java
index fa19a5f..2b5eb07 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterFeaturesKey.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterFeaturesKey.java
@@ -23,7 +23,9 @@
* A meter features key represents a meter features uniquely.
* Right now only deviceId is used but this class might be useful in
* virtualization in which a unique deviceId could have multiple features (guess).
+ * @deprecated in onos-2.5 replaced by {@link MeterTableKey}
*/
+@Deprecated
public final class MeterFeaturesKey {
private final DeviceId deviceId;
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterKey.java b/core/api/src/main/java/org/onosproject/net/meter/MeterKey.java
index 8c528b2..21717b6 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterKey.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterKey.java
@@ -26,9 +26,9 @@
public final class MeterKey {
private final DeviceId deviceId;
- private final MeterId id;
+ private final MeterCellId id;
- private MeterKey(DeviceId deviceId, MeterId id) {
+ private MeterKey(DeviceId deviceId, MeterCellId id) {
this.deviceId = deviceId;
this.id = id;
}
@@ -37,7 +37,22 @@
return deviceId;
}
+ /**
+ * @return a MeterId iff the id is a MeterId
+ * otherwise, return null
+ * @deprecated in onos-2.5 replaced by {@link #key(DeviceId,MeterCellId)}
+ * extends MeterKey to support both MeterId and PiMeterCellId
+ */
+ @Deprecated
public MeterId meterId() {
+ if (id instanceof MeterId) {
+ return (MeterId) id;
+ } else {
+ return null;
+ }
+ }
+
+ public MeterCellId meterCellId() {
return id;
}
@@ -63,10 +78,22 @@
public String toString() {
return toStringHelper(this)
.add("deviceId", deviceId)
- .add("meterId", id).toString();
+ .add("meterCellId", id).toString();
}
+ /**
+ * @param deviceId a DeviceId
+ * @param id a MeterId
+ * @return a MeterKey contains DeviceId and MeterId
+ * @deprecated in onos-2.5 replaced by {@link #key(DeviceId,MeterCellId)}
+ * extends MeterKey to support both MeterId and PiMeterCellId
+ */
+ @Deprecated
public static MeterKey key(DeviceId deviceId, MeterId id) {
return new MeterKey(deviceId, id);
}
+
+ public static MeterKey key(DeviceId deviceId, MeterCellId id) {
+ return new MeterKey(deviceId, id);
+ }
}
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterProgrammable.java b/core/api/src/main/java/org/onosproject/net/meter/MeterProgrammable.java
index 4b8ea07..74eab4d 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterProgrammable.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterProgrammable.java
@@ -42,4 +42,11 @@
* @return completable future with the collection of meters
*/
CompletableFuture<Collection<Meter>> getMeters();
+
+ /**
+ * Queries the meter features from the device.
+ *
+ * @return completable future with the collection of meter features
+ */
+ CompletableFuture<Collection<MeterFeatures>> getMeterFeatures();
}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java b/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java
index 29c251c..e96e224 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterProviderService.java
@@ -54,6 +54,14 @@
void pushMeterFeatures(DeviceId deviceId,
MeterFeatures meterfeatures);
+ /**
+ * Pushes the collection of meter features collected from the device.
+ *
+ * @param deviceId the device Id
+ * @param meterfeatures the meter features
+ */
+ void pushMeterFeatures(DeviceId deviceId,
+ Collection<MeterFeatures> meterfeatures);
/**
* Delete meter features collected from the device.
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterScope.java b/core/api/src/main/java/org/onosproject/net/meter/MeterScope.java
new file mode 100644
index 0000000..06eb448
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterScope.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.meter;
+
+import org.onlab.util.Identifier;
+
+/**
+ * Scope of Meter Features.
+ *
+ * There are multiple meter tables in a P4RT device,
+ * to distinguish and represent them uniquely,
+ * we added a Scope field.
+ *
+ * For P4RT device, value will be the PiMeterId.
+ * For OF device, we use "global" by default, since there is only 1 table in OF.
+ * In general, a Meter Scope is referring to a Meter Table.
+ * It can be a PiMeterId or "global" for the single OF meter table.
+ *
+ * During runtime, users need to provide a PiMeterId to indicate which Meter Cell they
+ * are intended to modify. The value will then be used to create a Meter Scope
+ * for the rest of the process.
+ * If no PiMeterId is provided, a "global" Meter Scope is created.
+ */
+public class MeterScope extends Identifier<String> {
+
+ public static final String METER_GLOBAL_SCOPE = "global";
+
+ /**
+ * Create a Meter Scope from id string.
+ * @param scope the scope
+ * @return a Meter Scope
+ */
+ public static MeterScope of(String scope) {
+ return new MeterScope(scope);
+ }
+
+ /**
+ * Create a global Meter Scope.
+ * @return a Meter Scope
+ */
+ public static MeterScope globalScope() {
+ return new MeterScope(METER_GLOBAL_SCOPE);
+ }
+
+ MeterScope(String scope) {
+ super(scope);
+ }
+
+ /**
+ * Global scope or not.
+ * @return true if global scope, false if not.
+ */
+ public boolean isGlobal() {
+ return identifier.equals(METER_GLOBAL_SCOPE);
+ }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterService.java b/core/api/src/main/java/org/onosproject/net/meter/MeterService.java
index 991715c..cf99b5e 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterService.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterService.java
@@ -74,7 +74,9 @@
* @param deviceId the device id
* @return the allocated meter id, null if there is an internal error
* or there are no meter ids available
+ * @deprecated in onos-2.5
*/
+ @Deprecated
MeterId allocateMeterId(DeviceId deviceId);
/**
@@ -82,7 +84,9 @@
*
* @param deviceId the device id
* @param meterId the id to be freed
+ * @deprecated in onos-2.5
*/
+ @Deprecated
void freeMeterId(DeviceId deviceId, MeterId meterId);
/**
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java b/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java
index 675592a..21696e4 100644
--- a/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterStore.java
@@ -112,15 +112,26 @@
* Delete this meter immediately.
*
* @param m a meter
+ * @deprecated in onos-2.5 renamed {@link #purgeMeter(Meter)}
*/
+ @Deprecated
void deleteMeterNow(Meter m);
/**
+ * Delete this meter immediately.
+ *
+ * @param m a meter
+ */
+ void purgeMeter(Meter m);
+
+ /**
* Retrieve maximum meters available for the device.
*
* @param key the meter features key
* @return the maximum number of meters supported by the device
+ * @deprecated in onos-2.5, Max meters is replaced by start and end index
*/
+ @Deprecated
long getMaxMeters(MeterFeaturesKey key);
/**
@@ -129,15 +140,30 @@
* @param deviceId the device id
* @return the meter Id or null if it was not possible
* to allocate a meter id
+ * @deprecated in onos-2.5 replaced by {@link #allocateMeterId(DeviceId, MeterScope)}
*/
+ @Deprecated
MeterId allocateMeterId(DeviceId deviceId);
/**
+ * Allocates the first available MeterId.
+ *
+ * @param deviceId the device id
+ * @param meterScope the meter scope
+ * @return the meter Id or null if it was not possible
+ * to allocate a meter id
+ */
+ MeterCellId allocateMeterId(DeviceId deviceId, MeterScope meterScope);
+
+ /**
* Frees the given meter id.
*
* @param deviceId the device id
* @param meterId the id to be freed
+ * @deprecated in onos-2.5, freeing an ID is closely related to removal of a meter
+ * so, this function is no longer exposed on interface
*/
+ @Deprecated
void freeMeterId(DeviceId deviceId, MeterId meterId);
/**
diff --git a/core/api/src/main/java/org/onosproject/net/meter/MeterTableKey.java b/core/api/src/main/java/org/onosproject/net/meter/MeterTableKey.java
new file mode 100644
index 0000000..dc76fee
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/meter/MeterTableKey.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.meter;
+
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * MeterTableKey is used to represent a single meter table in each device uniquely.
+ */
+public final class MeterTableKey {
+ private final DeviceId deviceId;
+ private final MeterScope scope;
+
+ private MeterTableKey(DeviceId deviceId, MeterScope scope) {
+ this.deviceId = deviceId;
+ this.scope = scope;
+ }
+
+ public static MeterTableKey key(DeviceId did, MeterScope scope) {
+ return new MeterTableKey(did, scope);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ MeterTableKey mtk = (MeterTableKey) obj;
+ return Objects.equals(deviceId, mtk.deviceId()) && Objects.equals(scope, mtk.scope());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(deviceId, scope);
+ }
+
+ @Override
+ public String toString() {
+ return "mtk@" + deviceId.toString() + " scope:" + scope.toString();
+ }
+
+ public DeviceId deviceId() {
+ return deviceId;
+ }
+
+ public MeterScope scope() {
+ return scope;
+ }
+}