
oracle.kv.util.http.HttpServer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of oracle-nosql-server Show documentation
Show all versions of oracle-nosql-server Show documentation
NoSQL Database Server - supplies build and runtime support for the server (store) side of the Oracle NoSQL Database.
The newest version!
/*-
* Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle NoSQL
* Database made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle NoSQL Database for a copy of the license and
* additional information.
*/
package oracle.kv.util.http;
import java.net.InetSocketAddress;
import oracle.kv.impl.util.sklogger.SkLogger;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ssl.SslContext;
/**
* Netty HTTP server. Initialization process:
*
* 1. create event loops for handling both accepting connections and data
* 2. bootstrap a server, setting the event loop groups, socket options, and
* a ChannelInitializer instance to initialize newly-created channels.
* 3. the ChannelInitializer is responsible for setting up the pipeline for
* handling data input on the channel. The pipeline includes an instance of
* ChannelInboundHandlerAdapter (HttpServerHandler in this case) configured to
* handle data and respond.
*
* An instance of RequestHandler must be implemented by the user of this
* class. That interface is used to handle all requests on this server instance.
*/
public class HttpServer {
static final int DEFAULT_NUM_ACCEPT_THREADS = 2;
static final int DEFAULT_NUM_WORKER_THREADS = 6;
static final int DEFAULT_MAX_REQUEST_SIZE = 4 * 1024 * 1024; // 4MB
static final int DEFAULT_MAX_CHUNK_SIZE = 65536;
static final int DEFAULT_IDLE_READ_TIMEOUT = 0;
private final Channel channel;
private final Channel httpsChannel;
private final HttpServerHandler handler;
/* hard-wired for now */
private final int maxRequestSize;
private final int maxChunkSize;
/* How many seconds before an idle channel read to timeout */
private final int idleReadTimeout;
/*
* bossGroup accepts incoming connections. The workerGroup handles data
* requests on established connections. The parameter is number of
* threads used in the event loop group.
*/
private final EventLoopGroup bossGroup;
private final EventLoopGroup workerGroup;
private final SkLogger logger;
public HttpServer(int httpPort,
int httpsPort,
int numAcceptThreads,
int numWorkerThreads,
RequestHandler requestHandler,
SslContext ctx,
SkLogger logger) throws InterruptedException {
this(null /* default to localhost */, httpPort, httpsPort,
numAcceptThreads, numWorkerThreads, 0 /* maxRequestSize */,
0 /* maxChunkSize */, 0 /* readIdleTimeout */,
requestHandler, ctx, logger);
}
public HttpServer(String httpHost,
int httpPort,
int httpsPort,
int numAcceptThreads,
int numWorkerThreads,
int maxRequestSize,
int maxChunkSize,
int idleReadTimeout,
RequestHandler requestHandler,
SslContext ctx,
SkLogger logger) throws InterruptedException {
this.logger = logger;
numAcceptThreads =
(numAcceptThreads == 0 ?
DEFAULT_NUM_ACCEPT_THREADS : numAcceptThreads);
numWorkerThreads =
(numWorkerThreads == 0 ?
DEFAULT_NUM_WORKER_THREADS : numWorkerThreads);
this.maxRequestSize =
(maxRequestSize == 0 ?
DEFAULT_MAX_REQUEST_SIZE : maxRequestSize);
this.maxChunkSize =
(maxChunkSize == 0 ?
DEFAULT_MAX_CHUNK_SIZE : maxChunkSize);
this.idleReadTimeout =
(idleReadTimeout == 0 ?
DEFAULT_IDLE_READ_TIMEOUT : idleReadTimeout);
bossGroup = new NioEventLoopGroup(numAcceptThreads);
workerGroup = new NioEventLoopGroup(numWorkerThreads);
handler = new HttpServerHandler(requestHandler, logger);
/*
* http and https are different channels that share workers and event
* loops
*/
channel =
(httpPort != 0 ? createChannel(httpHost, httpPort, null) : null);
if (httpsPort != 0 && ctx != null) {
httpsChannel = createChannel(httpHost, httpsPort, ctx);
} else {
httpsChannel = null;
}
}
/**
* Shared code for creating channels based on http vs https
*/
private Channel createChannel(String host, int port, SslContext sslCtx)
throws InterruptedException {
ServerBootstrap sb = new ServerBootstrap();
sb.group(bossGroup, workerGroup)
/* use a new NioServerSocketChannel instance for new channels */
.channel(NioServerSocketChannel.class)
/* use HttpServerInitializer to init new channels */
.childHandler(new HttpServerInitializer(handler,
this,
sslCtx,
logger))
/* set some socket options */
.option(ChannelOption.SO_BACKLOG, 1024)
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_KEEPALIVE, true);
/*
* Bind to specific host name
*/
if (host != null) {
return sb.bind(new InetSocketAddress(host, port)).sync().channel();
}
/* Bind and start to accept incoming connections */
return sb.bind(port).sync().channel();
}
int getMaxRequestSize() {
return maxRequestSize;
}
int getMaxChunkSize() {
return maxChunkSize;
}
int getIdleReadTimeout() {
return idleReadTimeout;
}
/**
* Wait for shutdown
*/
public HttpServer waitForShutdown() throws InterruptedException {
if (channel != null) {
channel.closeFuture().await();
}
if (httpsChannel != null) {
httpsChannel.closeFuture().await();
}
return this;
}
/**
* Cleanly shut down the server and threads.
*/
public HttpServer shutdown() throws InterruptedException {
if (channel != null) {
channel.close();
}
if (httpsChannel != null) {
httpsChannel.close();
}
logger.info("Shutting down HttpServer");
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
waitForShutdown();
return this;
}
/**
* Return HTTP server's SkLogger
*/
public SkLogger getLogger() {
return logger;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy