blob: a3c0aed6327d508f6854df53b255b9d9f822aaea [file] [log] [blame]
Yixiao Chen68bfab22016-11-11 11:04:10 -05001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Yixiao Chen68bfab22016-11-11 11:04:10 -05003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.tetopology.management.impl;
17
Ray Milkeyd84f89b2018-08-17 14:54:17 -070018import com.google.common.base.MoreObjects;
19import com.google.common.collect.Lists;
20import com.google.common.collect.Maps;
Yixiao Chen68bfab22016-11-11 11:04:10 -050021import org.apache.commons.collections.CollectionUtils;
22import org.apache.commons.collections.MapUtils;
Yixiao Chen68bfab22016-11-11 11:04:10 -050023import org.onlab.packet.Ip4Address;
24import org.onosproject.app.ApplicationException;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
Yixiao Chen68bfab22016-11-11 11:04:10 -050027import org.onosproject.net.DeviceId;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070028import org.onosproject.net.config.ConfigException;
Yixiao Chen68bfab22016-11-11 11:04:10 -050029import org.onosproject.net.config.ConfigFactory;
30import org.onosproject.net.config.NetworkConfigEvent;
31import org.onosproject.net.config.NetworkConfigListener;
32import org.onosproject.net.config.NetworkConfigRegistry;
33import org.onosproject.net.device.DeviceProviderRegistry;
34import org.onosproject.net.device.DeviceService;
35import org.onosproject.net.link.LinkProviderRegistry;
36import org.onosproject.net.link.LinkService;
37import org.onosproject.net.provider.AbstractListenerProviderRegistry;
38import org.onosproject.net.provider.AbstractProviderService;
39import org.onosproject.tetopology.management.api.CommonTopologyData;
40import org.onosproject.tetopology.management.api.DefaultNetwork;
41import org.onosproject.tetopology.management.api.DefaultNetworks;
42import org.onosproject.tetopology.management.api.DefaultTeTopologies;
43import org.onosproject.tetopology.management.api.DefaultTeTopology;
44import org.onosproject.tetopology.management.api.KeyId;
45import org.onosproject.tetopology.management.api.Network;
46import org.onosproject.tetopology.management.api.Networks;
Yixiao Chen68bfab22016-11-11 11:04:10 -050047import org.onosproject.tetopology.management.api.TeConstants;
48import org.onosproject.tetopology.management.api.TeTopologies;
49import org.onosproject.tetopology.management.api.TeTopology;
50import org.onosproject.tetopology.management.api.TeTopologyEvent;
51import org.onosproject.tetopology.management.api.TeTopologyKey;
52import org.onosproject.tetopology.management.api.TeTopologyListener;
53import org.onosproject.tetopology.management.api.TeTopologyProvider;
54import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry;
55import org.onosproject.tetopology.management.api.TeTopologyProviderService;
56import org.onosproject.tetopology.management.api.TeTopologyService;
57import org.onosproject.tetopology.management.api.link.CommonLinkData;
58import org.onosproject.tetopology.management.api.link.DefaultTeLink;
59import org.onosproject.tetopology.management.api.link.ExternalLink;
60import org.onosproject.tetopology.management.api.link.LinkBandwidth;
61import org.onosproject.tetopology.management.api.link.NetworkLink;
62import org.onosproject.tetopology.management.api.link.NetworkLinkEventSubject;
63import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
64import org.onosproject.tetopology.management.api.link.TeLink;
65import org.onosproject.tetopology.management.api.link.TeLinkEventSubject;
66import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
67import org.onosproject.tetopology.management.api.link.TeLinkTpKey;
68import org.onosproject.tetopology.management.api.link.TePathAttributes;
69import org.onosproject.tetopology.management.api.link.UnderlayPath;
70import org.onosproject.tetopology.management.api.node.CommonNodeData;
71import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
72import org.onosproject.tetopology.management.api.node.DefaultTeNode;
Yixiao Chen265b3bb2017-01-13 10:17:03 -050073import org.onosproject.tetopology.management.api.node.DefaultTunnelTerminationPoint;
Yixiao Chen68bfab22016-11-11 11:04:10 -050074import org.onosproject.tetopology.management.api.node.NetworkNode;
75import org.onosproject.tetopology.management.api.node.NetworkNodeEventSubject;
76import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
77import org.onosproject.tetopology.management.api.node.TeNode;
78import org.onosproject.tetopology.management.api.node.TeNodeEventSubject;
79import org.onosproject.tetopology.management.api.node.TeNodeKey;
80import org.onosproject.tetopology.management.api.node.TerminationPoint;
81import org.onosproject.tetopology.management.api.node.TerminationPointKey;
82import org.onosproject.tetopology.management.api.node.TtpKey;
83import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070084import org.osgi.service.component.annotations.Activate;
85import org.osgi.service.component.annotations.Component;
86import org.osgi.service.component.annotations.Deactivate;
87import org.osgi.service.component.annotations.Reference;
88import org.osgi.service.component.annotations.ReferenceCardinality;
Yixiao Chen68bfab22016-11-11 11:04:10 -050089import org.slf4j.Logger;
90import org.slf4j.LoggerFactory;
91
Ray Milkeyd84f89b2018-08-17 14:54:17 -070092import java.util.BitSet;
93import java.util.List;
94import java.util.Map;
95import java.util.concurrent.ExecutorService;
96
97import static java.util.concurrent.Executors.newFixedThreadPool;
98import static org.onlab.util.Tools.groupedThreads;
99import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
100import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
101import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
102import static org.onosproject.tetopology.management.api.OptimizationType.NOT_OPTIMIZED;
103import static org.onosproject.tetopology.management.api.TeTopology.BIT_CUSTOMIZED;
104import static org.onosproject.tetopology.management.api.TeTopology.BIT_LEARNT;
105import static org.onosproject.tetopology.management.api.TeTopology.BIT_MERGED;
106import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_ADDED;
107import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_REMOVED;
108import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_UPDATED;
109import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED;
110import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED;
111import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_ADDED;
112import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_REMOVED;
113import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_UPDATED;
114import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_ADDED;
115import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_REMOVED;
116import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_UPDATED;
117import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_ADDED;
118import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_REMOVED;
119import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_UPDATED;
120import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED;
121import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
122import static org.onosproject.tetopology.management.api.link.TeLink.BIT_ACCESS_INTERDOMAIN;
123import static org.onosproject.tetopology.management.impl.TeMgrUtil.linkBuilder;
124import static org.onosproject.tetopology.management.impl.TeMgrUtil.networkBuilder;
125import static org.onosproject.tetopology.management.impl.TeMgrUtil.networkLinkKey;
126import static org.onosproject.tetopology.management.impl.TeMgrUtil.networkNodeKey;
127import static org.onosproject.tetopology.management.impl.TeMgrUtil.nodeBuilder;
128import static org.onosproject.tetopology.management.impl.TeMgrUtil.toNetworkId;
129import static org.onosproject.tetopology.management.impl.TeMgrUtil.toNetworkLinkId;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500130
131/**
132 * Implementation of the topology management service.
133 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700134@Component(immediate = true, service = { TeTopologyService.class, TeTopologyProviderRegistry.class })
Yixiao Chen68bfab22016-11-11 11:04:10 -0500135public class TeTopologyManager
136 extends AbstractListenerProviderRegistry<TeTopologyEvent, TeTopologyListener,
137 TeTopologyProvider, TeTopologyProviderService>
138 implements TeTopologyService, TeTopologyProviderRegistry {
139 private static final String APP_NAME = "org.onosproject.tetopology";
Yixiao Chen29f06332016-12-07 16:14:29 -0500140 private static final long DEFAULT_PROVIDER_ID = 77777;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500141 private static final long DEFAULT_CLIENT_ID = 0x00L;
142 private long providerId = DEFAULT_PROVIDER_ID;
143 private static final int MAX_THREADS = 1;
Yixiao Chen29f06332016-12-07 16:14:29 -0500144 private static final Ip4Address DEFAULT_TENODE_ID_START = Ip4Address.valueOf("10.10.10.10");
Yixiao Chen68bfab22016-11-11 11:04:10 -0500145 private static final Ip4Address DEFAULT_TENODE_ID_END = Ip4Address.valueOf("250.250.250.250");
146 private Ip4Address teNodeIpStart = DEFAULT_TENODE_ID_START;
147 private Ip4Address teNodeIpEnd = DEFAULT_TENODE_ID_END;
148 private long nextTeNodeId = teNodeIpStart.toInt();
Yixiao Chen29f06332016-12-07 16:14:29 -0500149 private boolean mdsc = true;
150 private static final String MDSC_MODE = "true";
151
Yixiao Chen68bfab22016-11-11 11:04:10 -0500152 private final Logger log = LoggerFactory.getLogger(getClass());
153
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700154 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500155 protected CoreService coreService;
156
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700157 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500158 protected NetworkConfigRegistry cfgService;
159
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700160 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500161 protected DeviceService deviceService;
162
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700163 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500164 protected LinkService linkService;
165
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700166 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500167 protected DeviceProviderRegistry deviceProviderRegistry;
168
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700169 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500170 protected LinkProviderRegistry linkProviderRegistry;
171
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700172 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen68bfab22016-11-11 11:04:10 -0500173 public TeTopologyStore store;
174
175 private TeTopologyStoreDelegate delegate = this::post;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500176 private final ConfigFactory<ApplicationId, TeTopologyConfig> factory =
177 new ConfigFactory<ApplicationId, TeTopologyConfig>(APP_SUBJECT_FACTORY,
178 TeTopologyConfig.class,
179 "teTopologyCfg",
180 false) {
181 @Override
182 public TeTopologyConfig createConfig() {
183 return new TeTopologyConfig();
184 }
185 };
186 private final NetworkConfigListener cfgLister = new InternalConfigListener();
187 private ApplicationId appId;
188 // The topology merged in MDSC
189 private TeTopology mergedTopology = null;
190 private TeTopologyKey mergedTopologyKey;
191 private Network mergedNetwork = null;
192 // Track new TE node id by its source TE node key
193 private Map<TeNodeKey, Long> sourceNewTeNodeIdMap = Maps.newHashMap();
194 // Track the external link keys by the plugId
195 private Map<Long, LinkKeyPair> externalLinkMap = Maps.newHashMap();
196 private ExecutorService executor;
197
198 /**
199 * Activation helper function.
200 */
201 public void activateBasics() {
202 store.setDelegate(delegate);
Yixiao Chen29f06332016-12-07 16:14:29 -0500203 store.setProviderId(providerId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500204 eventDispatcher.addSink(TeTopologyEvent.class, listenerRegistry);
205 }
206
207 /**
208 * Deactivation helper function.
209 */
210 public void deactivateBasics() {
211 store.unsetDelegate(delegate);
212 eventDispatcher.removeSink(TeTopologyEvent.class);
213 }
214
215 @Activate
216 public void activate() {
217 activateBasics();
218 appId = coreService.registerApplication(APP_NAME);
219 cfgService.registerConfigFactory(factory);
220 executor = newFixedThreadPool(MAX_THREADS, groupedThreads("onos/tetopology", "build-%d", log));
221
222 cfgService.addListener(cfgLister);
223 executor.execute(new TopologyMergerTask());
224 log.info("Started");
225 }
226
227 @Deactivate
228 public void deactivate() {
229 deactivateBasics();
230 externalLinkMap.clear();
231 cfgService.removeListener(cfgLister);
232 cfgService.unregisterConfigFactory(factory);
233 executor.shutdownNow();
234 executor = null;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500235 log.info("Stopped");
236 }
237
238 @Override
239 protected TeTopologyProviderService createProviderService(TeTopologyProvider provider) {
240 return new InternalTopologyProviderService(provider);
241 }
242
243 private class InternalTopologyProviderService
244 extends AbstractProviderService<TeTopologyProvider>
245 implements TeTopologyProviderService {
246
247 protected InternalTopologyProviderService(TeTopologyProvider provider) {
248 super(provider);
249 }
250
251 @Override
252 public void networkUpdated(Network network) {
253 store.updateNetwork(network);
254 }
255
256 @Override
257 public void networkRemoved(KeyId networkId) {
258 store.removeNetwork(networkId);
259 }
260
261 @Override
262 public void linkUpdated(NetworkLinkKey linkKey, NetworkLink link) {
263 store.updateNetworkLink(linkKey, link);
264 }
265
266 @Override
267 public void linkRemoved(NetworkLinkKey linkKey) {
268 store.removeNetworkLink(linkKey);
269 }
270
271 @Override
272 public void nodeUpdated(NetworkNodeKey nodeKey, NetworkNode node) {
273 store.updateNetworkNode(nodeKey, node);
274 }
275
276 @Override
277 public void nodeRemoved(NetworkNodeKey nodeKey) {
278 store.removeNetworkNode(nodeKey);
279 }
280
281 @Override
282 public void terminationPointUpdated(TerminationPointKey terminationPointKey,
283 TerminationPoint terminationPoint) {
284 store.updateTerminationPoint(terminationPointKey, terminationPoint);
285 }
286
287 @Override
288 public void terminationPointRemoved(TerminationPointKey terminationPointKey) {
289 store.removeTerminationPoint(terminationPointKey);
290 }
291 }
292
293 private boolean isCustomizedLearnedTopology(TeTopologyKey key) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500294 if (store.teTopology(key).flags().get(BIT_CUSTOMIZED) &&
295 store.teTopology(key).flags().get(BIT_LEARNT)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500296 return true;
297 }
298 return false;
299 }
300
301 // Task for merge the learned topology.
302 private class TopologyMergerTask implements Runnable {
303
304 public TopologyMergerTask() {
305 }
306
307 @Override
308 public void run() {
309 try {
310 TeTopologyMapEvent event;
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500311 while ((event = store.mapEventQueue().take()) != null) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500312 switch (event.type()) {
313 case TE_TOPOLOGY_ADDED:
314 case TE_TOPOLOGY_UPDATED:
315 TeTopology teTopology = store.teTopology(event.teTopologyKey());
316 post(new TeTopologyEvent(event.type(), teTopology));
Yixiao Chen29f06332016-12-07 16:14:29 -0500317 if (mdsc && event.type() == TE_TOPOLOGY_ADDED &&
318 teTopology.flags().get(BIT_CUSTOMIZED) &&
319 teTopology.flags().get(BIT_LEARNT)) {
320 log.debug("TeTopology to be merged: {}", teTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500321 mergeTopology(teTopology);
322 }
323 break;
324 case TE_TOPOLOGY_REMOVED:
325 post(new TeTopologyEvent(TE_TOPOLOGY_REMOVED,
326 new DefaultTeTopology(event.teTopologyKey(),
327 null, null, null, null)));
328 break;
329 case TE_NODE_ADDED:
330 case TE_NODE_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500331 if (store.teTopology(event.teNodeKey().teTopologyKey()) == null) {
332 // Event should be ignored when the topology is not there.
333 break;
334 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500335 TeNode teNode = store.teNode(event.teNodeKey());
336 post(new TeTopologyEvent(event.type(),
337 new TeNodeEventSubject(event.teNodeKey(), teNode)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500338 if (mdsc && isCustomizedLearnedTopology(event.teNodeKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500339 updateSourceTeNode(mergedTopology.teNodes(),
340 event.teNodeKey().teTopologyKey(), teNode, true);
341 }
342 break;
343 case TE_NODE_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500344 if (store.teTopology(event.teNodeKey().teTopologyKey()) == null) {
345 // Event should be ignored when the topology is not there.
346 break;
347 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500348 post(new TeTopologyEvent(TE_NODE_REMOVED,
349 new TeNodeEventSubject(event.teNodeKey(), null)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500350 if (mdsc && isCustomizedLearnedTopology(event.teNodeKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500351 removeSourceTeNode(mergedTopology.teNodes(), event.teNodeKey(), true);
352 }
353 break;
354 case TE_LINK_ADDED:
355 case TE_LINK_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500356 if (store.teTopology(event.teLinkKey().teTopologyKey()) == null ||
357 store.teNode(event.teLinkKey().teNodeKey()) == null) {
358 // Event should be ignored when the topology or node is not there.
359 break;
360 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500361 TeLink teLink = store.teLink(event.teLinkKey());
362 post(new TeTopologyEvent(event.type(),
363 new TeLinkEventSubject(event.teLinkKey(), teLink)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500364 if (mdsc && isCustomizedLearnedTopology(event.teLinkKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500365 Map<TeLinkTpKey, TeLink> teLinks = Maps.newHashMap(mergedTopology.teLinks());
366 updateSourceTeLink(teLinks, event.teLinkKey().teTopologyKey(), teLink, true);
367 updateMergedTopology(mergedTopology.teNodes(), teLinks);
368 }
369 break;
370 case TE_LINK_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500371 if (store.teTopology(event.teLinkKey().teTopologyKey()) == null ||
372 store.teNode(event.teLinkKey().teNodeKey()) == null) {
373 // Event should be ignored when the topology or node is not there.
374 break;
375 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500376 post(new TeTopologyEvent(TE_LINK_REMOVED,
377 new TeLinkEventSubject(event.teLinkKey(), null)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500378 if (mdsc && isCustomizedLearnedTopology(event.teLinkKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500379 Map<TeLinkTpKey, TeLink> teLinks = Maps.newHashMap(mergedTopology.teLinks());
380 removeSourceTeLink(teLinks, event.teLinkKey(), true);
381 updateMergedTopology(mergedTopology.teNodes(), teLinks);
382 }
383 break;
384 case NETWORK_ADDED:
385 case NETWORK_UPDATED:
386 Network network = store.network(event.networkKey());
387 post(new TeTopologyEvent(event.type(), network));
388 break;
389 case NETWORK_REMOVED:
390 post(new TeTopologyEvent(NETWORK_REMOVED,
Aihua Guo0bc12092017-02-10 09:53:55 -0500391 new DefaultNetwork(event.networkKey(), null, null,
392 null, null, false, null,
393 NOT_OPTIMIZED)));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500394 break;
395 case NODE_ADDED:
396 case NODE_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500397 if (store.network(event.networkNodeKey().networkId()) == null) {
398 // Event should be ignored when the network is not there.
399 break;
400 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500401 NetworkNode node = store.networkNode(event.networkNodeKey());
402 post(new TeTopologyEvent(event.type(),
403 new NetworkNodeEventSubject(event.networkNodeKey(), node)));
404 break;
405 case NODE_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500406 if (store.network(event.networkNodeKey().networkId()) == null) {
407 // Event should be ignored when the network is not there.
408 break;
409 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500410 post(new TeTopologyEvent(NODE_REMOVED,
411 new NetworkNodeEventSubject(event.networkNodeKey(), null)));
412 break;
413 case LINK_ADDED:
414 case LINK_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500415 if (store.network(event.networkLinkKey().networkId()) == null) {
416 // Event should be ignored when the network is not there.
417 break;
418 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500419 NetworkLink link = store.networkLink(event.networkLinkKey());
420 post(new TeTopologyEvent(event.type(),
421 new NetworkLinkEventSubject(event.networkLinkKey(), link)));
422 break;
423 case LINK_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500424 if (store.network(event.networkLinkKey().networkId()) == null) {
425 // Event should be ignored when the network is not there.
426 break;
427 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500428 post(new TeTopologyEvent(LINK_REMOVED,
429 new NetworkLinkEventSubject(event.networkLinkKey(), null)));
430 break;
431 default:
432 break;
433 }
434 }
435 } catch (InterruptedException e) {
436 log.warn("TopologyMergerTask is interrupted");
Ray Milkey5c7d4882018-02-05 14:50:39 -0800437 Thread.currentThread().interrupt();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500438 } catch (Exception e) {
439 log.warn("Unable to merge topology", e);
440 }
441 }
442 }
443
444 private void removeSourceTeNode(Map<Long, TeNode> teNodes,
445 TeNodeKey srcNodeKey, boolean postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500446 Long mergedTeNodeId = sourceNewTeNodeIdMap.remove(srcNodeKey);
447 if (mergedTeNodeId == null) {
448 return;
449 }
450 if (teNodes.remove(mergedTeNodeId) != null && postEvent) {
451 TeNodeKey nodeKey = new TeNodeKey(mergedTopologyKey,
452 mergedTeNodeId);
453 post(new TeTopologyEvent(TE_NODE_REMOVED,
454 new TeNodeEventSubject(nodeKey, null)));
455 post(new TeTopologyEvent(NODE_REMOVED,
456 new NetworkNodeEventSubject(TeMgrUtil
457 .networkNodeKey(nodeKey), null)));
458 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500459 }
460
461 private void updateSourceTeNode(Map<Long, TeNode> teNodes, TeTopologyKey srcTopoKey,
462 TeNode srcNode, boolean postEvent) {
463 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey, srcNode.teNodeId());
464 Long mergedTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeId);
465 boolean addNode = false;
466 if (mergedTeNodeId == null) {
467 // New node
468 addNode = true;
469 mergedTeNodeId = nextTeNodeId;
470 nextTeNodeId++;
471 if (nextTeNodeId >= teNodeIpEnd.toInt()) {
472 nextTeNodeId = teNodeIpStart.toInt();
473 log.warn("TE node Id is wrapped back");
474 }
475 sourceNewTeNodeIdMap.put(sourceTeNodeId, mergedTeNodeId);
476 }
477 TeTopologyKey underlayTopologyId = null; // No underlay
478 TeNodeKey supportTeNodeId = null; // No supporting
479
480 CommonNodeData common = new CommonNodeData(srcNode.name(), srcNode.adminStatus(),
481 srcNode.opStatus(), srcNode.flags()); // No change
482 Map<Long, ConnectivityMatrix> connMatrices = srcNode.connectivityMatrices();
483 List<Long> teLinkIds = srcNode.teLinkIds(); // No change
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500484 Map<Long, TunnelTerminationPoint> ttps = null;
485 if (MapUtils.isNotEmpty(srcNode.tunnelTerminationPoints())) {
486 ttps = Maps.newHashMap();
487 for (Map.Entry<Long, TunnelTerminationPoint> entry : srcNode.tunnelTerminationPoints().entrySet()) {
488 TunnelTerminationPoint ttp = entry.getValue();
489 ttps.put(entry.getKey(),
490 new DefaultTunnelTerminationPoint(ttp.ttpId(), ttp.switchingLayer(),
491 ttp.encodingLayer(), ttp.flags(),
492 ttp.interLayerLockList(),
493 ttp.localLinkConnectivityList(),
494 ttp.availAdaptBandwidth(),
495 null)); //Remove supporting TTP Ids
496 }
497 }
498
Yixiao Chen68bfab22016-11-11 11:04:10 -0500499 List<Long> teTpIds = srcNode.teTerminationPointIds(); // No change
500 DefaultTeNode newNode = new DefaultTeNode(mergedTeNodeId, underlayTopologyId,
501 supportTeNodeId, sourceTeNodeId, common, connMatrices, teLinkIds,
502 ttps, teTpIds);
503 teNodes.put(mergedTeNodeId, newNode);
504 if (postEvent) {
505 //Post event for the TE node in the merged topology
506 TeNodeKey globalKey = new TeNodeKey(mergedTopologyKey, mergedTeNodeId);
507 post(new TeTopologyEvent(addNode ? TE_NODE_ADDED : TE_NODE_UPDATED,
508 new TeNodeEventSubject(globalKey, newNode)));
509 post(new TeTopologyEvent(addNode ? NODE_ADDED : NODE_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500510 new NetworkNodeEventSubject(networkNodeKey(globalKey),
511 nodeBuilder(KeyId.keyId(
512 Ip4Address.valueOf((int) newNode.teNodeId()).toString()),
513 newNode))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500514 }
515 }
516
517 // Merge TE nodes
518 private void mergeNodes(Map<Long, TeNode> nodes, TeTopology topology) {
519
520 if (!MapUtils.isEmpty(topology.teNodes())) {
521 for (Map.Entry<Long, TeNode> entry : topology.teNodes().entrySet()) {
522 updateSourceTeNode(nodes, topology.teTopologyId(), entry.getValue(),
523 mergedTopology != null);
524 }
525 }
526 }
527
528 // Returns a new TeLink based on an existing TeLink with new attributes
529 private TeLink updateTeLink(TeLinkTpKey newKey, TeLinkTpKey peerTeLinkKey,
530 TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
531 TeLinkTpGlobalKey sourceTeLinkId, ExternalLink externalLink,
532 TeLink exLink) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500533 UnderlayPath underlayPath = null;
534 if (underlayTopologyId != null &&
535 underlayTopologyId.equals(exLink.underlayTeTopologyId())) {
536 underlayPath = new UnderlayPath(exLink.primaryPath(),
537 exLink.backupPaths(), exLink.tunnelProtectionType(),
538 exLink.sourceTtpId(), exLink.destinationTtpId(),
539 exLink.teTunnelId()
540 );
541 }
542
Yixiao Chen68bfab22016-11-11 11:04:10 -0500543 TePathAttributes teAttributes = new TePathAttributes(exLink.cost(),
544 exLink.delay(), exLink.srlgs());
545 LinkBandwidth bandwidth = new LinkBandwidth(exLink.maxBandwidth(),
546 exLink.availBandwidth(),
547 exLink.maxAvailLspBandwidth(),
548 exLink.minAvailLspBandwidth(),
549 exLink.oduResource());
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500550 BitSet flags = exLink.flags();
551 if (peerTeLinkKey != null &&
552 externalLink != null && externalLink.plugId() != null) {
553 // Assuming this is an inter-domain link which is merged with its peer,
554 // needs to clear BIT_ACCESS_INTERDOMAIN
555 flags.clear(BIT_ACCESS_INTERDOMAIN);
556 } else if (peerTeLinkKey == null &&
557 externalLink != null && externalLink.plugId() != null) {
558 // Assuming this is an inter-domain link which lost its peer,
559 // needs to clear BIT_ACCESS_INTERDOMAIN
560 flags.set(BIT_ACCESS_INTERDOMAIN);
561 }
562
Yixiao Chen68bfab22016-11-11 11:04:10 -0500563 CommonLinkData common = new CommonLinkData(exLink.adminStatus(), exLink.opStatus(),
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500564 flags, exLink.switchingLayer(), exLink.encodingLayer(),
Yixiao Chen68bfab22016-11-11 11:04:10 -0500565 externalLink, underlayPath, teAttributes,
566 exLink.administrativeGroup(), exLink.interLayerLocks(),
567 bandwidth);
568 return new DefaultTeLink(newKey, peerTeLinkKey, underlayTopologyId,
569 supportTeLinkId, sourceTeLinkId, common);
570 }
571
572 private class LinkKeyPair {
573 private TeLinkTpKey firstKey;
574 private TeLinkTpKey secondKey;
575
576 public LinkKeyPair(TeLinkTpKey firstKey) {
577 this.firstKey = firstKey;
578 }
579
580 public TeLinkTpKey firstKey() {
581 return firstKey;
582 }
583
584 public void setFirstKey(TeLinkTpKey firstKey) {
585 this.firstKey = firstKey;
586 }
587
588 public TeLinkTpKey secondKey() {
589 return secondKey;
590 }
591
592 public void setSecondKey(TeLinkTpKey secondKey) {
593 this.secondKey = secondKey;
594 }
595
Yixiao Chen29f06332016-12-07 16:14:29 -0500596 public boolean isFirstKey(TeLinkTpKey linkKey) {
597 return firstKey == null ? false : firstKey.equals(linkKey);
598 }
599
600 public boolean isSecondKey(TeLinkTpKey linkKey) {
601 return secondKey == null ? false : secondKey.equals(linkKey);
602 }
603
604 public boolean isEmpty() {
605 return firstKey == null && secondKey == null;
606 }
607
Yixiao Chen68bfab22016-11-11 11:04:10 -0500608 @Override
609 public String toString() {
610 return MoreObjects.toStringHelper(this)
611 .add("firstKey", firstKey)
612 .add("secondKey", secondKey)
613 .toString();
614 }
615 }
616
617 private void removeSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeLinkTpGlobalKey teLinkKey,
618 boolean postEvent) {
619 TeNodeKey sourceTeNodeKey = teLinkKey.teNodeKey();
620 Long newTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeKey);
621 if (newTeNodeId == null) {
622 return;
623 }
624 TeLinkTpKey newLinkKey = new TeLinkTpKey(newTeNodeId, teLinkKey.teLinkTpId());
625 TeLink teLink = teLinks.remove(newLinkKey);
626 if (teLink == null) {
627 return;
628 }
629 //Post event
630 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500631 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
632 newLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500633 post(new TeTopologyEvent(TE_LINK_REMOVED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500634 new TeLinkEventSubject(globalKey, null)));
635 post(new TeTopologyEvent(LINK_REMOVED,
636 new NetworkLinkEventSubject(networkLinkKey(globalKey),
637 null)));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500638 }
639
640 if (teLink.externalLink() != null && teLink.externalLink().plugId() != null) {
641 // Update the LinkKeyPair in externalLinkMap
642 LinkKeyPair pair = externalLinkMap.get(teLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500643 if (pair.isFirstKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500644 pair.setFirstKey(null);
Yixiao Chen29f06332016-12-07 16:14:29 -0500645 } else if (pair.isSecondKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500646 pair.setSecondKey(null);
647 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500648 if (pair.isEmpty()) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500649 externalLinkMap.remove(teLink.externalLink().plugId());
650 }
651 }
652 TeLinkTpKey peerTeLinkKey = teLink.peerTeLinkKey();
653 if (peerTeLinkKey != null) {
654 // Update peerLink's peerTeLinkKey to null
655 TeLink peerLink = teLinks.get(peerTeLinkKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500656 if (peerLink == null || peerLink.peerTeLinkKey() == null) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500657 return;
658 }
659 TeLink newPeerLink = updateTeLink(peerTeLinkKey, null,
660 peerLink.underlayTeTopologyId(), peerLink.supportingTeLinkId(),
661 peerLink.sourceTeLinkId(), peerLink.externalLink(), peerLink);
662 teLinks.put(peerTeLinkKey, newPeerLink);
663 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500664 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
665 peerTeLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500666 post(new TeTopologyEvent(TE_LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500667 new TeLinkEventSubject(globalKey,
668 newPeerLink)));
669 post(new TeTopologyEvent(LINK_UPDATED,
670 new NetworkLinkEventSubject(networkLinkKey(globalKey),
671 linkBuilder(toNetworkLinkId(peerTeLinkKey),
672 newPeerLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500673 }
674 }
675 }
676
677 private void updateSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeTopologyKey srcTopoKey,
678 TeLink srcLink, boolean postEvent) {
679 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey,
680 srcLink.teLinkKey().teNodeId());
681 TeLinkTpKey newKey = new TeLinkTpKey(
682 sourceNewTeNodeIdMap.get(sourceTeNodeId),
683 srcLink.teLinkKey().teLinkTpId());
684 TeLinkTpKey peerTeLinkKey = null;
685 if (srcLink.peerTeLinkKey() != null) {
686 TeNodeKey sourcePeerNode = new TeNodeKey(srcTopoKey,
687 srcLink.peerTeLinkKey().teNodeId());
688 peerTeLinkKey = new TeLinkTpKey(
689 sourceNewTeNodeIdMap.get(sourcePeerNode),
690 srcLink.peerTeLinkKey().teLinkTpId());
691 }
692
693 if (srcLink.externalLink() != null &&
694 srcLink.externalLink().plugId() != null) {
695 // externalLinkKey doesn't have topology Id.
696 // using plugId for now
697 LinkKeyPair pair = externalLinkMap.get(srcLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500698 if (pair == null) {
699 // Store it in the map
700 externalLinkMap.put(srcLink.externalLink().plugId(),
701 new LinkKeyPair(newKey));
702 } else {
703 if (newKey.equals(pair.firstKey())) {
704 peerTeLinkKey = pair.secondKey();
705 } else if (newKey.equals(pair.secondKey())) {
706 peerTeLinkKey = pair.firstKey();
707 } else if (pair.firstKey() == null) {
708 peerTeLinkKey = pair.secondKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500709 pair.setFirstKey(newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500710 } else if (pair.secondKey() == null) {
711 peerTeLinkKey = pair.firstKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500712 pair.setSecondKey(newKey);
713 }
714
Yixiao Chen29f06332016-12-07 16:14:29 -0500715 if (peerTeLinkKey != null) {
716 TeLink peerLink = teLinks.get(peerTeLinkKey);
717 if (peerLink != null && (peerLink.peerTeLinkKey() == null
718 || !peerLink.peerTeLinkKey().equals(newKey))) {
719 // Update peer Link with local link key
720 TeLink newPeerLink = updateTeLink(peerTeLinkKey, newKey,
721 peerLink.underlayTeTopologyId(),
722 peerLink.supportingTeLinkId(),
723 peerLink.sourceTeLinkId(),
724 peerLink.externalLink(),
725 peerLink);
726 teLinks.put(peerTeLinkKey, newPeerLink);
727 if (postEvent) {
728 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
729 peerTeLinkKey);
730 post(new TeTopologyEvent(TE_LINK_UPDATED,
731 new TeLinkEventSubject(globalKey,
732 newPeerLink)));
733 post(new TeTopologyEvent(LINK_UPDATED,
734 new NetworkLinkEventSubject(
735 networkLinkKey(globalKey),
736 linkBuilder(toNetworkLinkId(peerTeLinkKey),
737 newPeerLink))));
738 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500739 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500740 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500741 }
742 }
743
744 TeTopologyKey underlayTopologyId = null; // No underlay
745 TeLinkTpGlobalKey supportTeLinkId = null; // No support
746 // Source link for the new updated link
747 TeLinkTpGlobalKey sourceTeLinkId = new TeLinkTpGlobalKey(srcTopoKey, srcLink.teLinkKey());
748 TeLink updatedLink = updateTeLink(newKey, peerTeLinkKey, underlayTopologyId,
749 supportTeLinkId, sourceTeLinkId,
750 srcLink.externalLink(), srcLink);
751 TeLinkTpGlobalKey newGlobalKey = new TeLinkTpGlobalKey(mergedTopologyKey, newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500752 boolean newLink = teLinks.get(newKey) == null ? true : false;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500753 teLinks.put(newKey, updatedLink);
754 if (postEvent) {
755 //Post event
756 post(new TeTopologyEvent(newLink ? TE_LINK_ADDED : TE_LINK_UPDATED,
757 new TeLinkEventSubject(newGlobalKey, updatedLink)));
758 post(new TeTopologyEvent(newLink ? LINK_ADDED : LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500759 new NetworkLinkEventSubject(networkLinkKey(newGlobalKey),
760 linkBuilder(toNetworkLinkId(updatedLink.teLinkKey()),
761 updatedLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500762 }
763 }
764
765 // Merge TE links
766 private void mergeLinks(Map<TeLinkTpKey, TeLink> teLinks, TeTopology topology) {
767 if (!MapUtils.isEmpty(topology.teLinks())) {
768 for (Map.Entry<TeLinkTpKey, TeLink> entry : topology.teLinks().entrySet()) {
769 TeLink srcLink = entry.getValue();
770 updateSourceTeLink(teLinks, topology.teTopologyId(), srcLink,
771 mergedTopology != null);
772 }
773 }
774 }
775
776 // Update the merged topology with new TE nodes and links
777 private void updateMergedTopology(Map<Long, TeNode> teNodes, Map<TeLinkTpKey, TeLink> teLinks) {
778 boolean newTopology = mergedTopology == null;
779 BitSet flags = newTopology ? new BitSet(TeConstants.FLAG_MAX_BITS) : mergedTopology.flags();
Yixiao Chen29f06332016-12-07 16:14:29 -0500780 flags.set(BIT_MERGED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500781 CommonTopologyData commonData = new CommonTopologyData(newTopology ?
Yixiao Chen29f06332016-12-07 16:14:29 -0500782 toNetworkId(mergedTopologyKey) :
Yixiao Chen68bfab22016-11-11 11:04:10 -0500783 mergedTopology.networkId(),
Yixiao Chen29f06332016-12-07 16:14:29 -0500784 NOT_OPTIMIZED,
Yixiao Chen68bfab22016-11-11 11:04:10 -0500785 flags, DeviceId.deviceId("localHost"));
786 mergedTopology = new DefaultTeTopology(mergedTopologyKey, teNodes, teLinks,
787 Long.toString(mergedTopologyKey.topologyId()), commonData);
Yixiao Chen29f06332016-12-07 16:14:29 -0500788 mergedNetwork = networkBuilder(mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500789 log.info("Nodes# {}, Links# {}", mergedTopology.teNodes().size(), mergedTopology.teLinks().size());
790 }
791
792 // Merge the new learned topology
793 private void mergeTopology(TeTopology topology) {
794 boolean newTopology = mergedTopology == null;
795 mergedTopologyKey = newTopology ?
796 new TeTopologyKey(providerId, DEFAULT_CLIENT_ID,
797 store.nextTeTopologyId()) :
798 mergedTopology.teTopologyId();
799
800 Map<Long, TeNode> teNodes = newTopology || mergedTopology.teNodes() == null ?
801 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teNodes());
802 mergeNodes(teNodes, topology);
803 Map<TeLinkTpKey, TeLink> teLinks = newTopology || mergedTopology.teLinks() == null ?
804 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teLinks());
805 mergeLinks(teLinks, topology);
806 updateMergedTopology(teNodes, teLinks);
Yixiao Chen29f06332016-12-07 16:14:29 -0500807 log.debug("mergedTopology {}", mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500808
809 if (newTopology) {
810 // Post events for the merged network topology;
811 post(new TeTopologyEvent(TE_TOPOLOGY_ADDED, mergedTopology));
812 post(new TeTopologyEvent(NETWORK_ADDED, mergedNetwork));
813 }
814 }
815
816 private TeTopologyKey newTeTopologyKey(TeTopology teTopology) {
817 TeTopologyKey key = teTopology.teTopologyId();
818 if (key == null || teTopology.teTopologyIdStringValue() == null) {
819 log.error("Ignoring the non-TE topology");
820 throw new ApplicationException("Missing TE topology ID");
821 }
822 // Get the topologyId numeric value
823 long idValue = key.topologyId();
824 if (idValue == TeConstants.NIL_LONG_VALUE) {
825 if (teTopology.teTopologyIdStringValue() != null) {
826 try {
827 idValue = Long.parseLong(teTopology.teTopologyIdStringValue());
828 } catch (NumberFormatException e) {
829 // Can't get the long value from the string.
830 // Use an assigned id value from local id pool,
831 idValue = store.nextTeTopologyId();
832 }
833 return new TeTopologyKey(key.providerId(), key.clientId(), idValue);
834 }
835 }
836 return null;
837 }
838
839 private class InternalConfigListener implements NetworkConfigListener {
840
841 @Override
842 public void event(NetworkConfigEvent event) {
843 try {
844 providerId = cfgService.getConfig(appId, TeTopologyConfig.class)
845 .providerId();
Yixiao Chen29f06332016-12-07 16:14:29 -0500846 store.setProviderId(providerId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500847 teNodeIpStart = cfgService.getConfig(appId, TeTopologyConfig.class)
848 .teNodeIpStart();
849 teNodeIpEnd = cfgService.getConfig(appId, TeTopologyConfig.class)
850 .teNodeIpEnd();
Yixiao Chen29f06332016-12-07 16:14:29 -0500851 mdsc = cfgService.getConfig(appId, TeTopologyConfig.class)
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500852 .mdsc().equals(MDSC_MODE);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500853 nextTeNodeId = teNodeIpStart.toInt();
854 } catch (ConfigException e) {
855 log.error("Configuration error {}", e);
856 }
857 }
858
859 @Override
860 public boolean isRelevant(NetworkConfigEvent event) {
861 return event.configClass().equals(TeTopologyConfig.class) &&
862 (event.type() == CONFIG_ADDED ||
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500863 event.type() == CONFIG_UPDATED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500864 }
865 }
866
867 @Override
868 public TeTopologies teTopologies() {
869 Map<TeTopologyKey, TeTopology> map;
870 if (MapUtils.isNotEmpty(store.teTopologies().teTopologies())) {
871 map = Maps.newHashMap(store.teTopologies().teTopologies());
872 } else {
873 map = Maps.newHashMap();
874 }
875 if (mergedTopology != null) {
876 map.put(mergedTopologyKey, mergedTopology);
877 }
878 return new DefaultTeTopologies(store.teTopologies().name(), map);
879 }
880
881 @Override
882 public TeTopology teTopology(TeTopologyKey topologyId) {
883 if (mergedTopology != null &&
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500884 topologyId != null &&
Yixiao Chen68bfab22016-11-11 11:04:10 -0500885 topologyId.equals(mergedTopologyKey)) {
886 return mergedTopology;
887 }
888 return store.teTopology(topologyId);
889 }
890
891 @Override
892 public TeTopology mergedTopology() {
893 return mergedTopology;
894 }
895
896 @Override
897 public void updateTeTopology(TeTopology teTopology) {
898 TeTopologyKey newKey = null;
899 try {
900 newKey = newTeTopologyKey(teTopology);
901 } catch (ApplicationException e) {
902 log.error("Ignoring the non-TE topology");
903 return;
904 }
905
906 // TE topology is updated here from other APP or NBI, the flag
907 // BIT_CUSTOMIZED or BIT_MERGED should be set.
908 BitSet flags = teTopology.flags();
909 if (flags == null ||
Yixiao Chen29f06332016-12-07 16:14:29 -0500910 !(flags.get(BIT_CUSTOMIZED) || flags.get(BIT_MERGED))) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500911 log.error("TE topology flags {} are not set properly", flags);
912 return;
913 }
914
915 if (newKey != null) {
916 DefaultTeTopology newTopology = new DefaultTeTopology(
Ray Milkeyfe0e0852018-01-18 11:14:05 -0800917 newKey,
Yixiao Chen68bfab22016-11-11 11:04:10 -0500918 teTopology.teNodes(), teTopology.teLinks(),
919 teTopology.teTopologyIdStringValue(), new CommonTopologyData(teTopology));
920 // Update with new data
921 store.updateTeTopology(newTopology);
922 } else {
923 store.updateTeTopology(teTopology);
924 }
925 }
926
927 @Override
928 public void removeTeTopology(TeTopologyKey topologyId) {
929 store.removeTeTopology(topologyId);
930 }
931
932 @Override
933 public Networks networks() {
934 List<Network> networks;
935 if (CollectionUtils.isNotEmpty(store.networks())) {
936 networks = Lists.newArrayList(store.networks());
937 } else {
938 networks = Lists.newArrayList();
939 }
940 if (mergedNetwork != null) {
941 networks.add(mergedNetwork);
942 }
943 return new DefaultNetworks(networks);
944 }
945
946 @Override
947 public Network network(KeyId networkId) {
948 if (mergedNetwork != null &&
949 mergedNetwork.networkId().equals(networkId)) {
950 return mergedNetwork;
951 }
952 return store.network(networkId);
953 }
954
955 @Override
956 public void updateNetwork(Network network) {
957 // TODO: This will be implemented if required.
958 }
959
960 @Override
961 public void removeNetwork(KeyId networkId) {
962 // TODO: This will be implemented if required.
963 }
964
965 @Override
966 public TeNode teNode(TeNodeKey nodeId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500967 return nodeId.teTopologyKey().equals(mergedTopologyKey) ?
968 mergedTopology.teNode(nodeId.teNodeId()) :
969 store.teNode(nodeId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500970 }
971
972 @Override
973 public TeLink teLink(TeLinkTpGlobalKey linkId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500974 return linkId.teTopologyKey().equals(mergedTopologyKey) ?
975 mergedTopology.teLink(linkId.teLinkTpKey()) :
976 store.teLink(linkId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500977 }
978
979 @Override
980 public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500981 return ttpId.teTopologyKey().equals(mergedTopologyKey) ?
982 mergedTopology.teNode(ttpId.teNodeId()).tunnelTerminationPoint(ttpId.ttpId()) :
983 store.tunnelTerminationPoint(ttpId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500984 }
985
986 @Override
987 public KeyId networkId(TeTopologyKey teTopologyKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500988 return teTopologyKey.equals(mergedTopologyKey) ?
989 mergedNetwork.networkId() :
990 store.networkId(teTopologyKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500991 }
992
993 @Override
994 public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500995 return teNodeKey.teTopologyKey().equals(mergedTopologyKey) ?
996 networkNodeKey(teNodeKey) :
997 store.nodeKey(teNodeKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500998 }
999
1000 @Override
1001 public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001002 return teLinkKey.teTopologyKey().equals(mergedTopologyKey) ?
1003 networkLinkKey(teLinkKey) :
1004 store.linkKey(teLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001005 }
1006
1007 @Override
1008 public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001009 return teTpKey.teTopologyKey().equals(mergedTopologyKey) ?
1010 new TerminationPointKey(networkNodeKey(teTpKey.teNodeKey()),
1011 KeyId.keyId(Long.toString(teTpKey.teLinkTpId()))) :
1012 store.terminationPointKey(teTpKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001013 }
Yixiao Chen265b3bb2017-01-13 10:17:03 -05001014
1015 @Override
1016 public long teContollerId() {
1017 return providerId;
1018 }
Yixiao Chen68bfab22016-11-11 11:04:10 -05001019}