ONOS-4154 generates consistent hash for flow ID across multiple instances
Change-Id: I8de850dcc5d6d40ed563f7d476c6e13a09060093
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
index b8605f1..313cbfc 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
@@ -16,6 +16,11 @@
package org.onosproject.net.flow;
import com.google.common.annotations.Beta;
+import com.google.common.base.Charsets;
+import com.google.common.hash.Funnel;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.HashFunction;
+import com.google.common.hash.Hashing;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.core.GroupId;
@@ -393,9 +398,20 @@
}
private int hash() {
- return Objects.hash(deviceId, priority, selector, tableId);
- }
+ Funnel<TrafficSelector> selectorFunnel = (from, into) -> from.criteria()
+ .stream()
+ .forEach(c -> into.putString(c.toString(), Charsets.UTF_8));
+ HashFunction hashFunction = Hashing.murmur3_32();
+ HashCode hashCode = hashFunction.newHasher()
+ .putString(deviceId.toString(), Charsets.UTF_8)
+ .putObject(selector, selectorFunnel)
+ .putInt(priority)
+ .putInt(tableId)
+ .hash();
+
+ return hashCode.asInt();
+ }
}
@Override
diff --git a/core/api/src/test/java/org/onosproject/net/flow/DefaultFlowRuleTest.java b/core/api/src/test/java/org/onosproject/net/flow/DefaultFlowRuleTest.java
index e8230f7..c0f11d6 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/DefaultFlowRuleTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/DefaultFlowRuleTest.java
@@ -158,4 +158,34 @@
assertThat(rule.treatment(), is(TREATMENT));
assertThat(rule.timeout(), is(44));
}
+
+ /**
+ * Tests flow ID is consistent.
+ */
+ @Test
+ public void testCreationWithConsistentFlowId() {
+ final FlowRule rule1 =
+ DefaultFlowRule.builder()
+ .forDevice(did("1"))
+ .withSelector(SELECTOR)
+ .withTreatment(TREATMENT)
+ .withPriority(22)
+ .forTable(1)
+ .fromApp(APP_ID)
+ .makeTemporary(44)
+ .build();
+
+ final FlowRule rule2 =
+ DefaultFlowRule.builder()
+ .forDevice(did("1"))
+ .withSelector(SELECTOR)
+ .withTreatment(TREATMENT)
+ .withPriority(22)
+ .forTable(1)
+ .fromApp(APP_ID)
+ .makeTemporary(44)
+ .build();
+
+ new EqualsTester().addEqualityGroup(rule1.id(), rule2.id()).testEquals();
+ }
}
diff --git a/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java b/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java
index 923de26..aaa3db5 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/DefaultTrafficSelectorTest.java
@@ -15,13 +15,16 @@
*/
package org.onosproject.net.flow;
+import java.util.List;
import java.util.Set;
+import com.google.common.collect.Lists;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Test;
+import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
@@ -78,6 +81,26 @@
}
/**
+ * Tests criteria order is consistent.
+ */
+ @Test
+ public void testCriteriaOrder() {
+ final TrafficSelector selector1 = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.portNumber(11))
+ .matchEthType(Ethernet.TYPE_ARP)
+ .build();
+ final TrafficSelector selector2 = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_ARP)
+ .matchInPort(PortNumber.portNumber(11))
+ .build();
+
+ List<Criterion> criteria1 = Lists.newArrayList(selector1.criteria());
+ List<Criterion> criteria2 = Lists.newArrayList(selector2.criteria());
+
+ new EqualsTester().addEqualityGroup(criteria1, criteria2).testEquals();
+ }
+
+ /**
* Hamcrest matcher to check that a selector contains a
* Criterion with the specified type.
*/
diff --git a/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java b/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java
index 1e621f5..235699d 100644
--- a/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/flow/impl/FlowRuleManagerTest.java
@@ -569,7 +569,7 @@
@Override
public Set<Criterion> criteria() {
- return null;
+ return Collections.emptySet();
}
@Override