Skip to content

Commit

Permalink
HTTP/2 for Jetty connector
Browse files Browse the repository at this point in the history
Signed-off-by: Maxim Nesen <[email protected]>
  • Loading branch information
senivam committed Mar 29, 2023
1 parent 0914c71 commit 73af39b
Show file tree
Hide file tree
Showing 9 changed files with 499 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@

import javax.net.ssl.SSLContext;

import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.client.util.BasicAuthentication;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.client.util.FutureResponseListener;
Expand Down Expand Up @@ -144,19 +146,13 @@ class JettyConnector implements Connector {
*/
JettyConnector(final Client jaxrsClient, final Configuration config) {
this.configuration = config;
HttpClient httpClient = null;
if (config.isRegistered(JettyHttpClientSupplier.class)) {
Optional<Object> contract = config.getInstances().stream()
.filter(a-> JettyHttpClientSupplier.class.isInstance(a)).findFirst();
if (contract.isPresent()) {
httpClient = ((JettyHttpClientSupplier) contract.get()).getHttpClient();
}
}
HttpClient httpClient = getRegisteredHttpClient(config);

if (httpClient == null) {
final SSLContext sslContext = jaxrsClient.getSslContext();
final SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(false);
sslContextFactory.setSslContext(sslContext);
httpClient = new HttpClient(sslContextFactory);
httpClient = new HttpClient(initClientTransport(), sslContextFactory);
}
this.client = httpClient;

Expand Down Expand Up @@ -224,6 +220,37 @@ class JettyConnector implements Connector {
this.cookieStore = client.getCookieStore();
}

/**
* provides required HTTP client transport for client
*
* the default transport is {@link HttpClientTransportOverHTTP}
*
* @return instance of {@link HttpClientTransport}
* @since 2.40
*/
HttpClientTransport initClientTransport() {
return new HttpClientTransportOverHTTP();
}

/**
* provides custom registered {@link HttpClient} if any (or NULL)
*
* @param config configuration where {@link HttpClient} could be registered
* @return {@link HttpClient} instance if any was previously registered or NULL
*
* @since 2.40
*/
HttpClient getRegisteredHttpClient(Configuration config) {
if (config.isRegistered(JettyHttpClientSupplier.class)) {
Optional<Object> contract = config.getInstances().stream()
.filter(a-> JettyHttpClientSupplier.class.isInstance(a)).findFirst();
if (contract.isPresent()) {
return ((JettyHttpClientSupplier) contract.get()).getHttpClient();
}
}
return null;
}

/**
* Get the {@link HttpClient}.
*
Expand Down
138 changes: 138 additions & 0 deletions connectors/jetty-http2-connector/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?xml version="1.0"?>
<!--
Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the
Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
version 2 with the GNU Classpath Exception, which is available at
https://www.gnu.org/software/classpath/license.html.
SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>project</artifactId>
<version>2.40-SNAPSHOT</version>
</parent>

<artifactId>jersey-jetty-http2-connector</artifactId>
<packaging>jar</packaging>
<name>jersey-connectors-jetty-http2</name>

<description>Jersey Client Transport via Jetty</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-jetty-connector</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.sun.istack</groupId>
<artifactId>istack-commons-maven-plugin</artifactId>
<inherited>true</inherited>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>true</inherited>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<instructions>
<Import-Package>
${jetty.osgi.version},
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>jdk11+</id>
<activation>
<jdk>[11,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-osgi</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.jetty.connector;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;

/**
* HTTP/2 enabled version of the {@link JettyHttpClientSupplier}
*
* @since 2.40
*/
public class JettyHttp2ClientSupplier implements JettyHttpClientContract {
private final HttpClient http2Client;

/**
* default Http2Client created for the supplier.
*/
public JettyHttp2ClientSupplier() {
this(createHttp2Client());
}
/**
* supplier for the {@code HttpClient} with {@code HttpClientTransportOverHTTP2} to be optionally registered
* to a {@link org.glassfish.jersey.client.ClientConfig}
* @param http2Client a HttpClient to be supplied when {@link JettyConnector#getHttpClient()} is called.
*/
public JettyHttp2ClientSupplier(HttpClient http2Client) {
this.http2Client = http2Client;
}

private static final HttpClient createHttp2Client() {
final HttpClientTransport transport = new HttpClientTransportOverHTTP2(new HTTP2Client());
return new HttpClient(transport);
}

@Override
public HttpClient getHttpClient() {
return http2Client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.jetty.connector;

import javax.ws.rs.client.Client;
import javax.ws.rs.core.Configuration;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;

import java.util.Optional;

/**
* Extends {@link JettyConnector} with HTTP/2 transport support
*
* @since 2.40
*/
class JettyHttp2Connector extends JettyConnector {


/**
* Create the new Jetty HTTP/2 client connector.
*
* @param jaxrsClient JAX-RS client instance, for which the connector is created.
* @param config client configuration.
*/
JettyHttp2Connector(Client jaxrsClient, Configuration config) {
super(jaxrsClient, config);
}

/**
* provides required {@link HttpClientTransport} for client
*
* The overriden method provides {@link HttpClientTransportOverHTTP2} with initialized {@link HTTP2Client}
*
* @return {@link HttpClientTransportOverHTTP2}
* @since 2.40
*/
@Override
HttpClientTransport initClientTransport() {
return new HttpClientTransportOverHTTP2(new HTTP2Client());
}

/**
* provides custom registered {@link HttpClient} (if any) with HTTP/2 support
*
* @param config configuration where {@link HttpClient} could be registered
* @return {@link HttpClient} instance if any was previously registered or NULL
*
* @since 2.40
*/
@Override
HttpClient getRegisteredHttpClient(Configuration config) {
if (config.isRegistered(JettyHttp2ClientSupplier.class)) {
Optional<Object> contract = config.getInstances().stream()
.filter(a-> JettyHttp2ClientSupplier.class.isInstance(a)).findFirst();
if (contract.isPresent()) {
return ((JettyHttp2ClientSupplier) contract.get()).getHttpClient();
}
}
return null;
}
}
Loading

0 comments on commit 73af39b

Please sign in to comment.