org.opendaylight.usc.plugin.UscPluginUdp.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.usc.plugin.UscPluginUdp.java

Source

/*
 * Copyright (c) 2015 Huawei, 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.usc.plugin;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandler;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOutboundHandler;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.local.LocalAddress;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.net.InetSocketAddress;

import javax.net.ssl.SSLException;

import org.opendaylight.usc.manager.UscRouteBrokerService;
import org.opendaylight.usc.manager.api.UscConfigurationService;
import org.opendaylight.usc.manager.api.UscSecureService;
import org.opendaylight.usc.plugin.model.UscChannel.ChannelType;
import org.opendaylight.usc.plugin.model.UscDevice;
import org.opendaylight.usc.util.UscServiceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * UscPlugin implemented for UDP traffic.
 */
public class UscPluginUdp extends UscPlugin {

    private static final Logger log = LoggerFactory.getLogger(UscPluginUdp.class);

    private final UscSecureService secureService;
    private final UscConfigurationService configService;
    private final EventLoopGroup agentGroup = new NioEventLoopGroup();
    private final Bootstrap agentBootstrap = new Bootstrap();
    private Bootstrap directBootstrap = null;
    private EventLoopGroup directGroup = null;

    private final ChannelInboundHandlerAdapter callHomeHandler = new ChannelInboundHandlerAdapter() {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            final Channel ch = ctx.channel();
            final InetSocketAddress remoteAddress = ((DatagramPacket) msg).sender();
            // this is to deal with UDP channels which don't by default have
            // remote address
            if (ch.remoteAddress() == null) {
                ch.connect(remoteAddress);
            }
            addCallHomeConnection(remoteAddress, ch);
            super.channelRead(ctx, msg);
            ch.pipeline().remove(this);
        }
    };

    /**
     * Constructs a new UscPluginUdp
     */
    public UscPluginUdp() {
        super(new LocalAddress("usc-local-server-udp"));

        UscRouteBrokerService routeBroker = UscServiceUtils.getService(UscRouteBrokerService.class);
        if (routeBroker != null) {
            routeBroker.setConnetionManager(ChannelType.UDP, super.getConnectionManager());
            routeBroker.setConnetionManager(ChannelType.DTLS, super.getConnectionManager());
        } else {
            log.error("UscRouteBrokerService is not found, failed to set connection manager for all UDP Channel!");
        }

        configService = UscServiceUtils.getService(UscConfigurationService.class);
        secureService = UscServiceUtils.getService(UscSecureService.class);
        agentBootstrap.group(agentGroup);
        agentBootstrap.channel(NioDatagramChannel.class);
        agentBootstrap.handler(new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(final Channel ch) throws Exception {
                if (secureService == null) {
                    log.error("UscSecureService is not initialized!");
                    return;
                }
                ChannelPipeline p = ch.pipeline();
                ChannelHandler dtlsHandler = secureService.getUdpClientHandler(ch);
                initAgentPipeline(p, dtlsHandler);
            }
        });

        final Bootstrap callHomeServerUdpBootstrap = new Bootstrap();
        callHomeServerUdpBootstrap.group(agentGroup);
        callHomeServerUdpBootstrap.channel(NioDatagramChannel.class);
        callHomeServerUdpBootstrap.handler(new ChannelInitializer<NioDatagramChannel>() {

            @Override
            public void initChannel(final NioDatagramChannel ch) throws Exception {
                if (secureService == null) {
                    log.error("UscSecureService is not initialized!");
                    return;
                }
                ChannelPipeline p = ch.pipeline();

                // no remoteAddress yet until data received, so need a
                // handler
                // to add the channel
                p.addLast("callHomeHandler", callHomeHandler);

                p.addLast(new LoggingHandler(LogLevel.TRACE));

                ChannelHandler dtlsHandler = secureService.getUdpServerHandler(ch);
                initAgentPipeline(ch.pipeline(), dtlsHandler);

            }
        });
        if (configService == null) {
            log.error("UscConfigurationService is not initialized!");
            return;
        }
        int pluginPort = configService.getConfigIntValue(UscConfigurationService.USC_PLUGIN_PORT);
        final ChannelFuture callHomeChannelUdpFuture = callHomeServerUdpBootstrap.bind(pluginPort);
        log.debug("callHomeChannelUdpFuture : " + callHomeChannelUdpFuture);
        try {
            callHomeChannelUdpFuture.sync();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    protected ChannelOutboundHandler getFrameEncoder() {
        return UscFrameEncoderUdp.getInstance();
    }

    @Override
    protected ChannelInboundHandler getFrameDecoder() {
        return UscFrameDecoderUdp.getInstance();
    }

    @Override
    public void close() {
        super.close();
        agentGroup.shutdownGracefully();
        if (directGroup != null)
            directGroup.shutdownGracefully();
    }

    @Override
    protected Channel connectToAgent(UscDevice device) throws InterruptedException {
        if (configService == null) {
            log.error("UscConfigurationService is not initialized!");
            return null;
        }
        final int agentPort = configService.getConfigIntValue(UscConfigurationService.USC_AGENT_PORT);
        Channel channel = null;

        try {
            channel = agentBootstrap.connect(device.getInetAddress(), agentPort).sync().channel();
        } catch (InterruptedException e) {
            throw e;
        }

        return channel;
    }

    @Override
    protected Channel connectToDeviceDirectly(UscDevice device) throws Exception {
        Channel channel = null;

        if (directBootstrap == null) {
            directBootstrap = new Bootstrap();
            directGroup = new NioEventLoopGroup();

            directBootstrap.group(directGroup);
            directBootstrap.channel(NioDatagramChannel.class);
            directBootstrap.handler(new ChannelInitializer<Channel>() {
                @Override
                public void initChannel(final Channel ch) throws Exception {
                    if (secureService == null) {
                        log.error("UscSecureService is not initialized!");
                        return;
                    }
                    ChannelPipeline p = ch.pipeline();
                    ChannelHandler dtlsHandler = secureService.getUdpClientHandler(ch);
                    initDirectPipeline(p, dtlsHandler);
                }
            });
        }

        try {
            channel = directBootstrap.connect(device.getInetAddress(), device.getPort()).sync().channel();
        } catch (Exception e) {
            throw e;
        }

        return channel;
    }

    @Override
    protected ChannelType getChannelType() {
        return ChannelType.DTLS;
    }

    /**
     * Returns the security handler for server-side use. Currently this is DTLS.
     *
     * @param ch
     *            The physical channel that the traffic will be sent through.
     * @return The channel handler, or null if the security service was not
     *         properly initialized.
     * @throws SSLException
     */
    public static ChannelHandler getSecureServerHandler(Channel ch) throws SSLException {
        UscSecureService service = UscServiceUtils.getService(UscSecureService.class);
        if (service == null) {
            log.error("UscSecureService is not initialized!");
            return null;
        }
        return service.getUdpServerHandler(ch);
    }

    /**
     * Returns the security handler for client-side use. Currently this is DTLS.
     *
     * @param ch
     *            The physical channel that the traffic will be sent through.
     * @return The channel handler, or null if the security service was not
     *         properly initialized.
     * @throws SSLException
     */
    public static ChannelHandler getSecureClientHandler(Channel ch) throws SSLException {
        UscSecureService service = UscServiceUtils.getService(UscSecureService.class);
        if (service == null) {
            log.error("UscSecureService is not initialized!");
            return null;
        }
        return service.getUdpClientHandler(ch);
    }

}