/** * 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.camel.component.lumberjack.io; import java.util.concurrent.ThreadFactory; import javax.net.ssl.SSLContext; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; 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.NioServerSocketChannel; import io.netty.util.concurrent.DefaultEventExecutorGroup; import io.netty.util.concurrent.EventExecutorGroup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class defines the Lumberjack server that will receive Lumberjack messages */ public final class LumberjackServer { private static final Logger LOG = LoggerFactory.getLogger(LumberjackServer.class); private static final int WORKER_THREADS = 16; private final String host; private final int port; private final SSLContext sslContext; private final ThreadFactory threadFactory; private final LumberjackMessageProcessor messageProcessor; private EventExecutorGroup executorService; private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; private Channel channel; public LumberjackServer(String host, int port, SSLContext sslContext, ThreadFactory threadFactory, LumberjackMessageProcessor messageProcessor) { this.host = host; this.port = port; this.sslContext = sslContext; this.threadFactory = threadFactory; this.messageProcessor = messageProcessor; } /** * Starts the server. * * @throws InterruptedException when interrupting while connecting the socket */ public void start() throws InterruptedException { LOG.info("Starting the LUMBERJACK server (host={}, port={}).", host, port); // Create the group that will listen for incoming connections bossGroup = new NioEventLoopGroup(1); // Create the group that will process the connections workerGroup = new NioEventLoopGroup(WORKER_THREADS); // Create the executor service that will process the payloads without blocking netty threads executorService = new DefaultEventExecutorGroup(WORKER_THREADS, threadFactory); // Create the channel initializer ChannelHandler initializer = new LumberjackChannelInitializer(sslContext, executorService, messageProcessor); // Bootstrap the netty server ServerBootstrap serverBootstrap = new ServerBootstrap() // .group(bossGroup, workerGroup) // .channel(NioServerSocketChannel.class) // .option(ChannelOption.SO_BACKLOG, 100) // .childHandler(initializer); // // Connect the socket channel = serverBootstrap.bind(host, port).sync().channel(); LOG.info("LUMBERJACK server is started (host={}, port={}).", host, port); } /** * Stops the server. * * @throws InterruptedException when interrupting while stopping the socket */ public void stop() throws InterruptedException { LOG.info("Stopping the LUMBERJACK server (host={}, port={}).", host, port); try { // Wait for the channel to be indeed closed before shutting the groups & service channel.close().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); executorService.shutdownGracefully(); } LOG.info("LUMBERJACK server is stopped (host={}, port={}).", host, port); } }