Hyunsun Moon
Committed by Gerrit Code Review

ONOS-4154 generates consistent hash for flow ID across multiple instances

Change-Id: I8de850dcc5d6d40ed563f7d476c6e13a09060093
......@@ -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 @@ public class DefaultFlowRule implements FlowRule {
}
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
......
......@@ -158,4 +158,34 @@ public class DefaultFlowRuleTest {
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();
}
}
......
......@@ -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 @@ public class DefaultTrafficSelectorTest {
}
/**
* 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.
*/
......
......@@ -569,7 +569,7 @@ public class FlowRuleManagerTest {
@Override
public Set<Criterion> criteria() {
return null;
return Collections.emptySet();
}
@Override
......