All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.cardinal.impl.OpenflowDeviceManager Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 2016 TCS and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.cardinal.impl;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.cardinal.openflow.rev161128.Devices;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.cardinal.openflow.rev161128.DevicesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.cardinal.openflow.rev161128.cardinalopenflowinfogrouping.Openflow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.cardinal.openflow.rev161128.cardinalopenflowinfogrouping.OpenflowBuilder;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.snmp4j.Snmp;
import org.snmp4j.agent.mo.MOAccessImpl;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.SMIConstants;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author Subodh Roy
 *
 */
// TODO: maintain closed state
@SuppressWarnings({ "deprecation", "unused" })
public class OpenflowDeviceManager implements DataChangeListener, AutoCloseable {
    private static final Logger LOG = LoggerFactory.getLogger(OpenflowDeviceManager.class);
    private static final InstanceIdentifier NODE_IID = InstanceIdentifier.builder(Nodes.class).child(Node.class)
            .build();
    private static final ScheduledExecutorService executorService = MoreExecutors
            .listeningDecorator(Executors.newScheduledThreadPool(1));
    private final DataBroker dataBroker;
    SnmpAgent agent;
    private ListenerRegistration dataChangeListenerRegistration;
    SnmpSet set = new SnmpSet();
    DevicesBuilder builder = new DevicesBuilder();
    OdlCardinalOpenflowInfoApi odlOpenflowApi = new OdlCardinalOpenflowInfoApi();
    String status = "NotConnected";
    String openFlowNode = null;
    String nodeprevious = "ovs";
    Integer nodeSize = 0;
    Integer updatedSize = 0;
    Integer removedPathssize = 0;
    final OID sysDescr = new OID(".1.3.6.1.2.1.1.1.0");
    final OID interfacesTable = new OID(".1.3.6.1.3.1.1.11.1");
    Map> featureListOid = new HashMap>();
    Map> featureListUpdated = new HashMap>();
    List featureList = new ArrayList();

    public OpenflowDeviceManager(DataBroker dataBroker, SnmpAgent sagent) {
        this.dataBroker = Preconditions.checkNotNull(dataBroker);
        odlOpenflowApi.setDataProvider(dataBroker);
        agent = sagent;
        dataChangeListenerRegistration = dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
                NODE_IID, this, AsyncDataBroker.DataChangeScope.BASE);
        if (dataChangeListenerRegistration != null) {
            LOG.info("Listener registered");
        } else {
            LOG.error("Failed to register onDataChanged Listener");
        }
    }

    @Override
    public void close() {
        if (dataChangeListenerRegistration != null) {
            LOG.info("closing onDataChanged listener registration");
            dataChangeListenerRegistration.close();
            dataChangeListenerRegistration = null;
        }
    }

    @Override
    public void onDataChanged(AsyncDataChangeEvent, DataObject> change) {
        LOG.info("data change event");
        handleDataCreated(change.getCreatedData());
        handleDataUpdated(change.getUpdatedData());
        handleDataRemoved(change.getRemovedPaths());
    }

    public String getNode(Set> Paths) {
        int index1 = Paths.toString().lastIndexOf("value=");
        int index2 = Paths.toString().lastIndexOf("]]]]}");
        String node1 = Paths.toString().substring(index1, index2);
        String[] nodevalues = node1.split("value=");
        String node = nodevalues[1];
        // for (String ovsNode : featureListUpdated.keySet()) {featureListOid
        for (String ovsNode : featureListOid.keySet()) {
            if (ovsNode.contains(node)) {
                node = ovsNode;
                featureList.add(node);
            }
        }
        return node;
    }

    private void handleDataRemoved(Set> removedPaths) {
        // TODO Auto-generated method stub
        Preconditions.checkNotNull(removedPaths);
        if (!removedPaths.isEmpty()) {
            removedPathssize++;
            LOG.info("Removed path is {}", removedPathssize);
            LOG.info("featureList size is {}", featureList.size());
            String node = getNode(removedPaths);
            // if (removedPathssize == featureList.size()) {
            final OID sysDescr = new OID(".1.3.6.1.2.1.1.1.0");
            final OID interfacesTable = new OID(".1.3.6.1.3.1.1.13.1");
            agent.stop();
            try {
                Thread.sleep(100);
                agent = new SnmpAgent("0.0.0.0/2003");
                agent.start();
            } catch (IOException | InterruptedException e) {
                // TODO Auto-generated catch block
                // e.printStackTrace();
                LOG.info("Exception in removed path");
            }
            agent.unregisterManagedObject(agent.getSnmpv2MIB());
            agent.registerManagedObject(MOScalarFactory.createReadOnly(sysDescr, "MySystemDescr"));
            MOTableBuilder builder = new MOTableBuilder(interfacesTable)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                    .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY);
            for (String ovsNode : featureList) {
                if (featureList.contains(ovsNode)) {
                    featureListOid.remove(ovsNode);
                    LOG.info("featureListOid size is {}", featureListOid.size());
                }
            }
            if (featureListOid.size() > 2) {
                for (String ovsNode : featureListOid.keySet()) {
                    List value = featureListOid.get(ovsNode);
                    builder.addRowValue(new OctetString(ovsNode)).addRowValue(new OctetString(value.get(0)))
                            .addRowValue(new OctetString(value.get(1))).addRowValue(new OctetString(value.get(2)))
                            .addRowValue(new OctetString(value.get(3))).addRowValue(new OctetString(value.get(4)))
                            .addRowValue(new OctetString(value.get(5)));
                }
                agent.registerManagedObject(builder.build());
                featureListUpdated = featureListOid;
                // nodeSize = featureListOid.size();
                updatedSize = featureListOid.size();
                nodeSize = 0;
                gettingTableOid();
                LOG.info("{} Node(s) removed", removedPaths.size());
            } else if (featureListOid.size() == 0) {
                int j = 11;
                for (int i = 0; i < 2; i++) {
                    try {
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".1.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".2.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".3.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".4.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".5.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".6.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".7.0", "");
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        // e.printStackTrace();
                    }
                    j++;
                }
                odlOpenflowApi.setValues(featureListOid);
                featureListUpdated = featureListOid;
                // nodeSize = featureListOid.size();
                updatedSize = featureListOid.size();
                nodeSize = 0;
            } else {
                int j = 11;
                for (String ovsNode : featureListOid.keySet()) {
                    List value = featureListOid.get(ovsNode);
                    try {
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".1.0", ovsNode);
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".2.0", value.get(0));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".3.0", value.get(1));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".4.0", value.get(2));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".5.0", value.get(3));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".6.0", " ");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".7.0", " ");
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        // e.printStackTrace();
                        LOG.info("Exception in deleting Openflow node");
                    }
                    j++;
                }
                odlOpenflowApi.setValues(featureListOid);
                featureListUpdated = featureListOid;
                // nodeSize = featureListOid.size();
                updatedSize = featureListOid.size();
                nodeSize = 0;
            }
            // }
        }
    }

    private void handleDataUpdated(Map, DataObject> updatedData) {
        Preconditions.checkNotNull(updatedData);
        LOG.info("handle Node(s) updated {}", updatedData);
        if (!updatedData.isEmpty()) {
            LOG.info("{} Node(s) updated", updatedData.size());
        }
    }

    private void handleDataCreated(Map, DataObject> createdData) {
        Preconditions.checkNotNull(createdData);
        if (!createdData.isEmpty()) {
            for (Map.Entry, DataObject> dataObjectEntry : createdData.entrySet()) {
                nodeSize = nodeSize + 1;
                LOG.info("Created nodeSize {}", nodeSize);
                @SuppressWarnings("unchecked")
                final InstanceIdentifier path = (InstanceIdentifier) dataObjectEntry.getKey();
                LOG.info("Created node {}", path.toString());
                // sleep 25ms and then re-read the Node information to give OF
                // a change to update with FlowCapable
                Future submit = executorService.schedule(new Callable() {
                    @Override
                    public Void call() throws Exception {
                        ReadOnlyTransaction readOnlyTransaction = dataBroker.newReadOnlyTransaction();
                        final CheckedFuture, ReadFailedException> readFuture = readOnlyTransaction
                                .read(LogicalDatastoreType.OPERATIONAL, path);
                        Futures.addCallback(readFuture, new FutureCallback>() {
                            @Override
                            public void onSuccess(Optional result) {
                                if (result.isPresent()) {
                                    identifyDevice(path, result.get());
                                } else {
                                    LOG.error("Read succeeded, node doesn't exist: {}", path);
                                }
                            }

                            @Override
                            public void onFailure(Throwable t) {
                                LOG.error("Failed to read Node: {}", path, t);
                            }
                        });
                        return null;
                    }
                }, 1000, TimeUnit.MILLISECONDS);
            }
        }
    }

    private void identifyDevice(final InstanceIdentifier path, Node node) {
        LOG.debug("Attempting to identify ", node.getId().toString());
        String hardware = null;
        String macaddress = null;
        String interfaceName = null;
        String manufacturer = null;
        String openFlowStats = " ";
        String openFlowMeterstats = " ";
        List nodeValues = new ArrayList();
        LOG.info("Read created node");
        FlowCapableNode flowCapableNode = node.getAugmentation(FlowCapableNode.class);
        // TODO: this needs to register for data change on hardware or something
        // because it's really still empty at this point
        List conn = node.getNodeConnector();
        openFlowNode = node.getId().getValue();
        NodeConnector nodeconn = conn.get(0);
        FlowCapableNodeConnector flowCapableNodeconn = nodeconn.getAugmentation(FlowCapableNodeConnector.class);
        if (flowCapableNodeconn != null) {
            NodeConnectorKey nodekey = nodeconn.getKey();
            NodeConnectorId nodekey1 = nodekey.getId();
            openFlowNode = nodekey1.getValue();
            interfaceName = flowCapableNodeconn.getName();
            macaddress = flowCapableNodeconn.getHardwareAddress().getValue();
            hardware = flowCapableNode.getHardware();
            manufacturer = flowCapableNode.getManufacturer();
            status = "Connected";
            try {
                nodeValues.add(interfaceName);
                nodeValues.add(macaddress);
                nodeValues.add(manufacturer);
                nodeValues.add(status);
                nodeValues.add(openFlowStats);
                nodeValues.add(openFlowMeterstats);
                /* to create map for the ovsnode and its values */
                if (openFlowNode != nodeprevious) {
                    featureListOid.put(openFlowNode, nodeValues);
                    updatedSize = updatedSize + 1;
                    nodeprevious = openFlowNode;
                }
                if (featureListOid.size() > 2) {
                    removedPathssize = 0;
                    featureList.clear();
                    featureListUpdated = featureListOid;
                    setOvsSwitchOid(featureListOid);
                    LOG.info("featureListOid size {}", featureListOid.size());
                    int j = 11;
                    for (int i = 0; i < 2; i++) {
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".1.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".2.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".3.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".4.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".5.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".6.0", "");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".7.0", "");
                        j++;
                    }

                } else {
                    int j = 11;
                    for (String ovsNode : featureListOid.keySet()) {
                        List value = featureListOid.get(ovsNode);
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".1.0", ovsNode);
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".2.0", value.get(0));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".3.0", value.get(1));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".4.0", value.get(2));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".5.0", value.get(3));
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".6.0", " ");
                        set.setVariableString(".1.3.6.1.3.1.1." + j + ".7.0", " ");
                        j++;
                    }
                    odlOpenflowApi.setValues(featureListOid);
                    removedPathssize = 0;
                    featureList.clear();
                    featureListUpdated = featureListOid;

                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                LOG.info("Exception in creating Openflownode {}", e);
            }
        }
    }

    public boolean setOvsSwitchOid(Map> ovsList) throws IOException {
        ovsList.entrySet().size();
        final OID sysDescr = new OID(".1.3.6.1.2.1.1.1.0");
        final OID interfacesTable = new OID(".1.3.6.1.3.1.1.11.1");
        agent.stop();
        agent = new SnmpAgent("0.0.0.0/2003");
        agent.start();
        agent.unregisterManagedObject(agent.getSnmpv2MIB());
        // Register a system description, use one from you product environment
        // to test with
        agent.registerManagedObject(MOScalarFactory.createReadOnly(sysDescr, "MySystemDescr"));
        MOTableBuilder builder = new MOTableBuilder(interfacesTable)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY)
                .addColumnType(SMIConstants.SYNTAX_OCTET_STRING, MOAccessImpl.ACCESS_READ_ONLY);
        for (String ovsNode : ovsList.keySet()) {
            List value = ovsList.get(ovsNode);
            builder.addRowValue(new OctetString(ovsNode)).addRowValue(new OctetString(value.get(0)))
                    .addRowValue(new OctetString(value.get(1))).addRowValue(new OctetString(value.get(2)))
                    .addRowValue(new OctetString(value.get(3))).addRowValue(new OctetString(value.get(4)))
                    .addRowValue(new OctetString(value.get(5)));
        }
        agent.registerManagedObject(builder.build());
        gettingTableOid();
        return true;
    }

    public void gettingTableOid() {
        OpenflowBuilder flow = new OpenflowBuilder();
        List openflowlist = new ArrayList();
        final OID interfacesTable = new OID(".1.3.6.1.3.1.1.11.1");
        SimpleSnmpClient client = new SimpleSnmpClient("udp:127.0.0.1/2003");
        List> tableContents = client
                .getTableAsStrings(new OID[] { new OID(interfacesTable.toString() + ".1"),
                        new OID(interfacesTable.toString() + ".2"), new OID(interfacesTable.toString() + ".3"),
                        new OID(interfacesTable.toString() + ".4"), new OID(interfacesTable.toString() + ".5") });
        LOG.info("openFlowNode Table :{}", tableContents);
        for (int i = 0; i < tableContents.size(); i++) {
            String openFlowNode = tableContents.get(i).get(0);
            String interfaceName = tableContents.get(i).get(1);
            String macaddress = tableContents.get(i).get(2);
            String manufacturer = tableContents.get(i).get(3);
            String status = tableContents.get(i).get(4);
            String openFlowStats = " ";
            String openFlowMeterstats = " ";
            flow.setNodeName(openFlowNode).setInterface(interfaceName).setMacAddress(macaddress)
                    .setManufacturer(manufacturer).setStatus(status).setFlowStats(openFlowStats)
                    .setMeterStats(openFlowMeterstats);
            openflowlist.add(flow.build());
        }
        builder.setOpenflow(openflowlist);
        builder.build();
        odlOpenflowApi.setOvsValues(builder.build());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy