Jonathan Hart
Committed by Gerrit Code Review

PeerConnectivityManager: recalculate peering intents on configuration change

Change-Id: I05944f995342b2351115a613e02ad3e2ed830eb4
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
15 */ 15 */
16 package org.onosproject.sdnip; 16 package org.onosproject.sdnip;
17 17
18 -import com.google.common.collect.HashMultimap;
19 -import com.google.common.collect.Multimap;
20 import org.onlab.packet.Ethernet; 18 import org.onlab.packet.Ethernet;
21 import org.onlab.packet.IPv4; 19 import org.onlab.packet.IPv4;
22 import org.onlab.packet.IPv6; 20 import org.onlab.packet.IPv6;
...@@ -27,6 +25,8 @@ import org.onosproject.core.ApplicationId; ...@@ -27,6 +25,8 @@ import org.onosproject.core.ApplicationId;
27 import org.onosproject.incubator.net.intf.Interface; 25 import org.onosproject.incubator.net.intf.Interface;
28 import org.onosproject.incubator.net.intf.InterfaceService; 26 import org.onosproject.incubator.net.intf.InterfaceService;
29 import org.onosproject.net.ConnectPoint; 27 import org.onosproject.net.ConnectPoint;
28 +import org.onosproject.net.config.NetworkConfigEvent;
29 +import org.onosproject.net.config.NetworkConfigListener;
30 import org.onosproject.net.config.NetworkConfigService; 30 import org.onosproject.net.config.NetworkConfigService;
31 import org.onosproject.net.flow.DefaultTrafficSelector; 31 import org.onosproject.net.flow.DefaultTrafficSelector;
32 import org.onosproject.net.flow.DefaultTrafficTreatment; 32 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -43,7 +43,9 @@ import org.slf4j.LoggerFactory; ...@@ -43,7 +43,9 @@ import org.slf4j.LoggerFactory;
43 43
44 import java.util.ArrayList; 44 import java.util.ArrayList;
45 import java.util.Collection; 45 import java.util.Collection;
46 +import java.util.HashMap;
46 import java.util.List; 47 import java.util.List;
48 +import java.util.Map;
47 49
48 import static com.google.common.base.Preconditions.checkNotNull; 50 import static com.google.common.base.Preconditions.checkNotNull;
49 51
...@@ -69,9 +71,10 @@ public class PeerConnectivityManager { ...@@ -69,9 +71,10 @@ public class PeerConnectivityManager {
69 private final ApplicationId appId; 71 private final ApplicationId appId;
70 private final ApplicationId routerAppId; 72 private final ApplicationId routerAppId;
71 73
72 - // Just putting something random here for now. Figure out exactly what 74 + private final Map<Key, PointToPointIntent> peerIntents;
73 - // indexes we need when we start making use of them. 75 +
74 - private final Multimap<BgpConfig.BgpSpeakerConfig, PointToPointIntent> peerIntents; 76 + private final InternalNetworkConfigListener configListener
77 + = new InternalNetworkConfigListener();
75 78
76 /** 79 /**
77 * Creates a new PeerConnectivityManager. 80 * Creates a new PeerConnectivityManager.
...@@ -93,13 +96,14 @@ public class PeerConnectivityManager { ...@@ -93,13 +96,14 @@ public class PeerConnectivityManager {
93 this.routerAppId = routerAppId; 96 this.routerAppId = routerAppId;
94 this.interfaceService = interfaceService; 97 this.interfaceService = interfaceService;
95 98
96 - peerIntents = HashMultimap.create(); 99 + peerIntents = new HashMap<>();
97 } 100 }
98 101
99 /** 102 /**
100 * Starts the peer connectivity manager. 103 * Starts the peer connectivity manager.
101 */ 104 */
102 public void start() { 105 public void start() {
106 + configService.addListener(configListener);
103 setUpConnectivity(); 107 setUpConnectivity();
104 } 108 }
105 109
...@@ -107,6 +111,7 @@ public class PeerConnectivityManager { ...@@ -107,6 +111,7 @@ public class PeerConnectivityManager {
107 * Stops the peer connectivity manager. 111 * Stops the peer connectivity manager.
108 */ 112 */
109 public void stop() { 113 public void stop() {
114 + configService.removeListener(configListener);
110 } 115 }
111 116
112 /** 117 /**
...@@ -121,16 +126,27 @@ public class PeerConnectivityManager { ...@@ -121,16 +126,27 @@ public class PeerConnectivityManager {
121 return; 126 return;
122 } 127 }
123 128
129 + Map<Key, PointToPointIntent> existingIntents = new HashMap<>(peerIntents);
130 +
124 for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) { 131 for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) {
125 log.debug("Start to set up BGP paths for BGP speaker: {}", 132 log.debug("Start to set up BGP paths for BGP speaker: {}",
126 bgpSpeaker); 133 bgpSpeaker);
127 134
128 buildSpeakerIntents(bgpSpeaker).forEach(i -> { 135 buildSpeakerIntents(bgpSpeaker).forEach(i -> {
129 - peerIntents.put(bgpSpeaker, i); 136 + PointToPointIntent intent = existingIntents.remove(i.key());
137 + if (intent == null || !IntentUtils.equals(i, intent)) {
138 + peerIntents.put(i.key(), i);
130 intentSynchronizer.submit(i); 139 intentSynchronizer.submit(i);
140 + }
131 }); 141 });
132 -
133 } 142 }
143 +
144 + // Remove any remaining intents that we used to have that we don't need
145 + // anymore
146 + existingIntents.values().forEach(i -> {
147 + peerIntents.remove(i.key());
148 + intentSynchronizer.withdraw(i);
149 + });
134 } 150 }
135 151
136 private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) { 152 private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) {
...@@ -356,7 +372,7 @@ public class PeerConnectivityManager { ...@@ -356,7 +372,7 @@ public class PeerConnectivityManager {
356 * @param srcIp source IP address 372 * @param srcIp source IP address
357 * @param dstIp destination IP address 373 * @param dstIp destination IP address
358 * @param suffix suffix string 374 * @param suffix suffix string
359 - * @return 375 + * @return intent key
360 */ 376 */
361 private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) { 377 private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) {
362 String keyString = new StringBuilder() 378 String keyString = new StringBuilder()
...@@ -370,4 +386,26 @@ public class PeerConnectivityManager { ...@@ -370,4 +386,26 @@ public class PeerConnectivityManager {
370 return Key.of(keyString, appId); 386 return Key.of(keyString, appId);
371 } 387 }
372 388
389 + private class InternalNetworkConfigListener implements NetworkConfigListener {
390 +
391 + @Override
392 + public void event(NetworkConfigEvent event) {
393 + switch (event.type()) {
394 + case CONFIG_REGISTERED:
395 + break;
396 + case CONFIG_UNREGISTERED:
397 + break;
398 + case CONFIG_ADDED:
399 + case CONFIG_UPDATED:
400 + case CONFIG_REMOVED:
401 + if (event.configClass() == RoutingService.CONFIG_CLASS) {
402 + setUpConnectivity();
403 + }
404 + break;
405 + default:
406 + break;
407 + }
408 + }
409 + }
410 +
373 } 411 }
......
...@@ -34,6 +34,7 @@ import org.onosproject.incubator.net.intf.InterfaceService; ...@@ -34,6 +34,7 @@ import org.onosproject.incubator.net.intf.InterfaceService;
34 import org.onosproject.net.ConnectPoint; 34 import org.onosproject.net.ConnectPoint;
35 import org.onosproject.net.DeviceId; 35 import org.onosproject.net.DeviceId;
36 import org.onosproject.net.PortNumber; 36 import org.onosproject.net.PortNumber;
37 +import org.onosproject.net.config.NetworkConfigListener;
37 import org.onosproject.net.config.NetworkConfigService; 38 import org.onosproject.net.config.NetworkConfigService;
38 import org.onosproject.net.flow.DefaultTrafficSelector; 39 import org.onosproject.net.flow.DefaultTrafficSelector;
39 import org.onosproject.net.flow.DefaultTrafficTreatment; 40 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -60,8 +61,10 @@ import java.util.Map; ...@@ -60,8 +61,10 @@ import java.util.Map;
60 import java.util.Optional; 61 import java.util.Optional;
61 import java.util.Set; 62 import java.util.Set;
62 63
64 +import static org.easymock.EasyMock.anyObject;
63 import static org.easymock.EasyMock.createMock; 65 import static org.easymock.EasyMock.createMock;
64 import static org.easymock.EasyMock.expect; 66 import static org.easymock.EasyMock.expect;
67 +import static org.easymock.EasyMock.expectLastCall;
65 import static org.easymock.EasyMock.replay; 68 import static org.easymock.EasyMock.replay;
66 import static org.easymock.EasyMock.reset; 69 import static org.easymock.EasyMock.reset;
67 import static org.easymock.EasyMock.verify; 70 import static org.easymock.EasyMock.verify;
...@@ -119,6 +122,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { ...@@ -119,6 +122,8 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest {
119 routingConfig = createMock(RoutingConfigurationService.class); 122 routingConfig = createMock(RoutingConfigurationService.class);
120 interfaceService = createMock(InterfaceService.class); 123 interfaceService = createMock(InterfaceService.class);
121 networkConfigService = createMock(NetworkConfigService.class); 124 networkConfigService = createMock(NetworkConfigService.class);
125 + networkConfigService.addListener(anyObject(NetworkConfigListener.class));
126 + expectLastCall().anyTimes();
122 bgpConfig = createMock(BgpConfig.class); 127 bgpConfig = createMock(BgpConfig.class);
123 128
124 // These will set expectations on routingConfig and interfaceService 129 // These will set expectations on routingConfig and interfaceService
......