blob: 5775a570dcf0dd9d47c00abf53ec28804d54acce [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
18import static java.util.concurrent.Executors.newFixedThreadPool;
19import static org.onlab.util.Tools.groupedThreads;
20import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
21import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
22import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
Yixiao Chen29f06332016-12-07 16:14:29 -050023import static org.onosproject.tetopology.management.api.OptimizationType.NOT_OPTIMIZED;
24import static org.onosproject.tetopology.management.api.TeTopology.BIT_CUSTOMIZED;
25import static org.onosproject.tetopology.management.api.TeTopology.BIT_LEARNT;
26import static org.onosproject.tetopology.management.api.TeTopology.BIT_MERGED;
Yixiao Chen68bfab22016-11-11 11:04:10 -050027import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_ADDED;
28import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_REMOVED;
29import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.LINK_UPDATED;
30import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED;
31import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED;
32import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_ADDED;
33import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_REMOVED;
34import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NODE_UPDATED;
35import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_ADDED;
36import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_REMOVED;
37import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_LINK_UPDATED;
38import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_ADDED;
39import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_REMOVED;
40import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_NODE_UPDATED;
41import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED;
42import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
Yixiao Chen265b3bb2017-01-13 10:17:03 -050043import static org.onosproject.tetopology.management.api.link.TeLink.BIT_ACCESS_INTERDOMAIN;
Yixiao Chen29f06332016-12-07 16:14:29 -050044import static org.onosproject.tetopology.management.impl.TeMgrUtil.linkBuilder;
45import static org.onosproject.tetopology.management.impl.TeMgrUtil.networkBuilder;
46import static org.onosproject.tetopology.management.impl.TeMgrUtil.networkLinkKey;
47import static org.onosproject.tetopology.management.impl.TeMgrUtil.networkNodeKey;
48import static org.onosproject.tetopology.management.impl.TeMgrUtil.nodeBuilder;
49import static org.onosproject.tetopology.management.impl.TeMgrUtil.toNetworkId;
50import static org.onosproject.tetopology.management.impl.TeMgrUtil.toNetworkLinkId;
Yixiao Chen68bfab22016-11-11 11:04:10 -050051
52import java.util.BitSet;
53import java.util.List;
54import java.util.Map;
Yixiao Chen68bfab22016-11-11 11:04:10 -050055import java.util.concurrent.ExecutorService;
Yixiao Chen68bfab22016-11-11 11:04:10 -050056
57import org.apache.commons.collections.CollectionUtils;
58import org.apache.commons.collections.MapUtils;
59import org.apache.felix.scr.annotations.Activate;
60import org.apache.felix.scr.annotations.Component;
61import org.apache.felix.scr.annotations.Deactivate;
62import org.apache.felix.scr.annotations.Reference;
63import org.apache.felix.scr.annotations.ReferenceCardinality;
64import org.apache.felix.scr.annotations.Service;
65import org.onlab.packet.Ip4Address;
66import org.onosproject.app.ApplicationException;
67import org.onosproject.core.ApplicationId;
68import org.onosproject.core.CoreService;
Ray Milkey6c013742017-08-15 10:16:43 -070069import org.onosproject.net.config.ConfigException;
Yixiao Chen68bfab22016-11-11 11:04:10 -050070import org.onosproject.net.DeviceId;
71import org.onosproject.net.config.ConfigFactory;
72import org.onosproject.net.config.NetworkConfigEvent;
73import org.onosproject.net.config.NetworkConfigListener;
74import org.onosproject.net.config.NetworkConfigRegistry;
75import org.onosproject.net.device.DeviceProviderRegistry;
76import org.onosproject.net.device.DeviceService;
77import org.onosproject.net.link.LinkProviderRegistry;
78import org.onosproject.net.link.LinkService;
79import org.onosproject.net.provider.AbstractListenerProviderRegistry;
80import org.onosproject.net.provider.AbstractProviderService;
81import org.onosproject.tetopology.management.api.CommonTopologyData;
82import org.onosproject.tetopology.management.api.DefaultNetwork;
83import org.onosproject.tetopology.management.api.DefaultNetworks;
84import org.onosproject.tetopology.management.api.DefaultTeTopologies;
85import org.onosproject.tetopology.management.api.DefaultTeTopology;
86import org.onosproject.tetopology.management.api.KeyId;
87import org.onosproject.tetopology.management.api.Network;
88import org.onosproject.tetopology.management.api.Networks;
Yixiao Chen68bfab22016-11-11 11:04:10 -050089import org.onosproject.tetopology.management.api.TeConstants;
90import org.onosproject.tetopology.management.api.TeTopologies;
91import org.onosproject.tetopology.management.api.TeTopology;
92import org.onosproject.tetopology.management.api.TeTopologyEvent;
93import org.onosproject.tetopology.management.api.TeTopologyKey;
94import org.onosproject.tetopology.management.api.TeTopologyListener;
95import org.onosproject.tetopology.management.api.TeTopologyProvider;
96import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry;
97import org.onosproject.tetopology.management.api.TeTopologyProviderService;
98import org.onosproject.tetopology.management.api.TeTopologyService;
99import org.onosproject.tetopology.management.api.link.CommonLinkData;
100import org.onosproject.tetopology.management.api.link.DefaultTeLink;
101import org.onosproject.tetopology.management.api.link.ExternalLink;
102import org.onosproject.tetopology.management.api.link.LinkBandwidth;
103import org.onosproject.tetopology.management.api.link.NetworkLink;
104import org.onosproject.tetopology.management.api.link.NetworkLinkEventSubject;
105import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
106import org.onosproject.tetopology.management.api.link.TeLink;
107import org.onosproject.tetopology.management.api.link.TeLinkEventSubject;
108import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
109import org.onosproject.tetopology.management.api.link.TeLinkTpKey;
110import org.onosproject.tetopology.management.api.link.TePathAttributes;
111import org.onosproject.tetopology.management.api.link.UnderlayPath;
112import org.onosproject.tetopology.management.api.node.CommonNodeData;
113import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
114import org.onosproject.tetopology.management.api.node.DefaultTeNode;
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500115import org.onosproject.tetopology.management.api.node.DefaultTunnelTerminationPoint;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500116import org.onosproject.tetopology.management.api.node.NetworkNode;
117import org.onosproject.tetopology.management.api.node.NetworkNodeEventSubject;
118import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
119import org.onosproject.tetopology.management.api.node.TeNode;
120import org.onosproject.tetopology.management.api.node.TeNodeEventSubject;
121import org.onosproject.tetopology.management.api.node.TeNodeKey;
122import org.onosproject.tetopology.management.api.node.TerminationPoint;
123import org.onosproject.tetopology.management.api.node.TerminationPointKey;
124import org.onosproject.tetopology.management.api.node.TtpKey;
125import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
126import org.slf4j.Logger;
127import org.slf4j.LoggerFactory;
128
129import com.google.common.base.MoreObjects;
130import com.google.common.collect.Lists;
131import com.google.common.collect.Maps;
132
133/**
134 * Implementation of the topology management service.
135 */
136@Component(immediate = true)
137@Service
138public class TeTopologyManager
139 extends AbstractListenerProviderRegistry<TeTopologyEvent, TeTopologyListener,
140 TeTopologyProvider, TeTopologyProviderService>
141 implements TeTopologyService, TeTopologyProviderRegistry {
142 private static final String APP_NAME = "org.onosproject.tetopology";
Yixiao Chen29f06332016-12-07 16:14:29 -0500143 private static final long DEFAULT_PROVIDER_ID = 77777;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500144 private static final long DEFAULT_CLIENT_ID = 0x00L;
145 private long providerId = DEFAULT_PROVIDER_ID;
146 private static final int MAX_THREADS = 1;
Yixiao Chen29f06332016-12-07 16:14:29 -0500147 private static final Ip4Address DEFAULT_TENODE_ID_START = Ip4Address.valueOf("10.10.10.10");
Yixiao Chen68bfab22016-11-11 11:04:10 -0500148 private static final Ip4Address DEFAULT_TENODE_ID_END = Ip4Address.valueOf("250.250.250.250");
149 private Ip4Address teNodeIpStart = DEFAULT_TENODE_ID_START;
150 private Ip4Address teNodeIpEnd = DEFAULT_TENODE_ID_END;
151 private long nextTeNodeId = teNodeIpStart.toInt();
Yixiao Chen29f06332016-12-07 16:14:29 -0500152 private boolean mdsc = true;
153 private static final String MDSC_MODE = "true";
154
Yixiao Chen68bfab22016-11-11 11:04:10 -0500155 private final Logger log = LoggerFactory.getLogger(getClass());
156
157 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
158 protected CoreService coreService;
159
160 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
161 protected NetworkConfigRegistry cfgService;
162
163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
164 protected DeviceService deviceService;
165
166 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
167 protected LinkService linkService;
168
169 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 protected DeviceProviderRegistry deviceProviderRegistry;
171
172 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
173 protected LinkProviderRegistry linkProviderRegistry;
174
175 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
176 public TeTopologyStore store;
177
178 private TeTopologyStoreDelegate delegate = this::post;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500179 private final ConfigFactory<ApplicationId, TeTopologyConfig> factory =
180 new ConfigFactory<ApplicationId, TeTopologyConfig>(APP_SUBJECT_FACTORY,
181 TeTopologyConfig.class,
182 "teTopologyCfg",
183 false) {
184 @Override
185 public TeTopologyConfig createConfig() {
186 return new TeTopologyConfig();
187 }
188 };
189 private final NetworkConfigListener cfgLister = new InternalConfigListener();
190 private ApplicationId appId;
191 // The topology merged in MDSC
192 private TeTopology mergedTopology = null;
193 private TeTopologyKey mergedTopologyKey;
194 private Network mergedNetwork = null;
195 // Track new TE node id by its source TE node key
196 private Map<TeNodeKey, Long> sourceNewTeNodeIdMap = Maps.newHashMap();
197 // Track the external link keys by the plugId
198 private Map<Long, LinkKeyPair> externalLinkMap = Maps.newHashMap();
199 private ExecutorService executor;
200
201 /**
202 * Activation helper function.
203 */
204 public void activateBasics() {
205 store.setDelegate(delegate);
Yixiao Chen29f06332016-12-07 16:14:29 -0500206 store.setProviderId(providerId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500207 eventDispatcher.addSink(TeTopologyEvent.class, listenerRegistry);
208 }
209
210 /**
211 * Deactivation helper function.
212 */
213 public void deactivateBasics() {
214 store.unsetDelegate(delegate);
215 eventDispatcher.removeSink(TeTopologyEvent.class);
216 }
217
218 @Activate
219 public void activate() {
220 activateBasics();
221 appId = coreService.registerApplication(APP_NAME);
222 cfgService.registerConfigFactory(factory);
223 executor = newFixedThreadPool(MAX_THREADS, groupedThreads("onos/tetopology", "build-%d", log));
224
225 cfgService.addListener(cfgLister);
226 executor.execute(new TopologyMergerTask());
227 log.info("Started");
228 }
229
230 @Deactivate
231 public void deactivate() {
232 deactivateBasics();
233 externalLinkMap.clear();
234 cfgService.removeListener(cfgLister);
235 cfgService.unregisterConfigFactory(factory);
236 executor.shutdownNow();
237 executor = null;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500238 log.info("Stopped");
239 }
240
241 @Override
242 protected TeTopologyProviderService createProviderService(TeTopologyProvider provider) {
243 return new InternalTopologyProviderService(provider);
244 }
245
246 private class InternalTopologyProviderService
247 extends AbstractProviderService<TeTopologyProvider>
248 implements TeTopologyProviderService {
249
250 protected InternalTopologyProviderService(TeTopologyProvider provider) {
251 super(provider);
252 }
253
254 @Override
255 public void networkUpdated(Network network) {
256 store.updateNetwork(network);
257 }
258
259 @Override
260 public void networkRemoved(KeyId networkId) {
261 store.removeNetwork(networkId);
262 }
263
264 @Override
265 public void linkUpdated(NetworkLinkKey linkKey, NetworkLink link) {
266 store.updateNetworkLink(linkKey, link);
267 }
268
269 @Override
270 public void linkRemoved(NetworkLinkKey linkKey) {
271 store.removeNetworkLink(linkKey);
272 }
273
274 @Override
275 public void nodeUpdated(NetworkNodeKey nodeKey, NetworkNode node) {
276 store.updateNetworkNode(nodeKey, node);
277 }
278
279 @Override
280 public void nodeRemoved(NetworkNodeKey nodeKey) {
281 store.removeNetworkNode(nodeKey);
282 }
283
284 @Override
285 public void terminationPointUpdated(TerminationPointKey terminationPointKey,
286 TerminationPoint terminationPoint) {
287 store.updateTerminationPoint(terminationPointKey, terminationPoint);
288 }
289
290 @Override
291 public void terminationPointRemoved(TerminationPointKey terminationPointKey) {
292 store.removeTerminationPoint(terminationPointKey);
293 }
294 }
295
296 private boolean isCustomizedLearnedTopology(TeTopologyKey key) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500297 if (store.teTopology(key).flags().get(BIT_CUSTOMIZED) &&
298 store.teTopology(key).flags().get(BIT_LEARNT)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500299 return true;
300 }
301 return false;
302 }
303
304 // Task for merge the learned topology.
305 private class TopologyMergerTask implements Runnable {
306
307 public TopologyMergerTask() {
308 }
309
310 @Override
311 public void run() {
312 try {
313 TeTopologyMapEvent event;
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500314 while ((event = store.mapEventQueue().take()) != null) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500315 switch (event.type()) {
316 case TE_TOPOLOGY_ADDED:
317 case TE_TOPOLOGY_UPDATED:
318 TeTopology teTopology = store.teTopology(event.teTopologyKey());
319 post(new TeTopologyEvent(event.type(), teTopology));
Yixiao Chen29f06332016-12-07 16:14:29 -0500320 if (mdsc && event.type() == TE_TOPOLOGY_ADDED &&
321 teTopology.flags().get(BIT_CUSTOMIZED) &&
322 teTopology.flags().get(BIT_LEARNT)) {
323 log.debug("TeTopology to be merged: {}", teTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500324 mergeTopology(teTopology);
325 }
326 break;
327 case TE_TOPOLOGY_REMOVED:
328 post(new TeTopologyEvent(TE_TOPOLOGY_REMOVED,
329 new DefaultTeTopology(event.teTopologyKey(),
330 null, null, null, null)));
331 break;
332 case TE_NODE_ADDED:
333 case TE_NODE_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500334 if (store.teTopology(event.teNodeKey().teTopologyKey()) == null) {
335 // Event should be ignored when the topology is not there.
336 break;
337 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500338 TeNode teNode = store.teNode(event.teNodeKey());
339 post(new TeTopologyEvent(event.type(),
340 new TeNodeEventSubject(event.teNodeKey(), teNode)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500341 if (mdsc && isCustomizedLearnedTopology(event.teNodeKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500342 updateSourceTeNode(mergedTopology.teNodes(),
343 event.teNodeKey().teTopologyKey(), teNode, true);
344 }
345 break;
346 case TE_NODE_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500347 if (store.teTopology(event.teNodeKey().teTopologyKey()) == null) {
348 // Event should be ignored when the topology is not there.
349 break;
350 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500351 post(new TeTopologyEvent(TE_NODE_REMOVED,
352 new TeNodeEventSubject(event.teNodeKey(), null)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500353 if (mdsc && isCustomizedLearnedTopology(event.teNodeKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500354 removeSourceTeNode(mergedTopology.teNodes(), event.teNodeKey(), true);
355 }
356 break;
357 case TE_LINK_ADDED:
358 case TE_LINK_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500359 if (store.teTopology(event.teLinkKey().teTopologyKey()) == null ||
360 store.teNode(event.teLinkKey().teNodeKey()) == null) {
361 // Event should be ignored when the topology or node is not there.
362 break;
363 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500364 TeLink teLink = store.teLink(event.teLinkKey());
365 post(new TeTopologyEvent(event.type(),
366 new TeLinkEventSubject(event.teLinkKey(), teLink)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500367 if (mdsc && isCustomizedLearnedTopology(event.teLinkKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500368 Map<TeLinkTpKey, TeLink> teLinks = Maps.newHashMap(mergedTopology.teLinks());
369 updateSourceTeLink(teLinks, event.teLinkKey().teTopologyKey(), teLink, true);
370 updateMergedTopology(mergedTopology.teNodes(), teLinks);
371 }
372 break;
373 case TE_LINK_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500374 if (store.teTopology(event.teLinkKey().teTopologyKey()) == null ||
375 store.teNode(event.teLinkKey().teNodeKey()) == null) {
376 // Event should be ignored when the topology or node is not there.
377 break;
378 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500379 post(new TeTopologyEvent(TE_LINK_REMOVED,
380 new TeLinkEventSubject(event.teLinkKey(), null)));
Yixiao Chen29f06332016-12-07 16:14:29 -0500381 if (mdsc && isCustomizedLearnedTopology(event.teLinkKey().teTopologyKey())) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500382 Map<TeLinkTpKey, TeLink> teLinks = Maps.newHashMap(mergedTopology.teLinks());
383 removeSourceTeLink(teLinks, event.teLinkKey(), true);
384 updateMergedTopology(mergedTopology.teNodes(), teLinks);
385 }
386 break;
387 case NETWORK_ADDED:
388 case NETWORK_UPDATED:
389 Network network = store.network(event.networkKey());
390 post(new TeTopologyEvent(event.type(), network));
391 break;
392 case NETWORK_REMOVED:
393 post(new TeTopologyEvent(NETWORK_REMOVED,
Aihua Guo0bc12092017-02-10 09:53:55 -0500394 new DefaultNetwork(event.networkKey(), null, null,
395 null, null, false, null,
396 NOT_OPTIMIZED)));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500397 break;
398 case NODE_ADDED:
399 case NODE_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500400 if (store.network(event.networkNodeKey().networkId()) == null) {
401 // Event should be ignored when the network is not there.
402 break;
403 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500404 NetworkNode node = store.networkNode(event.networkNodeKey());
405 post(new TeTopologyEvent(event.type(),
406 new NetworkNodeEventSubject(event.networkNodeKey(), node)));
407 break;
408 case NODE_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500409 if (store.network(event.networkNodeKey().networkId()) == null) {
410 // Event should be ignored when the network is not there.
411 break;
412 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500413 post(new TeTopologyEvent(NODE_REMOVED,
414 new NetworkNodeEventSubject(event.networkNodeKey(), null)));
415 break;
416 case LINK_ADDED:
417 case LINK_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500418 if (store.network(event.networkLinkKey().networkId()) == null) {
419 // Event should be ignored when the network is not there.
420 break;
421 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500422 NetworkLink link = store.networkLink(event.networkLinkKey());
423 post(new TeTopologyEvent(event.type(),
424 new NetworkLinkEventSubject(event.networkLinkKey(), link)));
425 break;
426 case LINK_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500427 if (store.network(event.networkLinkKey().networkId()) == null) {
428 // Event should be ignored when the network is not there.
429 break;
430 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500431 post(new TeTopologyEvent(LINK_REMOVED,
432 new NetworkLinkEventSubject(event.networkLinkKey(), null)));
433 break;
434 default:
435 break;
436 }
437 }
438 } catch (InterruptedException e) {
439 log.warn("TopologyMergerTask is interrupted");
Ray Milkey5c7d4882018-02-05 14:50:39 -0800440 Thread.currentThread().interrupt();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500441 } catch (Exception e) {
442 log.warn("Unable to merge topology", e);
443 }
444 }
445 }
446
447 private void removeSourceTeNode(Map<Long, TeNode> teNodes,
448 TeNodeKey srcNodeKey, boolean postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500449 Long mergedTeNodeId = sourceNewTeNodeIdMap.remove(srcNodeKey);
450 if (mergedTeNodeId == null) {
451 return;
452 }
453 if (teNodes.remove(mergedTeNodeId) != null && postEvent) {
454 TeNodeKey nodeKey = new TeNodeKey(mergedTopologyKey,
455 mergedTeNodeId);
456 post(new TeTopologyEvent(TE_NODE_REMOVED,
457 new TeNodeEventSubject(nodeKey, null)));
458 post(new TeTopologyEvent(NODE_REMOVED,
459 new NetworkNodeEventSubject(TeMgrUtil
460 .networkNodeKey(nodeKey), null)));
461 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500462 }
463
464 private void updateSourceTeNode(Map<Long, TeNode> teNodes, TeTopologyKey srcTopoKey,
465 TeNode srcNode, boolean postEvent) {
466 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey, srcNode.teNodeId());
467 Long mergedTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeId);
468 boolean addNode = false;
469 if (mergedTeNodeId == null) {
470 // New node
471 addNode = true;
472 mergedTeNodeId = nextTeNodeId;
473 nextTeNodeId++;
474 if (nextTeNodeId >= teNodeIpEnd.toInt()) {
475 nextTeNodeId = teNodeIpStart.toInt();
476 log.warn("TE node Id is wrapped back");
477 }
478 sourceNewTeNodeIdMap.put(sourceTeNodeId, mergedTeNodeId);
479 }
480 TeTopologyKey underlayTopologyId = null; // No underlay
481 TeNodeKey supportTeNodeId = null; // No supporting
482
483 CommonNodeData common = new CommonNodeData(srcNode.name(), srcNode.adminStatus(),
484 srcNode.opStatus(), srcNode.flags()); // No change
485 Map<Long, ConnectivityMatrix> connMatrices = srcNode.connectivityMatrices();
486 List<Long> teLinkIds = srcNode.teLinkIds(); // No change
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500487 Map<Long, TunnelTerminationPoint> ttps = null;
488 if (MapUtils.isNotEmpty(srcNode.tunnelTerminationPoints())) {
489 ttps = Maps.newHashMap();
490 for (Map.Entry<Long, TunnelTerminationPoint> entry : srcNode.tunnelTerminationPoints().entrySet()) {
491 TunnelTerminationPoint ttp = entry.getValue();
492 ttps.put(entry.getKey(),
493 new DefaultTunnelTerminationPoint(ttp.ttpId(), ttp.switchingLayer(),
494 ttp.encodingLayer(), ttp.flags(),
495 ttp.interLayerLockList(),
496 ttp.localLinkConnectivityList(),
497 ttp.availAdaptBandwidth(),
498 null)); //Remove supporting TTP Ids
499 }
500 }
501
Yixiao Chen68bfab22016-11-11 11:04:10 -0500502 List<Long> teTpIds = srcNode.teTerminationPointIds(); // No change
503 DefaultTeNode newNode = new DefaultTeNode(mergedTeNodeId, underlayTopologyId,
504 supportTeNodeId, sourceTeNodeId, common, connMatrices, teLinkIds,
505 ttps, teTpIds);
506 teNodes.put(mergedTeNodeId, newNode);
507 if (postEvent) {
508 //Post event for the TE node in the merged topology
509 TeNodeKey globalKey = new TeNodeKey(mergedTopologyKey, mergedTeNodeId);
510 post(new TeTopologyEvent(addNode ? TE_NODE_ADDED : TE_NODE_UPDATED,
511 new TeNodeEventSubject(globalKey, newNode)));
512 post(new TeTopologyEvent(addNode ? NODE_ADDED : NODE_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500513 new NetworkNodeEventSubject(networkNodeKey(globalKey),
514 nodeBuilder(KeyId.keyId(
515 Ip4Address.valueOf((int) newNode.teNodeId()).toString()),
516 newNode))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500517 }
518 }
519
520 // Merge TE nodes
521 private void mergeNodes(Map<Long, TeNode> nodes, TeTopology topology) {
522
523 if (!MapUtils.isEmpty(topology.teNodes())) {
524 for (Map.Entry<Long, TeNode> entry : topology.teNodes().entrySet()) {
525 updateSourceTeNode(nodes, topology.teTopologyId(), entry.getValue(),
526 mergedTopology != null);
527 }
528 }
529 }
530
531 // Returns a new TeLink based on an existing TeLink with new attributes
532 private TeLink updateTeLink(TeLinkTpKey newKey, TeLinkTpKey peerTeLinkKey,
533 TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
534 TeLinkTpGlobalKey sourceTeLinkId, ExternalLink externalLink,
535 TeLink exLink) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500536 UnderlayPath underlayPath = null;
537 if (underlayTopologyId != null &&
538 underlayTopologyId.equals(exLink.underlayTeTopologyId())) {
539 underlayPath = new UnderlayPath(exLink.primaryPath(),
540 exLink.backupPaths(), exLink.tunnelProtectionType(),
541 exLink.sourceTtpId(), exLink.destinationTtpId(),
542 exLink.teTunnelId()
543 );
544 }
545
Yixiao Chen68bfab22016-11-11 11:04:10 -0500546 TePathAttributes teAttributes = new TePathAttributes(exLink.cost(),
547 exLink.delay(), exLink.srlgs());
548 LinkBandwidth bandwidth = new LinkBandwidth(exLink.maxBandwidth(),
549 exLink.availBandwidth(),
550 exLink.maxAvailLspBandwidth(),
551 exLink.minAvailLspBandwidth(),
552 exLink.oduResource());
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500553 BitSet flags = exLink.flags();
554 if (peerTeLinkKey != null &&
555 externalLink != null && externalLink.plugId() != null) {
556 // Assuming this is an inter-domain link which is merged with its peer,
557 // needs to clear BIT_ACCESS_INTERDOMAIN
558 flags.clear(BIT_ACCESS_INTERDOMAIN);
559 } else if (peerTeLinkKey == null &&
560 externalLink != null && externalLink.plugId() != null) {
561 // Assuming this is an inter-domain link which lost its peer,
562 // needs to clear BIT_ACCESS_INTERDOMAIN
563 flags.set(BIT_ACCESS_INTERDOMAIN);
564 }
565
Yixiao Chen68bfab22016-11-11 11:04:10 -0500566 CommonLinkData common = new CommonLinkData(exLink.adminStatus(), exLink.opStatus(),
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500567 flags, exLink.switchingLayer(), exLink.encodingLayer(),
Yixiao Chen68bfab22016-11-11 11:04:10 -0500568 externalLink, underlayPath, teAttributes,
569 exLink.administrativeGroup(), exLink.interLayerLocks(),
570 bandwidth);
571 return new DefaultTeLink(newKey, peerTeLinkKey, underlayTopologyId,
572 supportTeLinkId, sourceTeLinkId, common);
573 }
574
575 private class LinkKeyPair {
576 private TeLinkTpKey firstKey;
577 private TeLinkTpKey secondKey;
578
579 public LinkKeyPair(TeLinkTpKey firstKey) {
580 this.firstKey = firstKey;
581 }
582
583 public TeLinkTpKey firstKey() {
584 return firstKey;
585 }
586
587 public void setFirstKey(TeLinkTpKey firstKey) {
588 this.firstKey = firstKey;
589 }
590
591 public TeLinkTpKey secondKey() {
592 return secondKey;
593 }
594
595 public void setSecondKey(TeLinkTpKey secondKey) {
596 this.secondKey = secondKey;
597 }
598
Yixiao Chen29f06332016-12-07 16:14:29 -0500599 public boolean isFirstKey(TeLinkTpKey linkKey) {
600 return firstKey == null ? false : firstKey.equals(linkKey);
601 }
602
603 public boolean isSecondKey(TeLinkTpKey linkKey) {
604 return secondKey == null ? false : secondKey.equals(linkKey);
605 }
606
607 public boolean isEmpty() {
608 return firstKey == null && secondKey == null;
609 }
610
Yixiao Chen68bfab22016-11-11 11:04:10 -0500611 @Override
612 public String toString() {
613 return MoreObjects.toStringHelper(this)
614 .add("firstKey", firstKey)
615 .add("secondKey", secondKey)
616 .toString();
617 }
618 }
619
620 private void removeSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeLinkTpGlobalKey teLinkKey,
621 boolean postEvent) {
622 TeNodeKey sourceTeNodeKey = teLinkKey.teNodeKey();
623 Long newTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeKey);
624 if (newTeNodeId == null) {
625 return;
626 }
627 TeLinkTpKey newLinkKey = new TeLinkTpKey(newTeNodeId, teLinkKey.teLinkTpId());
628 TeLink teLink = teLinks.remove(newLinkKey);
629 if (teLink == null) {
630 return;
631 }
632 //Post event
633 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500634 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
635 newLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500636 post(new TeTopologyEvent(TE_LINK_REMOVED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500637 new TeLinkEventSubject(globalKey, null)));
638 post(new TeTopologyEvent(LINK_REMOVED,
639 new NetworkLinkEventSubject(networkLinkKey(globalKey),
640 null)));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500641 }
642
643 if (teLink.externalLink() != null && teLink.externalLink().plugId() != null) {
644 // Update the LinkKeyPair in externalLinkMap
645 LinkKeyPair pair = externalLinkMap.get(teLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500646 if (pair.isFirstKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500647 pair.setFirstKey(null);
Yixiao Chen29f06332016-12-07 16:14:29 -0500648 } else if (pair.isSecondKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500649 pair.setSecondKey(null);
650 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500651 if (pair.isEmpty()) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500652 externalLinkMap.remove(teLink.externalLink().plugId());
653 }
654 }
655 TeLinkTpKey peerTeLinkKey = teLink.peerTeLinkKey();
656 if (peerTeLinkKey != null) {
657 // Update peerLink's peerTeLinkKey to null
658 TeLink peerLink = teLinks.get(peerTeLinkKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500659 if (peerLink == null || peerLink.peerTeLinkKey() == null) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500660 return;
661 }
662 TeLink newPeerLink = updateTeLink(peerTeLinkKey, null,
663 peerLink.underlayTeTopologyId(), peerLink.supportingTeLinkId(),
664 peerLink.sourceTeLinkId(), peerLink.externalLink(), peerLink);
665 teLinks.put(peerTeLinkKey, newPeerLink);
666 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500667 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
668 peerTeLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500669 post(new TeTopologyEvent(TE_LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500670 new TeLinkEventSubject(globalKey,
671 newPeerLink)));
672 post(new TeTopologyEvent(LINK_UPDATED,
673 new NetworkLinkEventSubject(networkLinkKey(globalKey),
674 linkBuilder(toNetworkLinkId(peerTeLinkKey),
675 newPeerLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500676 }
677 }
678 }
679
680 private void updateSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeTopologyKey srcTopoKey,
681 TeLink srcLink, boolean postEvent) {
682 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey,
683 srcLink.teLinkKey().teNodeId());
684 TeLinkTpKey newKey = new TeLinkTpKey(
685 sourceNewTeNodeIdMap.get(sourceTeNodeId),
686 srcLink.teLinkKey().teLinkTpId());
687 TeLinkTpKey peerTeLinkKey = null;
688 if (srcLink.peerTeLinkKey() != null) {
689 TeNodeKey sourcePeerNode = new TeNodeKey(srcTopoKey,
690 srcLink.peerTeLinkKey().teNodeId());
691 peerTeLinkKey = new TeLinkTpKey(
692 sourceNewTeNodeIdMap.get(sourcePeerNode),
693 srcLink.peerTeLinkKey().teLinkTpId());
694 }
695
696 if (srcLink.externalLink() != null &&
697 srcLink.externalLink().plugId() != null) {
698 // externalLinkKey doesn't have topology Id.
699 // using plugId for now
700 LinkKeyPair pair = externalLinkMap.get(srcLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500701 if (pair == null) {
702 // Store it in the map
703 externalLinkMap.put(srcLink.externalLink().plugId(),
704 new LinkKeyPair(newKey));
705 } else {
706 if (newKey.equals(pair.firstKey())) {
707 peerTeLinkKey = pair.secondKey();
708 } else if (newKey.equals(pair.secondKey())) {
709 peerTeLinkKey = pair.firstKey();
710 } else if (pair.firstKey() == null) {
711 peerTeLinkKey = pair.secondKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500712 pair.setFirstKey(newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500713 } else if (pair.secondKey() == null) {
714 peerTeLinkKey = pair.firstKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500715 pair.setSecondKey(newKey);
716 }
717
Yixiao Chen29f06332016-12-07 16:14:29 -0500718 if (peerTeLinkKey != null) {
719 TeLink peerLink = teLinks.get(peerTeLinkKey);
720 if (peerLink != null && (peerLink.peerTeLinkKey() == null
721 || !peerLink.peerTeLinkKey().equals(newKey))) {
722 // Update peer Link with local link key
723 TeLink newPeerLink = updateTeLink(peerTeLinkKey, newKey,
724 peerLink.underlayTeTopologyId(),
725 peerLink.supportingTeLinkId(),
726 peerLink.sourceTeLinkId(),
727 peerLink.externalLink(),
728 peerLink);
729 teLinks.put(peerTeLinkKey, newPeerLink);
730 if (postEvent) {
731 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
732 peerTeLinkKey);
733 post(new TeTopologyEvent(TE_LINK_UPDATED,
734 new TeLinkEventSubject(globalKey,
735 newPeerLink)));
736 post(new TeTopologyEvent(LINK_UPDATED,
737 new NetworkLinkEventSubject(
738 networkLinkKey(globalKey),
739 linkBuilder(toNetworkLinkId(peerTeLinkKey),
740 newPeerLink))));
741 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500742 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500743 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500744 }
745 }
746
747 TeTopologyKey underlayTopologyId = null; // No underlay
748 TeLinkTpGlobalKey supportTeLinkId = null; // No support
749 // Source link for the new updated link
750 TeLinkTpGlobalKey sourceTeLinkId = new TeLinkTpGlobalKey(srcTopoKey, srcLink.teLinkKey());
751 TeLink updatedLink = updateTeLink(newKey, peerTeLinkKey, underlayTopologyId,
752 supportTeLinkId, sourceTeLinkId,
753 srcLink.externalLink(), srcLink);
754 TeLinkTpGlobalKey newGlobalKey = new TeLinkTpGlobalKey(mergedTopologyKey, newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500755 boolean newLink = teLinks.get(newKey) == null ? true : false;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500756 teLinks.put(newKey, updatedLink);
757 if (postEvent) {
758 //Post event
759 post(new TeTopologyEvent(newLink ? TE_LINK_ADDED : TE_LINK_UPDATED,
760 new TeLinkEventSubject(newGlobalKey, updatedLink)));
761 post(new TeTopologyEvent(newLink ? LINK_ADDED : LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500762 new NetworkLinkEventSubject(networkLinkKey(newGlobalKey),
763 linkBuilder(toNetworkLinkId(updatedLink.teLinkKey()),
764 updatedLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500765 }
766 }
767
768 // Merge TE links
769 private void mergeLinks(Map<TeLinkTpKey, TeLink> teLinks, TeTopology topology) {
770 if (!MapUtils.isEmpty(topology.teLinks())) {
771 for (Map.Entry<TeLinkTpKey, TeLink> entry : topology.teLinks().entrySet()) {
772 TeLink srcLink = entry.getValue();
773 updateSourceTeLink(teLinks, topology.teTopologyId(), srcLink,
774 mergedTopology != null);
775 }
776 }
777 }
778
779 // Update the merged topology with new TE nodes and links
780 private void updateMergedTopology(Map<Long, TeNode> teNodes, Map<TeLinkTpKey, TeLink> teLinks) {
781 boolean newTopology = mergedTopology == null;
782 BitSet flags = newTopology ? new BitSet(TeConstants.FLAG_MAX_BITS) : mergedTopology.flags();
Yixiao Chen29f06332016-12-07 16:14:29 -0500783 flags.set(BIT_MERGED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500784 CommonTopologyData commonData = new CommonTopologyData(newTopology ?
Yixiao Chen29f06332016-12-07 16:14:29 -0500785 toNetworkId(mergedTopologyKey) :
Yixiao Chen68bfab22016-11-11 11:04:10 -0500786 mergedTopology.networkId(),
Yixiao Chen29f06332016-12-07 16:14:29 -0500787 NOT_OPTIMIZED,
Yixiao Chen68bfab22016-11-11 11:04:10 -0500788 flags, DeviceId.deviceId("localHost"));
789 mergedTopology = new DefaultTeTopology(mergedTopologyKey, teNodes, teLinks,
790 Long.toString(mergedTopologyKey.topologyId()), commonData);
Yixiao Chen29f06332016-12-07 16:14:29 -0500791 mergedNetwork = networkBuilder(mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500792 log.info("Nodes# {}, Links# {}", mergedTopology.teNodes().size(), mergedTopology.teLinks().size());
793 }
794
795 // Merge the new learned topology
796 private void mergeTopology(TeTopology topology) {
797 boolean newTopology = mergedTopology == null;
798 mergedTopologyKey = newTopology ?
799 new TeTopologyKey(providerId, DEFAULT_CLIENT_ID,
800 store.nextTeTopologyId()) :
801 mergedTopology.teTopologyId();
802
803 Map<Long, TeNode> teNodes = newTopology || mergedTopology.teNodes() == null ?
804 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teNodes());
805 mergeNodes(teNodes, topology);
806 Map<TeLinkTpKey, TeLink> teLinks = newTopology || mergedTopology.teLinks() == null ?
807 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teLinks());
808 mergeLinks(teLinks, topology);
809 updateMergedTopology(teNodes, teLinks);
Yixiao Chen29f06332016-12-07 16:14:29 -0500810 log.debug("mergedTopology {}", mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500811
812 if (newTopology) {
813 // Post events for the merged network topology;
814 post(new TeTopologyEvent(TE_TOPOLOGY_ADDED, mergedTopology));
815 post(new TeTopologyEvent(NETWORK_ADDED, mergedNetwork));
816 }
817 }
818
819 private TeTopologyKey newTeTopologyKey(TeTopology teTopology) {
820 TeTopologyKey key = teTopology.teTopologyId();
821 if (key == null || teTopology.teTopologyIdStringValue() == null) {
822 log.error("Ignoring the non-TE topology");
823 throw new ApplicationException("Missing TE topology ID");
824 }
825 // Get the topologyId numeric value
826 long idValue = key.topologyId();
827 if (idValue == TeConstants.NIL_LONG_VALUE) {
828 if (teTopology.teTopologyIdStringValue() != null) {
829 try {
830 idValue = Long.parseLong(teTopology.teTopologyIdStringValue());
831 } catch (NumberFormatException e) {
832 // Can't get the long value from the string.
833 // Use an assigned id value from local id pool,
834 idValue = store.nextTeTopologyId();
835 }
836 return new TeTopologyKey(key.providerId(), key.clientId(), idValue);
837 }
838 }
839 return null;
840 }
841
842 private class InternalConfigListener implements NetworkConfigListener {
843
844 @Override
845 public void event(NetworkConfigEvent event) {
846 try {
847 providerId = cfgService.getConfig(appId, TeTopologyConfig.class)
848 .providerId();
Yixiao Chen29f06332016-12-07 16:14:29 -0500849 store.setProviderId(providerId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500850 teNodeIpStart = cfgService.getConfig(appId, TeTopologyConfig.class)
851 .teNodeIpStart();
852 teNodeIpEnd = cfgService.getConfig(appId, TeTopologyConfig.class)
853 .teNodeIpEnd();
Yixiao Chen29f06332016-12-07 16:14:29 -0500854 mdsc = cfgService.getConfig(appId, TeTopologyConfig.class)
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500855 .mdsc().equals(MDSC_MODE);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500856 nextTeNodeId = teNodeIpStart.toInt();
857 } catch (ConfigException e) {
858 log.error("Configuration error {}", e);
859 }
860 }
861
862 @Override
863 public boolean isRelevant(NetworkConfigEvent event) {
864 return event.configClass().equals(TeTopologyConfig.class) &&
865 (event.type() == CONFIG_ADDED ||
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500866 event.type() == CONFIG_UPDATED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500867 }
868 }
869
870 @Override
871 public TeTopologies teTopologies() {
872 Map<TeTopologyKey, TeTopology> map;
873 if (MapUtils.isNotEmpty(store.teTopologies().teTopologies())) {
874 map = Maps.newHashMap(store.teTopologies().teTopologies());
875 } else {
876 map = Maps.newHashMap();
877 }
878 if (mergedTopology != null) {
879 map.put(mergedTopologyKey, mergedTopology);
880 }
881 return new DefaultTeTopologies(store.teTopologies().name(), map);
882 }
883
884 @Override
885 public TeTopology teTopology(TeTopologyKey topologyId) {
886 if (mergedTopology != null &&
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500887 topologyId != null &&
Yixiao Chen68bfab22016-11-11 11:04:10 -0500888 topologyId.equals(mergedTopologyKey)) {
889 return mergedTopology;
890 }
891 return store.teTopology(topologyId);
892 }
893
894 @Override
895 public TeTopology mergedTopology() {
896 return mergedTopology;
897 }
898
899 @Override
900 public void updateTeTopology(TeTopology teTopology) {
901 TeTopologyKey newKey = null;
902 try {
903 newKey = newTeTopologyKey(teTopology);
904 } catch (ApplicationException e) {
905 log.error("Ignoring the non-TE topology");
906 return;
907 }
908
909 // TE topology is updated here from other APP or NBI, the flag
910 // BIT_CUSTOMIZED or BIT_MERGED should be set.
911 BitSet flags = teTopology.flags();
912 if (flags == null ||
Yixiao Chen29f06332016-12-07 16:14:29 -0500913 !(flags.get(BIT_CUSTOMIZED) || flags.get(BIT_MERGED))) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500914 log.error("TE topology flags {} are not set properly", flags);
915 return;
916 }
917
918 if (newKey != null) {
919 DefaultTeTopology newTopology = new DefaultTeTopology(
Ray Milkeyfe0e0852018-01-18 11:14:05 -0800920 newKey,
Yixiao Chen68bfab22016-11-11 11:04:10 -0500921 teTopology.teNodes(), teTopology.teLinks(),
922 teTopology.teTopologyIdStringValue(), new CommonTopologyData(teTopology));
923 // Update with new data
924 store.updateTeTopology(newTopology);
925 } else {
926 store.updateTeTopology(teTopology);
927 }
928 }
929
930 @Override
931 public void removeTeTopology(TeTopologyKey topologyId) {
932 store.removeTeTopology(topologyId);
933 }
934
935 @Override
936 public Networks networks() {
937 List<Network> networks;
938 if (CollectionUtils.isNotEmpty(store.networks())) {
939 networks = Lists.newArrayList(store.networks());
940 } else {
941 networks = Lists.newArrayList();
942 }
943 if (mergedNetwork != null) {
944 networks.add(mergedNetwork);
945 }
946 return new DefaultNetworks(networks);
947 }
948
949 @Override
950 public Network network(KeyId networkId) {
951 if (mergedNetwork != null &&
952 mergedNetwork.networkId().equals(networkId)) {
953 return mergedNetwork;
954 }
955 return store.network(networkId);
956 }
957
958 @Override
959 public void updateNetwork(Network network) {
960 // TODO: This will be implemented if required.
961 }
962
963 @Override
964 public void removeNetwork(KeyId networkId) {
965 // TODO: This will be implemented if required.
966 }
967
968 @Override
969 public TeNode teNode(TeNodeKey nodeId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500970 return nodeId.teTopologyKey().equals(mergedTopologyKey) ?
971 mergedTopology.teNode(nodeId.teNodeId()) :
972 store.teNode(nodeId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500973 }
974
975 @Override
976 public TeLink teLink(TeLinkTpGlobalKey linkId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500977 return linkId.teTopologyKey().equals(mergedTopologyKey) ?
978 mergedTopology.teLink(linkId.teLinkTpKey()) :
979 store.teLink(linkId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500980 }
981
982 @Override
983 public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500984 return ttpId.teTopologyKey().equals(mergedTopologyKey) ?
985 mergedTopology.teNode(ttpId.teNodeId()).tunnelTerminationPoint(ttpId.ttpId()) :
986 store.tunnelTerminationPoint(ttpId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500987 }
988
989 @Override
990 public KeyId networkId(TeTopologyKey teTopologyKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500991 return teTopologyKey.equals(mergedTopologyKey) ?
992 mergedNetwork.networkId() :
993 store.networkId(teTopologyKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500994 }
995
996 @Override
997 public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500998 return teNodeKey.teTopologyKey().equals(mergedTopologyKey) ?
999 networkNodeKey(teNodeKey) :
1000 store.nodeKey(teNodeKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001001 }
1002
1003 @Override
1004 public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001005 return teLinkKey.teTopologyKey().equals(mergedTopologyKey) ?
1006 networkLinkKey(teLinkKey) :
1007 store.linkKey(teLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001008 }
1009
1010 @Override
1011 public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001012 return teTpKey.teTopologyKey().equals(mergedTopologyKey) ?
1013 new TerminationPointKey(networkNodeKey(teTpKey.teNodeKey()),
1014 KeyId.keyId(Long.toString(teTpKey.teLinkTpId()))) :
1015 store.terminationPointKey(teTpKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001016 }
Yixiao Chen265b3bb2017-01-13 10:17:03 -05001017
1018 @Override
1019 public long teContollerId() {
1020 return providerId;
1021 }
Yixiao Chen68bfab22016-11-11 11:04:10 -05001022}