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