Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NextHop column to Routes answerer #7838

Merged
merged 2 commits into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.batfish.common.util;

import java.util.Comparator;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.batfish.datamodel.Ip;
import org.batfish.datamodel.route.nh.NextHop;
import org.batfish.datamodel.route.nh.NextHopDiscard;
import org.batfish.datamodel.route.nh.NextHopInterface;
import org.batfish.datamodel.route.nh.NextHopIp;
import org.batfish.datamodel.route.nh.NextHopVisitor;
import org.batfish.datamodel.route.nh.NextHopVrf;
import org.batfish.datamodel.route.nh.NextHopVtep;

/** A {@link Comparator} implementation for next hops.. */
@ParametersAreNonnullByDefault
public final class NextHopComparator implements Comparator<NextHop> {

private static final NextHopComparator INSTANCE = new NextHopComparator();

public static @Nonnull NextHopComparator instance() {
return INSTANCE;
}

@Override
public int compare(NextHop o1, NextHop o2) {
// First order by type
if (!o1.getClass().equals(o2.getClass())) {
return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
}
return COMPARATOR_SELECTOR.visit(o1).compare(o1, o2);
}

private static final Comparator<NextHop> COMPARATOR_IP =
Comparator.comparing(nh -> ((NextHopIp) nh).getIp());

private static final Comparator<NextHop> COMPARATOR_INTERFACE =
Comparator.<NextHop, Ip>comparing(
nh -> ((NextHopInterface) nh).getIp(),
Comparator.nullsFirst(Comparator.naturalOrder()))
.thenComparing(
nh -> ((NextHopInterface) nh).getInterfaceName(), InterfaceNameComparator.instance());

private static final Comparator<NextHop> COMPARATOR_DISCARD = (nh1, nh2) -> 0;

private static final Comparator<NextHop> COMPARATOR_VRF =
Comparator.comparing(nh -> ((NextHopVrf) nh).getVrfName());

private static final Comparator<NextHop> COMPARATOR_VTEP =
Comparator.<NextHop, Integer>comparing(nh -> ((NextHopVtep) nh).getVni())
.thenComparing(nh -> ((NextHopVtep) nh).getVtepIp());

private static final ComparatorSelector COMPARATOR_SELECTOR = new ComparatorSelector();

private static final class ComparatorSelector implements NextHopVisitor<Comparator<NextHop>> {

@Override
public Comparator<NextHop> visitNextHopIp(NextHopIp nextHopIp) {
return COMPARATOR_IP;
}

@Override
public Comparator<NextHop> visitNextHopInterface(NextHopInterface nextHopInterface) {
return COMPARATOR_INTERFACE;
}

@Override
public Comparator<NextHop> visitNextHopDiscard(NextHopDiscard nextHopDiscard) {
return COMPARATOR_DISCARD;
}

@Override
public Comparator<NextHop> visitNextHopVrf(NextHopVrf nextHopVrf) {
return COMPARATOR_VRF;
}

@Override
public Comparator<NextHop> visitNextHopVtep(NextHopVtep nextHopVtep) {
return COMPARATOR_VTEP;
}
}

private NextHopComparator() {} // prevent instantiation of utility class
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.batfish.datamodel.pojo.Node;
import org.batfish.datamodel.questions.BgpRoute;
import org.batfish.datamodel.questions.BgpRouteDiffs;
import org.batfish.datamodel.route.nh.NextHop;
import org.batfish.datamodel.trace.TraceTree;

public class Schema {
Expand Down Expand Up @@ -52,6 +53,7 @@ private static String getClassString(Class<?> cls) {
.put("Ip", getClassString(Ip.class))
.put("Issue", getClassString(Issue.class))
.put("Long", getClassString(Long.class))
.put("NextHop", getClassString(NextHop.class))
.put("Object", getClassString(Object.class))
.put("Node", getClassString(Node.class))
.put("Prefix", getClassString(Prefix.class))
Expand All @@ -72,6 +74,7 @@ private static String getClassString(Class<?> cls) {
public static final Schema IP = new Schema("Ip");
public static final Schema ISSUE = new Schema("Issue");
public static final Schema LONG = new Schema("Long");
public static final Schema NEXT_HOP = new Schema("NextHop");
public static final Schema OBJECT = new Schema("Object");
public static final Schema NODE = new Schema("Node");
public static final Schema PREFIX = new Schema("Prefix");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.batfish.datamodel.flow.Trace;
import org.batfish.datamodel.pojo.Node;
import org.batfish.datamodel.questions.Exclusion;
import org.batfish.datamodel.route.nh.NextHop;

/**
* Represents one row of the table answer. Each row is basically a map of key value pairs, where the
Expand Down Expand Up @@ -318,6 +319,10 @@ public Prefix getPrefix(String column) {
return (Prefix) get(column, Schema.PREFIX);
}

public @Nullable NextHop getNextHop(String column) {
return (NextHop) get(column, Schema.NEXT_HOP);
}

public SelfDescribingObject getSelfDescribing(String column) {
return (SelfDescribingObject) get(column, Schema.SELF_DESCRIBING);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.batfish.common.util;

import static org.batfish.common.util.NextHopComparator.instance;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.lessThan;
import static org.junit.Assert.assertThat;

import org.batfish.datamodel.Ip;
import org.batfish.datamodel.route.nh.NextHopDiscard;
import org.batfish.datamodel.route.nh.NextHopInterface;
import org.batfish.datamodel.route.nh.NextHopIp;
import org.batfish.datamodel.route.nh.NextHopVrf;
import org.batfish.datamodel.route.nh.NextHopVtep;
import org.junit.Test;

/** Test of {@link NextHopComparator}. */
public final class NextHopComparatorTest {

@Test
public void testCompareClass() {
NextHopDiscard discard = NextHopDiscard.instance();
NextHopInterface iface = NextHopInterface.of("foo");
NextHopIp ip = NextHopIp.of(Ip.parse("1.1.1.1"));
NextHopVrf vrf = NextHopVrf.of("foo");
NextHopVtep vtep = NextHopVtep.of(5, Ip.parse("1.1.1.1"));

assertThat(instance().compare(discard, iface), lessThan(0));
assertThat(instance().compare(discard, ip), lessThan(0));
assertThat(instance().compare(discard, vrf), lessThan(0));
assertThat(instance().compare(discard, vtep), lessThan(0));

assertThat(instance().compare(iface, ip), lessThan(0));
assertThat(instance().compare(iface, vrf), lessThan(0));
assertThat(instance().compare(iface, vtep), lessThan(0));

assertThat(instance().compare(ip, vrf), lessThan(0));
assertThat(instance().compare(ip, vtep), lessThan(0));

assertThat(instance().compare(vrf, vtep), lessThan(0));
}

@Test
public void testCompareNextHopDiscard() {
assertThat(
instance().compare(NextHopDiscard.instance(), NextHopDiscard.instance()), equalTo(0));
}

@Test
public void testCompareNextHopInterface() {
assertThat(
instance().compare(NextHopInterface.of("foo"), NextHopInterface.of("foo")), equalTo(0));
assertThat(instance().compare(NextHopInterface.of("a"), NextHopInterface.of("b")), lessThan(0));
assertThat(
instance().compare(NextHopInterface.of("Ethernet2"), NextHopInterface.of("Ethernet11")),
lessThan(0));
assertThat(
instance()
.compare(NextHopInterface.of("foo"), NextHopInterface.of("foo", Ip.parse("1.1.1.1"))),
lessThan(0));
assertThat(
instance()
.compare(NextHopInterface.of("foo"), NextHopInterface.of("bar", Ip.parse("1.1.1.1"))),
lessThan(0));
assertThat(
instance()
.compare(
NextHopInterface.of("foo", Ip.parse("2.2.2.2")),
NextHopInterface.of("foo", Ip.parse("11.0.0.0"))),
lessThan(0));
assertThat(
instance()
.compare(
NextHopInterface.of("foo", Ip.parse("2.2.2.2")),
NextHopInterface.of("foo", Ip.parse("2.2.2.2"))),
equalTo(0));
assertThat(
instance()
.compare(
NextHopInterface.of("foo", Ip.parse("1.1.1.1")),
NextHopInterface.of("bar", Ip.parse("2.2.2.2"))),
lessThan(0));
}

@Test
public void testCompareNextHopIp() {
assertThat(
instance().compare(NextHopIp.of(Ip.parse("1.1.1.1")), NextHopIp.of(Ip.parse("1.1.1.1"))),
equalTo(0));
assertThat(
instance().compare(NextHopIp.of(Ip.parse("1.1.1.1")), NextHopIp.of(Ip.parse("1.1.1.2"))),
lessThan(0));
assertThat(
instance().compare(NextHopIp.of(Ip.parse("2.2.2.2")), NextHopIp.of(Ip.parse("11.0.0.0"))),
lessThan(0));
}

@Test
public void testCompareNextHopVrf() {
assertThat(instance().compare(NextHopVrf.of("foo"), NextHopVrf.of("foo")), equalTo(0));
assertThat(instance().compare(NextHopVrf.of("foo"), NextHopVrf.of("foo1")), lessThan(0));
assertThat(instance().compare(NextHopVrf.of("foo1"), NextHopVrf.of("foo2")), lessThan(0));
}

@Test
public void testCompareNextHopVtep() {
assertThat(
instance()
.compare(
NextHopVtep.of(5, Ip.parse("1.1.1.1")), NextHopVtep.of(5, Ip.parse("1.1.1.1"))),
equalTo(0));
assertThat(
instance()
.compare(
NextHopVtep.of(5, Ip.parse("1.1.1.1")), NextHopVtep.of(6, Ip.parse("1.1.1.1"))),
lessThan(0));
assertThat(
instance()
.compare(
NextHopVtep.of(5, Ip.parse("2.2.2.2")), NextHopVtep.of(6, Ip.parse("1.1.1.1"))),
lessThan(0));
assertThat(
instance()
.compare(
NextHopVtep.of(5, Ip.parse("1.1.1.1")), NextHopVtep.of(5, Ip.parse("2.2.2.2"))),
lessThan(0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javax.annotation.ParametersAreNonnullByDefault;
import org.batfish.datamodel.BgpRoute;
import org.batfish.datamodel.Ip;
import org.batfish.datamodel.route.nh.NextHop;

/**
* Class representing the secondary key used for grouping {@link
Expand All @@ -13,11 +14,14 @@
@ParametersAreNonnullByDefault
public class RouteRowSecondaryKey {

@Nonnull private final NextHop _nextHop;

@Nonnull private final Ip _nextHopIp;

@Nonnull private final String _protocol;

public RouteRowSecondaryKey(Ip nextHopIp, String protocol) {
public RouteRowSecondaryKey(NextHop nextHop, Ip nextHopIp, String protocol) {
_nextHop = nextHop;
_nextHopIp = nextHopIp;
_protocol = protocol;
}
Expand All @@ -31,12 +35,19 @@ public boolean equals(Object o) {
return false;
}
RouteRowSecondaryKey that = (RouteRowSecondaryKey) o;
return Objects.equals(_nextHopIp, that._nextHopIp) && Objects.equals(_protocol, that._protocol);
return _nextHop.equals(that._nextHop)
&& _nextHopIp.equals(that._nextHopIp)
&& _protocol.equals(that._protocol);
}

@Override
public int hashCode() {
return Objects.hash(_nextHopIp, _protocol);
return Objects.hash(_nextHop, _nextHopIp, _protocol);
}

@Nonnull
public NextHop getNextHop() {
return _nextHop;
}

@Nonnull
Expand Down
Loading