CLI command to help debug the mapping of next-Objectives to the
groups that are created by device drivers.
Change-Id: Iff9e04e5e96b2cabbdb40e83215315d2e27791a6
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java b/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java
index dcfc588..d1604be 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/Pipeliner.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.net.behaviour;
+import java.util.List;
+
import org.onosproject.net.DeviceId;
import org.onosproject.net.driver.HandlerBehaviour;
import org.onosproject.net.flowobjective.FilteringObjective;
@@ -54,4 +56,18 @@
* @param nextObjective a next objectives
*/
void next(NextObjective nextObjective);
+
+ /**
+ * Retrieves a mapping of the nextObjective to the groups in the dataplane,
+ * and returns it in a form that can be displayed on the CLI. Typically
+ * group-ids are returned for groups with multiple buckets, where each list element
+ * represents a bucket. For nextObjectives that are converted to flow-actions,
+ * an empty list is returned.
+ *
+ * @param nextGroup representation of the nextObjective. This representation
+ * is stored in the distributed group store
+ * @return a list of preformatted strings representing group information, or
+ * an empty list if no groups were created
+ */
+ List<String> getNextMappings(NextGroup nextGroup);
}
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
index 415264e..6e905de 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
@@ -16,6 +16,9 @@
package org.onosproject.net.flowobjective;
import com.google.common.annotations.Beta;
+
+import java.util.List;
+
import org.onosproject.net.DeviceId;
/**
@@ -82,4 +85,17 @@
throw new UnsupportedOperationException("Unsupported objective of type " + objective.getClass());
}
}
+
+ /**
+ * Retrieve all nextObjective to group mappings known to this onos instance,
+ * in a format meant for display on the CLI, to help with debugging. Applications
+ * are only aware of next-Ids, while the group sub-system is only aware of group-ids.
+ * This method fills in the gap by providing information on the mapping
+ * between next-ids and group-ids done by device-drivers.
+ *
+ * @return a list of strings preformatted by the device-drivers to provide
+ * information on next-id to group-id mapping. Consumed by the
+ * "next-ids" command on the CLI.
+ */
+ List<String> getNextMappings();
}
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java
index 85dec0f..a0a7634 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveStore.java
@@ -16,6 +16,9 @@
package org.onosproject.net.flowobjective;
import com.google.common.annotations.Beta;
+
+import java.util.Map;
+
import org.onosproject.net.behaviour.NextGroup;
import org.onosproject.store.Store;
@@ -53,6 +56,13 @@
NextGroup removeNextGroup(Integer nextId);
/**
+ * Fetch all groups from the store and their mapping to nextIds.
+ *
+ * @return a map that represents the current snapshot of Next-ids to NextGroups
+ */
+ Map<Integer, NextGroup> getAllGroups();
+
+ /**
* Allocates a next objective id. This id is globally unique
*
* @return an integer
diff --git a/core/api/src/test/java/org/onosproject/net/behaviour/PipelinerAdapter.java b/core/api/src/test/java/org/onosproject/net/behaviour/PipelinerAdapter.java
index 73e83cd..203bbbe 100644
--- a/core/api/src/test/java/org/onosproject/net/behaviour/PipelinerAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/behaviour/PipelinerAdapter.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.net.behaviour;
+import java.util.List;
+
import org.onosproject.net.DeviceId;
import org.onosproject.net.driver.DriverData;
import org.onosproject.net.driver.DriverHandler;
@@ -65,4 +67,9 @@
public void setData(DriverData data) {
}
+
+ @Override
+ public List<String> getNextMappings(NextGroup nextGroup) {
+ return null;
+ }
}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
index d82b6f7..b7287c7 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
@@ -30,6 +30,7 @@
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.NextGroup;
import org.onosproject.net.behaviour.Pipeliner;
import org.onosproject.net.behaviour.PipelinerContext;
import org.onosproject.net.device.DeviceEvent;
@@ -53,7 +54,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -123,6 +126,10 @@
private Map<Integer, Set<PendingNext>> pendingForwards = Maps.newConcurrentMap();
+ // local store to track which nextObjectives were sent to which device
+ // for debugging purposes
+ private Map<Integer, DeviceId> nextToDevice = Maps.newConcurrentMap();
+
private ExecutorService executorService;
@Activate
@@ -143,6 +150,7 @@
executorService.shutdown();
pipeliners.clear();
driverHandlers.clear();
+ nextToDevice.clear();
log.info("Stopped");
}
@@ -215,6 +223,7 @@
@Override
public void next(DeviceId deviceId, NextObjective nextObjective) {
checkPermission(FLOWRULE_WRITE);
+ nextToDevice.put(nextObjective.id(), deviceId);
executorService.submit(new ObjectiveInstaller(deviceId, nextObjective));
}
@@ -443,4 +452,33 @@
return false;
}
}
+
+ @Override
+ public List<String> getNextMappings() {
+ List<String> mappings = new ArrayList<>();
+ Map<Integer, NextGroup> allnexts = flowObjectiveStore.getAllGroups();
+ // XXX if the NextGroup upon decoding stored info of the deviceId
+ // then info on any nextObj could be retrieved from one controller instance.
+ // Right now the drivers on one instance can only fetch for next-ids that came
+ // to them.
+ // Also, we still need to send the right next-id to the right driver as potentially
+ // there can be different drivers for different devices. But on that account,
+ // no instance should be decoding for another instance's nextIds.
+
+ for (Map.Entry<Integer, NextGroup> e : allnexts.entrySet()) {
+ // get the device this next Objective was sent to
+ DeviceId deviceId = nextToDevice.get(e.getKey());
+ mappings.add("NextId " + e.getKey() + ": " +
+ ((deviceId != null) ? deviceId : "nextId not in this onos instance"));
+ if (deviceId != null) {
+ // this instance of the controller sent the nextObj to a driver
+ Pipeliner pipeliner = getDevicePipeliner(deviceId);
+ List<String> nextMappings = pipeliner.getNextMappings(e.getValue());
+ if (nextMappings != null) {
+ mappings.addAll(nextMappings);
+ }
+ }
+ }
+ return mappings;
+ }
}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
index 2041b5b..b0bca13 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
@@ -436,4 +436,10 @@
str += ")";
return str;
}
+
+ @Override
+ public List<String> getNextMappings() {
+ // TODO Implementation deferred as this is an experimental component.
+ return null;
+ }
}
diff --git a/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveStoreAdapter.java b/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveStoreAdapter.java
index 378ea73..d73cc59 100644
--- a/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveStoreAdapter.java
+++ b/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveStoreAdapter.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.net.flowobjective.impl;
+import java.util.Map;
+
import org.onosproject.net.behaviour.NextGroup;
import org.onosproject.net.flowobjective.FlowObjectiveStore;
import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
@@ -57,4 +59,9 @@
public boolean hasDelegate() {
return false;
}
+
+ @Override
+ public Map<Integer, NextGroup> getAllGroups() {
+ return null;
+ }
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/flowobjective/impl/DistributedFlowObjectiveStore.java b/core/store/dist/src/main/java/org/onosproject/store/flowobjective/impl/DistributedFlowObjectiveStore.java
index 75a9b89..534289c 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/flowobjective/impl/DistributedFlowObjectiveStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/flowobjective/impl/DistributedFlowObjectiveStore.java
@@ -37,6 +37,9 @@
import static org.slf4j.LoggerFactory.getLogger;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Manages the inventory of created next groups.
*/
@@ -106,6 +109,18 @@
}
@Override
+ public Map<Integer, NextGroup> getAllGroups() {
+ Map<Integer, NextGroup> nextGroupMappings = new HashMap<>();
+ for (int key : nextGroups.keySet()) {
+ NextGroup nextGroup = getNextGroup(key);
+ if (nextGroup != null) {
+ nextGroupMappings.put(key, nextGroup);
+ }
+ }
+ return nextGroupMappings;
+ }
+
+ @Override
public int allocateNextId() {
return (int) nextIds.incrementAndGet();
}