diff --git a/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java b/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java index ffca61530dbcab3eda7159bec0a7f86014682ac1..2259e6f0a53e26166a210e55925cbe11966a9101 100644 --- a/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java +++ b/src/main/java/net/floodlightcontroller/util/OFMessageUtils.java @@ -35,6 +35,61 @@ public class OFMessageUtils { */ private OFMessageUtils() {}; + /** + * Simple class to streamline the use of OFMessage's + * equalsIgnoreXid() and hashCodeIgnoreXid() functions. + * Use this class to wrap OFMessages prior to inserting + * them in containers where lookup or equality checks + * should not include the XID. + * + * See {@link net.floodlightcontroller.util.OFMessageDamper} + * as an example where it's used to help cache OFMessages. + * @author rizard + */ + public static class OFMessageIgnoreXid { + private OFMessage m; + + private OFMessageIgnoreXid() {} + private OFMessageIgnoreXid(OFMessage m) { + this.m = m; + } + + /** + * Wrap an OFMessage to ignore the XID + * when checking for equality or computing + * the OFMessage's hash. + * @param m + * @return + */ + public static OFMessageIgnoreXid of(OFMessage m) { + return new OFMessageIgnoreXid(m); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((m == null) ? 0 : m.hashCodeIgnoreXid()); + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + OFMessageIgnoreXid other = (OFMessageIgnoreXid) obj; + if (m == null) { + if (other.m != null) + return false; + } else if (!m.equalsIgnoreXid(other.m)) + return false; + return true; + } + } + /** * Get the ingress port of a packet-in message. The manner in which * this is done depends on the OpenFlow version. OF1.0 and 1.1 have @@ -81,24 +136,6 @@ public class OFMessageUtils { return pi.getMatch().get(MatchField.VLAN_VID) == null ? OFVlanVidMatch.UNTAGGED : pi.getMatch().get(MatchField.VLAN_VID); } - /** - * Returns true if each object is deeply-equal in the same manner that - * Object's equals() does with the exception of the XID field, which is - * ignored; otherwise, returns false. - * - * NOTE: This function is VERY INEFFICIENT and creates a new OFMessage - * object in order to the the comparison minus the XID. It is advised - * that you use it sparingly and ideally only within unit tests. - * - * @param a; object A to compare - * @param b; object B to compare - * @return true if A and B are deeply-equal; false otherwise - */ - public static boolean equalsIgnoreXid(OFMessage a, OFMessage b) { - OFMessage.Builder mb = b.createBuilder().setXid(a.getXid()); - return a.equals(mb.build()); - } - /** * Writes an OFPacketOut message to a switch. * diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java index 9d68ba9f98a4309d13fda155978e799f12b083db..a3e5dab0b3add80a12ce3e48291b292c31e8bd45 100644 --- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java +++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java @@ -488,15 +488,15 @@ public class ForwardingTest extends FloodlightTestCase { for (OFMessage m: msglist) { if (m instanceof OFFlowMod) - assertTrue(OFMessageUtils.equalsIgnoreXid(fm1, m)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(fm1), OFMessageUtils.OFMessageIgnoreXid.of(m)); else if (m instanceof OFPacketOut) { - assertTrue(OFMessageUtils.equalsIgnoreXid(packetOut, m)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(packetOut), OFMessageUtils.OFMessageIgnoreXid.of(m)); } } OFMessage m = wc2.getValue(); assert (m instanceof OFFlowMod); - assertTrue(OFMessageUtils.equalsIgnoreXid(m, fm2)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(m), OFMessageUtils.OFMessageIgnoreXid.of(fm2)); removeDeviceFromContext(); } @@ -558,15 +558,15 @@ public class ForwardingTest extends FloodlightTestCase { for (OFMessage m: msglist) { if (m instanceof OFFlowMod) - assertTrue(OFMessageUtils.equalsIgnoreXid(fm1, m)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(fm1), OFMessageUtils.OFMessageIgnoreXid.of(m)); else if (m instanceof OFPacketOut) { - assertTrue(OFMessageUtils.equalsIgnoreXid(packetOutIPv6, m)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(packetOutIPv6), OFMessageUtils.OFMessageIgnoreXid.of(m)); } } OFMessage m = wc2.getValue(); assert (m instanceof OFFlowMod); - assertTrue(OFMessageUtils.equalsIgnoreXid(m, fm2)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(m), OFMessageUtils.OFMessageIgnoreXid.of(fm2)); removeDeviceFromContext(); } @@ -619,8 +619,8 @@ public class ForwardingTest extends FloodlightTestCase { assertTrue(wc1.hasCaptured()); assertTrue(wc2.hasCaptured()); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), fm1)); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc2.getValue(), packetOut)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm1)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc2.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOut)); removeDeviceFromContext(); } @@ -673,8 +673,8 @@ public class ForwardingTest extends FloodlightTestCase { assertTrue(wc1.hasCaptured()); assertTrue(wc2.hasCaptured()); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), fm1)); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc2.getValue(), packetOutIPv6)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm1)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc2.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOutIPv6)); removeDeviceFromContext(); } @@ -763,7 +763,7 @@ public class ForwardingTest extends FloodlightTestCase { verify(sw1, sw2, routingEngine); assertTrue(wc1.hasCaptured()); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), packetOutFlooded)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOutFlooded)); removeDeviceFromContext(); } @@ -796,7 +796,7 @@ public class ForwardingTest extends FloodlightTestCase { verify(sw1, sw2, routingEngine); assertTrue(wc1.hasCaptured()); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), packetOutFloodedIPv6)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOutFloodedIPv6)); removeDeviceFromContext(); } diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java index 6fcd37e81669945e853450426cb09a2fb97b8c23..61ddd24bad2daa35e5e9f44e11cb2b2bc1547b95 100644 --- a/src/test/java/net/floodlightcontroller/hub/HubTest.java +++ b/src/test/java/net/floodlightcontroller/hub/HubTest.java @@ -138,7 +138,7 @@ public class HubTest extends FloodlightTestCase { assertTrue(wc1.hasCaptured()); OFMessage m = wc1.getValue(); - assertTrue(OFMessageUtils.equalsIgnoreXid(m, po)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(m), OFMessageUtils.OFMessageIgnoreXid.of(po)); } @Test diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java index eb884f4406694a574b31dd31a1a3fb33d1dd176b..8796e3f62f5f8b0153cc18565b55d10de5985e62 100644 --- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java +++ b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java @@ -204,7 +204,7 @@ public class LearningSwitchTest extends FloodlightTestCase { verify(mockSwitch); assertTrue(wc1.hasCaptured()); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), po)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(po)); // Verify the MAC table inside the switch assertEquals(OFPort.of(1), result); @@ -291,9 +291,9 @@ public class LearningSwitchTest extends FloodlightTestCase { assertTrue(wc1.hasCaptured()); assertTrue(wc2.hasCaptured()); assertTrue(wc3.hasCaptured()); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc1.getValue(), packetOut)); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc2.getValue(), fm1)); - assertTrue(OFMessageUtils.equalsIgnoreXid(wc3.getValue(), fm2)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc1.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(packetOut)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc2.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm1)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(wc3.getValue()), OFMessageUtils.OFMessageIgnoreXid.of(fm2)); // Verify the MAC table inside the switch assertEquals(OFPort.of(1), result); diff --git a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java index 09bfec33a7769a78c7896a7204cf0de561b30868..9bd3c98fe87de373c3cd5b2ebfb42d32fa8be5f2 100644 --- a/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java +++ b/src/test/java/net/floodlightcontroller/loadbalancer/LoadBalancerTest.java @@ -541,7 +541,7 @@ public class LoadBalancerTest extends FloodlightTestCase { for (OFMessage m: msglist1) { if (m instanceof OFPacketOut) - assertTrue(OFMessageUtils.equalsIgnoreXid(arpReplyPacketOut1, m)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(arpReplyPacketOut1), OFMessageUtils.OFMessageIgnoreXid.of(m)); else assertTrue(false); // unexpected message } diff --git a/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java b/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java index a2a6eb964d58d84c71b0d1d777927bb6859b6c3e..e2b52156f53676e2986fefc099687274aa590361 100644 --- a/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java +++ b/src/test/java/net/floodlightcontroller/staticentry/StaticFlowTests.java @@ -175,7 +175,7 @@ public class StaticFlowTests extends FloodlightTestCase { // dont' bother testing the cookie; just copy it over goodFlowMod = goodFlowMod.createBuilder().setCookie(testFlowMod.getCookie()).build(); // .. so we can continue to use .equals() - assertTrue(OFMessageUtils.equalsIgnoreXid(goodFlowMod, testFlowMod)); + assertEquals(OFMessageUtils.OFMessageIgnoreXid.of(goodFlowMod), OFMessageUtils.OFMessageIgnoreXid.of(testFlowMod)); }