[AETHER-1104] Calculate PiPipeconf fingerprint in a deterministic way
New master after taking over a switch was pushing again the pipeline
and all the flows and groups. This was happening because DefaultPiPipeconf
fingerprint was not calculated in a deterministic way across the cluster.
This patch introduces the following changes:
- Implements toString method in each abstraction representing a pipeline
- Hashes the p4Info file to generate a consistent hash of the pipeline model
- Uses a sorted collection to generate a consistent hash of the extensions
Change-Id: I792283b0a9b821284add36b3aba52843f33527c3
diff --git a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
index d5bf2e6..7c1fd1a 100644
--- a/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
+++ b/protocols/p4runtime/model/src/main/java/org/onosproject/p4runtime/model/P4InfoParser.java
@@ -20,6 +20,8 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import com.google.common.hash.Hashing;
+import com.google.common.hash.HashingInputStream;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.TextFormat;
import org.onosproject.net.pi.model.PiActionId;
@@ -135,6 +137,19 @@
throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
}
+ // Generate fingerprint of the pipeline by hashing p4info file
+ final int fingerprint;
+ try {
+ HashingInputStream hin = new HashingInputStream(Hashing.crc32(), p4InfoUrl.openStream());
+ //noinspection StatementWithEmptyBody
+ while (hin.read() != -1) {
+ // Do nothing. Reading all input stream to update hash.
+ }
+ fingerprint = hin.hash().asInt();
+ } catch (IOException e) {
+ throw new P4InfoParserException("Unable to generate fingerprint " + p4InfoUrl.toString(), e);
+ }
+
// Start by parsing and mapping instances to to their integer P4Info IDs.
// Convenient to build the table model at the end.
@@ -243,7 +258,8 @@
meterImmMap,
registerImmMap,
actProfileImmMap,
- ImmutableMap.copyOf(pktOpMap));
+ ImmutableMap.copyOf(pktOpMap),
+ fingerprint);
}