blob: 30ca4e254ff633651edd47c1ca67d9622aedef6a [file] [log] [blame]
Yixiao Chen68bfab22016-11-11 11:04:10 -05001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
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;
69import org.onosproject.incubator.net.config.basics.ConfigException;
70import 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,
394 new DefaultNetwork(event.networkKey(),
395 null, null, null, null, false, null)));
396 break;
397 case NODE_ADDED:
398 case NODE_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500399 if (store.network(event.networkNodeKey().networkId()) == null) {
400 // Event should be ignored when the network is not there.
401 break;
402 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500403 NetworkNode node = store.networkNode(event.networkNodeKey());
404 post(new TeTopologyEvent(event.type(),
405 new NetworkNodeEventSubject(event.networkNodeKey(), node)));
406 break;
407 case NODE_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500408 if (store.network(event.networkNodeKey().networkId()) == null) {
409 // Event should be ignored when the network is not there.
410 break;
411 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500412 post(new TeTopologyEvent(NODE_REMOVED,
413 new NetworkNodeEventSubject(event.networkNodeKey(), null)));
414 break;
415 case LINK_ADDED:
416 case LINK_UPDATED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500417 if (store.network(event.networkLinkKey().networkId()) == null) {
418 // Event should be ignored when the network is not there.
419 break;
420 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500421 NetworkLink link = store.networkLink(event.networkLinkKey());
422 post(new TeTopologyEvent(event.type(),
423 new NetworkLinkEventSubject(event.networkLinkKey(), link)));
424 break;
425 case LINK_REMOVED:
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500426 if (store.network(event.networkLinkKey().networkId()) == null) {
427 // Event should be ignored when the network is not there.
428 break;
429 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500430 post(new TeTopologyEvent(LINK_REMOVED,
431 new NetworkLinkEventSubject(event.networkLinkKey(), null)));
432 break;
433 default:
434 break;
435 }
436 }
437 } catch (InterruptedException e) {
438 log.warn("TopologyMergerTask is interrupted");
439 } catch (Exception e) {
440 log.warn("Unable to merge topology", e);
441 }
442 }
443 }
444
445 private void removeSourceTeNode(Map<Long, TeNode> teNodes,
446 TeNodeKey srcNodeKey, boolean postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500447 Long mergedTeNodeId = sourceNewTeNodeIdMap.remove(srcNodeKey);
448 if (mergedTeNodeId == null) {
449 return;
450 }
451 if (teNodes.remove(mergedTeNodeId) != null && postEvent) {
452 TeNodeKey nodeKey = new TeNodeKey(mergedTopologyKey,
453 mergedTeNodeId);
454 post(new TeTopologyEvent(TE_NODE_REMOVED,
455 new TeNodeEventSubject(nodeKey, null)));
456 post(new TeTopologyEvent(NODE_REMOVED,
457 new NetworkNodeEventSubject(TeMgrUtil
458 .networkNodeKey(nodeKey), null)));
459 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500460 }
461
462 private void updateSourceTeNode(Map<Long, TeNode> teNodes, TeTopologyKey srcTopoKey,
463 TeNode srcNode, boolean postEvent) {
464 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey, srcNode.teNodeId());
465 Long mergedTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeId);
466 boolean addNode = false;
467 if (mergedTeNodeId == null) {
468 // New node
469 addNode = true;
470 mergedTeNodeId = nextTeNodeId;
471 nextTeNodeId++;
472 if (nextTeNodeId >= teNodeIpEnd.toInt()) {
473 nextTeNodeId = teNodeIpStart.toInt();
474 log.warn("TE node Id is wrapped back");
475 }
476 sourceNewTeNodeIdMap.put(sourceTeNodeId, mergedTeNodeId);
477 }
478 TeTopologyKey underlayTopologyId = null; // No underlay
479 TeNodeKey supportTeNodeId = null; // No supporting
480
481 CommonNodeData common = new CommonNodeData(srcNode.name(), srcNode.adminStatus(),
482 srcNode.opStatus(), srcNode.flags()); // No change
483 Map<Long, ConnectivityMatrix> connMatrices = srcNode.connectivityMatrices();
484 List<Long> teLinkIds = srcNode.teLinkIds(); // No change
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500485 Map<Long, TunnelTerminationPoint> ttps = null;
486 if (MapUtils.isNotEmpty(srcNode.tunnelTerminationPoints())) {
487 ttps = Maps.newHashMap();
488 for (Map.Entry<Long, TunnelTerminationPoint> entry : srcNode.tunnelTerminationPoints().entrySet()) {
489 TunnelTerminationPoint ttp = entry.getValue();
490 ttps.put(entry.getKey(),
491 new DefaultTunnelTerminationPoint(ttp.ttpId(), ttp.switchingLayer(),
492 ttp.encodingLayer(), ttp.flags(),
493 ttp.interLayerLockList(),
494 ttp.localLinkConnectivityList(),
495 ttp.availAdaptBandwidth(),
496 null)); //Remove supporting TTP Ids
497 }
498 }
499
Yixiao Chen68bfab22016-11-11 11:04:10 -0500500 List<Long> teTpIds = srcNode.teTerminationPointIds(); // No change
501 DefaultTeNode newNode = new DefaultTeNode(mergedTeNodeId, underlayTopologyId,
502 supportTeNodeId, sourceTeNodeId, common, connMatrices, teLinkIds,
503 ttps, teTpIds);
504 teNodes.put(mergedTeNodeId, newNode);
505 if (postEvent) {
506 //Post event for the TE node in the merged topology
507 TeNodeKey globalKey = new TeNodeKey(mergedTopologyKey, mergedTeNodeId);
508 post(new TeTopologyEvent(addNode ? TE_NODE_ADDED : TE_NODE_UPDATED,
509 new TeNodeEventSubject(globalKey, newNode)));
510 post(new TeTopologyEvent(addNode ? NODE_ADDED : NODE_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500511 new NetworkNodeEventSubject(networkNodeKey(globalKey),
512 nodeBuilder(KeyId.keyId(
513 Ip4Address.valueOf((int) newNode.teNodeId()).toString()),
514 newNode))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500515 }
516 }
517
518 // Merge TE nodes
519 private void mergeNodes(Map<Long, TeNode> nodes, TeTopology topology) {
520
521 if (!MapUtils.isEmpty(topology.teNodes())) {
522 for (Map.Entry<Long, TeNode> entry : topology.teNodes().entrySet()) {
523 updateSourceTeNode(nodes, topology.teTopologyId(), entry.getValue(),
524 mergedTopology != null);
525 }
526 }
527 }
528
529 // Returns a new TeLink based on an existing TeLink with new attributes
530 private TeLink updateTeLink(TeLinkTpKey newKey, TeLinkTpKey peerTeLinkKey,
531 TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
532 TeLinkTpGlobalKey sourceTeLinkId, ExternalLink externalLink,
533 TeLink exLink) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500534 UnderlayPath underlayPath = null;
535 if (underlayTopologyId != null &&
536 underlayTopologyId.equals(exLink.underlayTeTopologyId())) {
537 underlayPath = new UnderlayPath(exLink.primaryPath(),
538 exLink.backupPaths(), exLink.tunnelProtectionType(),
539 exLink.sourceTtpId(), exLink.destinationTtpId(),
540 exLink.teTunnelId()
541 );
542 }
543
Yixiao Chen68bfab22016-11-11 11:04:10 -0500544 TePathAttributes teAttributes = new TePathAttributes(exLink.cost(),
545 exLink.delay(), exLink.srlgs());
546 LinkBandwidth bandwidth = new LinkBandwidth(exLink.maxBandwidth(),
547 exLink.availBandwidth(),
548 exLink.maxAvailLspBandwidth(),
549 exLink.minAvailLspBandwidth(),
550 exLink.oduResource());
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500551 BitSet flags = exLink.flags();
552 if (peerTeLinkKey != null &&
553 externalLink != null && externalLink.plugId() != null) {
554 // Assuming this is an inter-domain link which is merged with its peer,
555 // needs to clear BIT_ACCESS_INTERDOMAIN
556 flags.clear(BIT_ACCESS_INTERDOMAIN);
557 } else if (peerTeLinkKey == null &&
558 externalLink != null && externalLink.plugId() != null) {
559 // Assuming this is an inter-domain link which lost its peer,
560 // needs to clear BIT_ACCESS_INTERDOMAIN
561 flags.set(BIT_ACCESS_INTERDOMAIN);
562 }
563
Yixiao Chen68bfab22016-11-11 11:04:10 -0500564 CommonLinkData common = new CommonLinkData(exLink.adminStatus(), exLink.opStatus(),
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500565 flags, exLink.switchingLayer(), exLink.encodingLayer(),
Yixiao Chen68bfab22016-11-11 11:04:10 -0500566 externalLink, underlayPath, teAttributes,
567 exLink.administrativeGroup(), exLink.interLayerLocks(),
568 bandwidth);
569 return new DefaultTeLink(newKey, peerTeLinkKey, underlayTopologyId,
570 supportTeLinkId, sourceTeLinkId, common);
571 }
572
573 private class LinkKeyPair {
574 private TeLinkTpKey firstKey;
575 private TeLinkTpKey secondKey;
576
577 public LinkKeyPair(TeLinkTpKey firstKey) {
578 this.firstKey = firstKey;
579 }
580
581 public TeLinkTpKey firstKey() {
582 return firstKey;
583 }
584
585 public void setFirstKey(TeLinkTpKey firstKey) {
586 this.firstKey = firstKey;
587 }
588
589 public TeLinkTpKey secondKey() {
590 return secondKey;
591 }
592
593 public void setSecondKey(TeLinkTpKey secondKey) {
594 this.secondKey = secondKey;
595 }
596
Yixiao Chen29f06332016-12-07 16:14:29 -0500597 public boolean isFirstKey(TeLinkTpKey linkKey) {
598 return firstKey == null ? false : firstKey.equals(linkKey);
599 }
600
601 public boolean isSecondKey(TeLinkTpKey linkKey) {
602 return secondKey == null ? false : secondKey.equals(linkKey);
603 }
604
605 public boolean isEmpty() {
606 return firstKey == null && secondKey == null;
607 }
608
Yixiao Chen68bfab22016-11-11 11:04:10 -0500609 @Override
610 public String toString() {
611 return MoreObjects.toStringHelper(this)
612 .add("firstKey", firstKey)
613 .add("secondKey", secondKey)
614 .toString();
615 }
616 }
617
618 private void removeSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeLinkTpGlobalKey teLinkKey,
619 boolean postEvent) {
620 TeNodeKey sourceTeNodeKey = teLinkKey.teNodeKey();
621 Long newTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeKey);
622 if (newTeNodeId == null) {
623 return;
624 }
625 TeLinkTpKey newLinkKey = new TeLinkTpKey(newTeNodeId, teLinkKey.teLinkTpId());
626 TeLink teLink = teLinks.remove(newLinkKey);
627 if (teLink == null) {
628 return;
629 }
630 //Post event
631 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500632 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
633 newLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500634 post(new TeTopologyEvent(TE_LINK_REMOVED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500635 new TeLinkEventSubject(globalKey, null)));
636 post(new TeTopologyEvent(LINK_REMOVED,
637 new NetworkLinkEventSubject(networkLinkKey(globalKey),
638 null)));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500639 }
640
641 if (teLink.externalLink() != null && teLink.externalLink().plugId() != null) {
642 // Update the LinkKeyPair in externalLinkMap
643 LinkKeyPair pair = externalLinkMap.get(teLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500644 if (pair.isFirstKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500645 pair.setFirstKey(null);
Yixiao Chen29f06332016-12-07 16:14:29 -0500646 } else if (pair.isSecondKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500647 pair.setSecondKey(null);
648 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500649 if (pair.isEmpty()) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500650 externalLinkMap.remove(teLink.externalLink().plugId());
651 }
652 }
653 TeLinkTpKey peerTeLinkKey = teLink.peerTeLinkKey();
654 if (peerTeLinkKey != null) {
655 // Update peerLink's peerTeLinkKey to null
656 TeLink peerLink = teLinks.get(peerTeLinkKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500657 if (peerLink == null || peerLink.peerTeLinkKey() == null) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500658 return;
659 }
660 TeLink newPeerLink = updateTeLink(peerTeLinkKey, null,
661 peerLink.underlayTeTopologyId(), peerLink.supportingTeLinkId(),
662 peerLink.sourceTeLinkId(), peerLink.externalLink(), peerLink);
663 teLinks.put(peerTeLinkKey, newPeerLink);
664 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500665 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
666 peerTeLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500667 post(new TeTopologyEvent(TE_LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500668 new TeLinkEventSubject(globalKey,
669 newPeerLink)));
670 post(new TeTopologyEvent(LINK_UPDATED,
671 new NetworkLinkEventSubject(networkLinkKey(globalKey),
672 linkBuilder(toNetworkLinkId(peerTeLinkKey),
673 newPeerLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500674 }
675 }
676 }
677
678 private void updateSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeTopologyKey srcTopoKey,
679 TeLink srcLink, boolean postEvent) {
680 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey,
681 srcLink.teLinkKey().teNodeId());
682 TeLinkTpKey newKey = new TeLinkTpKey(
683 sourceNewTeNodeIdMap.get(sourceTeNodeId),
684 srcLink.teLinkKey().teLinkTpId());
685 TeLinkTpKey peerTeLinkKey = null;
686 if (srcLink.peerTeLinkKey() != null) {
687 TeNodeKey sourcePeerNode = new TeNodeKey(srcTopoKey,
688 srcLink.peerTeLinkKey().teNodeId());
689 peerTeLinkKey = new TeLinkTpKey(
690 sourceNewTeNodeIdMap.get(sourcePeerNode),
691 srcLink.peerTeLinkKey().teLinkTpId());
692 }
693
694 if (srcLink.externalLink() != null &&
695 srcLink.externalLink().plugId() != null) {
696 // externalLinkKey doesn't have topology Id.
697 // using plugId for now
698 LinkKeyPair pair = externalLinkMap.get(srcLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500699 if (pair == null) {
700 // Store it in the map
701 externalLinkMap.put(srcLink.externalLink().plugId(),
702 new LinkKeyPair(newKey));
703 } else {
704 if (newKey.equals(pair.firstKey())) {
705 peerTeLinkKey = pair.secondKey();
706 } else if (newKey.equals(pair.secondKey())) {
707 peerTeLinkKey = pair.firstKey();
708 } else if (pair.firstKey() == null) {
709 peerTeLinkKey = pair.secondKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500710 pair.setFirstKey(newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500711 } else if (pair.secondKey() == null) {
712 peerTeLinkKey = pair.firstKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500713 pair.setSecondKey(newKey);
714 }
715
Yixiao Chen29f06332016-12-07 16:14:29 -0500716 if (peerTeLinkKey != null) {
717 TeLink peerLink = teLinks.get(peerTeLinkKey);
718 if (peerLink != null && (peerLink.peerTeLinkKey() == null
719 || !peerLink.peerTeLinkKey().equals(newKey))) {
720 // Update peer Link with local link key
721 TeLink newPeerLink = updateTeLink(peerTeLinkKey, newKey,
722 peerLink.underlayTeTopologyId(),
723 peerLink.supportingTeLinkId(),
724 peerLink.sourceTeLinkId(),
725 peerLink.externalLink(),
726 peerLink);
727 teLinks.put(peerTeLinkKey, newPeerLink);
728 if (postEvent) {
729 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
730 peerTeLinkKey);
731 post(new TeTopologyEvent(TE_LINK_UPDATED,
732 new TeLinkEventSubject(globalKey,
733 newPeerLink)));
734 post(new TeTopologyEvent(LINK_UPDATED,
735 new NetworkLinkEventSubject(
736 networkLinkKey(globalKey),
737 linkBuilder(toNetworkLinkId(peerTeLinkKey),
738 newPeerLink))));
739 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500740 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500741 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500742 }
743 }
744
745 TeTopologyKey underlayTopologyId = null; // No underlay
746 TeLinkTpGlobalKey supportTeLinkId = null; // No support
747 // Source link for the new updated link
748 TeLinkTpGlobalKey sourceTeLinkId = new TeLinkTpGlobalKey(srcTopoKey, srcLink.teLinkKey());
749 TeLink updatedLink = updateTeLink(newKey, peerTeLinkKey, underlayTopologyId,
750 supportTeLinkId, sourceTeLinkId,
751 srcLink.externalLink(), srcLink);
752 TeLinkTpGlobalKey newGlobalKey = new TeLinkTpGlobalKey(mergedTopologyKey, newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500753 boolean newLink = teLinks.get(newKey) == null ? true : false;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500754 teLinks.put(newKey, updatedLink);
755 if (postEvent) {
756 //Post event
757 post(new TeTopologyEvent(newLink ? TE_LINK_ADDED : TE_LINK_UPDATED,
758 new TeLinkEventSubject(newGlobalKey, updatedLink)));
759 post(new TeTopologyEvent(newLink ? LINK_ADDED : LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500760 new NetworkLinkEventSubject(networkLinkKey(newGlobalKey),
761 linkBuilder(toNetworkLinkId(updatedLink.teLinkKey()),
762 updatedLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500763 }
764 }
765
766 // Merge TE links
767 private void mergeLinks(Map<TeLinkTpKey, TeLink> teLinks, TeTopology topology) {
768 if (!MapUtils.isEmpty(topology.teLinks())) {
769 for (Map.Entry<TeLinkTpKey, TeLink> entry : topology.teLinks().entrySet()) {
770 TeLink srcLink = entry.getValue();
771 updateSourceTeLink(teLinks, topology.teTopologyId(), srcLink,
772 mergedTopology != null);
773 }
774 }
775 }
776
777 // Update the merged topology with new TE nodes and links
778 private void updateMergedTopology(Map<Long, TeNode> teNodes, Map<TeLinkTpKey, TeLink> teLinks) {
779 boolean newTopology = mergedTopology == null;
780 BitSet flags = newTopology ? new BitSet(TeConstants.FLAG_MAX_BITS) : mergedTopology.flags();
Yixiao Chen29f06332016-12-07 16:14:29 -0500781 flags.set(BIT_MERGED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500782 CommonTopologyData commonData = new CommonTopologyData(newTopology ?
Yixiao Chen29f06332016-12-07 16:14:29 -0500783 toNetworkId(mergedTopologyKey) :
Yixiao Chen68bfab22016-11-11 11:04:10 -0500784 mergedTopology.networkId(),
Yixiao Chen29f06332016-12-07 16:14:29 -0500785 NOT_OPTIMIZED,
Yixiao Chen68bfab22016-11-11 11:04:10 -0500786 flags, DeviceId.deviceId("localHost"));
787 mergedTopology = new DefaultTeTopology(mergedTopologyKey, teNodes, teLinks,
788 Long.toString(mergedTopologyKey.topologyId()), commonData);
Yixiao Chen29f06332016-12-07 16:14:29 -0500789 mergedNetwork = networkBuilder(mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500790 log.info("Nodes# {}, Links# {}", mergedTopology.teNodes().size(), mergedTopology.teLinks().size());
791 }
792
793 // Merge the new learned topology
794 private void mergeTopology(TeTopology topology) {
795 boolean newTopology = mergedTopology == null;
796 mergedTopologyKey = newTopology ?
797 new TeTopologyKey(providerId, DEFAULT_CLIENT_ID,
798 store.nextTeTopologyId()) :
799 mergedTopology.teTopologyId();
800
801 Map<Long, TeNode> teNodes = newTopology || mergedTopology.teNodes() == null ?
802 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teNodes());
803 mergeNodes(teNodes, topology);
804 Map<TeLinkTpKey, TeLink> teLinks = newTopology || mergedTopology.teLinks() == null ?
805 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teLinks());
806 mergeLinks(teLinks, topology);
807 updateMergedTopology(teNodes, teLinks);
Yixiao Chen29f06332016-12-07 16:14:29 -0500808 log.debug("mergedTopology {}", mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500809
810 if (newTopology) {
811 // Post events for the merged network topology;
812 post(new TeTopologyEvent(TE_TOPOLOGY_ADDED, mergedTopology));
813 post(new TeTopologyEvent(NETWORK_ADDED, mergedNetwork));
814 }
815 }
816
817 private TeTopologyKey newTeTopologyKey(TeTopology teTopology) {
818 TeTopologyKey key = teTopology.teTopologyId();
819 if (key == null || teTopology.teTopologyIdStringValue() == null) {
820 log.error("Ignoring the non-TE topology");
821 throw new ApplicationException("Missing TE topology ID");
822 }
823 // Get the topologyId numeric value
824 long idValue = key.topologyId();
825 if (idValue == TeConstants.NIL_LONG_VALUE) {
826 if (teTopology.teTopologyIdStringValue() != null) {
827 try {
828 idValue = Long.parseLong(teTopology.teTopologyIdStringValue());
829 } catch (NumberFormatException e) {
830 // Can't get the long value from the string.
831 // Use an assigned id value from local id pool,
832 idValue = store.nextTeTopologyId();
833 }
834 return new TeTopologyKey(key.providerId(), key.clientId(), idValue);
835 }
836 }
837 return null;
838 }
839
840 private class InternalConfigListener implements NetworkConfigListener {
841
842 @Override
843 public void event(NetworkConfigEvent event) {
844 try {
845 providerId = cfgService.getConfig(appId, TeTopologyConfig.class)
846 .providerId();
Yixiao Chen29f06332016-12-07 16:14:29 -0500847 store.setProviderId(providerId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500848 teNodeIpStart = cfgService.getConfig(appId, TeTopologyConfig.class)
849 .teNodeIpStart();
850 teNodeIpEnd = cfgService.getConfig(appId, TeTopologyConfig.class)
851 .teNodeIpEnd();
Yixiao Chen29f06332016-12-07 16:14:29 -0500852 mdsc = cfgService.getConfig(appId, TeTopologyConfig.class)
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500853 .mdsc().equals(MDSC_MODE);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500854 nextTeNodeId = teNodeIpStart.toInt();
855 } catch (ConfigException e) {
856 log.error("Configuration error {}", e);
857 }
858 }
859
860 @Override
861 public boolean isRelevant(NetworkConfigEvent event) {
862 return event.configClass().equals(TeTopologyConfig.class) &&
863 (event.type() == CONFIG_ADDED ||
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500864 event.type() == CONFIG_UPDATED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500865 }
866 }
867
868 @Override
869 public TeTopologies teTopologies() {
870 Map<TeTopologyKey, TeTopology> map;
871 if (MapUtils.isNotEmpty(store.teTopologies().teTopologies())) {
872 map = Maps.newHashMap(store.teTopologies().teTopologies());
873 } else {
874 map = Maps.newHashMap();
875 }
876 if (mergedTopology != null) {
877 map.put(mergedTopologyKey, mergedTopology);
878 }
879 return new DefaultTeTopologies(store.teTopologies().name(), map);
880 }
881
882 @Override
883 public TeTopology teTopology(TeTopologyKey topologyId) {
884 if (mergedTopology != null &&
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500885 topologyId != null &&
Yixiao Chen68bfab22016-11-11 11:04:10 -0500886 topologyId.equals(mergedTopologyKey)) {
887 return mergedTopology;
888 }
889 return store.teTopology(topologyId);
890 }
891
892 @Override
893 public TeTopology mergedTopology() {
894 return mergedTopology;
895 }
896
897 @Override
898 public void updateTeTopology(TeTopology teTopology) {
899 TeTopologyKey newKey = null;
900 try {
901 newKey = newTeTopologyKey(teTopology);
902 } catch (ApplicationException e) {
903 log.error("Ignoring the non-TE topology");
904 return;
905 }
906
907 // TE topology is updated here from other APP or NBI, the flag
908 // BIT_CUSTOMIZED or BIT_MERGED should be set.
909 BitSet flags = teTopology.flags();
910 if (flags == null ||
Yixiao Chen29f06332016-12-07 16:14:29 -0500911 !(flags.get(BIT_CUSTOMIZED) || flags.get(BIT_MERGED))) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500912 log.error("TE topology flags {} are not set properly", flags);
913 return;
914 }
915
916 if (newKey != null) {
917 DefaultTeTopology newTopology = new DefaultTeTopology(
918 newKey == null ? teTopology.teTopologyId() : newKey,
919 teTopology.teNodes(), teTopology.teLinks(),
920 teTopology.teTopologyIdStringValue(), new CommonTopologyData(teTopology));
921 // Update with new data
922 store.updateTeTopology(newTopology);
923 } else {
924 store.updateTeTopology(teTopology);
925 }
926 }
927
928 @Override
929 public void removeTeTopology(TeTopologyKey topologyId) {
930 store.removeTeTopology(topologyId);
931 }
932
933 @Override
934 public Networks networks() {
935 List<Network> networks;
936 if (CollectionUtils.isNotEmpty(store.networks())) {
937 networks = Lists.newArrayList(store.networks());
938 } else {
939 networks = Lists.newArrayList();
940 }
941 if (mergedNetwork != null) {
942 networks.add(mergedNetwork);
943 }
944 return new DefaultNetworks(networks);
945 }
946
947 @Override
948 public Network network(KeyId networkId) {
949 if (mergedNetwork != null &&
950 mergedNetwork.networkId().equals(networkId)) {
951 return mergedNetwork;
952 }
953 return store.network(networkId);
954 }
955
956 @Override
957 public void updateNetwork(Network network) {
958 // TODO: This will be implemented if required.
959 }
960
961 @Override
962 public void removeNetwork(KeyId networkId) {
963 // TODO: This will be implemented if required.
964 }
965
966 @Override
967 public TeNode teNode(TeNodeKey nodeId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500968 return nodeId.teTopologyKey().equals(mergedTopologyKey) ?
969 mergedTopology.teNode(nodeId.teNodeId()) :
970 store.teNode(nodeId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500971 }
972
973 @Override
974 public TeLink teLink(TeLinkTpGlobalKey linkId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500975 return linkId.teTopologyKey().equals(mergedTopologyKey) ?
976 mergedTopology.teLink(linkId.teLinkTpKey()) :
977 store.teLink(linkId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500978 }
979
980 @Override
981 public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500982 return ttpId.teTopologyKey().equals(mergedTopologyKey) ?
983 mergedTopology.teNode(ttpId.teNodeId()).tunnelTerminationPoint(ttpId.ttpId()) :
984 store.tunnelTerminationPoint(ttpId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500985 }
986
987 @Override
988 public KeyId networkId(TeTopologyKey teTopologyKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500989 return teTopologyKey.equals(mergedTopologyKey) ?
990 mergedNetwork.networkId() :
991 store.networkId(teTopologyKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500992 }
993
994 @Override
995 public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500996 return teNodeKey.teTopologyKey().equals(mergedTopologyKey) ?
997 networkNodeKey(teNodeKey) :
998 store.nodeKey(teNodeKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500999 }
1000
1001 @Override
1002 public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001003 return teLinkKey.teTopologyKey().equals(mergedTopologyKey) ?
1004 networkLinkKey(teLinkKey) :
1005 store.linkKey(teLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001006 }
1007
1008 @Override
1009 public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001010 return teTpKey.teTopologyKey().equals(mergedTopologyKey) ?
1011 new TerminationPointKey(networkNodeKey(teTpKey.teNodeKey()),
1012 KeyId.keyId(Long.toString(teTpKey.teLinkTpId()))) :
1013 store.terminationPointKey(teTpKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001014 }
Yixiao Chen265b3bb2017-01-13 10:17:03 -05001015
1016 @Override
1017 public long teContollerId() {
1018 return providerId;
1019 }
Yixiao Chen68bfab22016-11-11 11:04:10 -05001020}