/* * 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.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInboundHandler; 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.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; 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 TCP traffic. */ public class UscPluginTcp extends UscPlugin { private static final Logger log = LoggerFactory .getLogger(UscPluginTcp.class); private final UscSecureService secureService; private final UscConfigurationService configService; private final EventLoopGroup agentGroup = new NioEventLoopGroup(); private final Bootstrap agentBootstrap = new Bootstrap(); private EventLoopGroup directGroup = null; private Bootstrap directBootstrap = null; /** * Constructs a new UscPluginTcp */ public UscPluginTcp() { super(new LocalAddress("usc-local-server-tcp")); UscRouteBrokerService routeBroker = UscServiceUtils .getService(UscRouteBrokerService.class); if (routeBroker != null) { routeBroker.setConnetionManager(ChannelType.TCP, super.getConnectionManager()); routeBroker.setConnetionManager(ChannelType.TLS, super.getConnectionManager()); } else { log.error("UscRouteBrokerService is not found, failed to set connection manager for all TCP Channel!"); } configService = UscServiceUtils .getService(UscConfigurationService.class); secureService = UscServiceUtils.getService(UscSecureService.class); agentBootstrap.group(agentGroup); agentBootstrap.channel(NioSocketChannel.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(); initAgentPipeline(p, secureService.getTcpClientHandler(ch)); } }); final ServerBootstrap callHomeServerTcpBootstrap = new ServerBootstrap(); callHomeServerTcpBootstrap.group(agentGroup); callHomeServerTcpBootstrap.channel(NioServerSocketChannel.class); // callHomeServerTcpBootstrap.handler(new // LoggingHandler(LogLevel.TRACE)); callHomeServerTcpBootstrap .childHandler(new ChannelInitializer<NioSocketChannel>() { @Override public void initChannel(final NioSocketChannel channel) throws Exception { if (secureService == null) { log.error("UscSecureService is not initialized!"); return; } log.debug("Received call home TCP connection"); ChannelPipeline p = channel.pipeline(); addCallHomeConnection(channel.remoteAddress(), channel); initAgentPipeline(p, secureService.getTcpServerHandler(channel)); } }); if (configService == null) { log.error("UscConfigurationService is not initialized!"); return; } final ChannelFuture callHomeChannelTcpFuture = callHomeServerTcpBootstrap .bind(configService .getConfigIntValue(UscConfigurationService.USC_PLUGIN_PORT)); log.debug("callHomeChannelTcpFuture : " + callHomeChannelTcpFuture); } @Override protected ChannelOutboundHandler getFrameEncoder() { return UscFrameEncoderTcp.getInstance(); } @Override protected ChannelInboundHandler getFrameDecoder() { // UscFrameDecoderTcp is NOT Sharable return new UscFrameDecoderTcp(); } @Override public void close() { super.close(); agentGroup.shutdownGracefully(); if (directGroup != null) directGroup.shutdownGracefully(); } @Override protected Channel connectToAgent(UscDevice device) throws Exception { 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 (Exception 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(NioSocketChannel.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(); initDirectPipeline(p, secureService.getTcpClientHandler(ch)); } }); } try { channel = directBootstrap .connect(device.getInetAddress(), device.getPort()).sync() .channel(); } catch (Exception e) { throw e; } return channel; } @Override protected ChannelType getChannelType() { return ChannelType.TLS; } /** * Returns the security handler for server-side use. Currently this is TLS. * * @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.getTcpServerHandler(ch); } /** * Returns the security handler for client-side use. Currently this is TLS. * * @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.getTcpClientHandler(ch); } }