2 * Copyright © 2017 AT&T and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.transportpce.networkmodel.listeners;
11 import java.util.Objects;
12 import java.util.Optional;
13 import java.util.concurrent.TimeUnit;
14 import java.util.regex.Matcher;
15 import java.util.regex.Pattern;
16 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
17 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
18 import org.opendaylight.transportpce.networkmodel.service.NetworkModelService;
19 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.ChangeNotification;
20 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OrgOpenroadmDeviceListener;
21 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.OtdrScanResult;
22 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.change.notification.Edit;
23 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
24 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
25 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
30 public class DeviceListener implements OrgOpenroadmDeviceListener {
32 private static final Logger LOG = LoggerFactory.getLogger(DeviceListener.class);
33 /* TODO: value obtained from DeviceTransactionManagerImpl and increased due to the timeout error described in
34 JIRA TRNSPRTPCE-249. The increase had no effect.
36 private static final long GET_DATA_SUBMIT_TIMEOUT = 5000;
37 private static final TimeUnit MAX_DURATION_TO_SUBMIT_TIMEUNIT = TimeUnit.MILLISECONDS;
38 private final DeviceTransactionManager deviceTransactionManager;
39 private final String nodeId;
40 private final NetworkModelService networkModelService;
42 public DeviceListener(DeviceTransactionManager deviceTransactionManager, String nodeId,
43 NetworkModelService networkModelService) {
44 this.deviceTransactionManager = deviceTransactionManager;
46 this.networkModelService = networkModelService;
50 * Callback for change-notification.
52 * @param notification ChangeNotification object
55 public void onChangeNotification(ChangeNotification notification) {
57 LOG.info("Notification {} received {}", ChangeNotification.QNAME, notification);
58 // NETCONF event notification handling
59 String deviceComponentChanged = null;
60 // Seems like there is only one edit in the NETCONF notification (from honeynode experience)
61 Edit edit = Objects.requireNonNull(notification.getEdit()).get(0);
62 deviceComponentChanged = Objects.requireNonNull(edit.getTarget()).getTargetType().getSimpleName();
63 // Only circuitPack type handled
64 switch (deviceComponentChanged) {
67 LOG.info("Interface modified on device {}", this.nodeId);
70 LOG.info("Circuit Pack modified on device {}", this.nodeId);
71 // 1. Get the name of the component modified
72 Iterable<InstanceIdentifier.PathArgument> pathArguments = edit.getTarget().getPathArguments();
73 String cpackId = null;
74 for (InstanceIdentifier.PathArgument pathArgument : pathArguments) {
75 if (!pathArgument.toString().contains("CircuitPacks")) {
76 LOG.warn("Path argument element doesnt reference a Circuit Pack");
79 Pattern pattern = Pattern.compile("\\{(.*?)}", Pattern.DOTALL);
80 Matcher matcher = pattern.matcher(pathArgument.toString());
81 while (matcher.find()) {
82 String cpackKey = matcher.group(1);
83 Pattern pattern1 = Pattern.compile("=(.*)", Pattern.DOTALL);
84 Matcher matcher1 = pattern1.matcher(cpackKey);
85 while (matcher1.find()) {
86 cpackId = matcher1.group(1);
90 // 2. Get new configuration of component from device
91 if (cpackId == null) {
92 LOG.warn("No Circuit pack id retrieved from NETCONF notification... aborting");
95 LOG.info("Circuit Pack {} modified on device {}", cpackId, this.nodeId);
96 if (!this.deviceTransactionManager.isDeviceMounted(nodeId)) {
97 LOG.error("Device {} not mounted yet", nodeId);
100 InstanceIdentifier<CircuitPacks> cpIID = InstanceIdentifier.create(OrgOpenroadmDevice.class)
101 .child(CircuitPacks.class, new CircuitPacksKey(cpackId));
102 /* Creating runnable to perform configuration retrieval and topology update in a new thread
103 to avoid JIRA TRNSPRTCE-251 */
104 Runnable handlenetconfEvent = new Runnable() {
105 private CircuitPacks circuitPacks;
107 public CircuitPacks getCircuitPacks() {
111 public void setCircuitPacks(CircuitPacks circuitPacks) {
112 this.circuitPacks = circuitPacks;
117 Optional<CircuitPacks> cpacksOptional = deviceTransactionManager
118 .getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, cpIID,
119 GET_DATA_SUBMIT_TIMEOUT, MAX_DURATION_TO_SUBMIT_TIMEUNIT);
120 if (!cpacksOptional.isPresent()) {
121 LOG.error("Couldnt read from device datastore");
124 setCircuitPacks(cpacksOptional.get());
125 LOG.info("Component {} configuration: {}", getCircuitPacks().getCircuitPackName(),
127 // 3. Update openroadm-topology
128 networkModelService.updateOpenRoadmNetworkTopology(nodeId, getCircuitPacks());
131 Thread thread = new Thread(handlenetconfEvent);
135 // TODO: handle more component types --> it implies development on honeynode simulator
136 LOG.warn("Component {} change not supported", deviceComponentChanged);
142 * Callback for otdr-scan-result.
144 * @param notification OtdrScanResult object
147 public void onOtdrScanResult(OtdrScanResult notification) {
149 LOG.info("Notification {} received {}", OtdrScanResult.QNAME, notification);