HTTP transport implementation
[netconf.git] / transport / transport-http / src / main / java / org / opendaylight / netconf / transport / http / HTTPServer.java
diff --git a/transport/transport-http/src/main/java/org/opendaylight/netconf/transport/http/HTTPServer.java b/transport/transport-http/src/main/java/org/opendaylight/netconf/transport/http/HTTPServer.java
new file mode 100644 (file)
index 0000000..ea8f06e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024 PANTHEON.tech s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.transport.http;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.bootstrap.ServerBootstrap;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.netconf.transport.api.TransportChannelListener;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.netconf.transport.tcp.TCPServer;
+import org.opendaylight.netconf.transport.tls.TLSServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.http.server.rev240208.HttpServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.http.server.rev240208.HttpServerStackGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.http.server.rev240208.http.server.stack.grouping.transport.Tcp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.http.server.rev240208.http.server.stack.grouping.transport.Tls;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev240208.TcpServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tls.server.rev240208.TlsServerGrouping;
+
+/**
+ * A {@link HTTPTransportStack} acting as a server.
+ */
+public final class HTTPServer extends HTTPTransportStack {
+
+    private HTTPServer(final TransportChannelListener listener, final HttpChannelInitializer channelInitializer) {
+        super(listener, channelInitializer);
+    }
+
+    /**
+     * Attempt to establish a {@link HTTPServer} on a local address.
+     *
+     * @param listener {@link TransportChannelListener} to notify when the session is established
+     * @param bootstrap {@link ServerBootstrap} to use for the underlying Netty server channel
+     * @param listenParams Listening parameters
+     * @return A future
+     * @throws UnsupportedConfigurationException when {@code listenParams} contains an unsupported options
+     * @throws NullPointerException if any argument is {@code null}
+     */
+    public static @NonNull ListenableFuture<HTTPServer> listen(final TransportChannelListener listener,
+            final ServerBootstrap bootstrap, final HttpServerStackGrouping listenParams,
+            final RequestDispatcher dispatcher) throws UnsupportedConfigurationException {
+        final HttpServerGrouping httpParams;
+        final TcpServerGrouping tcpParams;
+        final TlsServerGrouping tlsParams;
+        final var transport = requireNonNull(listenParams).getTransport();
+        if (transport instanceof Tcp tcp) {
+            httpParams = tcp.getTcp().getHttpServerParameters();
+            tcpParams = tcp.getTcp().nonnullTcpServerParameters();
+            tlsParams = null;
+        } else if (transport instanceof Tls tls) {
+            httpParams = tls.getTls().getHttpServerParameters();
+            tcpParams = tls.getTls().nonnullTcpServerParameters();
+            tlsParams = tls.getTls().nonnullTlsServerParameters();
+        } else {
+            throw new UnsupportedConfigurationException("Unsupported transport: " + transport);
+        }
+        final var server = new HTTPServer(listener,
+            new ServerChannelInitializer(httpParams, requireNonNull(dispatcher)));
+        final var underlay = tlsParams == null
+            ? TCPServer.listen(server.asListener(), bootstrap, tcpParams)
+            : TLSServer.listen(server.asListener(), bootstrap, tcpParams, new HttpSslHandlerFactory(tlsParams));
+        return transformUnderlay(server, underlay);
+    }
+}