blob: 236fbf70cc22e13a00b2d4229106dfbdcb336f4e [file] [log] [blame]
janani bf7060cd2017-03-28 19:06:30 +05301/*
2 * Copyright 2017-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 */
16
17package org.onosproject.drivers.huawei;
18
Gaurav Agrawal9912f292017-03-30 01:22:40 +053019import com.google.common.collect.Lists;
janani bf7060cd2017-03-28 19:06:30 +053020import org.dom4j.Document;
21import org.dom4j.DocumentException;
22import org.dom4j.DocumentHelper;
23import org.dom4j.Element;
24import org.onosproject.net.DefaultAnnotations;
Gaurav Agrawal9912f292017-03-30 01:22:40 +053025import org.onosproject.net.DeviceId;
janani bf7060cd2017-03-28 19:06:30 +053026import org.onosproject.net.device.DefaultPortDescription;
Gaurav Agrawal9912f292017-03-30 01:22:40 +053027import org.onosproject.net.device.DefaultPortStatistics;
janani bf7060cd2017-03-28 19:06:30 +053028import org.onosproject.net.device.PortDescription;
Gaurav Agrawal9912f292017-03-30 01:22:40 +053029import org.onosproject.net.device.PortStatistics;
janani bf7060cd2017-03-28 19:06:30 +053030
31import java.util.ArrayList;
32import java.util.Arrays;
Gaurav Agrawal9912f292017-03-30 01:22:40 +053033import java.util.Collection;
janani bf7060cd2017-03-28 19:06:30 +053034import java.util.Iterator;
35import java.util.List;
36
37import static org.onosproject.net.AnnotationKeys.PORT_NAME;
38import static org.onosproject.net.Port.Type.COPPER;
39import static org.onosproject.net.PortNumber.portNumber;
40
41/**
Gaurav Agrawal9912f292017-03-30 01:22:40 +053042 * Representation of Huawei XML parser.
janani bf7060cd2017-03-28 19:06:30 +053043 */
Gaurav Agrawal9912f292017-03-30 01:22:40 +053044public final class HuaweiXmlParser {
janani bf7060cd2017-03-28 19:06:30 +053045
46 private static final String DATA = "data";
47 private static final String IFM = "ifm";
48 private static final String IFS = "interfaces";
49 private static final String IF = "interface";
50 private static final String IF_TYPE = "ifPhyType";
Gaurav Agrawal9912f292017-03-30 01:22:40 +053051 private static final String IF_STATS = "ifStatistics";
janani bf7060cd2017-03-28 19:06:30 +053052 private static final String IF_STAT = "ifPhyStatus";
53 private static final String IF_NUM = "ifNumber";
54 private static final String IF_SPEED = "ifOperSpeed";
55 private static final String IF_NAME = "ifName";
56 private static final String UP = "up";
57 private static final String DYN_INFO = "ifDynamicInfo";
58 private static final String DELIMITER = "/";
59 private static final String SYS = "system";
60 private static final String SYS_INFO = "systemInfo";
61 private static final String SYS_NAME = "sysName";
62 private static final String PDT_VER = "productVer";
63 private static final String PLATFORM_VER = "platformVer";
64 private static final String SYS_ID = "sysObjectId";
Gaurav Agrawal9912f292017-03-30 01:22:40 +053065 private static final String P_RCVD = "receivePacket";
66 private static final String P_SENT = "sendPacket";
67 private static final String B_RCVD = "receiveByte";
68 private static final String B_SENT = "sendByte";
69 private static final String RX_DROP = "rcvDropPacket";
70 private static final String TX_DROP = "sendDropPacket";
71 private static final String RX_ERROR = "rcvErrorPacket";
72 private static final String TX_ERROR = "sendErrorPacket";
janani bf7060cd2017-03-28 19:06:30 +053073
74 private static final String DEV_PARSE_ERR = "Unable to parse the received" +
75 " xml reply for system details from the huawei device";
76 private static final String INT_PARSE_ERR = "Unable to parse the received" +
77 " xml reply for interface details from the huawei device";
78 private static final String P_NAME_INVALID = "Invalid port name.";
79
80 //TODO: All type of interfaces has to be added.
81 private static final List INTERFACES = Arrays.asList(
Vidyashree Ramad89a1532017-03-30 15:13:52 +053082 "MEth", "Ethernet", "POS", "GigabitEthernet");
janani bf7060cd2017-03-28 19:06:30 +053083
84 private List<PortDescription> ports = new ArrayList<>();
85 private String xml;
86 private int portInc;
87 private String[] info = new String[4];
88
89 /**
90 * Constructs huawei XML parser with xml reply.
91 *
92 * @param xml xml reply
93 */
94 public HuaweiXmlParser(String xml) {
95 this.xml = xml;
96 }
97
98 /**
99 * Returns the system info.
100 *
101 * @return system info
102 */
103 String[] getInfo() {
104 return info;
105 }
106
107 /**
108 * Returns the port list.
109 *
110 * @return port list
111 */
112 List<PortDescription> getPorts() {
113 return ports;
114 }
115
116 /**
117 * Parses system info xml reply.
118 */
119 void parseSysInfo() {
120 Document doc;
121 try {
122 doc = DocumentHelper.parseText(xml);
123 } catch (DocumentException e) {
124 throw new IllegalArgumentException(DEV_PARSE_ERR);
125 }
126
127 Element root = doc.getRootElement();
128 Element parent = root.element(DATA).element(SYS).element(SYS_INFO);
129 info[0] = parent.element(SYS_NAME).getText();
130 info[1] = parent.element(PDT_VER).getText();
131 info[2] = parent.element(PLATFORM_VER).getText();
132 info[3] = parent.element(SYS_ID).getText();
133 }
134
135 /**
136 * Parses interface xml reply and creates ports to be updated.
137 */
138 void parseInterfaces() {
Gaurav Agrawal9912f292017-03-30 01:22:40 +0530139 Iterator itr = getInterfaceIterator();
140 while (itr.hasNext()) {
141 Element ifElement = (Element) itr.next();
142 addPorts(ifElement);
143 }
144 }
145
146 private Iterator getInterfaceIterator() {
janani bf7060cd2017-03-28 19:06:30 +0530147 Document doc;
148 try {
149 doc = DocumentHelper.parseText(xml);
150 } catch (DocumentException e) {
151 throw new IllegalArgumentException(INT_PARSE_ERR);
152 }
153 Element root = doc.getRootElement();
154 Element parent = root.element(DATA).element(IFM).element(IFS);
Gaurav Agrawal9912f292017-03-30 01:22:40 +0530155 return parent.elementIterator(IF);
janani bf7060cd2017-03-28 19:06:30 +0530156 }
157
158 /**
159 * Adds port information to the port list from the xml reply.
160 *
161 * @param ifElement interface element
162 */
163 private void addPorts(Element ifElement) {
164 String ifType = ifElement.element(IF_TYPE).getText();
165
166 if (INTERFACES.contains(ifType)) {
167 Element info = ifElement.element(DYN_INFO);
168 String status = info.element(IF_STAT).getText();
169 String port = getPortNum(ifElement.element(IF_NUM).getText());
170 String speed = info.element(IF_SPEED).getText();
171 String ifName = ifElement.element(IF_NAME).getText();
172
173 boolean isEnabled = false;
174 if (status.equals(UP)) {
175 isEnabled = true;
176 }
177
178 Long portSpeed = 0L;
179 if (!speed.isEmpty()) {
180 portSpeed = Long.valueOf(speed);
181 }
182
183 DefaultAnnotations annotations = DefaultAnnotations.builder()
184 .set(PORT_NAME, ifName).build();
185 ports.add(new DefaultPortDescription(portNumber(port), isEnabled,
186 COPPER, portSpeed,
187 annotations));
188 }
189 }
190
191 /**
192 * Returns port number from the port name. As many type of port can have
193 * same port number, each port number will be prepended with a incrementing
194 * number to make it unique in the list.
195 *
196 * @param portName port name
197 * @return port number
198 */
199 private String getPortNum(String portName) {
200 String port;
201 if (!portName.contains(DELIMITER)) {
202 portInc++;
203 port = String.valueOf(portInc) + portName;
204 } else if (portName.indexOf(DELIMITER) > 0) {
205 try {
206 port = portName.substring(
207 portName.lastIndexOf(DELIMITER) + 1);
208 portInc++;
209 port = String.valueOf(portInc) + port;
210 } catch (StringIndexOutOfBoundsException e) {
211 throw new IllegalArgumentException(P_NAME_INVALID);
212 }
213 } else {
214 throw new IllegalArgumentException(P_NAME_INVALID);
215 }
216 return port;
217 }
Gaurav Agrawal9912f292017-03-30 01:22:40 +0530218
219 /**
220 * Returns port statistics information for a device.
221 *
222 * @param deviceId device for which port statistics to be fetched
223 * @return port statistics
224 */
225 Collection<PortStatistics> parsePortsStatistics(DeviceId deviceId) {
226 Collection<PortStatistics> pss = Lists.newArrayList();
227 Iterator itr = getInterfaceIterator();
228 while (itr.hasNext()) {
229 Element ifElement = (Element) itr.next();
230 pss.add(getPortStatistics(ifElement, deviceId));
231 }
232 return pss;
233 }
234
235 private PortStatistics getPortStatistics(Element ifElement, DeviceId id) {
236 String ifType = ifElement.element(IF_TYPE).getText();
237
238 DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder();
239
240 if (INTERFACES.contains(ifType)) {
Gaurav Agrawal9912f292017-03-30 01:22:40 +0530241 int port = Integer.parseInt(getPortNum(ifElement.element(IF_NUM)
242 .getText()));
243 Element statInfo = ifElement.element(IF_STATS);
244 long packetReceived = Long.parseLong(statInfo.element(P_RCVD)
245 .getText());
246 long packetSent = Long.parseLong(statInfo.element(P_SENT).getText());
247 long bytesReceived = Long.parseLong(statInfo.element(B_RCVD)
248 .getText());
249 long bytesSent = Long.parseLong(statInfo.element(B_SENT).getText());
250 long packetsRxDropped = Long.parseLong(statInfo.element(RX_DROP)
251 .getText());
252 long packetsTxDropped = Long.parseLong(statInfo.element(TX_DROP)
253 .getText());
254 long packetsRxErrors = Long.parseLong(statInfo.element(RX_ERROR)
255 .getText());
256 long packetsTxErrors = Long.parseLong(statInfo.element(TX_ERROR)
257 .getText());
258
259 return builder.setDeviceId(id)
Vidyashree Ramad89a1532017-03-30 15:13:52 +0530260 .setPort(port)
Gaurav Agrawal9912f292017-03-30 01:22:40 +0530261 .setPacketsReceived(packetReceived)
262 .setPacketsSent(packetSent)
263 .setBytesReceived(bytesReceived)
264 .setBytesSent(bytesSent)
265 .setPacketsRxDropped(packetsRxDropped)
266 .setPacketsRxErrors(packetsRxErrors)
267 .setPacketsTxDropped(packetsTxDropped)
268 .setPacketsTxErrors(packetsTxErrors).build();
269 }
270 return builder.build();
271 }
janani bf7060cd2017-03-28 19:06:30 +0530272}