Carry previous next hop information in RouteEvent
Change-Id: Ib66a9191892c0e62b54fddcbfdc5645f305e9fcf
diff --git a/apps/routing/src/test/java/org/onosproject/routing/impl/SingleSwitchFibInstallerTest.java b/apps/routing/src/test/java/org/onosproject/routing/impl/SingleSwitchFibInstallerTest.java
index 2b60f91..1e6efb5 100644
--- a/apps/routing/src/test/java/org/onosproject/routing/impl/SingleSwitchFibInstallerTest.java
+++ b/apps/routing/src/test/java/org/onosproject/routing/impl/SingleSwitchFibInstallerTest.java
@@ -335,6 +335,7 @@
testRouteAdd();
reset(flowObjectiveService);
+ ResolvedRoute oldRoute = new ResolvedRoute(PREFIX1, NEXT_HOP1, MAC1, SW1_ETH1);
ResolvedRoute route = new ResolvedRoute(PREFIX1, NEXT_HOP2, MAC2, SW1_ETH2);
// Create the next objective
@@ -348,7 +349,7 @@
setUpFlowObjectiveService();
// Send in the update event
- routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, route));
+ routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, route, oldRoute));
verify(flowObjectiveService);
}
@@ -365,7 +366,7 @@
testRouteAdd();
// Construct the existing route
- ResolvedRoute route = new ResolvedRoute(PREFIX1, null, null, null);
+ ResolvedRoute route = new ResolvedRoute(PREFIX1, NEXT_HOP1, MAC1, SW1_ETH1);
// Create the flow objective
reset(flowObjectiveService);
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
index a764c83..31e1cde 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -244,6 +244,7 @@
testRouteAddToNoVlan();
// Build the new route entries for prefix1 and prefix2
+ ResolvedRoute oldRoutePrefixOne = new ResolvedRoute(PREFIX1, IP3, MAC3, SW3_ETH1);
ResolvedRoute routePrefixOne = new ResolvedRoute(PREFIX1, IP1, MAC1, SW1_ETH1);
// Create the new expected intents
@@ -258,7 +259,7 @@
// Send in the update events
routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
- routePrefixOne));
+ routePrefixOne, oldRoutePrefixOne));
verify(intentSynchronizer);
}
@@ -278,6 +279,7 @@
testRouteAddToVlan();
// Build the new route entries for prefix1 and prefix2
+ ResolvedRoute oldRoutePrefix = new ResolvedRoute(PREFIX2, IP1, MAC1, SW1_ETH1);
ResolvedRoute routePrefix = new ResolvedRoute(PREFIX2, IP3, MAC3, SW3_ETH1);
// Create the new expected intents
@@ -293,7 +295,7 @@
// Send in the update events
routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
- routePrefix));
+ routePrefix, oldRoutePrefix));
verify(intentSynchronizer);
}
@@ -310,7 +312,7 @@
testRouteAddToNoVlan();
// Construct the existing route entry
- ResolvedRoute route = new ResolvedRoute(PREFIX1, null, null, null);
+ ResolvedRoute route = new ResolvedRoute(PREFIX1, IP3, MAC3, SW3_ETH1);
// Create existing intent
MultiPointToSinglePointIntent removedIntent =
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteEvent.java b/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteEvent.java
index 1889a53..fc5199d 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteEvent.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteEvent.java
@@ -16,15 +16,20 @@
package org.onosproject.incubator.net.routing;
+import org.joda.time.LocalDateTime;
import org.onosproject.event.AbstractEvent;
import java.util.Objects;
+import static com.google.common.base.MoreObjects.toStringHelper;
+
/**
* Describes an event about a route.
*/
public class RouteEvent extends AbstractEvent<RouteEvent.Type, ResolvedRoute> {
+ private final ResolvedRoute prevSubject;
+
/**
* Route event type.
*/
@@ -32,28 +37,38 @@
/**
* Route is new.
+ * <p>
+ * The subject of this event should be the route being added.
+ * The prevSubject of this event should be null.
*/
ROUTE_ADDED,
/**
* Route has updated information.
+ * <p>
+ * The subject of this event should be the new route.
+ * The prevSubject of this event should be the old route.
*/
ROUTE_UPDATED,
/**
* Route was removed.
+ * <p>
+ * The subject of this event should be the route being removed.
+ * The prevSubject of this event should be null.
*/
ROUTE_REMOVED
}
/**
- * Creates a new route event.
+ * Creates a new route event without specifying previous subject.
*
* @param type event type
* @param subject event subject
*/
public RouteEvent(Type type, ResolvedRoute subject) {
super(type, subject);
+ this.prevSubject = null;
}
/**
@@ -65,11 +80,33 @@
*/
protected RouteEvent(Type type, ResolvedRoute subject, long time) {
super(type, subject, time);
+ this.prevSubject = null;
+ }
+
+ /**
+ * Creates a new route event with previous subject.
+ *
+ * @param type event type
+ * @param subject event subject
+ * @param prevSubject previous subject
+ */
+ public RouteEvent(Type type, ResolvedRoute subject, ResolvedRoute prevSubject) {
+ super(type, subject);
+ this.prevSubject = prevSubject;
+ }
+
+ /**
+ * Returns the previous subject of the event.
+ *
+ * @return previous subject to which this event pertains
+ */
+ public ResolvedRoute prevSubject() {
+ return prevSubject;
}
@Override
public int hashCode() {
- return Objects.hash(subject(), type());
+ return Objects.hash(subject(), type(), prevSubject());
}
@Override
@@ -85,6 +122,17 @@
RouteEvent that = (RouteEvent) other;
return Objects.equals(this.subject(), that.subject()) &&
- Objects.equals(this.type(), that.type());
+ Objects.equals(this.type(), that.type()) &&
+ Objects.equals(this.prevSubject(), that.prevSubject());
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("time", new LocalDateTime(time()))
+ .add("type", type())
+ .add("subject", subject())
+ .add("prevSubject", prevSubject())
+ .toString();
}
}
diff --git a/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteStore.java b/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteStore.java
index 9eac65c..22a6285 100644
--- a/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteStore.java
+++ b/incubator/api/src/main/java/org/onosproject/incubator/net/routing/RouteStore.java
@@ -74,7 +74,7 @@
Collection<Route> getRoutesForNextHop(IpAddress ip);
/**
- * Updates a next hop IP and MAC in the store.
+ * Updates a next hop information in the store.
*
* @param ip IP address
* @param nextHopData Information of the next hop
@@ -82,7 +82,7 @@
void updateNextHop(IpAddress ip, NextHopData nextHopData);
/**
- * Removes a next hop IP and MAC from the store.
+ * Removes a next hop information from the store.
*
* @param ip IP address
* @param nextHopData Information of the next hop
@@ -90,7 +90,7 @@
void removeNextHop(IpAddress ip, NextHopData nextHopData);
/**
- * Returns the MAC address of the given next hop.
+ * Returns the information of the given next hop.
*
* @param ip next hop IP
* @return Information of the next hop
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/routing/impl/RouteManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/routing/impl/RouteManager.java
index 4c0f59e..6669281 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/routing/impl/RouteManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/routing/impl/RouteManager.java
@@ -120,7 +120,7 @@
if (routes != null) {
routes.forEach(route -> {
NextHopData nextHopData = routeStore.getNextHop(route.nextHop());
- l.post(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
+ l.post(new RouteEvent(RouteEvent.Type.ROUTE_ADDED,
new ResolvedRoute(route, nextHopData.mac(),
nextHopData.location())));
});
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/routing/impl/RouteManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/routing/impl/RouteManagerTest.java
index 86ba6f6..ba73cde 100644
--- a/incubator/net/src/test/java/org/onosproject/incubator/net/routing/impl/RouteManagerTest.java
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/routing/impl/RouteManagerTest.java
@@ -215,23 +215,26 @@
public void testRouteUpdate() {
Route route = new Route(Route.Source.STATIC, V4_PREFIX1, V4_NEXT_HOP1);
Route updatedRoute = new Route(Route.Source.STATIC, V4_PREFIX1, V4_NEXT_HOP2);
+ ResolvedRoute resolvedRoute = new ResolvedRoute(updatedRoute, MAC1, CP1);
ResolvedRoute updatedResolvedRoute = new ResolvedRoute(updatedRoute, MAC2, CP1);
- verifyRouteRemoveThenAdd(route, updatedRoute, updatedResolvedRoute);
+ verifyRouteRemoveThenAdd(route, updatedRoute, resolvedRoute, updatedResolvedRoute);
// Different prefix pointing to the same next hop.
// In this case we expect to receive a ROUTE_UPDATED event.
route = new Route(Route.Source.STATIC, V4_PREFIX2, V4_NEXT_HOP1);
updatedRoute = new Route(Route.Source.STATIC, V4_PREFIX2, V4_NEXT_HOP2);
+ resolvedRoute = new ResolvedRoute(route, MAC1, CP1);
updatedResolvedRoute = new ResolvedRoute(updatedRoute, MAC2, CP1);
- verifyRouteUpdated(route, updatedRoute, updatedResolvedRoute);
+ verifyRouteUpdated(route, updatedRoute, resolvedRoute, updatedResolvedRoute);
route = new Route(Route.Source.STATIC, V6_PREFIX1, V6_NEXT_HOP1);
updatedRoute = new Route(Route.Source.STATIC, V6_PREFIX1, V6_NEXT_HOP2);
+ resolvedRoute = new ResolvedRoute(route, MAC3, CP1);
updatedResolvedRoute = new ResolvedRoute(updatedRoute, MAC4, CP1);
- verifyRouteRemoveThenAdd(route, updatedRoute, updatedResolvedRoute);
+ verifyRouteRemoveThenAdd(route, updatedRoute, resolvedRoute, updatedResolvedRoute);
}
/**
@@ -240,16 +243,18 @@
*
* @param original original route
* @param updated updated route
+ * @param resolvedRoute resolved route before update
* @param updatedResolvedRoute resolved route that is expected to be sent to
* the route listener
*/
private void verifyRouteRemoveThenAdd(Route original, Route updated,
+ ResolvedRoute resolvedRoute,
ResolvedRoute updatedResolvedRoute) {
// First add the original route
addRoute(original);
routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED,
- new ResolvedRoute(original, null, null)));
+ new ResolvedRoute(original, resolvedRoute.nextHopMac(), resolvedRoute.location())));
expectLastCall().once();
routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_ADDED, updatedResolvedRoute));
expectLastCall().once();
@@ -267,15 +272,18 @@
*
* @param original original route
* @param updated updated route
+ * @param resolvedRoute resolved route before update
* @param updatedResolvedRoute resolved route that is expected to be sent to
* the route listener
*/
private void verifyRouteUpdated(Route original, Route updated,
+ ResolvedRoute resolvedRoute,
ResolvedRoute updatedResolvedRoute) {
// First add the original route
addRoute(original);
- routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED, updatedResolvedRoute));
+ routeListener.event(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
+ updatedResolvedRoute, resolvedRoute));
expectLastCall().once();
replay(routeListener);
@@ -291,12 +299,14 @@
@Test
public void testRouteDelete() {
Route route = new Route(Route.Source.STATIC, V4_PREFIX1, V4_NEXT_HOP1);
+ ResolvedRoute removedResolvedRoute = new ResolvedRoute(route, MAC1, CP1);
- verifyDelete(route);
+ verifyDelete(route, removedResolvedRoute);
route = new Route(Route.Source.STATIC, V6_PREFIX1, V6_NEXT_HOP1);
+ removedResolvedRoute = new ResolvedRoute(route, MAC3, CP1);
- verifyDelete(route);
+ verifyDelete(route, removedResolvedRoute);
}
/**
@@ -304,12 +314,13 @@
* the route listener.
*
* @param route route to delete
+ * @param removedResolvedRoute the resolved route being removed
*/
- private void verifyDelete(Route route) {
+ private void verifyDelete(Route route, ResolvedRoute removedResolvedRoute) {
addRoute(route);
RouteEvent withdrawRouteEvent = new RouteEvent(RouteEvent.Type.ROUTE_REMOVED,
- new ResolvedRoute(route, null, null));
+ removedResolvedRoute);
reset(routeListener);
routeListener.event(withdrawRouteEvent);
diff --git a/incubator/store/src/main/java/org/onosproject/incubator/store/routing/impl/LocalRouteStore.java b/incubator/store/src/main/java/org/onosproject/incubator/store/routing/impl/LocalRouteStore.java
index a1e3120..70bca92 100644
--- a/incubator/store/src/main/java/org/onosproject/incubator/store/routing/impl/LocalRouteStore.java
+++ b/incubator/store/src/main/java/org/onosproject/incubator/store/routing/impl/LocalRouteStore.java
@@ -118,15 +118,16 @@
Collection<Route> routes = getDefaultRouteTable(ip).getRoutesForNextHop(ip);
if (!routes.isEmpty() && !nextHopData.equals(nextHops.get(ip))) {
- NextHopData oldNextHop = nextHops.put(ip, nextHopData);
+ NextHopData oldNextHopData = nextHops.put(ip, nextHopData);
for (Route route : routes) {
- if (oldNextHop == null) {
+ if (oldNextHopData == null) {
notifyDelegate(new RouteEvent(RouteEvent.Type.ROUTE_ADDED,
new ResolvedRoute(route, nextHopData.mac(), nextHopData.location())));
} else {
notifyDelegate(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
- new ResolvedRoute(route, nextHopData.mac(), nextHopData.location())));
+ new ResolvedRoute(route, nextHopData.mac(), nextHopData.location()),
+ new ResolvedRoute(route, oldNextHopData.mac(), oldNextHopData.location())));
}
}
}
@@ -138,7 +139,7 @@
Collection<Route> routes = getDefaultRouteTable(ip).getRoutesForNextHop(ip);
for (Route route : routes) {
notifyDelegate(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED,
- new ResolvedRoute(route, null, null)));
+ new ResolvedRoute(route, nextHopData.mac(), nextHopData.location())));
}
}
}
@@ -202,6 +203,8 @@
* @param route route to update
*/
public void update(Route route) {
+ NextHopData oldNextHopData = null;
+
synchronized (this) {
Route oldRoute = routes.put(route.prefix(), route);
routeTable.put(createBinaryString(route.prefix()), route);
@@ -214,7 +217,7 @@
reverseIndex.remove(oldRoute.nextHop(), oldRoute);
if (reverseIndex.get(oldRoute.nextHop()).isEmpty()) {
- nextHops.remove(oldRoute.nextHop());
+ oldNextHopData = nextHops.remove(oldRoute.nextHop());
}
}
@@ -226,14 +229,20 @@
NextHopData nextHopData = nextHops.get(route.nextHop());
if (oldRoute != null && !oldRoute.nextHop().equals(route.nextHop())) {
+ ResolvedRoute oldResolvedRoute =
+ new ResolvedRoute(oldRoute,
+ (oldNextHopData == null) ? null : oldNextHopData.mac(),
+ (oldNextHopData == null) ? null : oldNextHopData.location());
+
if (nextHopData == null) {
// We don't know the new MAC address yet so delete the route
notifyDelegate(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED,
- new ResolvedRoute(oldRoute, null, null)));
+ oldResolvedRoute));
} else {
// We know the new MAC address so update the route
notifyDelegate(new RouteEvent(RouteEvent.Type.ROUTE_UPDATED,
- new ResolvedRoute(route, nextHopData.mac(), nextHopData.location())));
+ new ResolvedRoute(route, nextHopData.mac(), nextHopData.location()),
+ oldResolvedRoute));
}
return;
}
@@ -258,8 +267,10 @@
if (removed != null) {
reverseIndex.remove(removed.nextHop(), removed);
+ NextHopData oldNextHopData = getNextHop(removed.nextHop());
notifyDelegate(new RouteEvent(RouteEvent.Type.ROUTE_REMOVED,
- new ResolvedRoute(route, null, null)));
+ new ResolvedRoute(route, oldNextHopData.mac(),
+ oldNextHopData.location())));
}
}
}