Updated SDN-IP to use the Intent framework batch-based intents.
Also, created a local cache of IPv4-to-MAC address mapping, to avoid relatively costly hostService.getHostsByIp() calls per added route. Change-Id: I8abed378985708e883fd99e85c54b01f38756515
Showing
10 changed files
with
381 additions
and
282 deletions
... | @@ -26,6 +26,7 @@ import java.util.concurrent.ExecutorService; | ... | @@ -26,6 +26,7 @@ import java.util.concurrent.ExecutorService; |
26 | import java.util.concurrent.Executors; | 26 | import java.util.concurrent.Executors; |
27 | import java.util.concurrent.Semaphore; | 27 | import java.util.concurrent.Semaphore; |
28 | 28 | ||
29 | +import org.apache.commons.lang3.tuple.Pair; | ||
29 | import org.onlab.onos.core.ApplicationId; | 30 | import org.onlab.onos.core.ApplicationId; |
30 | import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; | 31 | import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; |
31 | import org.onlab.onos.net.flow.criteria.Criterion; | 32 | import org.onlab.onos.net.flow.criteria.Criterion; |
... | @@ -116,7 +117,7 @@ public class IntentSynchronizer { | ... | @@ -116,7 +117,7 @@ public class IntentSynchronizer { |
116 | // | 117 | // |
117 | log.debug("SDN-IP Intent Synchronizer shutdown: " + | 118 | log.debug("SDN-IP Intent Synchronizer shutdown: " + |
118 | "withdrawing all intents..."); | 119 | "withdrawing all intents..."); |
119 | - IntentOperations.Builder builder = IntentOperations.builder(); | 120 | + IntentOperations.Builder builder = IntentOperations.builder(appId); |
120 | for (Intent intent : intentService.getIntents()) { | 121 | for (Intent intent : intentService.getIntents()) { |
121 | // Skip the intents from other applications | 122 | // Skip the intents from other applications |
122 | if (!intent.appId().equals(appId)) { | 123 | if (!intent.appId().equals(appId)) { |
... | @@ -234,51 +235,84 @@ public class IntentSynchronizer { | ... | @@ -234,51 +235,84 @@ public class IntentSynchronizer { |
234 | } | 235 | } |
235 | 236 | ||
236 | /** | 237 | /** |
237 | - * Submits a multi-point-to-single-point intent. | 238 | + * Updates multi-point-to-single-point route intents. |
238 | * | 239 | * |
239 | - * @param prefix the IPv4 matching prefix for the intent to submit | 240 | + * @param submitIntents the intents to submit |
240 | - * @param intent the intent to submit | 241 | + * @param withdrawPrefixes the IPv4 matching prefixes for the intents |
242 | + * to withdraw | ||
241 | */ | 243 | */ |
242 | - void submitRouteIntent(Ip4Prefix prefix, | 244 | + void updateRouteIntents( |
243 | - MultiPointToSinglePointIntent intent) { | 245 | + Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> submitIntents, |
246 | + Collection<Ip4Prefix> withdrawPrefixes) { | ||
247 | + | ||
248 | + // | ||
249 | + // NOTE: Semantically, we MUST withdraw existing intents before | ||
250 | + // submitting new intents. | ||
251 | + // | ||
244 | synchronized (this) { | 252 | synchronized (this) { |
245 | - MultiPointToSinglePointIntent oldIntent = | 253 | + MultiPointToSinglePointIntent intent; |
246 | - routeIntents.put(prefix, intent); | ||
247 | 254 | ||
248 | - if (isElectedLeader && isActivatedLeader) { | 255 | + log.debug("SDN-IP submitting intents = {} withdrawing = {}", |
249 | - if (oldIntent != null) { | 256 | + submitIntents.size(), withdrawPrefixes.size()); |
250 | - // | 257 | + |
251 | - // TODO: Short-term solution to explicitly withdraw | 258 | + // |
252 | - // instead of using "replace" operation. | 259 | + // Prepare the Intent batch operations for the intents to withdraw |
253 | - // | 260 | + // |
254 | - log.debug("SDN-IP Withdrawing old intent: {}", oldIntent); | 261 | + IntentOperations.Builder withdrawBuilder = |
255 | - intentService.withdraw(oldIntent); | 262 | + IntentOperations.builder(appId); |
263 | + for (Ip4Prefix prefix : withdrawPrefixes) { | ||
264 | + intent = routeIntents.remove(prefix); | ||
265 | + if (intent == null) { | ||
266 | + log.debug("SDN-IP No intent in routeIntents to delete " + | ||
267 | + "for prefix: {}", prefix); | ||
268 | + continue; | ||
269 | + } | ||
270 | + if (isElectedLeader && isActivatedLeader) { | ||
271 | + log.debug("SDN-IP Withdrawing intent: {}", intent); | ||
272 | + withdrawBuilder.addWithdrawOperation(intent.id()); | ||
256 | } | 273 | } |
257 | - log.debug("SDN-IP Submitting intent: {}", intent); | ||
258 | - intentService.submit(intent); | ||
259 | } | 274 | } |
260 | - } | ||
261 | - } | ||
262 | 275 | ||
263 | - /** | 276 | + // |
264 | - * Withdraws a multi-point-to-single-point intent. | 277 | + // Prepare the Intent batch operations for the intents to submit |
265 | - * | 278 | + // |
266 | - * @param prefix the IPv4 matching prefix for the intent to withdraw. | 279 | + IntentOperations.Builder submitBuilder = |
267 | - */ | 280 | + IntentOperations.builder(appId); |
268 | - void withdrawRouteIntent(Ip4Prefix prefix) { | 281 | + for (Pair<Ip4Prefix, MultiPointToSinglePointIntent> pair : |
269 | - synchronized (this) { | 282 | + submitIntents) { |
270 | - MultiPointToSinglePointIntent intent = | 283 | + Ip4Prefix prefix = pair.getLeft(); |
271 | - routeIntents.remove(prefix); | 284 | + intent = pair.getRight(); |
272 | - | 285 | + MultiPointToSinglePointIntent oldIntent = |
273 | - if (intent == null) { | 286 | + routeIntents.put(prefix, intent); |
274 | - log.debug("SDN-IP no intent in routeIntents to delete for " + | 287 | + if (isElectedLeader && isActivatedLeader) { |
275 | - "prefix: {}", prefix); | 288 | + if (oldIntent != null) { |
276 | - return; | 289 | + // |
290 | + // TODO: Short-term solution to explicitly withdraw | ||
291 | + // instead of using "replace" operation. | ||
292 | + // | ||
293 | + log.debug("SDN-IP Withdrawing old intent: {}", | ||
294 | + oldIntent); | ||
295 | + withdrawBuilder.addWithdrawOperation(oldIntent.id()); | ||
296 | + } | ||
297 | + log.debug("SDN-IP Submitting intent: {}", intent); | ||
298 | + submitBuilder.addSubmitOperation(intent); | ||
299 | + } | ||
277 | } | 300 | } |
278 | 301 | ||
302 | + // | ||
303 | + // Submit the Intent operations | ||
304 | + // | ||
279 | if (isElectedLeader && isActivatedLeader) { | 305 | if (isElectedLeader && isActivatedLeader) { |
280 | - log.debug("SDN-IP Withdrawing intent: {}", intent); | 306 | + IntentOperations intentOperations = withdrawBuilder.build(); |
281 | - intentService.withdraw(intent); | 307 | + if (!intentOperations.operations().isEmpty()) { |
308 | + log.debug("SDN-IP Withdrawing intents executed"); | ||
309 | + intentService.execute(intentOperations); | ||
310 | + } | ||
311 | + intentOperations = submitBuilder.build(); | ||
312 | + if (!intentOperations.operations().isEmpty()) { | ||
313 | + log.debug("SDN-IP Submitting intents executed"); | ||
314 | + intentService.execute(intentOperations); | ||
315 | + } | ||
282 | } | 316 | } |
283 | } | 317 | } |
284 | } | 318 | } | ... | ... |
... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
15 | */ | 15 | */ |
16 | package org.onlab.onos.sdnip; | 16 | package org.onlab.onos.sdnip; |
17 | 17 | ||
18 | +import java.util.Collection; | ||
19 | + | ||
18 | /** | 20 | /** |
19 | * An interface to receive route updates from route providers. | 21 | * An interface to receive route updates from route providers. |
20 | */ | 22 | */ |
... | @@ -22,7 +24,7 @@ public interface RouteListener { | ... | @@ -22,7 +24,7 @@ public interface RouteListener { |
22 | /** | 24 | /** |
23 | * Receives a route update from a route provider. | 25 | * Receives a route update from a route provider. |
24 | * | 26 | * |
25 | - * @param routeUpdate the updated route information | 27 | + * @param routeUpdates the collection with updated route information |
26 | */ | 28 | */ |
27 | - public void update(RouteUpdate routeUpdate); | 29 | + public void update(Collection<RouteUpdate> routeUpdates); |
28 | } | 30 | } | ... | ... |
... | @@ -20,12 +20,15 @@ import java.util.HashSet; | ... | @@ -20,12 +20,15 @@ import java.util.HashSet; |
20 | import java.util.Iterator; | 20 | import java.util.Iterator; |
21 | import java.util.LinkedList; | 21 | import java.util.LinkedList; |
22 | import java.util.List; | 22 | import java.util.List; |
23 | +import java.util.Map; | ||
23 | import java.util.Set; | 24 | import java.util.Set; |
24 | import java.util.concurrent.BlockingQueue; | 25 | import java.util.concurrent.BlockingQueue; |
26 | +import java.util.concurrent.ConcurrentHashMap; | ||
25 | import java.util.concurrent.ExecutorService; | 27 | import java.util.concurrent.ExecutorService; |
26 | import java.util.concurrent.Executors; | 28 | import java.util.concurrent.Executors; |
27 | import java.util.concurrent.LinkedBlockingQueue; | 29 | import java.util.concurrent.LinkedBlockingQueue; |
28 | 30 | ||
31 | +import org.apache.commons.lang3.tuple.Pair; | ||
29 | import org.onlab.onos.core.ApplicationId; | 32 | import org.onlab.onos.core.ApplicationId; |
30 | import org.onlab.onos.net.ConnectPoint; | 33 | import org.onlab.onos.net.ConnectPoint; |
31 | import org.onlab.onos.net.Host; | 34 | import org.onlab.onos.net.Host; |
... | @@ -74,11 +77,14 @@ public class Router implements RouteListener { | ... | @@ -74,11 +77,14 @@ public class Router implements RouteListener { |
74 | private InvertedRadixTree<RouteEntry> bgpRoutes; | 77 | private InvertedRadixTree<RouteEntry> bgpRoutes; |
75 | 78 | ||
76 | // Stores all incoming route updates in a queue. | 79 | // Stores all incoming route updates in a queue. |
77 | - private final BlockingQueue<RouteUpdate> routeUpdates; | 80 | + private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue; |
78 | 81 | ||
79 | // The Ip4Address is the next hop address of each route update. | 82 | // The Ip4Address is the next hop address of each route update. |
80 | private final SetMultimap<Ip4Address, RouteEntry> routesWaitingOnArp; | 83 | private final SetMultimap<Ip4Address, RouteEntry> routesWaitingOnArp; |
81 | 84 | ||
85 | + // The IPv4 address to MAC address mapping | ||
86 | + private final Map<Ip4Address, MacAddress> ip2Mac; | ||
87 | + | ||
82 | private final ApplicationId appId; | 88 | private final ApplicationId appId; |
83 | private final IntentSynchronizer intentSynchronizer; | 89 | private final IntentSynchronizer intentSynchronizer; |
84 | private final HostService hostService; | 90 | private final HostService hostService; |
... | @@ -110,9 +116,10 @@ public class Router implements RouteListener { | ... | @@ -110,9 +116,10 @@ public class Router implements RouteListener { |
110 | 116 | ||
111 | bgpRoutes = new ConcurrentInvertedRadixTree<>( | 117 | bgpRoutes = new ConcurrentInvertedRadixTree<>( |
112 | new DefaultByteArrayNodeFactory()); | 118 | new DefaultByteArrayNodeFactory()); |
113 | - routeUpdates = new LinkedBlockingQueue<>(); | 119 | + routeUpdatesQueue = new LinkedBlockingQueue<>(); |
114 | routesWaitingOnArp = Multimaps.synchronizedSetMultimap( | 120 | routesWaitingOnArp = Multimaps.synchronizedSetMultimap( |
115 | HashMultimap.<Ip4Address, RouteEntry>create()); | 121 | HashMultimap.<Ip4Address, RouteEntry>create()); |
122 | + ip2Mac = new ConcurrentHashMap<>(); | ||
116 | 123 | ||
117 | bgpUpdatesExecutor = Executors.newSingleThreadExecutor( | 124 | bgpUpdatesExecutor = Executors.newSingleThreadExecutor( |
118 | new ThreadFactoryBuilder() | 125 | new ThreadFactoryBuilder() |
... | @@ -146,19 +153,18 @@ public class Router implements RouteListener { | ... | @@ -146,19 +153,18 @@ public class Router implements RouteListener { |
146 | // Cleanup all local state | 153 | // Cleanup all local state |
147 | bgpRoutes = new ConcurrentInvertedRadixTree<>( | 154 | bgpRoutes = new ConcurrentInvertedRadixTree<>( |
148 | new DefaultByteArrayNodeFactory()); | 155 | new DefaultByteArrayNodeFactory()); |
149 | - routeUpdates.clear(); | 156 | + routeUpdatesQueue.clear(); |
150 | routesWaitingOnArp.clear(); | 157 | routesWaitingOnArp.clear(); |
158 | + ip2Mac.clear(); | ||
151 | } | 159 | } |
152 | } | 160 | } |
153 | 161 | ||
154 | @Override | 162 | @Override |
155 | - public void update(RouteUpdate routeUpdate) { | 163 | + public void update(Collection<RouteUpdate> routeUpdates) { |
156 | - log.debug("Received new route update: {}", routeUpdate); | ||
157 | - | ||
158 | try { | 164 | try { |
159 | - routeUpdates.put(routeUpdate); | 165 | + routeUpdatesQueue.put(routeUpdates); |
160 | } catch (InterruptedException e) { | 166 | } catch (InterruptedException e) { |
161 | - log.debug("Interrupted while putting on routeUpdates queue", e); | 167 | + log.debug("Interrupted while putting on routeUpdatesQueue", e); |
162 | Thread.currentThread().interrupt(); | 168 | Thread.currentThread().interrupt(); |
163 | } | 169 | } |
164 | } | 170 | } |
... | @@ -171,18 +177,9 @@ public class Router implements RouteListener { | ... | @@ -171,18 +177,9 @@ public class Router implements RouteListener { |
171 | try { | 177 | try { |
172 | while (!interrupted) { | 178 | while (!interrupted) { |
173 | try { | 179 | try { |
174 | - RouteUpdate update = routeUpdates.take(); | 180 | + Collection<RouteUpdate> routeUpdates = |
175 | - switch (update.type()) { | 181 | + routeUpdatesQueue.take(); |
176 | - case UPDATE: | 182 | + processRouteUpdates(routeUpdates); |
177 | - processRouteAdd(update.routeEntry()); | ||
178 | - break; | ||
179 | - case DELETE: | ||
180 | - processRouteDelete(update.routeEntry()); | ||
181 | - break; | ||
182 | - default: | ||
183 | - log.error("Unknown update Type: {}", update.type()); | ||
184 | - break; | ||
185 | - } | ||
186 | } catch (InterruptedException e) { | 183 | } catch (InterruptedException e) { |
187 | log.debug("Interrupted while taking from updates queue", e); | 184 | log.debug("Interrupted while taking from updates queue", e); |
188 | interrupted = true; | 185 | interrupted = true; |
... | @@ -198,98 +195,137 @@ public class Router implements RouteListener { | ... | @@ -198,98 +195,137 @@ public class Router implements RouteListener { |
198 | } | 195 | } |
199 | 196 | ||
200 | /** | 197 | /** |
201 | - * Processes adding a route entry. | 198 | + * Processes route updates. |
202 | - * <p> | ||
203 | - * Put new route entry into the radix tree. If there was an existing | ||
204 | - * next hop for this prefix, but the next hop was different, then execute | ||
205 | - * deleting old route entry. If the next hop is the SDN domain, we do not | ||
206 | - * handle it at the moment. Otherwise, execute adding a route. | ||
207 | - * </p> | ||
208 | * | 199 | * |
209 | - * @param routeEntry the route entry to add | 200 | + * @param routeUpdates the route updates to process |
210 | */ | 201 | */ |
211 | - void processRouteAdd(RouteEntry routeEntry) { | 202 | + void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { |
212 | synchronized (this) { | 203 | synchronized (this) { |
213 | - log.debug("Processing route add: {}", routeEntry); | 204 | + Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> |
214 | - | 205 | + submitIntents = new LinkedList<>(); |
215 | - Ip4Prefix prefix = routeEntry.prefix(); | 206 | + Collection<Ip4Prefix> withdrawPrefixes = new LinkedList<>(); |
216 | - Ip4Address nextHop = null; | 207 | + MultiPointToSinglePointIntent intent; |
217 | - RouteEntry foundRouteEntry = | 208 | + |
218 | - bgpRoutes.put(RouteEntry.createBinaryString(prefix), | 209 | + for (RouteUpdate update : routeUpdates) { |
219 | - routeEntry); | 210 | + switch (update.type()) { |
220 | - if (foundRouteEntry != null) { | 211 | + case UPDATE: |
221 | - nextHop = foundRouteEntry.nextHop(); | 212 | + intent = processRouteAdd(update.routeEntry(), |
222 | - } | 213 | + withdrawPrefixes); |
223 | - | 214 | + if (intent != null) { |
224 | - if (nextHop != null && !nextHop.equals(routeEntry.nextHop())) { | 215 | + submitIntents.add(Pair.of(update.routeEntry().prefix(), |
225 | - // There was an existing nexthop for this prefix. This update | 216 | + intent)); |
226 | - // supersedes that, so we need to remove the old flows for this | 217 | + } |
227 | - // prefix from the switches | 218 | + break; |
228 | - executeRouteDelete(routeEntry); | 219 | + case DELETE: |
229 | - } | 220 | + processRouteDelete(update.routeEntry(), withdrawPrefixes); |
230 | - if (nextHop != null && nextHop.equals(routeEntry.nextHop())) { | 221 | + break; |
231 | - return; | 222 | + default: |
232 | - } | 223 | + log.error("Unknown update Type: {}", update.type()); |
233 | - | 224 | + break; |
234 | - if (routeEntry.nextHop().equals(LOCAL_NEXT_HOP)) { | 225 | + } |
235 | - // Route originated by SDN domain | ||
236 | - // We don't handle these at the moment | ||
237 | - log.debug("Own route {} to {}", | ||
238 | - routeEntry.prefix(), routeEntry.nextHop()); | ||
239 | - return; | ||
240 | } | 226 | } |
241 | 227 | ||
242 | - executeRouteAdd(routeEntry); | 228 | + intentSynchronizer.updateRouteIntents(submitIntents, |
229 | + withdrawPrefixes); | ||
243 | } | 230 | } |
244 | } | 231 | } |
245 | 232 | ||
246 | /** | 233 | /** |
247 | - * Executes adding a route entry. | 234 | + * Processes adding a route entry. |
235 | + * <p> | ||
236 | + * The route entry is added to the radix tree. If there was an existing | ||
237 | + * next hop for this prefix, but the next hop was different, then the | ||
238 | + * old route entry is deleted. | ||
239 | + * </p> | ||
248 | * <p> | 240 | * <p> |
249 | - * Find out the egress Interface and MAC address of next hop router for | 241 | + * NOTE: Currently, we don't handle routes if the next hop is within the |
250 | - * this route entry. If the MAC address can not be found in ARP cache, | 242 | + * SDN domain. |
251 | - * then this prefix will be put in routesWaitingOnArp queue. Otherwise, | ||
252 | - * new route intent will be created and installed. | ||
253 | * </p> | 243 | * </p> |
254 | * | 244 | * |
255 | * @param routeEntry the route entry to add | 245 | * @param routeEntry the route entry to add |
246 | + * @param withdrawPrefixes the collection of accumulated prefixes whose | ||
247 | + * intents will be withdrawn | ||
248 | + * @return the corresponding intent that should be submitted, or null | ||
256 | */ | 249 | */ |
257 | - private void executeRouteAdd(RouteEntry routeEntry) { | 250 | + private MultiPointToSinglePointIntent processRouteAdd( |
258 | - log.debug("Executing route add: {}", routeEntry); | 251 | + RouteEntry routeEntry, |
252 | + Collection<Ip4Prefix> withdrawPrefixes) { | ||
253 | + log.debug("Processing route add: {}", routeEntry); | ||
254 | + | ||
255 | + Ip4Prefix prefix = routeEntry.prefix(); | ||
256 | + Ip4Address nextHop = null; | ||
257 | + RouteEntry foundRouteEntry = | ||
258 | + bgpRoutes.put(RouteEntry.createBinaryString(prefix), | ||
259 | + routeEntry); | ||
260 | + if (foundRouteEntry != null) { | ||
261 | + nextHop = foundRouteEntry.nextHop(); | ||
262 | + } | ||
259 | 263 | ||
260 | - // Monitor the IP address so we'll get notified of updates to the MAC | 264 | + if (nextHop != null && !nextHop.equals(routeEntry.nextHop())) { |
261 | - // address. | 265 | + // There was an existing nexthop for this prefix. This update |
262 | - hostService.startMonitoringIp(routeEntry.nextHop()); | 266 | + // supersedes that, so we need to remove the old flows for this |
267 | + // prefix from the switches | ||
268 | + withdrawPrefixes.add(routeEntry.prefix()); | ||
269 | + } | ||
270 | + if (nextHop != null && nextHop.equals(routeEntry.nextHop())) { | ||
271 | + return null; | ||
272 | + } | ||
263 | 273 | ||
264 | - // See if we know the MAC address of the next hop | 274 | + if (routeEntry.nextHop().equals(LOCAL_NEXT_HOP)) { |
265 | - MacAddress nextHopMacAddress = null; | 275 | + // Route originated by SDN domain |
266 | - Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop()); | 276 | + // We don't handle these at the moment |
267 | - if (!hosts.isEmpty()) { | 277 | + log.debug("Own route {} to {}", |
268 | - // TODO how to handle if multiple hosts are returned? | 278 | + routeEntry.prefix(), routeEntry.nextHop()); |
269 | - nextHopMacAddress = hosts.iterator().next().mac(); | 279 | + return null; |
270 | } | 280 | } |
271 | 281 | ||
282 | + // | ||
283 | + // Find the MAC address of next hop router for this route entry. | ||
284 | + // If the MAC address can not be found in ARP cache, then this prefix | ||
285 | + // will be put in routesWaitingOnArp queue. Otherwise, generate | ||
286 | + // a new route intent. | ||
287 | + // | ||
288 | + | ||
289 | + // Monitor the IP address for updates of the MAC address | ||
290 | + hostService.startMonitoringIp(routeEntry.nextHop()); | ||
291 | + | ||
292 | + // Check if we know the MAC address of the next hop | ||
293 | + MacAddress nextHopMacAddress = ip2Mac.get(routeEntry.nextHop()); | ||
294 | + if (nextHopMacAddress == null) { | ||
295 | + Set<Host> hosts = hostService.getHostsByIp(routeEntry.nextHop()); | ||
296 | + if (!hosts.isEmpty()) { | ||
297 | + // TODO how to handle if multiple hosts are returned? | ||
298 | + nextHopMacAddress = hosts.iterator().next().mac(); | ||
299 | + } | ||
300 | + if (nextHopMacAddress != null) { | ||
301 | + ip2Mac.put(routeEntry.nextHop(), nextHopMacAddress); | ||
302 | + } | ||
303 | + } | ||
272 | if (nextHopMacAddress == null) { | 304 | if (nextHopMacAddress == null) { |
273 | routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry); | 305 | routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry); |
274 | - return; | 306 | + return null; |
275 | } | 307 | } |
276 | - | 308 | + return generateRouteIntent(routeEntry.prefix(), routeEntry.nextHop(), |
277 | - addRouteIntentToNextHop(routeEntry.prefix(), | 309 | + nextHopMacAddress); |
278 | - routeEntry.nextHop(), | ||
279 | - nextHopMacAddress); | ||
280 | } | 310 | } |
281 | 311 | ||
282 | /** | 312 | /** |
283 | - * Adds a route intent given a prefix and a next hop IP address. This | 313 | + * Generates a route intent for a prefix, the next hop IP address, and |
284 | - * method will find the egress interface for the intent. | 314 | + * the next hop MAC address. |
315 | + * <p/> | ||
316 | + * This method will find the egress interface for the intent. | ||
317 | + * Intent will match dst IP prefix and rewrite dst MAC address at all other | ||
318 | + * border switches, then forward packets according to dst MAC address. | ||
285 | * | 319 | * |
286 | * @param prefix IP prefix of the route to add | 320 | * @param prefix IP prefix of the route to add |
287 | * @param nextHopIpAddress IP address of the next hop | 321 | * @param nextHopIpAddress IP address of the next hop |
288 | * @param nextHopMacAddress MAC address of the next hop | 322 | * @param nextHopMacAddress MAC address of the next hop |
323 | + * @return the generated intent, or null if no intent should be submitted | ||
289 | */ | 324 | */ |
290 | - private void addRouteIntentToNextHop(Ip4Prefix prefix, | 325 | + private MultiPointToSinglePointIntent generateRouteIntent( |
291 | - Ip4Address nextHopIpAddress, | 326 | + Ip4Prefix prefix, |
292 | - MacAddress nextHopMacAddress) { | 327 | + Ip4Address nextHopIpAddress, |
328 | + MacAddress nextHopMacAddress) { | ||
293 | 329 | ||
294 | // Find the attachment point (egress interface) of the next hop | 330 | // Find the attachment point (egress interface) of the next hop |
295 | Interface egressInterface; | 331 | Interface egressInterface; |
... | @@ -308,30 +344,17 @@ public class Router implements RouteListener { | ... | @@ -308,30 +344,17 @@ public class Router implements RouteListener { |
308 | if (egressInterface == null) { | 344 | if (egressInterface == null) { |
309 | log.warn("No outgoing interface found for {}", | 345 | log.warn("No outgoing interface found for {}", |
310 | nextHopIpAddress); | 346 | nextHopIpAddress); |
311 | - return; | 347 | + return null; |
312 | } | 348 | } |
313 | } | 349 | } |
314 | 350 | ||
315 | - doAddRouteIntent(prefix, egressInterface, nextHopMacAddress); | 351 | + // |
316 | - } | 352 | + // Generate the intent itself |
317 | - | 353 | + // |
318 | - /** | ||
319 | - * Installs a route intent for a prefix. | ||
320 | - * <p/> | ||
321 | - * Intent will match dst IP prefix and rewrite dst MAC address at all other | ||
322 | - * border switches, then forward packets according to dst MAC address. | ||
323 | - * | ||
324 | - * @param prefix IP prefix from route | ||
325 | - * @param egressInterface egress Interface connected to next hop router | ||
326 | - * @param nextHopMacAddress MAC address of next hop router | ||
327 | - */ | ||
328 | - private void doAddRouteIntent(Ip4Prefix prefix, Interface egressInterface, | ||
329 | - MacAddress nextHopMacAddress) { | ||
330 | - log.debug("Adding intent for prefix {}, next hop mac {}", | ||
331 | - prefix, nextHopMacAddress); | ||
332 | - | ||
333 | Set<ConnectPoint> ingressPorts = new HashSet<>(); | 354 | Set<ConnectPoint> ingressPorts = new HashSet<>(); |
334 | ConnectPoint egressPort = egressInterface.connectPoint(); | 355 | ConnectPoint egressPort = egressInterface.connectPoint(); |
356 | + log.debug("Generating intent for prefix {}, next hop mac {}", | ||
357 | + prefix, nextHopMacAddress); | ||
335 | 358 | ||
336 | for (Interface intf : interfaceService.getInterfaces()) { | 359 | for (Interface intf : interfaceService.getInterfaces()) { |
337 | if (!intf.connectPoint().equals(egressInterface.connectPoint())) { | 360 | if (!intf.connectPoint().equals(egressInterface.connectPoint())) { |
... | @@ -351,51 +374,39 @@ public class Router implements RouteListener { | ... | @@ -351,51 +374,39 @@ public class Router implements RouteListener { |
351 | .setEthDst(nextHopMacAddress) | 374 | .setEthDst(nextHopMacAddress) |
352 | .build(); | 375 | .build(); |
353 | 376 | ||
354 | - MultiPointToSinglePointIntent intent = | 377 | + return new MultiPointToSinglePointIntent(appId, selector, treatment, |
355 | - new MultiPointToSinglePointIntent(appId, selector, treatment, | 378 | + ingressPorts, egressPort); |
356 | - ingressPorts, egressPort); | ||
357 | - | ||
358 | - intentSynchronizer.submitRouteIntent(prefix, intent); | ||
359 | } | 379 | } |
360 | 380 | ||
361 | /** | 381 | /** |
362 | - * Executes deleting a route entry. | 382 | + * Processes the deletion of a route entry. |
363 | * <p> | 383 | * <p> |
364 | - * Removes prefix from radix tree, and if successful, then try to delete | 384 | + * The prefix for the routing entry is removed from radix tree. |
365 | - * the related intent. | 385 | + * If the operation is successful, the prefix is added to the collection |
386 | + * of prefixes whose intents that will be withdrawn. | ||
366 | * </p> | 387 | * </p> |
367 | * | 388 | * |
368 | * @param routeEntry the route entry to delete | 389 | * @param routeEntry the route entry to delete |
390 | + * @param withdrawPrefixes the collection of accumulated prefixes whose | ||
391 | + * intents will be withdrawn | ||
369 | */ | 392 | */ |
370 | - void processRouteDelete(RouteEntry routeEntry) { | 393 | + private void processRouteDelete(RouteEntry routeEntry, |
371 | - synchronized (this) { | 394 | + Collection<Ip4Prefix> withdrawPrefixes) { |
372 | - log.debug("Processing route delete: {}", routeEntry); | 395 | + log.debug("Processing route delete: {}", routeEntry); |
373 | - Ip4Prefix prefix = routeEntry.prefix(); | 396 | + Ip4Prefix prefix = routeEntry.prefix(); |
374 | - | 397 | + |
375 | - if (bgpRoutes.remove(RouteEntry.createBinaryString(prefix))) { | 398 | + if (bgpRoutes.remove(RouteEntry.createBinaryString(prefix))) { |
376 | - // | 399 | + // |
377 | - // Only delete flows if an entry was actually removed from the | 400 | + // Only withdraw intents if an entry was actually removed from the |
378 | - // tree. If no entry was removed, the <prefix, nexthop> wasn't | 401 | + // tree. If no entry was removed, the <prefix, nexthop> wasn't |
379 | - // there so it's probably already been removed and we don't | 402 | + // there so it's probably already been removed and we don't |
380 | - // need to do anything. | 403 | + // need to do anything. |
381 | - // | 404 | + // |
382 | - executeRouteDelete(routeEntry); | 405 | + withdrawPrefixes.add(routeEntry.prefix()); |
383 | - } | ||
384 | - | ||
385 | - routesWaitingOnArp.remove(routeEntry.nextHop(), routeEntry); | ||
386 | - // TODO cancel the request in the ARP manager as well | ||
387 | } | 406 | } |
388 | - } | ||
389 | - | ||
390 | - /** | ||
391 | - * Executed deleting a route entry. | ||
392 | - * | ||
393 | - * @param routeEntry the route entry to delete | ||
394 | - */ | ||
395 | - private void executeRouteDelete(RouteEntry routeEntry) { | ||
396 | - log.debug("Executing route delete: {}", routeEntry); | ||
397 | 407 | ||
398 | - intentSynchronizer.withdrawRouteIntent(routeEntry.prefix()); | 408 | + routesWaitingOnArp.remove(routeEntry.nextHop(), routeEntry); |
409 | + // TODO cancel the request in the ARP manager as well | ||
399 | } | 410 | } |
400 | 411 | ||
401 | /** | 412 | /** |
... | @@ -418,6 +429,9 @@ public class Router implements RouteListener { | ... | @@ -418,6 +429,9 @@ public class Router implements RouteListener { |
418 | // while we're pushing intents. If the tree changes, the | 429 | // while we're pushing intents. If the tree changes, the |
419 | // tree and intents could get out of sync. | 430 | // tree and intents could get out of sync. |
420 | synchronized (this) { | 431 | synchronized (this) { |
432 | + Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> | ||
433 | + submitIntents = new LinkedList<>(); | ||
434 | + MultiPointToSinglePointIntent intent; | ||
421 | 435 | ||
422 | Set<RouteEntry> routesToPush = | 436 | Set<RouteEntry> routesToPush = |
423 | routesWaitingOnArp.removeAll(ipAddress); | 437 | routesWaitingOnArp.removeAll(ipAddress); |
... | @@ -429,18 +443,30 @@ public class Router implements RouteListener { | ... | @@ -429,18 +443,30 @@ public class Router implements RouteListener { |
429 | RouteEntry foundRouteEntry = | 443 | RouteEntry foundRouteEntry = |
430 | bgpRoutes.getValueForExactKey(binaryString); | 444 | bgpRoutes.getValueForExactKey(binaryString); |
431 | if (foundRouteEntry != null && | 445 | if (foundRouteEntry != null && |
432 | - foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { | 446 | + foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { |
433 | // We only push prefix flows if the prefix is still in the | 447 | // We only push prefix flows if the prefix is still in the |
434 | // radix tree and the next hop is the same as our | 448 | // radix tree and the next hop is the same as our |
435 | // update. | 449 | // update. |
436 | // The prefix could have been removed while we were waiting | 450 | // The prefix could have been removed while we were waiting |
437 | // for the ARP, or the next hop could have changed. | 451 | // for the ARP, or the next hop could have changed. |
438 | - addRouteIntentToNextHop(prefix, ipAddress, macAddress); | 452 | + intent = generateRouteIntent(prefix, ipAddress, |
453 | + macAddress); | ||
454 | + if (intent != null) { | ||
455 | + submitIntents.add(Pair.of(prefix, intent)); | ||
456 | + } | ||
439 | } else { | 457 | } else { |
440 | log.debug("{} has been revoked before the MAC was resolved", | 458 | log.debug("{} has been revoked before the MAC was resolved", |
441 | - routeEntry); | 459 | + routeEntry); |
442 | } | 460 | } |
443 | } | 461 | } |
462 | + | ||
463 | + if (!submitIntents.isEmpty()) { | ||
464 | + Collection<Ip4Prefix> withdrawPrefixes = new LinkedList<>(); | ||
465 | + intentSynchronizer.updateRouteIntents(submitIntents, | ||
466 | + withdrawPrefixes); | ||
467 | + } | ||
468 | + | ||
469 | + ip2Mac.put(ipAddress, macAddress); | ||
444 | } | 470 | } |
445 | } | 471 | } |
446 | 472 | ||
... | @@ -469,9 +495,13 @@ public class Router implements RouteListener { | ... | @@ -469,9 +495,13 @@ public class Router implements RouteListener { |
469 | class InternalHostListener implements HostListener { | 495 | class InternalHostListener implements HostListener { |
470 | @Override | 496 | @Override |
471 | public void event(HostEvent event) { | 497 | public void event(HostEvent event) { |
472 | - if (event.type() == HostEvent.Type.HOST_ADDED || | 498 | + log.debug("Received HostEvent {}", event); |
473 | - event.type() == HostEvent.Type.HOST_UPDATED) { | 499 | + |
474 | - Host host = event.subject(); | 500 | + Host host = event.subject(); |
501 | + switch (event.type()) { | ||
502 | + case HOST_ADDED: | ||
503 | + // FALLTHROUGH | ||
504 | + case HOST_UPDATED: | ||
475 | for (IpAddress ip : host.ipAddresses()) { | 505 | for (IpAddress ip : host.ipAddresses()) { |
476 | Ip4Address ip4Address = ip.getIp4Address(); | 506 | Ip4Address ip4Address = ip.getIp4Address(); |
477 | if (ip4Address == null) { | 507 | if (ip4Address == null) { |
... | @@ -480,6 +510,19 @@ public class Router implements RouteListener { | ... | @@ -480,6 +510,19 @@ public class Router implements RouteListener { |
480 | } | 510 | } |
481 | updateMac(ip4Address, host.mac()); | 511 | updateMac(ip4Address, host.mac()); |
482 | } | 512 | } |
513 | + break; | ||
514 | + case HOST_REMOVED: | ||
515 | + for (IpAddress ip : host.ipAddresses()) { | ||
516 | + Ip4Address ip4Address = ip.getIp4Address(); | ||
517 | + if (ip4Address == null) { | ||
518 | + // TODO: For now we support only IPv4 | ||
519 | + continue; | ||
520 | + } | ||
521 | + ip2Mac.remove(ip4Address); | ||
522 | + } | ||
523 | + break; | ||
524 | + default: | ||
525 | + break; | ||
483 | } | 526 | } |
484 | } | 527 | } |
485 | } | 528 | } | ... | ... |
... | @@ -22,6 +22,7 @@ import java.net.InetAddress; | ... | @@ -22,6 +22,7 @@ import java.net.InetAddress; |
22 | import java.net.InetSocketAddress; | 22 | import java.net.InetSocketAddress; |
23 | import java.net.SocketAddress; | 23 | import java.net.SocketAddress; |
24 | import java.util.Collection; | 24 | import java.util.Collection; |
25 | +import java.util.LinkedList; | ||
25 | import java.util.concurrent.ConcurrentHashMap; | 26 | import java.util.concurrent.ConcurrentHashMap; |
26 | import java.util.concurrent.ConcurrentMap; | 27 | import java.util.concurrent.ConcurrentMap; |
27 | import java.util.concurrent.Executors; | 28 | import java.util.concurrent.Executors; |
... | @@ -248,18 +249,28 @@ public class BgpSessionManager { | ... | @@ -248,18 +249,28 @@ public class BgpSessionManager { |
248 | synchronized void routeUpdates(BgpSession bgpSession, | 249 | synchronized void routeUpdates(BgpSession bgpSession, |
249 | Collection<BgpRouteEntry> addedBgpRouteEntries, | 250 | Collection<BgpRouteEntry> addedBgpRouteEntries, |
250 | Collection<BgpRouteEntry> deletedBgpRouteEntries) { | 251 | Collection<BgpRouteEntry> deletedBgpRouteEntries) { |
252 | + Collection<RouteUpdate> routeUpdates = new LinkedList<>(); | ||
253 | + RouteUpdate routeUpdate; | ||
254 | + | ||
251 | if (isShutdown) { | 255 | if (isShutdown) { |
252 | return; // Ignore any leftover updates if shutdown | 256 | return; // Ignore any leftover updates if shutdown |
253 | } | 257 | } |
254 | // Process the deleted route entries | 258 | // Process the deleted route entries |
255 | for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) { | 259 | for (BgpRouteEntry bgpRouteEntry : deletedBgpRouteEntries) { |
256 | - processDeletedRoute(bgpSession, bgpRouteEntry); | 260 | + routeUpdate = processDeletedRoute(bgpSession, bgpRouteEntry); |
261 | + if (routeUpdate != null) { | ||
262 | + routeUpdates.add(routeUpdate); | ||
263 | + } | ||
257 | } | 264 | } |
258 | 265 | ||
259 | // Process the added/updated route entries | 266 | // Process the added/updated route entries |
260 | for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) { | 267 | for (BgpRouteEntry bgpRouteEntry : addedBgpRouteEntries) { |
261 | - processAddedRoute(bgpSession, bgpRouteEntry); | 268 | + routeUpdate = processAddedRoute(bgpSession, bgpRouteEntry); |
269 | + if (routeUpdate != null) { | ||
270 | + routeUpdates.add(routeUpdate); | ||
271 | + } | ||
262 | } | 272 | } |
273 | + routeListener.update(routeUpdates); | ||
263 | } | 274 | } |
264 | 275 | ||
265 | /** | 276 | /** |
... | @@ -268,9 +279,11 @@ public class BgpSessionManager { | ... | @@ -268,9 +279,11 @@ public class BgpSessionManager { |
268 | * @param bgpSession the BGP session the route entry update was | 279 | * @param bgpSession the BGP session the route entry update was |
269 | * received on | 280 | * received on |
270 | * @param bgpRouteEntry the added/updated route entry | 281 | * @param bgpRouteEntry the added/updated route entry |
282 | + * @return the result route update that should be forwarded to the | ||
283 | + * Route Listener, or null if no route update should be forwarded | ||
271 | */ | 284 | */ |
272 | - private void processAddedRoute(BgpSession bgpSession, | 285 | + private RouteUpdate processAddedRoute(BgpSession bgpSession, |
273 | - BgpRouteEntry bgpRouteEntry) { | 286 | + BgpRouteEntry bgpRouteEntry) { |
274 | RouteUpdate routeUpdate; | 287 | RouteUpdate routeUpdate; |
275 | BgpRouteEntry bestBgpRouteEntry = | 288 | BgpRouteEntry bestBgpRouteEntry = |
276 | bgpRoutes.get(bgpRouteEntry.prefix()); | 289 | bgpRoutes.get(bgpRouteEntry.prefix()); |
... | @@ -284,9 +297,7 @@ public class BgpSessionManager { | ... | @@ -284,9 +297,7 @@ public class BgpSessionManager { |
284 | bgpRoutes.put(bgpRouteEntry.prefix(), bgpRouteEntry); | 297 | bgpRoutes.put(bgpRouteEntry.prefix(), bgpRouteEntry); |
285 | routeUpdate = | 298 | routeUpdate = |
286 | new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry); | 299 | new RouteUpdate(RouteUpdate.Type.UPDATE, bgpRouteEntry); |
287 | - // Forward the result route updates to the Route Listener | 300 | + return routeUpdate; |
288 | - routeListener.update(routeUpdate); | ||
289 | - return; | ||
290 | } | 301 | } |
291 | 302 | ||
292 | // | 303 | // |
... | @@ -296,7 +307,7 @@ public class BgpSessionManager { | ... | @@ -296,7 +307,7 @@ public class BgpSessionManager { |
296 | // | 307 | // |
297 | if (bestBgpRouteEntry.getBgpSession() != | 308 | if (bestBgpRouteEntry.getBgpSession() != |
298 | bgpRouteEntry.getBgpSession()) { | 309 | bgpRouteEntry.getBgpSession()) { |
299 | - return; | 310 | + return null; // Nothing to do |
300 | } | 311 | } |
301 | 312 | ||
302 | // Find the next best route | 313 | // Find the next best route |
... | @@ -315,8 +326,7 @@ public class BgpSessionManager { | ... | @@ -315,8 +326,7 @@ public class BgpSessionManager { |
315 | bgpRoutes.put(bestBgpRouteEntry.prefix(), bestBgpRouteEntry); | 326 | bgpRoutes.put(bestBgpRouteEntry.prefix(), bestBgpRouteEntry); |
316 | routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | 327 | routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
317 | bestBgpRouteEntry); | 328 | bestBgpRouteEntry); |
318 | - // Forward the result route updates to the Route Listener | 329 | + return routeUpdate; |
319 | - routeListener.update(routeUpdate); | ||
320 | } | 330 | } |
321 | 331 | ||
322 | /** | 332 | /** |
... | @@ -325,9 +335,11 @@ public class BgpSessionManager { | ... | @@ -325,9 +335,11 @@ public class BgpSessionManager { |
325 | * @param bgpSession the BGP session the route entry update was | 335 | * @param bgpSession the BGP session the route entry update was |
326 | * received on | 336 | * received on |
327 | * @param bgpRouteEntry the deleted route entry | 337 | * @param bgpRouteEntry the deleted route entry |
338 | + * @return the result route update that should be forwarded to the | ||
339 | + * Route Listener, or null if no route update should be forwarded | ||
328 | */ | 340 | */ |
329 | - private void processDeletedRoute(BgpSession bgpSession, | 341 | + private RouteUpdate processDeletedRoute(BgpSession bgpSession, |
330 | - BgpRouteEntry bgpRouteEntry) { | 342 | + BgpRouteEntry bgpRouteEntry) { |
331 | RouteUpdate routeUpdate; | 343 | RouteUpdate routeUpdate; |
332 | BgpRouteEntry bestBgpRouteEntry = | 344 | BgpRouteEntry bestBgpRouteEntry = |
333 | bgpRoutes.get(bgpRouteEntry.prefix()); | 345 | bgpRoutes.get(bgpRouteEntry.prefix()); |
... | @@ -340,7 +352,7 @@ public class BgpSessionManager { | ... | @@ -340,7 +352,7 @@ public class BgpSessionManager { |
340 | // because we need to check whether this is same object. | 352 | // because we need to check whether this is same object. |
341 | // | 353 | // |
342 | if (bgpRouteEntry != bestBgpRouteEntry) { | 354 | if (bgpRouteEntry != bestBgpRouteEntry) { |
343 | - return; // Nothing to do | 355 | + return null; // Nothing to do |
344 | } | 356 | } |
345 | 357 | ||
346 | // | 358 | // |
... | @@ -353,9 +365,7 @@ public class BgpSessionManager { | ... | @@ -353,9 +365,7 @@ public class BgpSessionManager { |
353 | bestBgpRouteEntry); | 365 | bestBgpRouteEntry); |
354 | routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, | 366 | routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
355 | bestBgpRouteEntry); | 367 | bestBgpRouteEntry); |
356 | - // Forward the result route updates to the Route Listener | 368 | + return routeUpdate; |
357 | - routeListener.update(routeUpdate); | ||
358 | - return; | ||
359 | } | 369 | } |
360 | 370 | ||
361 | // | 371 | // |
... | @@ -364,8 +374,7 @@ public class BgpSessionManager { | ... | @@ -364,8 +374,7 @@ public class BgpSessionManager { |
364 | bgpRoutes.remove(bgpRouteEntry.prefix()); | 374 | bgpRoutes.remove(bgpRouteEntry.prefix()); |
365 | routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, | 375 | routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, |
366 | bgpRouteEntry); | 376 | bgpRouteEntry); |
367 | - // Forward the result route updates to the Route Listener | 377 | + return routeUpdate; |
368 | - routeListener.update(routeUpdate); | ||
369 | } | 378 | } |
370 | 379 | ||
371 | /** | 380 | /** | ... | ... |
... | @@ -325,13 +325,13 @@ public class IntentSyncTest extends AbstractIntentTest { | ... | @@ -325,13 +325,13 @@ public class IntentSyncTest extends AbstractIntentTest { |
325 | .andReturn(IntentState.WITHDRAWING).anyTimes(); | 325 | .andReturn(IntentState.WITHDRAWING).anyTimes(); |
326 | expect(intentService.getIntents()).andReturn(intents).anyTimes(); | 326 | expect(intentService.getIntents()).andReturn(intents).anyTimes(); |
327 | 327 | ||
328 | - IntentOperations.Builder builder = IntentOperations.builder(null); //FIXME null | 328 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
329 | builder.addWithdrawOperation(intent2.id()); | 329 | builder.addWithdrawOperation(intent2.id()); |
330 | builder.addWithdrawOperation(intent4.id()); | 330 | builder.addWithdrawOperation(intent4.id()); |
331 | intentService.execute(TestIntentServiceHelper.eqExceptId( | 331 | intentService.execute(TestIntentServiceHelper.eqExceptId( |
332 | builder.build())); | 332 | builder.build())); |
333 | 333 | ||
334 | - builder = IntentOperations.builder(null); //FIXME null | 334 | + builder = IntentOperations.builder(APPID); |
335 | builder.addSubmitOperation(intent3); | 335 | builder.addSubmitOperation(intent3); |
336 | builder.addSubmitOperation(intent4Update); | 336 | builder.addSubmitOperation(intent4Update); |
337 | builder.addSubmitOperation(intent6); | 337 | builder.addSubmitOperation(intent6); | ... | ... |
... | @@ -566,7 +566,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -566,7 +566,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
566 | reset(intentService); | 566 | reset(intentService); |
567 | 567 | ||
568 | // Setup the expected intents | 568 | // Setup the expected intents |
569 | - IntentOperations.Builder builder = IntentOperations.builder(null); //FIXME null | 569 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
570 | for (Intent intent : intentList) { | 570 | for (Intent intent : intentList) { |
571 | builder.addSubmitOperation(intent); | 571 | builder.addSubmitOperation(intent); |
572 | } | 572 | } |
... | @@ -601,9 +601,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -601,9 +601,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
601 | replay(configInfoService); | 601 | replay(configInfoService); |
602 | 602 | ||
603 | reset(intentService); | 603 | reset(intentService); |
604 | - IntentOperations.Builder builder = IntentOperations.builder(null); //FIXME null | 604 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
605 | - intentService.execute(TestIntentServiceHelper.eqExceptId( | 605 | + intentService.execute(builder.build()); |
606 | - builder.build())); | ||
607 | replay(intentService); | 606 | replay(intentService); |
608 | peerConnectivityManager.start(); | 607 | peerConnectivityManager.start(); |
609 | verify(intentService); | 608 | verify(intentService); |
... | @@ -627,9 +626,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -627,9 +626,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
627 | replay(configInfoService); | 626 | replay(configInfoService); |
628 | 627 | ||
629 | reset(intentService); | 628 | reset(intentService); |
630 | - IntentOperations.Builder builder = IntentOperations.builder(null); //FIXME null | 629 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
631 | - intentService.execute(TestIntentServiceHelper.eqExceptId( | 630 | + intentService.execute(builder.build()); |
632 | - builder.build())); | ||
633 | replay(intentService); | 631 | replay(intentService); |
634 | peerConnectivityManager.start(); | 632 | peerConnectivityManager.start(); |
635 | verify(intentService); | 633 | verify(intentService); | ... | ... |
... | @@ -25,6 +25,7 @@ import static org.easymock.EasyMock.verify; | ... | @@ -25,6 +25,7 @@ import static org.easymock.EasyMock.verify; |
25 | import static org.junit.Assert.assertEquals; | 25 | import static org.junit.Assert.assertEquals; |
26 | import static org.junit.Assert.assertTrue; | 26 | import static org.junit.Assert.assertTrue; |
27 | 27 | ||
28 | +import java.util.Collections; | ||
28 | import java.util.HashMap; | 29 | import java.util.HashMap; |
29 | import java.util.HashSet; | 30 | import java.util.HashSet; |
30 | import java.util.Map; | 31 | import java.util.Map; |
... | @@ -50,6 +51,7 @@ import org.onlab.onos.net.host.HostListener; | ... | @@ -50,6 +51,7 @@ import org.onlab.onos.net.host.HostListener; |
50 | import org.onlab.onos.net.host.HostService; | 51 | import org.onlab.onos.net.host.HostService; |
51 | import org.onlab.onos.net.host.InterfaceIpAddress; | 52 | import org.onlab.onos.net.host.InterfaceIpAddress; |
52 | import org.onlab.onos.net.intent.Intent; | 53 | import org.onlab.onos.net.intent.Intent; |
54 | +import org.onlab.onos.net.intent.IntentOperations; | ||
53 | import org.onlab.onos.net.intent.IntentService; | 55 | import org.onlab.onos.net.intent.IntentService; |
54 | import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; | 56 | import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; |
55 | import org.onlab.onos.net.intent.AbstractIntentTest; | 57 | import org.onlab.onos.net.intent.AbstractIntentTest; |
... | @@ -234,7 +236,7 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -234,7 +236,7 @@ public class RouterTest extends AbstractIntentTest { |
234 | * This method tests adding a route entry. | 236 | * This method tests adding a route entry. |
235 | */ | 237 | */ |
236 | @Test | 238 | @Test |
237 | - public void testProcessRouteAdd() throws TestUtilsException { | 239 | + public void testRouteAdd() throws TestUtilsException { |
238 | // Construct a route entry | 240 | // Construct a route entry |
239 | RouteEntry routeEntry = new RouteEntry( | 241 | RouteEntry routeEntry = new RouteEntry( |
240 | Ip4Prefix.valueOf("1.1.1.0/24"), | 242 | Ip4Prefix.valueOf("1.1.1.0/24"), |
... | @@ -261,13 +263,19 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -261,13 +263,19 @@ public class RouterTest extends AbstractIntentTest { |
261 | 263 | ||
262 | // Set up test expectation | 264 | // Set up test expectation |
263 | reset(intentService); | 265 | reset(intentService); |
264 | - intentService.submit(TestIntentServiceHelper.eqExceptId(intent)); | 266 | + // Setup the expected intents |
267 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); | ||
268 | + builder.addSubmitOperation(intent); | ||
269 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
270 | + builder.build())); | ||
265 | replay(intentService); | 271 | replay(intentService); |
266 | 272 | ||
267 | - // Call the processRouteAdd() method in Router class | 273 | + // Call the processRouteUpdates() method in Router class |
268 | intentSynchronizer.leaderChanged(true); | 274 | intentSynchronizer.leaderChanged(true); |
269 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 275 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
270 | - router.processRouteAdd(routeEntry); | 276 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
277 | + routeEntry); | ||
278 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
271 | 279 | ||
272 | // Verify | 280 | // Verify |
273 | assertEquals(router.getRoutes().size(), 1); | 281 | assertEquals(router.getRoutes().size(), 1); |
... | @@ -289,32 +297,16 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -289,32 +297,16 @@ public class RouterTest extends AbstractIntentTest { |
289 | @Test | 297 | @Test |
290 | public void testRouteUpdate() throws TestUtilsException { | 298 | public void testRouteUpdate() throws TestUtilsException { |
291 | // Firstly add a route | 299 | // Firstly add a route |
292 | - testProcessRouteAdd(); | 300 | + testRouteAdd(); |
301 | + | ||
302 | + Intent addedIntent = | ||
303 | + intentSynchronizer.getRouteIntents().iterator().next(); | ||
293 | 304 | ||
294 | // Construct the existing route entry | 305 | // Construct the existing route entry |
295 | RouteEntry routeEntry = new RouteEntry( | 306 | RouteEntry routeEntry = new RouteEntry( |
296 | Ip4Prefix.valueOf("1.1.1.0/24"), | 307 | Ip4Prefix.valueOf("1.1.1.0/24"), |
297 | Ip4Address.valueOf("192.168.10.1")); | 308 | Ip4Address.valueOf("192.168.10.1")); |
298 | 309 | ||
299 | - // Construct the existing MultiPointToSinglePointIntent intent | ||
300 | - TrafficSelector.Builder selectorBuilder = | ||
301 | - DefaultTrafficSelector.builder(); | ||
302 | - selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst( | ||
303 | - routeEntry.prefix()); | ||
304 | - | ||
305 | - TrafficTreatment.Builder treatmentBuilder = | ||
306 | - DefaultTrafficTreatment.builder(); | ||
307 | - treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01")); | ||
308 | - | ||
309 | - Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>(); | ||
310 | - ingressPoints.add(SW2_ETH1); | ||
311 | - ingressPoints.add(SW3_ETH1); | ||
312 | - | ||
313 | - MultiPointToSinglePointIntent intent = | ||
314 | - new MultiPointToSinglePointIntent(APPID, | ||
315 | - selectorBuilder.build(), treatmentBuilder.build(), | ||
316 | - ingressPoints, SW1_ETH1); | ||
317 | - | ||
318 | // Start to construct a new route entry and new intent | 310 | // Start to construct a new route entry and new intent |
319 | RouteEntry routeEntryUpdate = new RouteEntry( | 311 | RouteEntry routeEntryUpdate = new RouteEntry( |
320 | Ip4Prefix.valueOf("1.1.1.0/24"), | 312 | Ip4Prefix.valueOf("1.1.1.0/24"), |
... | @@ -343,14 +335,23 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -343,14 +335,23 @@ public class RouterTest extends AbstractIntentTest { |
343 | 335 | ||
344 | // Set up test expectation | 336 | // Set up test expectation |
345 | reset(intentService); | 337 | reset(intentService); |
346 | - intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent)); | 338 | + // Setup the expected intents |
347 | - intentService.submit(TestIntentServiceHelper.eqExceptId(intentNew)); | 339 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
340 | + builder.addWithdrawOperation(addedIntent.id()); | ||
341 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
342 | + builder.build())); | ||
343 | + builder = IntentOperations.builder(APPID); | ||
344 | + builder.addSubmitOperation(intentNew); | ||
345 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
346 | + builder.build())); | ||
348 | replay(intentService); | 347 | replay(intentService); |
349 | 348 | ||
350 | - // Call the processRouteAdd() method in Router class | 349 | + // Call the processRouteUpdates() method in Router class |
351 | intentSynchronizer.leaderChanged(true); | 350 | intentSynchronizer.leaderChanged(true); |
352 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 351 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
353 | - router.processRouteAdd(routeEntryUpdate); | 352 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
353 | + routeEntryUpdate); | ||
354 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
354 | 355 | ||
355 | // Verify | 356 | // Verify |
356 | assertEquals(router.getRoutes().size(), 1); | 357 | assertEquals(router.getRoutes().size(), 1); |
... | @@ -368,43 +369,33 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -368,43 +369,33 @@ public class RouterTest extends AbstractIntentTest { |
368 | * This method tests deleting a route entry. | 369 | * This method tests deleting a route entry. |
369 | */ | 370 | */ |
370 | @Test | 371 | @Test |
371 | - public void testProcessRouteDelete() throws TestUtilsException { | 372 | + public void testRouteDelete() throws TestUtilsException { |
372 | // Firstly add a route | 373 | // Firstly add a route |
373 | - testProcessRouteAdd(); | 374 | + testRouteAdd(); |
375 | + | ||
376 | + Intent addedIntent = | ||
377 | + intentSynchronizer.getRouteIntents().iterator().next(); | ||
374 | 378 | ||
375 | // Construct the existing route entry | 379 | // Construct the existing route entry |
376 | RouteEntry routeEntry = new RouteEntry( | 380 | RouteEntry routeEntry = new RouteEntry( |
377 | Ip4Prefix.valueOf("1.1.1.0/24"), | 381 | Ip4Prefix.valueOf("1.1.1.0/24"), |
378 | Ip4Address.valueOf("192.168.10.1")); | 382 | Ip4Address.valueOf("192.168.10.1")); |
379 | 383 | ||
380 | - // Construct the existing MultiPointToSinglePointIntent intent | ||
381 | - TrafficSelector.Builder selectorBuilder = | ||
382 | - DefaultTrafficSelector.builder(); | ||
383 | - selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst( | ||
384 | - routeEntry.prefix()); | ||
385 | - | ||
386 | - TrafficTreatment.Builder treatmentBuilder = | ||
387 | - DefaultTrafficTreatment.builder(); | ||
388 | - treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01")); | ||
389 | - | ||
390 | - Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>(); | ||
391 | - ingressPoints.add(SW2_ETH1); | ||
392 | - ingressPoints.add(SW3_ETH1); | ||
393 | - | ||
394 | - MultiPointToSinglePointIntent intent = | ||
395 | - new MultiPointToSinglePointIntent(APPID, | ||
396 | - selectorBuilder.build(), treatmentBuilder.build(), | ||
397 | - ingressPoints, SW1_ETH1); | ||
398 | - | ||
399 | // Set up expectation | 384 | // Set up expectation |
400 | reset(intentService); | 385 | reset(intentService); |
401 | - intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent)); | 386 | + // Setup the expected intents |
387 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); | ||
388 | + builder.addWithdrawOperation(addedIntent.id()); | ||
389 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
390 | + builder.build())); | ||
402 | replay(intentService); | 391 | replay(intentService); |
403 | 392 | ||
404 | - // Call route deleting method in Router class | 393 | + // Call the processRouteUpdates() method in Router class |
405 | intentSynchronizer.leaderChanged(true); | 394 | intentSynchronizer.leaderChanged(true); |
406 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 395 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
407 | - router.processRouteDelete(routeEntry); | 396 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, |
397 | + routeEntry); | ||
398 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
408 | 399 | ||
409 | // Verify | 400 | // Verify |
410 | assertEquals(router.getRoutes().size(), 0); | 401 | assertEquals(router.getRoutes().size(), 0); |
... | @@ -428,10 +419,12 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -428,10 +419,12 @@ public class RouterTest extends AbstractIntentTest { |
428 | reset(intentService); | 419 | reset(intentService); |
429 | replay(intentService); | 420 | replay(intentService); |
430 | 421 | ||
431 | - // Call the processRouteAdd() method in Router class | 422 | + // Call the processRouteUpdates() method in Router class |
432 | intentSynchronizer.leaderChanged(true); | 423 | intentSynchronizer.leaderChanged(true); |
433 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 424 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
434 | - router.processRouteAdd(routeEntry); | 425 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
426 | + routeEntry); | ||
427 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
435 | 428 | ||
436 | // Verify | 429 | // Verify |
437 | assertEquals(router.getRoutes().size(), 1); | 430 | assertEquals(router.getRoutes().size(), 1); | ... | ... |
... | @@ -24,6 +24,7 @@ import static org.easymock.EasyMock.verify; | ... | @@ -24,6 +24,7 @@ import static org.easymock.EasyMock.verify; |
24 | import static org.junit.Assert.assertEquals; | 24 | import static org.junit.Assert.assertEquals; |
25 | import static org.junit.Assert.assertTrue; | 25 | import static org.junit.Assert.assertTrue; |
26 | 26 | ||
27 | +import java.util.Collections; | ||
27 | import java.util.HashMap; | 28 | import java.util.HashMap; |
28 | import java.util.HashSet; | 29 | import java.util.HashSet; |
29 | import java.util.Map; | 30 | import java.util.Map; |
... | @@ -50,6 +51,7 @@ import org.onlab.onos.net.host.HostEvent; | ... | @@ -50,6 +51,7 @@ import org.onlab.onos.net.host.HostEvent; |
50 | import org.onlab.onos.net.host.HostService; | 51 | import org.onlab.onos.net.host.HostService; |
51 | import org.onlab.onos.net.host.InterfaceIpAddress; | 52 | import org.onlab.onos.net.host.InterfaceIpAddress; |
52 | import org.onlab.onos.net.intent.Intent; | 53 | import org.onlab.onos.net.intent.Intent; |
54 | +import org.onlab.onos.net.intent.IntentOperations; | ||
53 | import org.onlab.onos.net.intent.IntentService; | 55 | import org.onlab.onos.net.intent.IntentService; |
54 | import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; | 56 | import org.onlab.onos.net.intent.MultiPointToSinglePointIntent; |
55 | import org.onlab.onos.net.intent.AbstractIntentTest; | 57 | import org.onlab.onos.net.intent.AbstractIntentTest; |
... | @@ -196,7 +198,7 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { | ... | @@ -196,7 +198,7 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { |
196 | * This method tests adding a route entry. | 198 | * This method tests adding a route entry. |
197 | */ | 199 | */ |
198 | @Test | 200 | @Test |
199 | - public void testProcessRouteAdd() throws TestUtilsException { | 201 | + public void testRouteAdd() throws TestUtilsException { |
200 | 202 | ||
201 | // Construct a route entry | 203 | // Construct a route entry |
202 | RouteEntry routeEntry = new RouteEntry( | 204 | RouteEntry routeEntry = new RouteEntry( |
... | @@ -214,13 +216,18 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { | ... | @@ -214,13 +216,18 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { |
214 | replay(hostService); | 216 | replay(hostService); |
215 | 217 | ||
216 | reset(intentService); | 218 | reset(intentService); |
217 | - intentService.submit(TestIntentServiceHelper.eqExceptId(intent)); | 219 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
220 | + builder.addSubmitOperation(intent); | ||
221 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
222 | + builder.build())); | ||
218 | replay(intentService); | 223 | replay(intentService); |
219 | 224 | ||
220 | - // Call the processRouteAdd() method in Router class | 225 | + // Call the processRouteUpdates() method in Router class |
221 | intentSynchronizer.leaderChanged(true); | 226 | intentSynchronizer.leaderChanged(true); |
222 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 227 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
223 | - router.processRouteAdd(routeEntry); | 228 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
229 | + routeEntry); | ||
230 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
224 | 231 | ||
225 | Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, | 232 | Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, |
226 | MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE, | 233 | MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE, |
... | @@ -299,14 +306,22 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { | ... | @@ -299,14 +306,22 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { |
299 | replay(hostService); | 306 | replay(hostService); |
300 | 307 | ||
301 | reset(intentService); | 308 | reset(intentService); |
302 | - intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent)); | 309 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
303 | - intentService.submit(TestIntentServiceHelper.eqExceptId(intentNew)); | 310 | + builder.addWithdrawOperation(intent.id()); |
311 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
312 | + builder.build())); | ||
313 | + builder = IntentOperations.builder(APPID); | ||
314 | + builder.addSubmitOperation(intentNew); | ||
315 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
316 | + builder.build())); | ||
304 | replay(intentService); | 317 | replay(intentService); |
305 | 318 | ||
306 | - // Call the processRouteAdd() method in Router class | 319 | + // Call the processRouteUpdates() method in Router class |
307 | intentSynchronizer.leaderChanged(true); | 320 | intentSynchronizer.leaderChanged(true); |
308 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 321 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
309 | - router.processRouteAdd(routeEntryUpdate); | 322 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.UPDATE, |
323 | + routeEntryUpdate); | ||
324 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
310 | 325 | ||
311 | Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, | 326 | Host host = new DefaultHost(ProviderId.NONE, HostId.NONE, |
312 | MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE, | 327 | MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE, |
... | @@ -334,7 +349,7 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { | ... | @@ -334,7 +349,7 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { |
334 | * This method tests deleting a route entry. | 349 | * This method tests deleting a route entry. |
335 | */ | 350 | */ |
336 | @Test | 351 | @Test |
337 | - public void testProcessRouteDelete() throws TestUtilsException { | 352 | + public void testRouteDelete() throws TestUtilsException { |
338 | 353 | ||
339 | // Construct the existing route entry | 354 | // Construct the existing route entry |
340 | RouteEntry routeEntry = new RouteEntry( | 355 | RouteEntry routeEntry = new RouteEntry( |
... | @@ -351,13 +366,18 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { | ... | @@ -351,13 +366,18 @@ public class RouterTestWithAsyncArp extends AbstractIntentTest { |
351 | 366 | ||
352 | // Set up expectation | 367 | // Set up expectation |
353 | reset(intentService); | 368 | reset(intentService); |
354 | - intentService.withdraw(TestIntentServiceHelper.eqExceptId(intent)); | 369 | + IntentOperations.Builder builder = IntentOperations.builder(APPID); |
370 | + builder.addWithdrawOperation(intent.id()); | ||
371 | + intentService.execute(TestIntentServiceHelper.eqExceptId( | ||
372 | + builder.build())); | ||
355 | replay(intentService); | 373 | replay(intentService); |
356 | 374 | ||
357 | - // Call route deleting method in Router class | 375 | + // Call the processRouteUpdates() method in Router class |
358 | intentSynchronizer.leaderChanged(true); | 376 | intentSynchronizer.leaderChanged(true); |
359 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 377 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
360 | - router.processRouteDelete(routeEntry); | 378 | + RouteUpdate routeUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, |
379 | + routeEntry); | ||
380 | + router.processRouteUpdates(Collections.<RouteUpdate>singletonList(routeUpdate)); | ||
361 | 381 | ||
362 | // Verify | 382 | // Verify |
363 | assertEquals(router.getRoutes().size(), 0); | 383 | assertEquals(router.getRoutes().size(), 0); | ... | ... |
... | @@ -236,9 +236,7 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -236,9 +236,7 @@ public class SdnIpTest extends AbstractIntentTest { |
236 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 236 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
237 | 237 | ||
238 | // Add route updates | 238 | // Add route updates |
239 | - for (RouteUpdate update : routeUpdates) { | 239 | + router.processRouteUpdates(routeUpdates); |
240 | - router.processRouteAdd(update.routeEntry()); | ||
241 | - } | ||
242 | 240 | ||
243 | latch.await(5000, TimeUnit.MILLISECONDS); | 241 | latch.await(5000, TimeUnit.MILLISECONDS); |
244 | 242 | ||
... | @@ -304,17 +302,19 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -304,17 +302,19 @@ public class SdnIpTest extends AbstractIntentTest { |
304 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 302 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
305 | 303 | ||
306 | // Send the add updates first | 304 | // Send the add updates first |
307 | - for (RouteUpdate update : routeUpdates) { | 305 | + router.processRouteUpdates(routeUpdates); |
308 | - router.processRouteAdd(update.routeEntry()); | ||
309 | - } | ||
310 | 306 | ||
311 | // Give some time to let the intents be submitted | 307 | // Give some time to let the intents be submitted |
312 | installCount.await(5000, TimeUnit.MILLISECONDS); | 308 | installCount.await(5000, TimeUnit.MILLISECONDS); |
313 | 309 | ||
314 | // Send the DELETE updates | 310 | // Send the DELETE updates |
311 | + List<RouteUpdate> deleteRouteUpdates = new ArrayList<>(); | ||
315 | for (RouteUpdate update : routeUpdates) { | 312 | for (RouteUpdate update : routeUpdates) { |
316 | - router.processRouteDelete(update.routeEntry()); | 313 | + RouteUpdate deleteUpdate = new RouteUpdate(RouteUpdate.Type.DELETE, |
314 | + update.routeEntry()); | ||
315 | + deleteRouteUpdates.add(deleteUpdate); | ||
317 | } | 316 | } |
317 | + router.processRouteUpdates(deleteRouteUpdates); | ||
318 | 318 | ||
319 | deleteCount.await(5000, TimeUnit.MILLISECONDS); | 319 | deleteCount.await(5000, TimeUnit.MILLISECONDS); |
320 | 320 | ... | ... |
... | @@ -82,7 +82,7 @@ public class BgpSessionManagerTest { | ... | @@ -82,7 +82,7 @@ public class BgpSessionManagerTest { |
82 | */ | 82 | */ |
83 | private class DummyRouteListener implements RouteListener { | 83 | private class DummyRouteListener implements RouteListener { |
84 | @Override | 84 | @Override |
85 | - public void update(RouteUpdate routeUpdate) { | 85 | + public void update(Collection<RouteUpdate> routeUpdate) { |
86 | // Nothing to do | 86 | // Nothing to do |
87 | } | 87 | } |
88 | } | 88 | } | ... | ... |
-
Please register or login to post a comment