org.opendaylight.netide.shim.ShimRelay.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.netide.shim.ShimRelay.java

Source

/*
 * Copyright (c) 2015 NetIDE Consortium 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.netide.shim;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.JdkFutureAdapters;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.UnpooledByteBufAllocator;
import java.util.concurrent.Future;
import org.opendaylight.netide.netiplib.Message;
import org.opendaylight.netide.netiplib.MessageType;
import org.opendaylight.netide.netiplib.NetIPUtils;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory;
import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl;
import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory;
import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author giuseppex.petralia@intel.com
 *
 */
public class ShimRelay {
    private static final Logger LOG = LoggerFactory.getLogger(ShimRelay.class);

    public SerializationFactory createSerializationFactory() {
        return new SerializationFactory();
    }

    public DeserializationFactory createDeserializationFactory() {
        return new DeserializationFactory();
    }

    public void sendOpenFlowMessageToCore(ZeroMQBaseConnector coreConnector, DataObject msg, short ofVersion,
            long xId, long datapathId, int moduleId) {

        SerializationFactory factory = createSerializationFactory();
        SerializerRegistry registry = new SerializerRegistryImpl();
        registry.init();
        ByteBuf output = UnpooledByteBufAllocator.DEFAULT.buffer();
        factory.setSerializerTable(registry);
        factory.messageToBuffer(ofVersion, output, msg);
        byte[] bytes = new byte[output.readableBytes()];
        output.readBytes(bytes);
        Message message = new Message(NetIPUtils.StubHeaderFromPayload(bytes), bytes);
        message.getHeader().setMessageType(MessageType.OPENFLOW);
        message.getHeader().setDatapathId(datapathId);
        message.getHeader().setModuleId(moduleId);
        message.getHeader().setTransactionId((int) xId);
        coreConnector.SendData(message.toByteRepresentation());
    }

    public void sendToSwitch(ConnectionAdapter connectionAdapter, ByteBuf input, short ofVersion,
            ZeroMQBaseConnector coreConnector, long datapathId, int moduleId) {

        DeserializationFactory factory = createDeserializationFactory();
        DeserializerRegistry registry = new DeserializerRegistryImpl();
        registry.init();
        factory.setRegistry(registry);
        DataObject msg = factory.deserialize(input, ofVersion);
        sendDataObjectToSwitch(connectionAdapter, msg, ofVersion, coreConnector, datapathId, moduleId);
    }

    public void sendDataObjectToSwitch(ConnectionAdapter connectionAdapter, DataObject msg, short ofVersion,
            ZeroMQBaseConnector coreConnector, long datapathId, int moduleId) {

        if (getImplementedInterface(msg).equals(BarrierInput.class.getName())) {
            Future<RpcResult<BarrierOutput>> reply = connectionAdapter.barrier((BarrierInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((BarrierInput) msg).getXid(), datapathId,
                    moduleId);

        } else if (getImplementedInterface(msg).equals(EchoInput.class.getName())) {

            Future<RpcResult<EchoOutput>> reply = connectionAdapter.echo((EchoInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((EchoInput) msg).getXid(), datapathId, moduleId);

        } else if (getImplementedInterface(msg).equals(EchoRequestMessage.class.getName())) {
            EchoInputBuilder builder = new EchoInputBuilder();
            EchoRequestMessage echoRequestMessage = (EchoRequestMessage) msg;
            if (echoRequestMessage.getData() != null)
                builder.setData(echoRequestMessage.getData());
            builder.setVersion(echoRequestMessage.getVersion());
            builder.setXid(echoRequestMessage.getXid());
            Future<RpcResult<EchoOutput>> reply = connectionAdapter.echo(builder.build());
            sendResponseToCore(reply, coreConnector, ofVersion, echoRequestMessage.getXid(), datapathId, moduleId);

        } else if (getImplementedInterface(msg).equals(EchoOutput.class.getName())) {

            EchoReplyInputBuilder builder = new EchoReplyInputBuilder();
            builder.setVersion(((EchoOutput) msg).getVersion());
            builder.setXid(((EchoOutput) msg).getXid());
            builder.setData(((EchoOutput) msg).getData());
            connectionAdapter.echoReply(builder.build());

        } else if (getImplementedInterface(msg).equals(ExperimenterInput.class.getName())) {

            connectionAdapter.experimenter((ExperimenterInput) msg);

        } else if (getImplementedInterface(msg).equals(FlowModInput.class.getName())) {

            connectionAdapter.flowMod((FlowModInput) msg);

        } else if (getImplementedInterface(msg).equals(GetAsyncInput.class.getName())) {

            Future<RpcResult<GetAsyncOutput>> reply = connectionAdapter.getAsync((GetAsyncInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((GetAsyncInput) msg).getXid(), datapathId,
                    moduleId);

        } else if (getImplementedInterface(msg).equals(GetConfigInput.class.getName())) {

            Future<RpcResult<GetConfigOutput>> reply = connectionAdapter.getConfig((GetConfigInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((GetConfigInput) msg).getXid(), datapathId,
                    moduleId);

        } else if (getImplementedInterface(msg).equals(GetFeaturesInput.class.getName())) {

            Future<RpcResult<GetFeaturesOutput>> reply = connectionAdapter.getFeatures((GetFeaturesInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((GetFeaturesInput) msg).getXid(), datapathId,
                    moduleId);

        } else if (getImplementedInterface(msg).equals(GetQueueConfigInput.class.getName())) {

            Future<RpcResult<GetQueueConfigOutput>> reply = connectionAdapter
                    .getQueueConfig((GetQueueConfigInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((GetQueueConfigInput) msg).getXid(), datapathId,
                    moduleId);

        } else if (getImplementedInterface(msg).equals(GroupModInput.class.getName())) {

            connectionAdapter.groupMod((GroupModInput) msg);

        } else if (getImplementedInterface(msg).equals(HelloInput.class.getName())) {

            connectionAdapter.hello((HelloInput) msg);

        } else if (getImplementedInterface(msg).equals(MeterModInput.class.getName())) {

            connectionAdapter.meterMod((MeterModInput) msg);

        } else if (getImplementedInterface(msg).equals(MultipartRequestInput.class.getName())) {

            connectionAdapter.multipartRequest((MultipartRequestInput) msg);

        } else if (getImplementedInterface(msg).equals(PacketOutInput.class.getName())) {

            connectionAdapter.packetOut((PacketOutInput) msg);

        } else if (getImplementedInterface(msg).equals(PortModInput.class.getName())) {

            connectionAdapter.portMod((PortModInput) msg);

        } else if (getImplementedInterface(msg).equals(SetAsyncInput.class.getName())) {

            connectionAdapter.setAsync((SetAsyncInput) msg);

        } else if (getImplementedInterface(msg).equals(SetConfigInput.class.getName())) {

            connectionAdapter.setConfig((SetConfigInput) msg);

        } else if (getImplementedInterface(msg).equals(TableModInput.class.getName())) {
            connectionAdapter.tableMod((TableModInput) msg);

        } else if (getImplementedInterface(msg).equals(RoleRequestInput.class.getName())) {
            Future<RpcResult<RoleRequestOutput>> reply = connectionAdapter.roleRequest((RoleRequestInput) msg);
            sendResponseToCore(reply, coreConnector, ofVersion, ((RoleRequestInput) msg).getXid(), datapathId,
                    moduleId);
        } else {
            LOG.info("SHIM RELAY: Dataobject not recognized " + getImplementedInterface(msg));
        }

    }

    public String getImplementedInterface(DataObject message) {
        return message.getImplementedInterface().getName();
    }

    public <E extends DataObject> void sendResponseToCore(Future<RpcResult<E>> switchReply,
            final ZeroMQBaseConnector coreConnector, final short ofVersion, final long xId, final long datapathId,
            final int moduleId) {

        Futures.addCallback(JdkFutureAdapters.listenInPoolThread(switchReply), new FutureCallback<RpcResult<E>>() {
            @Override
            public void onSuccess(RpcResult<E> rpcReply) {
                if (rpcReply.isSuccessful()) {
                    E result = rpcReply.getResult();

                    sendOpenFlowMessageToCore(coreConnector, result, ofVersion, xId, datapathId, moduleId);
                } else {
                    for (RpcError rpcError : rpcReply.getErrors()) {
                        LOG.info("SHIM RELAY: error in communication with switch: {}", rpcError.getMessage());
                    }
                }
            }

            @Override
            public void onFailure(Throwable t) {
                LOG.info("SHIM RELAY: failure on communication with switch");
            }
        });
    }
}