2 * Copyright © 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.ovsdb.lib.impl;
10 import com.google.common.util.concurrent.ThreadFactoryBuilder;
11 import io.netty.bootstrap.Bootstrap;
12 import io.netty.bootstrap.ServerBootstrap;
13 import io.netty.channel.AdaptiveRecvByteBufAllocator;
14 import io.netty.channel.ChannelOption;
15 import io.netty.channel.EventLoopGroup;
16 import io.netty.channel.epoll.Epoll;
17 import io.netty.channel.epoll.EpollEventLoopGroup;
18 import io.netty.channel.epoll.EpollServerSocketChannel;
19 import io.netty.channel.epoll.EpollSocketChannel;
20 import io.netty.channel.nio.NioEventLoopGroup;
21 import io.netty.channel.socket.nio.NioServerSocketChannel;
22 import io.netty.channel.socket.nio.NioSocketChannel;
23 import java.util.concurrent.ThreadFactory;
24 import javax.annotation.PreDestroy;
25 import javax.inject.Inject;
26 import javax.inject.Singleton;
27 import org.osgi.service.component.annotations.Activate;
28 import org.osgi.service.component.annotations.Component;
29 import org.osgi.service.component.annotations.Deactivate;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * A globally-instantiated context for use with OvsdbConnectionService.
37 @Component(service = NettyBootstrapFactory.class)
38 public final class NettyBootstrapFactoryImpl implements NettyBootstrapFactory, AutoCloseable {
39 private abstract static class Provider {
41 * Return user friendly name, suitable for system operators.
43 * @return An admin-friendly name.
45 abstract String name();
47 abstract EventLoopGroup createGroup(ThreadFactory threadFactory);
49 abstract Bootstrap createBootstrap();
51 abstract ServerBootstrap createServerBootstrap();
54 private static final class EpollProvider extends Provider {
61 EventLoopGroup createGroup(final ThreadFactory threadFactory) {
62 return new EpollEventLoopGroup(0, threadFactory);
66 Bootstrap createBootstrap() {
67 return new Bootstrap()
68 .channel(EpollSocketChannel.class);
72 ServerBootstrap createServerBootstrap() {
73 return new ServerBootstrap()
74 .channel(EpollServerSocketChannel.class);
78 private static final class NioProvider extends Provider {
85 EventLoopGroup createGroup(final ThreadFactory threadFactory) {
86 return new NioEventLoopGroup(0, threadFactory);
90 Bootstrap createBootstrap() {
91 return new Bootstrap()
92 .channel(NioSocketChannel.class);
96 ServerBootstrap createServerBootstrap() {
97 return new ServerBootstrap()
98 .channel(NioServerSocketChannel.class);
102 private static final Logger LOG = LoggerFactory.getLogger(NettyBootstrapFactoryImpl.class);
104 // Minimum footprint runtime-constant
105 private static final Provider PROVIDER = Epoll.isAvailable() ? new EpollProvider() : new NioProvider();
107 private final EventLoopGroup bossGroup;
108 private final EventLoopGroup workerGroup;
112 public NettyBootstrapFactoryImpl() {
113 bossGroup = PROVIDER.createGroup(new ThreadFactoryBuilder().setNameFormat("OVSDB listener-%d").build());
114 workerGroup = PROVIDER.createGroup(new ThreadFactoryBuilder().setNameFormat("OVSDB connection-%d").build());
115 LOG.info("OVSDB global Netty context started with {}", PROVIDER.name());
121 public void close() {
122 LOG.info("OVSDB global Netty context terminating");
123 bossGroup.shutdownGracefully().addListener(ignore -> {
124 LOG.info("OVSDB global server group terminated");
126 workerGroup.shutdownGracefully().addListener(ignore -> {
127 LOG.info("OVSDB global channel group terminated");
132 public Bootstrap newClient() {
133 return PROVIDER.createBootstrap()
135 .option(ChannelOption.TCP_NODELAY, true)
136 .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(65535, 65535, 65535));
140 public ServerBootstrap newServer() {
141 return PROVIDER.createServerBootstrap()
142 .group(bossGroup, workerGroup)
143 .option(ChannelOption.TCP_NODELAY, true)
144 .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(65535, 65535, 65535))
145 .option(ChannelOption.SO_BACKLOG, 100);