org.apache.pulsar.io.netty.server.NettyServer Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.pulsar.io.netty.server;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.io.netty.NettySource;
import org.apache.pulsar.io.netty.http.NettyHttpChannelInitializer;
import org.apache.pulsar.io.netty.http.NettyHttpServerHandler;
import org.apache.pulsar.io.netty.tcp.NettyTCPChannelInitializer;
import org.apache.pulsar.io.netty.tcp.NettyTCPServerHandler;
import org.apache.pulsar.io.netty.udp.NettyUDPChannelInitializer;
import org.apache.pulsar.io.netty.udp.NettyUDPServerHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Netty Server to accept incoming data via the configured type.
*/
public class NettyServer {
private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);
private Type type;
private String host;
private int port;
private NettySource nettySource;
private int numberOfThreads;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private NettyServer(Builder builder) {
this.type = builder.type;
this.host = builder.host;
this.port = builder.port;
this.nettySource = builder.nettySource;
this.numberOfThreads = builder.numberOfThreads;
}
public void run() {
try {
switch (type) {
case UDP:
runUdp();
break;
case HTTP:
runHttp();
break;
case TCP:
default:
runTcp();
break;
}
} catch (Exception ex) {
logger.error("Error occurred when Netty Server is running", ex);
} finally {
shutdownGracefully();
}
}
public void shutdownGracefully() {
if (workerGroup != null) {
workerGroup.shutdownGracefully();
}
if (bossGroup != null) {
bossGroup.shutdownGracefully();
}
}
private void runUdp() throws InterruptedException {
workerGroup = new NioEventLoopGroup(this.numberOfThreads);
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(workerGroup);
bootstrap.channel(NioDatagramChannel.class);
bootstrap.handler(new NettyUDPChannelInitializer(new NettyUDPServerHandler(this.nettySource)))
.option(ChannelOption.SO_BACKLOG, 1024);
ChannelFuture channelFuture = bootstrap.bind(this.host, this.port).sync();
channelFuture.channel().closeFuture().sync();
}
private void runTcp() throws InterruptedException {
ServerBootstrap serverBootstrap = getServerBootstrap(
new NettyTCPChannelInitializer(new NettyTCPServerHandler(this.nettySource)));
ChannelFuture channelFuture = serverBootstrap.bind(this.host, this.port).sync();
channelFuture.channel().closeFuture().sync();
}
private void runHttp() throws InterruptedException {
ServerBootstrap serverBootstrap = getServerBootstrap(
new NettyHttpChannelInitializer(new NettyHttpServerHandler(this.nettySource), null));
ChannelFuture channelFuture = serverBootstrap.bind(this.host, this.port).sync();
channelFuture.channel().closeFuture().sync();
}
private ServerBootstrap getServerBootstrap(ChannelHandler childHandler) {
bossGroup = new NioEventLoopGroup(this.numberOfThreads);
workerGroup = new NioEventLoopGroup(this.numberOfThreads);
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.childHandler(childHandler)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.SO_KEEPALIVE, true);
return serverBootstrap;
}
/**
* Pulsar Netty Server Builder.
*/
public static class Builder {
private Type type;
private String host;
private int port;
private NettySource nettySource;
private int numberOfThreads;
public Builder setType(Type type) {
this.type = type;
return this;
}
public Builder setHost(String host) {
this.host = host;
return this;
}
public Builder setPort(int port) {
this.port = port;
return this;
}
public Builder setNettySource(NettySource nettySource) {
this.nettySource = nettySource;
return this;
}
public Builder setNumberOfThreads(int numberOfThreads) {
this.numberOfThreads = numberOfThreads;
return this;
}
public NettyServer build() {
checkNotNull(this.type, "type cannot be blank/null");
checkArgument(StringUtils.isNotBlank(host), "host cannot be blank/null");
checkArgument(this.port >= 1024, "port must be set equal or bigger than 1024");
checkNotNull(this.nettySource, "nettySource must be set");
checkArgument(this.numberOfThreads > 0,
"numberOfThreads must be set as positive");
return new NettyServer(this);
}
}
/**
* Network protocol.
*/
public enum Type {
TCP,
UDP,
HTTP
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy