blob: 8bc44da18dabe7d127f484ab3cbd54b0b31e1859 [file] [log] [blame]
Yixiao Chen5ece00f2016-09-14 16:23:24 -04001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Yixiao Chen5ece00f2016-09-14 16:23:24 -04003 *
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.provider.te.topology;
17
Hesam Rahimi01f6ae02017-02-01 13:57:00 -050018import static org.onlab.util.Tools.groupedThreads;
19import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_ADDED;
20import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UPDATED;
21import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
22import static org.onosproject.provider.te.utils.TeTopologyRestconfEventType.TE_TOPOLOGY_LINK_NOTIFICATION;
23import static org.onosproject.provider.te.utils.TeTopologyRestconfEventType.TE_TOPOLOGY_NODE_NOTIFICATION;
24import static org.slf4j.LoggerFactory.getLogger;
25
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.StringWriter;
29import java.nio.charset.StandardCharsets;
30import java.util.HashSet;
31import java.util.List;
32import java.util.Set;
33import java.util.concurrent.ExecutorService;
34import java.util.concurrent.Executors;
35
Yixiao Chen5ece00f2016-09-14 16:23:24 -040036import org.apache.commons.io.IOUtils;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070037import org.osgi.service.component.annotations.Activate;
38import org.osgi.service.component.annotations.Component;
39import org.osgi.service.component.annotations.Deactivate;
40import org.osgi.service.component.annotations.Reference;
41import org.osgi.service.component.annotations.ReferenceCardinality;
Yixiao Chen5ece00f2016-09-14 16:23:24 -040042import org.onosproject.core.ApplicationId;
43import org.onosproject.core.CoreService;
44import org.onosproject.incubator.net.config.basics.ConfigException;
45import org.onosproject.net.DeviceId;
46import org.onosproject.net.config.ConfigFactory;
47import org.onosproject.net.config.NetworkConfigEvent;
48import org.onosproject.net.config.NetworkConfigListener;
49import org.onosproject.net.config.NetworkConfigRegistry;
50import org.onosproject.net.device.DeviceProviderRegistry;
51import org.onosproject.net.provider.AbstractProvider;
52import org.onosproject.net.provider.ProviderId;
53import org.onosproject.protocol.rest.RestSBDevice;
54import org.onosproject.protocol.restconf.RestConfSBController;
chengfan9d60b6e2016-12-01 11:06:39 +080055import org.onosproject.provider.te.utils.DefaultJsonCodec;
Henry Yu05dcc212017-01-05 16:05:26 -050056import org.onosproject.provider.te.utils.RestconfNotificationEventProcessor;
57import org.onosproject.provider.te.utils.TeTopologyRestconfEventListener;
chengfan9d60b6e2016-12-01 11:06:39 +080058import org.onosproject.provider.te.utils.YangCompositeEncodingImpl;
Yixiao Chen5ece00f2016-09-14 16:23:24 -040059import org.onosproject.tetopology.management.api.TeTopologyProvider;
60import org.onosproject.tetopology.management.api.TeTopologyProviderRegistry;
61import org.onosproject.tetopology.management.api.TeTopologyProviderService;
Henry Yu4b4a7eb2016-11-09 20:07:53 -050062import org.onosproject.tetopology.management.api.TeTopologyService;
63import org.onosproject.tetopology.management.api.link.NetworkLink;
64import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
65import org.onosproject.tetopology.management.api.node.NetworkNode;
66import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
67import org.onosproject.teyang.utils.topology.LinkConverter;
Yixiao Chen5ece00f2016-09-14 16:23:24 -040068import org.onosproject.teyang.utils.topology.NetworkConverter;
Henry Yu4b4a7eb2016-11-09 20:07:53 -050069import org.onosproject.teyang.utils.topology.NodeConverter;
Yixiao Chen5ece00f2016-09-14 16:23:24 -040070import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.IetfNetwork;
71import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev20151208.ietfnetwork.networks.Network;
72import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.topology.rev20151208.IetfNetworkTopology;
Hesam Rahimi01f6ae02017-02-01 13:57:00 -050073import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20170110.IetfTeTopology;
74import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20170110.ietftetopology.IetfTeTopologyEvent;
75import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20170110.ietftetopology.TeLinkEvent;
76import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.topology.rev20170110.ietftetopology.TeNodeEvent;
77import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.te.types.rev20160705.ietftetypes.tetopologyeventtype.TeTopologyEventTypeEnum;
Yixiao Chen5ece00f2016-09-14 16:23:24 -040078import org.onosproject.yms.ych.YangCodecHandler;
79import org.onosproject.yms.ych.YangProtocolEncodingFormat;
80import org.onosproject.yms.ych.YangResourceIdentifierType;
81import org.onosproject.yms.ydt.YmsOperationType;
82import org.onosproject.yms.ymsm.YmsService;
83import org.slf4j.Logger;
84
Hesam Rahimi01f6ae02017-02-01 13:57:00 -050085import com.google.common.base.Preconditions;
Yixiao Chen5ece00f2016-09-14 16:23:24 -040086
87/**
88 * Provider for IETF TE Topology that use RESTCONF as means of communication.
89 */
90@Component(immediate = true)
91public class TeTopologyRestconfProvider extends AbstractProvider
92 implements TeTopologyProvider {
Henry Yu8ac364b2016-12-15 18:24:20 -050093 private static final String APP_NAME = "org.onosproject.teprovider";
Yixiao Chen5ece00f2016-09-14 16:23:24 -040094 private static final String RESTCONF = "restconf";
Henry Yu4b4a7eb2016-11-09 20:07:53 -050095 private static final String PROVIDER =
96 "org.onosproject.teprovider.restconf.domain";
Yixiao Chen5ece00f2016-09-14 16:23:24 -040097 private static final String IETF_NETWORK_URI = "ietf-network:networks";
Henry Yu4b4a7eb2016-11-09 20:07:53 -050098 private static final String IETF_NETWORKS_PREFIX =
99 "{\"ietf-network:networks\":";
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500100 private static final String TE_LINK_EVENT_PREFIX =
101 "{\"ietf-te-topology:te-link-event\":";
102 private static final String TE_NODE_EVENT_PREFIX =
103 "{\"ietf-te-topology:te-node-event\":";
104 private static final String IETF_NOTIFICATION_URI = "netconf";
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400105 private static final String JSON = "json";
106 private static final String E_DEVICE_NULL = "Restconf device is null";
107
108 private final Logger log = getLogger(getClass());
109
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700110 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400111 protected DeviceProviderRegistry deviceProviderRegistry;
112
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700113 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400114 protected TeTopologyProviderRegistry topologyProviderRegistry;
115
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700116 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400117 protected RestConfSBController restconfClient;
118
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700119 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400120 protected NetworkConfigRegistry cfgService;
121
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700122 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400123 protected CoreService coreService;
124
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700125 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400126 protected YmsService ymsService;
127
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700128 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500129 protected TeTopologyService teTopologyService;
130
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400131 private YangCodecHandler codecHandler;
132
133 private TeTopologyProviderService topologyProviderService;
134
135 private final ExecutorService executor =
136 Executors.newFixedThreadPool(5, groupedThreads("onos/restconfsbprovider",
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500137 "device-installer-%d", log));
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400138
139 private final ConfigFactory<ApplicationId, RestconfServerConfig> factory =
140 new ConfigFactory<ApplicationId, RestconfServerConfig>(APP_SUBJECT_FACTORY,
141 RestconfServerConfig.class,
142 "restconfDevices",
143 true) {
144 @Override
145 public RestconfServerConfig createConfig() {
146 return new RestconfServerConfig();
147 }
148 };
149
150 private final NetworkConfigListener cfgLister = new InternalNetworkConfigListener();
151 private ApplicationId appId;
152
153 private Set<DeviceId> addedDevices = new HashSet<>();
154
155 @Activate
156 public void activate() {
157 // Get the codec handler.
158 codecHandler = ymsService.getYangCodecHandler();
159 // Register all three IETF Topology YANG model schema with YMS.
160 codecHandler.addDeviceSchema(IetfNetwork.class);
161 codecHandler.addDeviceSchema(IetfNetworkTopology.class);
162 codecHandler.addDeviceSchema(IetfTeTopology.class);
163 // Register JSON CODEC functions
chengfan9d60b6e2016-12-01 11:06:39 +0800164 codecHandler.registerOverriddenCodec(new DefaultJsonCodec(ymsService),
Shankara-Huaweid5823ab2016-11-22 10:14:52 +0530165 YangProtocolEncodingFormat.JSON);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400166
167 appId = coreService.registerApplication(APP_NAME);
168 topologyProviderService = topologyProviderRegistry.register(this);
169 cfgService.registerConfigFactory(factory);
170 cfgService.addListener(cfgLister);
171 executor.execute(TeTopologyRestconfProvider.this::connectDevices);
172 log.info("Started");
173 }
174
175 @Deactivate
176 public void deactivate() {
177 cfgService.removeListener(cfgLister);
178 restconfClient.getDevices().keySet().forEach(this::deviceRemoved);
179 topologyProviderRegistry.unregister(this);
180 cfgService.unregisterConfigFactory(factory);
181 log.info("Stopped");
182 }
183
184 /**
185 * Creates an instance of TeTopologyRestconf provider.
186 */
187 public TeTopologyRestconfProvider() {
188 super(new ProviderId(RESTCONF, PROVIDER));
189 }
190
191 private void deviceAdded(RestSBDevice nodeId) {
192 Preconditions.checkNotNull(nodeId, E_DEVICE_NULL);
193 nodeId.setActive(true);
194 addedDevices.add(nodeId.deviceId());
195 }
196
197 private void deviceRemoved(DeviceId deviceId) {
198 Preconditions.checkNotNull(deviceId, E_DEVICE_NULL);
199 restconfClient.removeDevice(deviceId);
200 }
201
202 private void connectDevices() {
203
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500204 RestconfServerConfig cfg = cfgService.getConfig(appId,
205 RestconfServerConfig.class);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400206 try {
207 if (cfg != null && cfg.getDevicesAddresses() != null) {
208 //Precomputing the devices to be removed
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500209 Set<RestSBDevice> toBeRemoved = new HashSet<>(restconfClient.
210 getDevices().values());
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400211 toBeRemoved.removeAll(cfg.getDevicesAddresses());
212 //Adding new devices
213 for (RestSBDevice device : cfg.getDevicesAddresses()) {
214 device.setActive(false);
215 restconfClient.addDevice(device);
216 deviceAdded(device);
217 }
218
219 //Removing devices not wanted anymore
220 toBeRemoved.forEach(device -> deviceRemoved(device.deviceId()));
221 }
222 } catch (ConfigException e) {
223 log.error("Configuration error {}", e);
224 }
225
226 // Discover the topology from RESTCONF server
227 addedDevices.forEach(this::retrieveTopology);
228 addedDevices.clear();
229 }
230
231 private void retrieveTopology(DeviceId deviceId) {
232 // Retrieve IETF Network at top level.
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500233 InputStream jsonStream = restconfClient.get(deviceId,
234 IETF_NETWORK_URI,
235 JSON);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400236 if (jsonStream == null) {
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500237 log.warn("Unable to retrieve network Topology from restconf " +
238 "server {}", deviceId);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400239 return;
240 }
241
242 // Need to convert Input stream to String.
243 StringWriter writer = new StringWriter();
244 try {
245 IOUtils.copy(jsonStream, writer, StandardCharsets.UTF_8);
246 } catch (IOException e) {
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500247 log.warn("There is an exception {} for copy jsonStream to " +
248 "stringWriter for restconf {}",
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400249 e.getMessage(), deviceId);
250 return;
251 }
252 String jsonString = writer.toString();
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500253 String networkLevelJsonString = removePrefixTagFromJson(jsonString,
254 IETF_NETWORKS_PREFIX);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400255
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500256 YangCompositeEncodingImpl yce =
257 new YangCompositeEncodingImpl(YangResourceIdentifierType.URI,
258 IETF_NETWORK_URI,
259 networkLevelJsonString);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400260
261 Object yo = codecHandler.decode(yce,
Shankara-Huaweid5823ab2016-11-22 10:14:52 +0530262 YangProtocolEncodingFormat.JSON,
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400263 YmsOperationType.QUERY_REPLY);
264
rohitsharan30078292017-04-13 11:36:32 +0530265 if (yo == null) {
266 log.error("YMS decoder returns null for restconf {}", deviceId);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400267 return;
268 }
269
270 // YMS returns an ArrayList in a single Object (i.e. yo in this case)
271 // this means yo is actually an ArrayList of size 1
272 IetfNetwork ietfNetwork = ((List<IetfNetwork>) yo).get(0);
273
274 if (ietfNetwork.networks() != null &&
275 ietfNetwork.networks().network() != null) {
276 //Convert the YO to TE Core data and update TE Core.
277 for (Network nw : ietfNetwork.networks().network()) {
278 topologyProviderService.networkUpdated(
Yixiao Chen265b3bb2017-01-13 10:17:03 -0500279 NetworkConverter.yang2TeSubsystemNetwork(nw, ietfNetwork.networks(), deviceId));
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400280 }
281 }
282
283 //TODO: Uncomment when YMS fixes the issue in NetworkState translation (network-ref)
284// org.onosproject.tetopology.management.api.Networks networks =
285// NetworkConverter.yang2TeSubsystemNetworks(ietfNetwork.networks(),
286// ietfNetwork.networksState());
287// if (networks == null || networks.networks() == null) {
288// log.error("Yang2Te returns null for restconf {}", deviceId);
289// return;
290// }
291// for (org.onosproject.tetopology.management.api.Network network : networks.networks()) {
292// topologyProviderService.networkUpdated(network);
293// }
294
Henry Yu05dcc212017-01-05 16:05:26 -0500295 subscribeRestconfNotification(deviceId);
296 }
297
298 private void subscribeRestconfNotification(DeviceId deviceId) {
299
300 TeTopologyRestconfEventListener listener =
301 new TeTopologyRestconfEventListener();
302
303 listener.addCallbackFunction(TE_TOPOLOGY_LINK_NOTIFICATION,
304 new InternalLinkEventProcessor());
305 listener.addCallbackFunction(TE_TOPOLOGY_NODE_NOTIFICATION,
306 new InternalNodeEventProcessor());
307
308 if (!restconfClient.isNotificationEnabled(deviceId)) {
309 restconfClient.enableNotifications(deviceId,
310 IETF_NOTIFICATION_URI,
311 "application/json",
312 listener);
313 } else {
314 restconfClient.addNotificationListener(deviceId, listener);
315 }
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400316 }
317
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500318 private String removePrefixTagFromJson(String jsonString, String prefixTag) {
319 if (jsonString.startsWith(prefixTag)) {
320 return jsonString.substring(prefixTag.length(), jsonString.length() - 1);
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400321 }
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400322 return jsonString;
323 }
324
Henry Yu05dcc212017-01-05 16:05:26 -0500325 private class InternalLinkEventProcessor implements
326 RestconfNotificationEventProcessor<String> {
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400327
328 @Override
Henry Yu05dcc212017-01-05 16:05:26 -0500329 public void processEventPayload(String payload) {
330 String linkString = removePrefixTagFromJson(payload,
331 TE_LINK_EVENT_PREFIX);
332 log.debug("link event={}", linkString);
333 handleRestconfLinkNotification(linkString);
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500334 }
335
336 private void handleRestconfLinkNotification(String linkString) {
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500337
Henry Yu8ac364b2016-12-15 18:24:20 -0500338 IetfTeTopologyEvent event = convertJson2IetfTeTopologyEvent(
339 "ietf-te-topology:te-link-event",
340 linkString);
341 if (event == null) {
342 log.error("ERROR: json to YO conversion failure");
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500343 return;
344 }
345
Henry Yu8ac364b2016-12-15 18:24:20 -0500346 if (event.type() != IetfTeTopologyEvent.Type.TE_LINK_EVENT) {
347 log.error("ERROR: wrong YO event type: {}", event.type());
348 return;
349 }
350
351 TeLinkEvent teLinkEvent = event.subject().teLinkEvent();
352
353 log.debug("TeLinkEvent: {}", teLinkEvent);
354
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500355 NetworkLinkKey linkKey = LinkConverter.yangLinkEvent2NetworkLinkKey(
Henry Yu8ac364b2016-12-15 18:24:20 -0500356 teLinkEvent);
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500357
Yuren You8be581b2017-02-01 16:35:51 -0500358 TeTopologyEventTypeEnum teLinkEventType = teLinkEvent.eventType()
359 .enumeration();
360
361 if (teLinkEventType == TeTopologyEventTypeEnum.REMOVE) {
362 topologyProviderService.linkRemoved(linkKey);
363 return;
364 }
365
366 NetworkLink networkLink = LinkConverter.yangLinkEvent2NetworkLink(teLinkEvent,
367 teTopologyService);
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500368
Henry Yu8ac364b2016-12-15 18:24:20 -0500369 if (networkLink == null) {
370 log.error("ERROR: yangLinkEvent2NetworkLink returns null");
371 return;
372 }
373
374 log.debug("networkLink: {}", networkLink);
375
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500376 topologyProviderService.linkUpdated(linkKey, networkLink);
377 }
Henry Yu05dcc212017-01-05 16:05:26 -0500378 }
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500379
Henry Yu05dcc212017-01-05 16:05:26 -0500380 private class InternalNodeEventProcessor implements
381 RestconfNotificationEventProcessor<String> {
Henry Yu8ac364b2016-12-15 18:24:20 -0500382
Henry Yu05dcc212017-01-05 16:05:26 -0500383 @Override
384 public void processEventPayload(String payload) {
385 String nodeString = removePrefixTagFromJson(payload, TE_NODE_EVENT_PREFIX);
386 log.debug("node event={}", nodeString);
387 handleRestconfNodeNotification(nodeString);
Henry Yu8ac364b2016-12-15 18:24:20 -0500388 }
389
390 private void handleRestconfNodeNotification(String nodeString) {
391
392 IetfTeTopologyEvent event = convertJson2IetfTeTopologyEvent(
393 "ietf-te-topology:te-node-event",
394 nodeString);
395
396 if (event == null) {
397 log.error("ERROR: json to YO conversion failure");
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500398 return;
399 }
400
Henry Yu8ac364b2016-12-15 18:24:20 -0500401 if (event.type() != IetfTeTopologyEvent.Type.TE_NODE_EVENT) {
402 log.error("ERROR: wrong YO event type: {}", event.type());
403 return;
404 }
405
406 TeNodeEvent teNodeEvent = event.subject().teNodeEvent();
407
408 log.debug("TeNodeEvent: {}", teNodeEvent);
409
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500410 NetworkNodeKey nodeKey = NodeConverter.yangNodeEvent2NetworkNodeKey(
Henry Yu8ac364b2016-12-15 18:24:20 -0500411 teNodeEvent);
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500412
Yuren You8be581b2017-02-01 16:35:51 -0500413 TeTopologyEventTypeEnum teNodeEventType = teNodeEvent.eventType()
414 .enumeration();
415
416 if (teNodeEventType == TeTopologyEventTypeEnum.REMOVE) {
417 topologyProviderService.nodeRemoved(nodeKey);
418 return;
419 }
420
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500421 NetworkNode networkNode = NodeConverter.yangNodeEvent2NetworkNode(
Henry Yu8ac364b2016-12-15 18:24:20 -0500422 teNodeEvent,
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500423 teTopologyService);
424
Henry Yu8ac364b2016-12-15 18:24:20 -0500425 if (networkNode == null) {
426 log.error("ERROR: yangNodeEvent2NetworkNode returns null");
427 return;
428 }
429
Henry Yu4b4a7eb2016-11-09 20:07:53 -0500430 topologyProviderService.nodeUpdated(nodeKey, networkNode);
431 }
432 }
Henry Yu05dcc212017-01-05 16:05:26 -0500433
434 private class InternalNetworkConfigListener implements NetworkConfigListener {
435
436 @Override
437 public void event(NetworkConfigEvent event) {
438 executor.execute(TeTopologyRestconfProvider.this::connectDevices);
439 }
440
441 @Override
442 public boolean isRelevant(NetworkConfigEvent event) {
443 return event.configClass().equals(RestconfServerConfig.class) &&
444 (event.type() == CONFIG_ADDED ||
445 event.type() == CONFIG_UPDATED);
446 }
447 }
448
449 private IetfTeTopologyEvent convertJson2IetfTeTopologyEvent(String uriString,
450 String jsonBody) {
451
452 YangCompositeEncodingImpl yce =
453 new YangCompositeEncodingImpl(YangResourceIdentifierType.URI,
454 uriString,
455 jsonBody);
456 Object yo = codecHandler.decode(yce,
457 YangProtocolEncodingFormat.JSON,
458 YmsOperationType.NOTIFICATION);
459
460 if (yo == null) {
461 log.error("YMS decoder error");
462 return null;
463 }
464
465 if (!(yo instanceof IetfTeTopologyEvent)) {
466 log.error("ERROR: YO is not IetfTeTopologyEvent");
467 return null;
468 }
469
470 return (IetfTeTopologyEvent) yo;
471 }
Yixiao Chen5ece00f2016-09-14 16:23:24 -0400472}