org.onosproject.drivers.huawei.HuaweiXmlParser.java Source code

Java tutorial

Introduction

Here is the source code for org.onosproject.drivers.huawei.HuaweiXmlParser.java

Source

/*
 * Copyright 2017-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onosproject.drivers.huawei;

import com.google.common.collect.Lists;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.net.Port.Type.COPPER;
import static org.onosproject.net.PortNumber.portNumber;

/**
 * Representation of Huawei XML parser.
 */
public final class HuaweiXmlParser {

    private static final String DATA = "data";
    private static final String IFM = "ifm";
    private static final String IFS = "interfaces";
    private static final String IF = "interface";
    private static final String IF_TYPE = "ifPhyType";
    private static final String IF_STATS = "ifStatistics";
    private static final String IF_STAT = "ifPhyStatus";
    private static final String IF_NUM = "ifNumber";
    private static final String IF_SPEED = "ifOperSpeed";
    private static final String IF_NAME = "ifName";
    private static final String UP = "up";
    private static final String DYN_INFO = "ifDynamicInfo";
    private static final String DELIMITER = "/";
    private static final String SYS = "system";
    private static final String SYS_INFO = "systemInfo";
    private static final String SYS_NAME = "sysName";
    private static final String PDT_VER = "productVer";
    private static final String PLATFORM_VER = "platformVer";
    private static final String SYS_ID = "sysObjectId";
    private static final String P_RCVD = "receivePacket";
    private static final String P_SENT = "sendPacket";
    private static final String B_RCVD = "receiveByte";
    private static final String B_SENT = "sendByte";
    private static final String RX_DROP = "rcvDropPacket";
    private static final String TX_DROP = "sendDropPacket";
    private static final String RX_ERROR = "rcvErrorPacket";
    private static final String TX_ERROR = "sendErrorPacket";

    private static final String DEV_PARSE_ERR = "Unable to parse the received"
            + " xml reply for system details from the huawei device";
    private static final String INT_PARSE_ERR = "Unable to parse the received"
            + " xml reply for interface details from the huawei device";
    private static final String P_NAME_INVALID = "Invalid port name.";

    //TODO: All type of interfaces has to be added.
    private static final List INTERFACES = Arrays.asList("MEth", "Ethernet", "POS", "GigabitEthernet");

    private List<PortDescription> ports = new ArrayList<>();
    private String xml;
    private int portInc;
    private String[] info = new String[4];

    /**
     * Constructs huawei XML parser with xml reply.
     *
     * @param xml xml reply
     */
    public HuaweiXmlParser(String xml) {
        this.xml = xml;
    }

    /**
     * Returns the system info.
     *
     * @return system info
     */
    String[] getInfo() {
        return info;
    }

    /**
     * Returns the port list.
     *
     * @return port list
     */
    List<PortDescription> getPorts() {
        return ports;
    }

    /**
     * Parses system info xml reply.
     */
    void parseSysInfo() {
        Document doc;
        try {
            doc = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            throw new IllegalArgumentException(DEV_PARSE_ERR);
        }

        Element root = doc.getRootElement();
        Element parent = root.element(DATA).element(SYS).element(SYS_INFO);
        info[0] = parent.element(SYS_NAME).getText();
        info[1] = parent.element(PDT_VER).getText();
        info[2] = parent.element(PLATFORM_VER).getText();
        info[3] = parent.element(SYS_ID).getText();
    }

    /**
     * Parses interface xml reply and creates ports to be updated.
     */
    void parseInterfaces() {
        Iterator itr = getInterfaceIterator();
        while (itr.hasNext()) {
            Element ifElement = (Element) itr.next();
            addPorts(ifElement);
        }
    }

    private Iterator getInterfaceIterator() {
        Document doc;
        try {
            doc = DocumentHelper.parseText(xml);
        } catch (DocumentException e) {
            throw new IllegalArgumentException(INT_PARSE_ERR);
        }
        Element root = doc.getRootElement();
        Element parent = root.element(DATA).element(IFM).element(IFS);
        return parent.elementIterator(IF);
    }

    /**
     * Adds port information to the port list from the xml reply.
     *
     * @param ifElement interface element
     */
    private void addPorts(Element ifElement) {
        String ifType = ifElement.element(IF_TYPE).getText();

        if (INTERFACES.contains(ifType)) {
            Element info = ifElement.element(DYN_INFO);
            String status = info.element(IF_STAT).getText();
            String port = getPortNum(ifElement.element(IF_NUM).getText());
            String speed = info.element(IF_SPEED).getText();
            String ifName = ifElement.element(IF_NAME).getText();

            boolean isEnabled = false;
            if (status.equals(UP)) {
                isEnabled = true;
            }

            Long portSpeed = 0L;
            if (!speed.isEmpty()) {
                portSpeed = Long.valueOf(speed);
            }

            DefaultAnnotations annotations = DefaultAnnotations.builder().set(PORT_NAME, ifName).build();
            ports.add(new DefaultPortDescription(portNumber(port), isEnabled, COPPER, portSpeed, annotations));
        }
    }

    /**
     * Returns port number from the port name. As many type of port can have
     * same port number, each port number will be prepended with a incrementing
     * number to make it unique in the list.
     *
     * @param portName port name
     * @return port number
     */
    private String getPortNum(String portName) {
        String port;
        if (!portName.contains(DELIMITER)) {
            portInc++;
            port = String.valueOf(portInc) + portName;
        } else if (portName.indexOf(DELIMITER) > 0) {
            try {
                port = portName.substring(portName.lastIndexOf(DELIMITER) + 1);
                portInc++;
                port = String.valueOf(portInc) + port;
            } catch (StringIndexOutOfBoundsException e) {
                throw new IllegalArgumentException(P_NAME_INVALID);
            }
        } else {
            throw new IllegalArgumentException(P_NAME_INVALID);
        }
        return port;
    }

    /**
     * Returns port statistics information for a device.
     *
     * @param deviceId device for which port statistics to be fetched
     * @return port statistics
     */
    Collection<PortStatistics> parsePortsStatistics(DeviceId deviceId) {
        Collection<PortStatistics> pss = Lists.newArrayList();
        Iterator itr = getInterfaceIterator();
        while (itr.hasNext()) {
            Element ifElement = (Element) itr.next();
            pss.add(getPortStatistics(ifElement, deviceId));
        }
        return pss;
    }

    private PortStatistics getPortStatistics(Element ifElement, DeviceId id) {
        String ifType = ifElement.element(IF_TYPE).getText();

        DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder();

        if (INTERFACES.contains(ifType)) {
            int port = Integer.parseInt(getPortNum(ifElement.element(IF_NUM).getText()));
            Element statInfo = ifElement.element(IF_STATS);
            long packetReceived = Long.parseLong(statInfo.element(P_RCVD).getText());
            long packetSent = Long.parseLong(statInfo.element(P_SENT).getText());
            long bytesReceived = Long.parseLong(statInfo.element(B_RCVD).getText());
            long bytesSent = Long.parseLong(statInfo.element(B_SENT).getText());
            long packetsRxDropped = Long.parseLong(statInfo.element(RX_DROP).getText());
            long packetsTxDropped = Long.parseLong(statInfo.element(TX_DROP).getText());
            long packetsRxErrors = Long.parseLong(statInfo.element(RX_ERROR).getText());
            long packetsTxErrors = Long.parseLong(statInfo.element(TX_ERROR).getText());

            return builder.setDeviceId(id).setPort(port).setPacketsReceived(packetReceived)
                    .setPacketsSent(packetSent).setBytesReceived(bytesReceived).setBytesSent(bytesSent)
                    .setPacketsRxDropped(packetsRxDropped).setPacketsRxErrors(packetsRxErrors)
                    .setPacketsTxDropped(packetsTxDropped).setPacketsTxErrors(packetsTxErrors).build();
        }
        return builder.build();
    }
}