2 * Copyright (c) 2022 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.netconf.transport.tcp;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.util.concurrent.ThreadFactoryBuilder;
13 import io.netty.bootstrap.Bootstrap;
14 import io.netty.bootstrap.ServerBootstrap;
15 import io.netty.channel.EventLoopGroup;
16 import io.netty.channel.epoll.Epoll;
17 import io.netty.channel.socket.ServerSocketChannel;
18 import io.netty.channel.socket.SocketChannel;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.common.rev231228.tcp.common.grouping.Keepalives;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
27 * Utility class providing indirection between various Netty transport implementations. An implementation is chosen
28 * based on run-time characteristics -- either {@code epoll(2)}-based or {@code java.nio}-based one.
31 public final class NettyTransportSupport {
32 private static final Logger LOG = LoggerFactory.getLogger(NettyTransportSupport.class);
33 private static final AbstractNettyImpl IMPL = Epoll.isAvailable() ? new EpollNettyImpl() : NioNettyImpl.INSTANCE;
36 LOG.info("Netty transport backed by {}", IMPL);
39 private NettyTransportSupport() {
44 * Return a new {@link Bootstrap} instance. The bootstrap has its {@link Bootstrap#channel(Class)} already
45 * initialized to the backing implementation's {@link SocketChannel} class.
47 * @return A new Bootstrap
49 public static Bootstrap newBootstrap() {
50 return new Bootstrap().channel(IMPL.channelClass());
54 * Return a new {@link Bootstrap} instance. The bootstrap has its {@link ServerBootstrap#channel(Class)} already
55 * initialized to the backing implementation's {@link ServerSocketChannel} class.
57 * @return A new ServerBootstrap
59 public static ServerBootstrap newServerBootstrap() {
60 return new ServerBootstrap().channel(IMPL.serverChannelClass());
64 * Create a new {@link EventLoopGroup} supporting the backing implementation with default number of threads. The
65 * default is twice the number of available processors, or controlled through the {@code io.netty.eventLoopThreads}
68 * @param name Thread naming prefix
69 * @return An EventLoopGroup
71 public static EventLoopGroup newEventLoopGroup(final String name) {
72 return newEventLoopGroup(name, 0);
76 * Create a new {@link EventLoopGroup} supporting the backing implementation with specified (or default) number of
79 * @param name Thread naming prefix
80 * @param numThreads Number of threads in the group, must be non-negative. Zero selects the default.
81 * @return An EventLoopGroup
83 public static EventLoopGroup newEventLoopGroup(final String name, final int numThreads) {
84 return IMPL.newEventLoopGroup(numThreads, new ThreadFactoryBuilder()
85 .setNameFormat(requireNonNull(name) + "-%d")
86 .setUncaughtExceptionHandler(
87 (thread, ex) -> LOG.error("Thread terminated due to uncaught exception: {}", thread.getName(), ex))
91 static boolean keepalivesSupported() {
92 return IMPL.supportsKeepalives();
95 static void configureKeepalives(final Bootstrap bootstrap, final @Nullable Keepalives keepalives)
96 throws UnsupportedConfigurationException {
97 if (keepalives != null) {
98 checkKeepalivesSupported();
99 IMPL.configureKeepalives(bootstrap, keepalives);
103 static void configureKeepalives(final ServerBootstrap bootstrap, final @Nullable Keepalives keepalives)
104 throws UnsupportedConfigurationException {
105 if (keepalives != null) {
106 checkKeepalivesSupported();
107 IMPL.configureKeepalives(bootstrap, keepalives);
111 private static void checkKeepalivesSupported() throws UnsupportedConfigurationException {
112 if (!keepalivesSupported()) {
113 throw new UnsupportedConfigurationException("Keepalives are not supported");