org.opendaylight.openflowplugin.pyretic.Utils.OutputUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.openflowplugin.pyretic.Utils.OutputUtils.java

Source

/**
 * Copyright (c) 2014, NetIDE Consortium (Create-Net (CN), Telefonica Investigacion Y Desarrollo SA (TID), Fujitsu 
 * Technology Solutions GmbH (FTS), Thales Communications & Security SAS (THALES), Fundacion Imdea Networks (IMDEA),
 * Universitaet Paderborn (UPB), Intel Research & Innovation Ireland Ltd (IRIIL) )
 *
 * 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
 *
 * Authors:
 *     Telefonica I+D
 */
/**
 * Copyright (c) 2013 Cisco Systems, Inc. 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.openflowplugin.pyretic.Utils;

import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import java.math.BigInteger;
import java.util.ArrayList;
import org.apache.commons.lang3.ArrayUtils;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
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.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInputBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;

import java.util.List;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;

/**
 * Created by Jennifer Hernndez Bcares on 11/12/14.
 */
public class OutputUtils {

    private OutputUtils() {
        throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
    }

    public static String makePingFlowForNode(final String nodeId, final ProviderContext pc) {
        NodeBuilder nodeBuilder = createNodeBuilder(nodeId);
        FlowBuilder flowBuilder = createFlowBuilder(1235, null, "ping");
        DataBroker dataBroker = pc.<DataBroker>getSALService(DataBroker.class);
        ReadWriteTransaction modif = dataBroker.newReadWriteTransaction();
        InstanceIdentifier<Flow> path = InstanceIdentifier.<Nodes>builder(Nodes.class)
                .<Node, NodeKey>child(Node.class, nodeBuilder.getKey())
                .<FlowCapableNode>augmentation(FlowCapableNode.class)
                .<Table, TableKey>child(Table.class, new TableKey(flowBuilder.getTableId()))
                .<Flow, FlowKey>child(Flow.class, flowBuilder.getKey()).build();
        modif.put(LogicalDatastoreType.CONFIGURATION, path, flowBuilder.build());
        CheckedFuture<Void, TransactionCommitFailedException> commitFuture = modif.submit();
        final StringBuffer aggregator = new StringBuffer();
        Futures.addCallback(commitFuture, new FutureCallback<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                aggregator.append("Status of Flow Data Loaded Transaction: succes ");
            }

            @Override
            public void onFailure(Throwable throwable) {
                aggregator.append(throwable.getClass().getName());
            }
        });
        return aggregator.toString();
    }

    public static NodeRef createNodeRef(final String nodeId) {
        NodeKey key = new NodeKey(new NodeId(nodeId));
        InstanceIdentifier<Node> path = InstanceIdentifier.<Nodes>builder(Nodes.class)
                .<Node, NodeKey>child(Node.class, key).toInstance();
        return new NodeRef(path);
    }

    public static NodeConnectorRef createNodeConnRef(final String nodeId, final String port) {
        StringBuilder sBuild = new StringBuilder(nodeId).append(':').append(port);
        NodeConnectorId _nodeConnectorId = new NodeConnectorId(sBuild.toString());
        NodeConnectorKey nConKey = new NodeConnectorKey(new NodeConnectorId(sBuild.toString()));
        InstanceIdentifier<NodeConnector> path = InstanceIdentifier.<Nodes>builder(Nodes.class)
                .<Node, NodeKey>child(Node.class, new NodeKey(new NodeId(nodeId)))
                .<NodeConnector, NodeConnectorKey>child(NodeConnector.class, nConKey).toInstance();
        return new NodeConnectorRef(path);
    }

    private static NodeBuilder createNodeBuilder(final String nodeId) {
        NodeBuilder builder = new NodeBuilder();
        builder.setId(new NodeId(nodeId));
        builder.setKey(new NodeKey(builder.getId()));
        return builder;
    }

    private static FlowBuilder createFlowBuilder(final long flowId, final String tableId, final String flowName) {
        FlowBuilder fBuild = new FlowBuilder();
        fBuild.setMatch(new MatchBuilder().build());
        fBuild.setInstructions(createPingInstructionsBuilder().build());
        FlowKey key = new FlowKey(new FlowId(Long.toString(flowId)));
        fBuild.setBarrier(false);
        // flow.setBufferId(new Long(12));
        final BigInteger value = BigInteger.valueOf(10);
        fBuild.setCookie(new FlowCookie(value));
        fBuild.setCookieMask(new FlowCookie(value));
        fBuild.setHardTimeout(0);
        fBuild.setIdleTimeout(0);
        fBuild.setInstallHw(false);
        fBuild.setStrict(false);
        fBuild.setContainerName(null);
        fBuild.setFlags(new FlowModFlags(false, false, false, false, false));
        fBuild.setId(new FlowId("12"));
        fBuild.setTableId(checkTableId(tableId));
        fBuild.setOutGroup(2L);
        fBuild.setOutPort(value);
        fBuild.setKey(key);
        fBuild.setPriority(2);
        fBuild.setFlowName(flowName);
        return fBuild;
    }

    private static InstructionsBuilder createPingInstructionsBuilder() {
        ArrayList<Action> aList = new ArrayList<Action>();
        ActionBuilder aBuild = new ActionBuilder();
        OutputActionBuilder output = new OutputActionBuilder();
        output.setMaxLength(56);
        output.setOutputNodeConnector(new Uri("CONTROLLER"));
        aBuild.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
        aBuild.setOrder(0);
        aBuild.setKey(new ActionKey(0));
        aList.add(aBuild.build());
        ApplyActionsBuilder asBuild = new ApplyActionsBuilder();
        asBuild.setAction(aList);
        InstructionBuilder iBuild = new InstructionBuilder();
        iBuild.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(asBuild.build()).build());
        iBuild.setOrder(0);
        iBuild.setKey(new InstructionKey(0));
        ArrayList<Instruction> instr = new ArrayList<Instruction>();
        instr.add(iBuild.build());
        return new InstructionsBuilder().setInstruction(instr);
    }

    private static short checkTableId(final String tableId) {
        try {
            return Short.parseShort(tableId);
        } catch (Exception ex) {
            return 2;
        }
    }

    /**
     * @param nodeId
     * @param payload
     * @param outPort
     * @param inPort
     * @return
     * */
    public synchronized static TransmitPacketInput createPacketOut(final String nodeId, final byte[] payload,
            final String outPort, final String inPort) {
        ArrayList<Byte> list = new ArrayList<Byte>(40);

        // FIXME payload should be added to packet
        for (byte b : payload) {
            list.add(b);
        }
        /*
        System.out.print("My super duper payload: ");
        for (int i = 0; i < list.size(); i++) System.out.printf("%02x ",0xff & list.get(i));
        System.out.println("");
        */

        NodeRef ref = createNodeRef(nodeId);
        NodeConnectorRef nEgressConfRef = new NodeConnectorRef(createNodeConnRef(nodeId, outPort));
        NodeConnectorRef nIngressConRef = new NodeConnectorRef(createNodeConnRef(nodeId, inPort));
        TransmitPacketInputBuilder tPackBuilder = new TransmitPacketInputBuilder();
        final ArrayList<Byte> _converted_list = list;
        byte[] _primitive = ArrayUtils.toPrimitive(_converted_list.toArray(new Byte[0]));

        List<Action> actionList = new ArrayList<Action>();
        ActionBuilder ab = new ActionBuilder();
        OutputActionBuilder output = new OutputActionBuilder();
        output.setMaxLength(Integer.valueOf(0xffff));
        Uri value = new Uri(OutputPortValues.NORMAL.toString());
        output.setOutputNodeConnector(value);
        ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
        ab.setOrder(0);
        ab.setKey(new ActionKey(0));
        actionList.add(ab.build());

        tPackBuilder.setConnectionCookie(null);
        tPackBuilder.setAction(actionList);
        tPackBuilder.setPayload(_primitive);
        tPackBuilder.setNode(ref);
        tPackBuilder.setEgress(nEgressConfRef);
        tPackBuilder.setIngress(nIngressConRef);
        tPackBuilder.setBufferId(Long.valueOf(0xffffffffL));

        return tPackBuilder.build();
    }

    /**
     * Receives a string with nibbles and creates an array of bytes
     * @param hexString
     * @return
     */
    public static final byte[] toByteArray(String hexString) {
        int arrLength = hexString.length() >> 1;
        byte buf[] = new byte[arrLength];

        for (int ii = 0; ii < arrLength; ii++) {
            int index = ii << 1;

            String l_digit = hexString.substring(index, index + 2);
            buf[ii] = (byte) Integer.parseInt(l_digit, 16);
        }

        return buf;
    }

    public static final String fromDecimalToHex(Long num) {
        int rem;

        // For storing result
        String str = "";

        // Digits in hexadecimal number system
        char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

        while (num > 0) {
            rem = Integer.parseInt(num.toString()) % 16;
            str = hex[rem] + str;
            num = num / 16;
        }
        while (str.length() < 2)
            str = "0" + str;
        return str;
    }
}