blob: 9f6f5e3030525d528305b7e4fae8122910bf5c1d [file] [log] [blame]
Jeff Groom34c28ce2018-04-26 19:42:18 -06001/*
2 * Copyright 2016-present Open Networking Foundation
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.drivers.ciena.waveserverai.netconf;
17
18import com.google.common.collect.ImmutableList;
19import org.onlab.packet.ChassisId;
20import org.onosproject.drivers.netconf.TemplateManager;
21import org.onosproject.net.AnnotationKeys;
22import org.onosproject.net.DefaultAnnotations;
23import org.onosproject.net.Device;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.Port;
26import org.onosproject.net.PortNumber;
27import org.onosproject.net.SparseAnnotations;
28import org.onosproject.net.device.DefaultDeviceDescription;
29import org.onosproject.net.device.DefaultPortDescription;
30import org.onosproject.net.device.DeviceDescription;
31import org.onosproject.net.device.DeviceDescriptionDiscovery;
32import org.onosproject.net.device.DeviceService;
33import org.onosproject.net.device.PortDescription;
34import org.onosproject.net.driver.AbstractHandlerBehaviour;
35import org.onosproject.netconf.NetconfController;
36import org.onosproject.netconf.NetconfDevice;
37import org.onosproject.netconf.NetconfException;
38import org.onosproject.netconf.NetconfSession;
39import org.slf4j.Logger;
40import org.w3c.dom.Node;
41import org.w3c.dom.NodeList;
42
43import javax.xml.xpath.XPath;
44import javax.xml.xpath.XPathConstants;
45import javax.xml.xpath.XPathExpressionException;
46import javax.xml.xpath.XPathFactory;
47import java.util.ArrayList;
48import java.util.List;
49
50import static com.google.common.base.Preconditions.checkNotNull;
51import static org.slf4j.LoggerFactory.getLogger;
52
53/**
54 * Discovers the device and ports from a Ciena WaveServer Ai Netconf device.
55 */
56
57public class CienaWaveserverAiDeviceDescription extends AbstractHandlerBehaviour
58 implements DeviceDescriptionDiscovery {
59 private static final TemplateManager TEMPLATE_MANAGER = new TemplateManager();
60
61 private final Logger log = getLogger(getClass());
62
63 public CienaWaveserverAiDeviceDescription() {
64 log.info("Loaded handler behaviour CienaWaveserverAiDeviceDescription.");
65 }
66
67 static {
68 TEMPLATE_MANAGER.load(CienaWaveserverAiDeviceDescription.class,
69 "/templates/requests/%s.j2",
70 "discoverDeviceDetails", "discoverPortDetails");
71 }
72
73 @Override
74 public DeviceDescription discoverDeviceDetails() {
75 log.debug("Adding description for Waveserver Ai device");
76
77 NetconfSession session = getNetconfSession();
78 Device device = getDevice(handler().data().deviceId());
79
80 try {
81 XPath xp = XPathFactory.newInstance().newXPath();
82
83 Node node = TEMPLATE_MANAGER.doRequest(session, "discoverDeviceDetails");
84 String chassisId = xp.evaluate("waveserver-chassis/mac-addresses/chassis/base/text()", node);
85 chassisId = chassisId.replace(":", "");
86 SparseAnnotations annotationDevice = DefaultAnnotations.builder()
87 .set("name", xp.evaluate("waveserver-system/host-name/current-host-name/text()", node))
88 .build();
89 return new DefaultDeviceDescription(device.id().uri(),
90 Device.Type.OTN,
91 "Ciena",
92 "WaverserverAi",
93 xp.evaluate("waveserver-software/status/active-version/text()",
94 node),
95 xp.evaluate("waveserver-chassis/identification/serial-number/text()",
96 node),
97 new ChassisId(Long.valueOf(chassisId, 16)),
98 (SparseAnnotations) annotationDevice);
99 } catch (NetconfException | XPathExpressionException e) {
100 log.error("Unable to retrieve device information for device {}, {}", device.chassisId(), e);
101 }
102
103 return new DefaultDeviceDescription(device.id().uri(), Device.Type.OTN, "Ciena", "WaverserverAi", "unknown",
104 "unknown", device.chassisId());
105 }
106
107 @Override
108 public List<PortDescription> discoverPortDetails() {
109 log.info("Adding ports for Waveserver Ai device");
110 List<PortDescription> ports = new ArrayList<>();
111
112 Device device = getDevice(handler().data().deviceId());
113 NetconfSession session = getNetconfSession();
114
115 try {
116 XPath xp = XPathFactory.newInstance().newXPath();
117 Node nodeListItem;
118
119 Node node = TEMPLATE_MANAGER.doRequest(session, "discoverPortDetails");
120 NodeList nodeList = (NodeList) xp.evaluate("waveserver-ports/ports", node, XPathConstants.NODESET);
121 int count = nodeList.getLength();
122 for (int i = 0; i < count; ++i) {
123 nodeListItem = nodeList.item(i);
124 DefaultAnnotations annotationPort = DefaultAnnotations.builder()
125 .set(AnnotationKeys.PORT_NAME, xp.evaluate("port-id/text()", nodeListItem))
126 .set(AnnotationKeys.PROTOCOL, xp.evaluate("id/type/text()", nodeListItem))
127 .build();
128 String port = xp.evaluate("port-id/text()", nodeListItem);
129 ports.add(DefaultPortDescription.builder()
130 .withPortNumber(PortNumber.portNumber(
131 portIdConvert(port), port))
132 .isEnabled(portStateConvert(
133 xp.evaluate("state/operational-state/text()", nodeListItem)))
134 .portSpeed(portSpeedToLong(xp.evaluate("id/speed/text()", nodeListItem)))
135 .type(Port.Type.PACKET)
136 .annotations(annotationPort)
137 .build());
138 }
139 } catch (NetconfException | XPathExpressionException e) {
140 log.error("Unable to retrieve port information for device {}, {}", device.chassisId(), e);
141 }
142 return ImmutableList.copyOf(ports);
143 }
144
145 /**
146 * Returns the Device of the deviceId.
147 *
148 * @return device
149 */
150 private Device getDevice(DeviceId deviceId) {
151 DeviceService deviceService = checkNotNull(handler().get(DeviceService.class));
152 return deviceService.getDevice(deviceId);
153 }
154
155 /**
156 * Returns the NETCONF session of the device.
157 *
158 * @return session
159 */
160 private NetconfSession getNetconfSession() {
161 NetconfController controller = checkNotNull(handler().get(NetconfController.class));
162 NetconfDevice ncDevice = controller.getDevicesMap().get(handler().data().deviceId());
163 if (ncDevice == null) {
164 log.error(
165 "Internal ONOS Error. Device has been marked as reachable, "
166 + "but deviceID {} is not in Devices Map. Continuing with empty description",
167 handler().data().deviceId());
168 }
169 return controller.getDevicesMap().get(handler().data().deviceId())
170 .getSession();
171 }
172
173 /**
174 * Convert port speed in Gbps tp port speed in Mbps.
175 *
176 * @param speed
177 * port speed as string
178 * @return port speed
179 */
180 public static Long portSpeedToLong(String speed) {
181 double d = Double.parseDouble(speed);
182 return (new Double(d * 1000)).longValue();
183 }
184
185 /**
186 * Convert port operational state to Boolean.
187 *
188 * @param state
189 * port state as string
190 * @return port state
191 */
192 public static Boolean portStateConvert(String state) {
193 switch (state) {
194 case "up":
195 return true;
196 case "enabled":
197 return true;
198 case "disabled":
199 return false;
200 case "down":
201 return false;
202 default:
203 return false;
204 }
205 }
206
207 /**
208 * Convert port operational state to Boolean.
209 *
210 * @param state
211 * port state as Boolean
212 * @return port state
213 */
214 public static String portStateConvert(Boolean state) {
215 if (state) {
216 return "enabled";
217 } else {
218 return "disabled";
219 }
220 }
221
222 /**
223 * Convert port name to port id.
224 *
225 * @param name
226 * port name as String
227 * @return port id
228 */
229 public static Long portIdConvert(String name) {
230 String result = "1";
231 String replaceString = name.replace("-Ethernet", "");
232 String[] arrOfStr = replaceString.split("-");
233 if (arrOfStr[0].length() == 1) {
234 result += "0" + arrOfStr[0];
235 } else {
236 result += arrOfStr[0];
237 }
238 if (arrOfStr[1].length() == 1) {
239 result += "0" + arrOfStr[1];
240 } else {
241 result += arrOfStr[1];
242 }
243 return Long.valueOf(result);
244 }
245 /**
246 * Convert port id to port name.
247 *
248 * @param id
249 * port id as Long
250 * @return port name as String
251 */
252 public static String portIdConvert(Long id) {
253 Integer pre = Integer.parseInt(id.toString().substring(1, 3));
254 Integer post = Integer.parseInt(id.toString().substring(3, 5));
255 return pre.toString() + "-" + post.toString();
256 }
257
258}