blob: 52667cc966c5475cb6e9c4e318cab668aa59469b [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;
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,
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");
440 } catch (Exception e) {
441 log.warn("Unable to merge topology", e);
442 }
443 }
444 }
445
446 private void removeSourceTeNode(Map<Long, TeNode> teNodes,
447 TeNodeKey srcNodeKey, boolean postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500448 Long mergedTeNodeId = sourceNewTeNodeIdMap.remove(srcNodeKey);
449 if (mergedTeNodeId == null) {
450 return;
451 }
452 if (teNodes.remove(mergedTeNodeId) != null && postEvent) {
453 TeNodeKey nodeKey = new TeNodeKey(mergedTopologyKey,
454 mergedTeNodeId);
455 post(new TeTopologyEvent(TE_NODE_REMOVED,
456 new TeNodeEventSubject(nodeKey, null)));
457 post(new TeTopologyEvent(NODE_REMOVED,
458 new NetworkNodeEventSubject(TeMgrUtil
459 .networkNodeKey(nodeKey), null)));
460 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500461 }
462
463 private void updateSourceTeNode(Map<Long, TeNode> teNodes, TeTopologyKey srcTopoKey,
464 TeNode srcNode, boolean postEvent) {
465 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey, srcNode.teNodeId());
466 Long mergedTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeId);
467 boolean addNode = false;
468 if (mergedTeNodeId == null) {
469 // New node
470 addNode = true;
471 mergedTeNodeId = nextTeNodeId;
472 nextTeNodeId++;
473 if (nextTeNodeId >= teNodeIpEnd.toInt()) {
474 nextTeNodeId = teNodeIpStart.toInt();
475 log.warn("TE node Id is wrapped back");
476 }
477 sourceNewTeNodeIdMap.put(sourceTeNodeId, mergedTeNodeId);
478 }
479 TeTopologyKey underlayTopologyId = null; // No underlay
480 TeNodeKey supportTeNodeId = null; // No supporting
481
482 CommonNodeData common = new CommonNodeData(srcNode.name(), srcNode.adminStatus(),
483 srcNode.opStatus(), srcNode.flags()); // No change
484 Map<Long, ConnectivityMatrix> connMatrices = srcNode.connectivityMatrices();
485 List<Long> teLinkIds = srcNode.teLinkIds(); // No change
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500486 Map<Long, TunnelTerminationPoint> ttps = null;
487 if (MapUtils.isNotEmpty(srcNode.tunnelTerminationPoints())) {
488 ttps = Maps.newHashMap();
489 for (Map.Entry<Long, TunnelTerminationPoint> entry : srcNode.tunnelTerminationPoints().entrySet()) {
490 TunnelTerminationPoint ttp = entry.getValue();
491 ttps.put(entry.getKey(),
492 new DefaultTunnelTerminationPoint(ttp.ttpId(), ttp.switchingLayer(),
493 ttp.encodingLayer(), ttp.flags(),
494 ttp.interLayerLockList(),
495 ttp.localLinkConnectivityList(),
496 ttp.availAdaptBandwidth(),
497 null)); //Remove supporting TTP Ids
498 }
499 }
500
Yixiao Chen68bfab22016-11-11 11:04:10 -0500501 List<Long> teTpIds = srcNode.teTerminationPointIds(); // No change
502 DefaultTeNode newNode = new DefaultTeNode(mergedTeNodeId, underlayTopologyId,
503 supportTeNodeId, sourceTeNodeId, common, connMatrices, teLinkIds,
504 ttps, teTpIds);
505 teNodes.put(mergedTeNodeId, newNode);
506 if (postEvent) {
507 //Post event for the TE node in the merged topology
508 TeNodeKey globalKey = new TeNodeKey(mergedTopologyKey, mergedTeNodeId);
509 post(new TeTopologyEvent(addNode ? TE_NODE_ADDED : TE_NODE_UPDATED,
510 new TeNodeEventSubject(globalKey, newNode)));
511 post(new TeTopologyEvent(addNode ? NODE_ADDED : NODE_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500512 new NetworkNodeEventSubject(networkNodeKey(globalKey),
513 nodeBuilder(KeyId.keyId(
514 Ip4Address.valueOf((int) newNode.teNodeId()).toString()),
515 newNode))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500516 }
517 }
518
519 // Merge TE nodes
520 private void mergeNodes(Map<Long, TeNode> nodes, TeTopology topology) {
521
522 if (!MapUtils.isEmpty(topology.teNodes())) {
523 for (Map.Entry<Long, TeNode> entry : topology.teNodes().entrySet()) {
524 updateSourceTeNode(nodes, topology.teTopologyId(), entry.getValue(),
525 mergedTopology != null);
526 }
527 }
528 }
529
530 // Returns a new TeLink based on an existing TeLink with new attributes
531 private TeLink updateTeLink(TeLinkTpKey newKey, TeLinkTpKey peerTeLinkKey,
532 TeTopologyKey underlayTopologyId, TeLinkTpGlobalKey supportTeLinkId,
533 TeLinkTpGlobalKey sourceTeLinkId, ExternalLink externalLink,
534 TeLink exLink) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500535 UnderlayPath underlayPath = null;
536 if (underlayTopologyId != null &&
537 underlayTopologyId.equals(exLink.underlayTeTopologyId())) {
538 underlayPath = new UnderlayPath(exLink.primaryPath(),
539 exLink.backupPaths(), exLink.tunnelProtectionType(),
540 exLink.sourceTtpId(), exLink.destinationTtpId(),
541 exLink.teTunnelId()
542 );
543 }
544
Yixiao Chen68bfab22016-11-11 11:04:10 -0500545 TePathAttributes teAttributes = new TePathAttributes(exLink.cost(),
546 exLink.delay(), exLink.srlgs());
547 LinkBandwidth bandwidth = new LinkBandwidth(exLink.maxBandwidth(),
548 exLink.availBandwidth(),
549 exLink.maxAvailLspBandwidth(),
550 exLink.minAvailLspBandwidth(),
551 exLink.oduResource());
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500552 BitSet flags = exLink.flags();
553 if (peerTeLinkKey != null &&
554 externalLink != null && externalLink.plugId() != null) {
555 // Assuming this is an inter-domain link which is merged with its peer,
556 // needs to clear BIT_ACCESS_INTERDOMAIN
557 flags.clear(BIT_ACCESS_INTERDOMAIN);
558 } else if (peerTeLinkKey == null &&
559 externalLink != null && externalLink.plugId() != null) {
560 // Assuming this is an inter-domain link which lost its peer,
561 // needs to clear BIT_ACCESS_INTERDOMAIN
562 flags.set(BIT_ACCESS_INTERDOMAIN);
563 }
564
Yixiao Chen68bfab22016-11-11 11:04:10 -0500565 CommonLinkData common = new CommonLinkData(exLink.adminStatus(), exLink.opStatus(),
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500566 flags, exLink.switchingLayer(), exLink.encodingLayer(),
Yixiao Chen68bfab22016-11-11 11:04:10 -0500567 externalLink, underlayPath, teAttributes,
568 exLink.administrativeGroup(), exLink.interLayerLocks(),
569 bandwidth);
570 return new DefaultTeLink(newKey, peerTeLinkKey, underlayTopologyId,
571 supportTeLinkId, sourceTeLinkId, common);
572 }
573
574 private class LinkKeyPair {
575 private TeLinkTpKey firstKey;
576 private TeLinkTpKey secondKey;
577
578 public LinkKeyPair(TeLinkTpKey firstKey) {
579 this.firstKey = firstKey;
580 }
581
582 public TeLinkTpKey firstKey() {
583 return firstKey;
584 }
585
586 public void setFirstKey(TeLinkTpKey firstKey) {
587 this.firstKey = firstKey;
588 }
589
590 public TeLinkTpKey secondKey() {
591 return secondKey;
592 }
593
594 public void setSecondKey(TeLinkTpKey secondKey) {
595 this.secondKey = secondKey;
596 }
597
Yixiao Chen29f06332016-12-07 16:14:29 -0500598 public boolean isFirstKey(TeLinkTpKey linkKey) {
599 return firstKey == null ? false : firstKey.equals(linkKey);
600 }
601
602 public boolean isSecondKey(TeLinkTpKey linkKey) {
603 return secondKey == null ? false : secondKey.equals(linkKey);
604 }
605
606 public boolean isEmpty() {
607 return firstKey == null && secondKey == null;
608 }
609
Yixiao Chen68bfab22016-11-11 11:04:10 -0500610 @Override
611 public String toString() {
612 return MoreObjects.toStringHelper(this)
613 .add("firstKey", firstKey)
614 .add("secondKey", secondKey)
615 .toString();
616 }
617 }
618
619 private void removeSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeLinkTpGlobalKey teLinkKey,
620 boolean postEvent) {
621 TeNodeKey sourceTeNodeKey = teLinkKey.teNodeKey();
622 Long newTeNodeId = sourceNewTeNodeIdMap.get(sourceTeNodeKey);
623 if (newTeNodeId == null) {
624 return;
625 }
626 TeLinkTpKey newLinkKey = new TeLinkTpKey(newTeNodeId, teLinkKey.teLinkTpId());
627 TeLink teLink = teLinks.remove(newLinkKey);
628 if (teLink == null) {
629 return;
630 }
631 //Post event
632 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500633 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
634 newLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500635 post(new TeTopologyEvent(TE_LINK_REMOVED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500636 new TeLinkEventSubject(globalKey, null)));
637 post(new TeTopologyEvent(LINK_REMOVED,
638 new NetworkLinkEventSubject(networkLinkKey(globalKey),
639 null)));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500640 }
641
642 if (teLink.externalLink() != null && teLink.externalLink().plugId() != null) {
643 // Update the LinkKeyPair in externalLinkMap
644 LinkKeyPair pair = externalLinkMap.get(teLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500645 if (pair.isFirstKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500646 pair.setFirstKey(null);
Yixiao Chen29f06332016-12-07 16:14:29 -0500647 } else if (pair.isSecondKey(newLinkKey)) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500648 pair.setSecondKey(null);
649 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500650 if (pair.isEmpty()) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500651 externalLinkMap.remove(teLink.externalLink().plugId());
652 }
653 }
654 TeLinkTpKey peerTeLinkKey = teLink.peerTeLinkKey();
655 if (peerTeLinkKey != null) {
656 // Update peerLink's peerTeLinkKey to null
657 TeLink peerLink = teLinks.get(peerTeLinkKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500658 if (peerLink == null || peerLink.peerTeLinkKey() == null) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500659 return;
660 }
661 TeLink newPeerLink = updateTeLink(peerTeLinkKey, null,
662 peerLink.underlayTeTopologyId(), peerLink.supportingTeLinkId(),
663 peerLink.sourceTeLinkId(), peerLink.externalLink(), peerLink);
664 teLinks.put(peerTeLinkKey, newPeerLink);
665 if (postEvent) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500666 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
667 peerTeLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500668 post(new TeTopologyEvent(TE_LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500669 new TeLinkEventSubject(globalKey,
670 newPeerLink)));
671 post(new TeTopologyEvent(LINK_UPDATED,
672 new NetworkLinkEventSubject(networkLinkKey(globalKey),
673 linkBuilder(toNetworkLinkId(peerTeLinkKey),
674 newPeerLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500675 }
676 }
677 }
678
679 private void updateSourceTeLink(Map<TeLinkTpKey, TeLink> teLinks, TeTopologyKey srcTopoKey,
680 TeLink srcLink, boolean postEvent) {
681 TeNodeKey sourceTeNodeId = new TeNodeKey(srcTopoKey,
682 srcLink.teLinkKey().teNodeId());
683 TeLinkTpKey newKey = new TeLinkTpKey(
684 sourceNewTeNodeIdMap.get(sourceTeNodeId),
685 srcLink.teLinkKey().teLinkTpId());
686 TeLinkTpKey peerTeLinkKey = null;
687 if (srcLink.peerTeLinkKey() != null) {
688 TeNodeKey sourcePeerNode = new TeNodeKey(srcTopoKey,
689 srcLink.peerTeLinkKey().teNodeId());
690 peerTeLinkKey = new TeLinkTpKey(
691 sourceNewTeNodeIdMap.get(sourcePeerNode),
692 srcLink.peerTeLinkKey().teLinkTpId());
693 }
694
695 if (srcLink.externalLink() != null &&
696 srcLink.externalLink().plugId() != null) {
697 // externalLinkKey doesn't have topology Id.
698 // using plugId for now
699 LinkKeyPair pair = externalLinkMap.get(srcLink.externalLink().plugId());
Yixiao Chen29f06332016-12-07 16:14:29 -0500700 if (pair == null) {
701 // Store it in the map
702 externalLinkMap.put(srcLink.externalLink().plugId(),
703 new LinkKeyPair(newKey));
704 } else {
705 if (newKey.equals(pair.firstKey())) {
706 peerTeLinkKey = pair.secondKey();
707 } else if (newKey.equals(pair.secondKey())) {
708 peerTeLinkKey = pair.firstKey();
709 } else if (pair.firstKey() == null) {
710 peerTeLinkKey = pair.secondKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500711 pair.setFirstKey(newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500712 } else if (pair.secondKey() == null) {
713 peerTeLinkKey = pair.firstKey();
Yixiao Chen68bfab22016-11-11 11:04:10 -0500714 pair.setSecondKey(newKey);
715 }
716
Yixiao Chen29f06332016-12-07 16:14:29 -0500717 if (peerTeLinkKey != null) {
718 TeLink peerLink = teLinks.get(peerTeLinkKey);
719 if (peerLink != null && (peerLink.peerTeLinkKey() == null
720 || !peerLink.peerTeLinkKey().equals(newKey))) {
721 // Update peer Link with local link key
722 TeLink newPeerLink = updateTeLink(peerTeLinkKey, newKey,
723 peerLink.underlayTeTopologyId(),
724 peerLink.supportingTeLinkId(),
725 peerLink.sourceTeLinkId(),
726 peerLink.externalLink(),
727 peerLink);
728 teLinks.put(peerTeLinkKey, newPeerLink);
729 if (postEvent) {
730 TeLinkTpGlobalKey globalKey = new TeLinkTpGlobalKey(mergedTopologyKey,
731 peerTeLinkKey);
732 post(new TeTopologyEvent(TE_LINK_UPDATED,
733 new TeLinkEventSubject(globalKey,
734 newPeerLink)));
735 post(new TeTopologyEvent(LINK_UPDATED,
736 new NetworkLinkEventSubject(
737 networkLinkKey(globalKey),
738 linkBuilder(toNetworkLinkId(peerTeLinkKey),
739 newPeerLink))));
740 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500741 }
Yixiao Chen29f06332016-12-07 16:14:29 -0500742 }
Yixiao Chen68bfab22016-11-11 11:04:10 -0500743 }
744 }
745
746 TeTopologyKey underlayTopologyId = null; // No underlay
747 TeLinkTpGlobalKey supportTeLinkId = null; // No support
748 // Source link for the new updated link
749 TeLinkTpGlobalKey sourceTeLinkId = new TeLinkTpGlobalKey(srcTopoKey, srcLink.teLinkKey());
750 TeLink updatedLink = updateTeLink(newKey, peerTeLinkKey, underlayTopologyId,
751 supportTeLinkId, sourceTeLinkId,
752 srcLink.externalLink(), srcLink);
753 TeLinkTpGlobalKey newGlobalKey = new TeLinkTpGlobalKey(mergedTopologyKey, newKey);
Yixiao Chen29f06332016-12-07 16:14:29 -0500754 boolean newLink = teLinks.get(newKey) == null ? true : false;
Yixiao Chen68bfab22016-11-11 11:04:10 -0500755 teLinks.put(newKey, updatedLink);
756 if (postEvent) {
757 //Post event
758 post(new TeTopologyEvent(newLink ? TE_LINK_ADDED : TE_LINK_UPDATED,
759 new TeLinkEventSubject(newGlobalKey, updatedLink)));
760 post(new TeTopologyEvent(newLink ? LINK_ADDED : LINK_UPDATED,
Yixiao Chen29f06332016-12-07 16:14:29 -0500761 new NetworkLinkEventSubject(networkLinkKey(newGlobalKey),
762 linkBuilder(toNetworkLinkId(updatedLink.teLinkKey()),
763 updatedLink))));
Yixiao Chen68bfab22016-11-11 11:04:10 -0500764 }
765 }
766
767 // Merge TE links
768 private void mergeLinks(Map<TeLinkTpKey, TeLink> teLinks, TeTopology topology) {
769 if (!MapUtils.isEmpty(topology.teLinks())) {
770 for (Map.Entry<TeLinkTpKey, TeLink> entry : topology.teLinks().entrySet()) {
771 TeLink srcLink = entry.getValue();
772 updateSourceTeLink(teLinks, topology.teTopologyId(), srcLink,
773 mergedTopology != null);
774 }
775 }
776 }
777
778 // Update the merged topology with new TE nodes and links
779 private void updateMergedTopology(Map<Long, TeNode> teNodes, Map<TeLinkTpKey, TeLink> teLinks) {
780 boolean newTopology = mergedTopology == null;
781 BitSet flags = newTopology ? new BitSet(TeConstants.FLAG_MAX_BITS) : mergedTopology.flags();
Yixiao Chen29f06332016-12-07 16:14:29 -0500782 flags.set(BIT_MERGED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500783 CommonTopologyData commonData = new CommonTopologyData(newTopology ?
Yixiao Chen29f06332016-12-07 16:14:29 -0500784 toNetworkId(mergedTopologyKey) :
Yixiao Chen68bfab22016-11-11 11:04:10 -0500785 mergedTopology.networkId(),
Yixiao Chen29f06332016-12-07 16:14:29 -0500786 NOT_OPTIMIZED,
Yixiao Chen68bfab22016-11-11 11:04:10 -0500787 flags, DeviceId.deviceId("localHost"));
788 mergedTopology = new DefaultTeTopology(mergedTopologyKey, teNodes, teLinks,
789 Long.toString(mergedTopologyKey.topologyId()), commonData);
Yixiao Chen29f06332016-12-07 16:14:29 -0500790 mergedNetwork = networkBuilder(mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500791 log.info("Nodes# {}, Links# {}", mergedTopology.teNodes().size(), mergedTopology.teLinks().size());
792 }
793
794 // Merge the new learned topology
795 private void mergeTopology(TeTopology topology) {
796 boolean newTopology = mergedTopology == null;
797 mergedTopologyKey = newTopology ?
798 new TeTopologyKey(providerId, DEFAULT_CLIENT_ID,
799 store.nextTeTopologyId()) :
800 mergedTopology.teTopologyId();
801
802 Map<Long, TeNode> teNodes = newTopology || mergedTopology.teNodes() == null ?
803 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teNodes());
804 mergeNodes(teNodes, topology);
805 Map<TeLinkTpKey, TeLink> teLinks = newTopology || mergedTopology.teLinks() == null ?
806 Maps.newHashMap() : Maps.newHashMap(mergedTopology.teLinks());
807 mergeLinks(teLinks, topology);
808 updateMergedTopology(teNodes, teLinks);
Yixiao Chen29f06332016-12-07 16:14:29 -0500809 log.debug("mergedTopology {}", mergedTopology);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500810
811 if (newTopology) {
812 // Post events for the merged network topology;
813 post(new TeTopologyEvent(TE_TOPOLOGY_ADDED, mergedTopology));
814 post(new TeTopologyEvent(NETWORK_ADDED, mergedNetwork));
815 }
816 }
817
818 private TeTopologyKey newTeTopologyKey(TeTopology teTopology) {
819 TeTopologyKey key = teTopology.teTopologyId();
820 if (key == null || teTopology.teTopologyIdStringValue() == null) {
821 log.error("Ignoring the non-TE topology");
822 throw new ApplicationException("Missing TE topology ID");
823 }
824 // Get the topologyId numeric value
825 long idValue = key.topologyId();
826 if (idValue == TeConstants.NIL_LONG_VALUE) {
827 if (teTopology.teTopologyIdStringValue() != null) {
828 try {
829 idValue = Long.parseLong(teTopology.teTopologyIdStringValue());
830 } catch (NumberFormatException e) {
831 // Can't get the long value from the string.
832 // Use an assigned id value from local id pool,
833 idValue = store.nextTeTopologyId();
834 }
835 return new TeTopologyKey(key.providerId(), key.clientId(), idValue);
836 }
837 }
838 return null;
839 }
840
841 private class InternalConfigListener implements NetworkConfigListener {
842
843 @Override
844 public void event(NetworkConfigEvent event) {
845 try {
846 providerId = cfgService.getConfig(appId, TeTopologyConfig.class)
847 .providerId();
Yixiao Chen29f06332016-12-07 16:14:29 -0500848 store.setProviderId(providerId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500849 teNodeIpStart = cfgService.getConfig(appId, TeTopologyConfig.class)
850 .teNodeIpStart();
851 teNodeIpEnd = cfgService.getConfig(appId, TeTopologyConfig.class)
852 .teNodeIpEnd();
Yixiao Chen29f06332016-12-07 16:14:29 -0500853 mdsc = cfgService.getConfig(appId, TeTopologyConfig.class)
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500854 .mdsc().equals(MDSC_MODE);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500855 nextTeNodeId = teNodeIpStart.toInt();
856 } catch (ConfigException e) {
857 log.error("Configuration error {}", e);
858 }
859 }
860
861 @Override
862 public boolean isRelevant(NetworkConfigEvent event) {
863 return event.configClass().equals(TeTopologyConfig.class) &&
864 (event.type() == CONFIG_ADDED ||
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500865 event.type() == CONFIG_UPDATED);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500866 }
867 }
868
869 @Override
870 public TeTopologies teTopologies() {
871 Map<TeTopologyKey, TeTopology> map;
872 if (MapUtils.isNotEmpty(store.teTopologies().teTopologies())) {
873 map = Maps.newHashMap(store.teTopologies().teTopologies());
874 } else {
875 map = Maps.newHashMap();
876 }
877 if (mergedTopology != null) {
878 map.put(mergedTopologyKey, mergedTopology);
879 }
880 return new DefaultTeTopologies(store.teTopologies().name(), map);
881 }
882
883 @Override
884 public TeTopology teTopology(TeTopologyKey topologyId) {
885 if (mergedTopology != null &&
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500886 topologyId != null &&
Yixiao Chen68bfab22016-11-11 11:04:10 -0500887 topologyId.equals(mergedTopologyKey)) {
888 return mergedTopology;
889 }
890 return store.teTopology(topologyId);
891 }
892
893 @Override
894 public TeTopology mergedTopology() {
895 return mergedTopology;
896 }
897
898 @Override
899 public void updateTeTopology(TeTopology teTopology) {
900 TeTopologyKey newKey = null;
901 try {
902 newKey = newTeTopologyKey(teTopology);
903 } catch (ApplicationException e) {
904 log.error("Ignoring the non-TE topology");
905 return;
906 }
907
908 // TE topology is updated here from other APP or NBI, the flag
909 // BIT_CUSTOMIZED or BIT_MERGED should be set.
910 BitSet flags = teTopology.flags();
911 if (flags == null ||
Yixiao Chen29f06332016-12-07 16:14:29 -0500912 !(flags.get(BIT_CUSTOMIZED) || flags.get(BIT_MERGED))) {
Yixiao Chen68bfab22016-11-11 11:04:10 -0500913 log.error("TE topology flags {} are not set properly", flags);
914 return;
915 }
916
917 if (newKey != null) {
918 DefaultTeTopology newTopology = new DefaultTeTopology(
919 newKey == null ? teTopology.teTopologyId() : newKey,
920 teTopology.teNodes(), teTopology.teLinks(),
921 teTopology.teTopologyIdStringValue(), new CommonTopologyData(teTopology));
922 // Update with new data
923 store.updateTeTopology(newTopology);
924 } else {
925 store.updateTeTopology(teTopology);
926 }
927 }
928
929 @Override
930 public void removeTeTopology(TeTopologyKey topologyId) {
931 store.removeTeTopology(topologyId);
932 }
933
934 @Override
935 public Networks networks() {
936 List<Network> networks;
937 if (CollectionUtils.isNotEmpty(store.networks())) {
938 networks = Lists.newArrayList(store.networks());
939 } else {
940 networks = Lists.newArrayList();
941 }
942 if (mergedNetwork != null) {
943 networks.add(mergedNetwork);
944 }
945 return new DefaultNetworks(networks);
946 }
947
948 @Override
949 public Network network(KeyId networkId) {
950 if (mergedNetwork != null &&
951 mergedNetwork.networkId().equals(networkId)) {
952 return mergedNetwork;
953 }
954 return store.network(networkId);
955 }
956
957 @Override
958 public void updateNetwork(Network network) {
959 // TODO: This will be implemented if required.
960 }
961
962 @Override
963 public void removeNetwork(KeyId networkId) {
964 // TODO: This will be implemented if required.
965 }
966
967 @Override
968 public TeNode teNode(TeNodeKey nodeId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500969 return nodeId.teTopologyKey().equals(mergedTopologyKey) ?
970 mergedTopology.teNode(nodeId.teNodeId()) :
971 store.teNode(nodeId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500972 }
973
974 @Override
975 public TeLink teLink(TeLinkTpGlobalKey linkId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500976 return linkId.teTopologyKey().equals(mergedTopologyKey) ?
977 mergedTopology.teLink(linkId.teLinkTpKey()) :
978 store.teLink(linkId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500979 }
980
981 @Override
982 public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500983 return ttpId.teTopologyKey().equals(mergedTopologyKey) ?
984 mergedTopology.teNode(ttpId.teNodeId()).tunnelTerminationPoint(ttpId.ttpId()) :
985 store.tunnelTerminationPoint(ttpId);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500986 }
987
988 @Override
989 public KeyId networkId(TeTopologyKey teTopologyKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500990 return teTopologyKey.equals(mergedTopologyKey) ?
991 mergedNetwork.networkId() :
992 store.networkId(teTopologyKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -0500993 }
994
995 @Override
996 public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -0500997 return teNodeKey.teTopologyKey().equals(mergedTopologyKey) ?
998 networkNodeKey(teNodeKey) :
999 store.nodeKey(teNodeKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001000 }
1001
1002 @Override
1003 public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001004 return teLinkKey.teTopologyKey().equals(mergedTopologyKey) ?
1005 networkLinkKey(teLinkKey) :
1006 store.linkKey(teLinkKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001007 }
1008
1009 @Override
1010 public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
Yixiao Chen29f06332016-12-07 16:14:29 -05001011 return teTpKey.teTopologyKey().equals(mergedTopologyKey) ?
1012 new TerminationPointKey(networkNodeKey(teTpKey.teNodeKey()),
1013 KeyId.keyId(Long.toString(teTpKey.teLinkTpId()))) :
1014 store.terminationPointKey(teTpKey);
Yixiao Chen68bfab22016-11-11 11:04:10 -05001015 }
Yixiao Chen265b3bb2017-01-13 10:17:03 -05001016
1017 @Override
1018 public long teContollerId() {
1019 return providerId;
1020 }
Yixiao Chen68bfab22016-11-11 11:04:10 -05001021}