/*
* Copyright 2014-2016 CyberVision, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kaaproject.kaa.server.common.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* <p>NettyHttpServer Class. Used to start Netty server. Config is used to handle
* netty server configuration. Usage: netty = new NettyHttpServer(conf);
* netty.init(); netty.start();</p>
*
* <p>To stop Netty: netty.shutdown();</p>
*
* @author Yaroslav Zeygerman
*/
public abstract class AbstractNettyServer extends Thread {
public static final AttributeKey<UUID> UUID_KEY = AttributeKey.valueOf("UUID");
private static final Logger LOG = LoggerFactory.getLogger(AbstractNettyServer.class);
private final String bindAddress;
private final int bindPort;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private ServerBootstrap btsServer;
private Channel bindChannel;
/**
* NettyHttpServer constructor.
*
* @param bindAddress bind address
* @param port bind port
*/
public AbstractNettyServer(String bindAddress, int port) {
this.bindAddress = bindAddress;
this.bindPort = port;
}
protected abstract ChannelInitializer<SocketChannel> configureInitializer() throws Exception;
/**
* Netty HTTP server initialization.
*/
public void init() {
try {
LOG.info("NettyServer Initializing...");
bossGroup = new NioEventLoopGroup();
LOG.debug("NettyServer bossGroup created");
workerGroup = new NioEventLoopGroup();
LOG.debug("NettyServer workGroup created");
btsServer = new ServerBootstrap();
LOG.debug("NettyServer ServerBootstrap created");
ChannelInitializer<SocketChannel> serverInit = configureInitializer();
LOG.debug("NettyServer InitClass instance created");
LOG.debug("NettyServer InitClass instance init()");
btsServer.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(serverInit)
.option(ChannelOption.SO_REUSEADDR, true);
LOG.debug("NettyServer ServerBootstrap group initialized");
bindChannel = btsServer.bind(bindAddress, bindPort).sync().channel();
} catch (Exception exception) {
LOG.error("NettyHttpServer init() failed", exception);
}
}
@Override
public void run() {
LOG.info("NettyHttpServer starting...");
try {
bindChannel.closeFuture().sync();
} catch (InterruptedException exption) {
LOG.error("NettyHttpServer error", exption);
} finally {
shutdown();
LOG.info("NettyHttpServer shut down");
}
}
/**
* Netty HTTP server shutdown.
*/
public void shutdown() {
LOG.info("NettyHttpServer stopping...");
if (bossGroup != null) {
try {
Future<? extends Object> future = bossGroup.shutdownGracefully(
250, 1000, TimeUnit.MILLISECONDS);
future.await();
} catch (InterruptedException exception) {
LOG.trace("NettyHttpServer stopping: bossGroup error", exception);
} finally {
bossGroup = null;
LOG.trace("NettyHttpServer stopping: bossGroup stoped");
}
}
if (workerGroup != null) {
try {
Future<? extends Object> future = workerGroup.shutdownGracefully(
250, 1000, TimeUnit.MILLISECONDS);
future.await();
} catch (InterruptedException exception) {
LOG.trace("NettyHttpServer stopping: workerGroup error", exception);
} finally {
workerGroup = null;
LOG.trace("NettyHttpServer stopping: workerGroup stopped");
}
}
}
}