Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce google-http-client-apache-v5 (Apache Client/Core 5.x) #1960

Merged
merged 54 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8efb1b1
chore: add base google-http-client-apache-v3
diegomarquezp Jun 26, 2024
6c0b7ed
exclude core 4.x
diegomarquezp Jun 26, 2024
a4d5c06
chore: demo usage of Apache HTTP Client 5.x
diegomarquezp Jun 26, 2024
7d7dd3a
implement transport using `classic` implementation
diegomarquezp Jun 27, 2024
413ccae
remove author comments
diegomarquezp Jun 27, 2024
6cde3cb
move test code to test class
diegomarquezp Jun 27, 2024
27836c7
remove redundant instanceof
diegomarquezp Jun 27, 2024
1b17559
use interface
diegomarquezp Aug 12, 2024
6b6b7e3
prepare for production
diegomarquezp Aug 12, 2024
06971ce
expose interfaces instead of implementation classes
diegomarquezp Aug 12, 2024
cb9c2c8
use executeOpen()
diegomarquezp Aug 13, 2024
68a4c62
rename to google-http-client-apache-v5
diegomarquezp Aug 13, 2024
e831876
format
diegomarquezp Aug 13, 2024
b23f1f7
format
diegomarquezp Aug 13, 2024
46128b2
remove @since annotations
diegomarquezp Aug 13, 2024
f9216de
remove unused beta annotatoins
diegomarquezp Aug 13, 2024
4950aa5
initial re-addition of unit tests in transport class
diegomarquezp Aug 13, 2024
8b75159
rough re-implementation of tests
diegomarquezp Aug 13, 2024
e8ccf0b
rename default client builder in transport
diegomarquezp Aug 13, 2024
84e3d02
use ModalCloseable to check if we can close() the client
diegomarquezp Aug 13, 2024
50ed0db
fix javadoc links
diegomarquezp Aug 13, 2024
dbbdc43
use ClassicHttpResponse
diegomarquezp Aug 13, 2024
871901c
use concrete exception
diegomarquezp Aug 14, 2024
afdc7f1
rename apache 5 mocks
diegomarquezp Aug 14, 2024
b3c57d0
rename v2 folder
diegomarquezp Aug 14, 2024
d6c4202
fix dependencies
diegomarquezp Aug 14, 2024
a7e347a
confirm that any type of requests can have content set
diegomarquezp Aug 14, 2024
4bc7b12
remove TODO
diegomarquezp Aug 15, 2024
ff1cba2
execute() with response handler
diegomarquezp Aug 15, 2024
c5fcd7f
adapt for java7
diegomarquezp Aug 15, 2024
bd7c990
move mock class to test flder
diegomarquezp Aug 15, 2024
aa3cc73
Revert "move mock class to test flder"
diegomarquezp Aug 15, 2024
36bf5e8
Revert "adapt for java7"
diegomarquezp Aug 15, 2024
ac8e24b
Revert "execute() with response handler"
diegomarquezp Aug 15, 2024
45f8142
make users close the response
diegomarquezp Aug 15, 2024
25d24be
add input stream wrapper
diegomarquezp Aug 19, 2024
d7187d8
add input stream test
diegomarquezp Aug 19, 2024
5f249d7
move deps to test scoped
diegomarquezp Aug 19, 2024
ca714dc
remove reflect-config.json
diegomarquezp Aug 19, 2024
e472ce6
fix dependencies
diegomarquezp Aug 19, 2024
663e7fc
rename project variable to apache-httpxxx-4
diegomarquezp Aug 19, 2024
fe1ef0a
exclude google apache 5 client from java 7 tests
diegomarquezp Aug 19, 2024
e87f1fb
Merge remote-tracking branch 'origin/google-http-client-apache-v3-htt…
diegomarquezp Aug 19, 2024
ff5c209
add javadoc for Apache5ResponseContent
diegomarquezp Aug 19, 2024
b4049e0
close() response only, emit getContent() exception
diegomarquezp Aug 19, 2024
de87435
format
diegomarquezp Aug 19, 2024
5485b46
implement all methods of InputStream
diegomarquezp Aug 20, 2024
86e70aa
improve javadoc of wrapped stream
diegomarquezp Aug 20, 2024
e21f993
add test to confirm the response is close()d
diegomarquezp Aug 20, 2024
d8c7f67
update docs to offer Apache5Http.*
diegomarquezp Aug 20, 2024
ec0ebb3
exclude apache 4 from test dependencies
diegomarquezp Aug 20, 2024
1cd91ea
throw IOException when disconnect()ing
diegomarquezp Aug 21, 2024
5da2b32
remove convenience integration tests
diegomarquezp Aug 21, 2024
5fd5dd1
fix deps
diegomarquezp Aug 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-java7.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
# dailymotion-simple-cmdline-sample and google-http-client-assembly depend on
# google-http-client-jackson2
mvn --batch-mode --show-version -ntp test \
--projects '!google-http-client-jackson2,!google-http-client-appengine,!samples/dailymotion-simple-cmdline-sample,!google-http-client-assembly' \
--projects '!google-http-client-jackson2,!google-http-client-appengine,!samples/dailymotion-simple-cmdline-sample,!google-http-client-assembly,!google-http-client-apache-v5' \
-Dclirr.skip=true -Denforcer.skip=true -Dmaven.javadoc.skip=true \
-Dgcloud.download.skip=true -T 1C \
-Dproject.surefire.version=2.22.2 \
Expand Down
133 changes: 133 additions & 0 deletions google-http-client-apache-v5/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<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>com.google.http-client</groupId>
<artifactId>google-http-client-parent</artifactId>
<version>1.44.3-SNAPSHOT</version><!-- {x-version-update:google-http-client-parent:current} -->
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>google-http-client-apache-v5</artifactId>
<version>1.44.3-SNAPSHOT</version><!-- {x-version-update:google-http-client-apache-v5:current} -->
<name>Apache HTTP transport v5 for the Google HTTP Client Library for Java.</name>

<build>
<plugins>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>https://download.oracle.com/javase/7/docs/api/</link>
</links>
<doctitle>${project.name} ${project.version}</doctitle>
<windowtitle>${project.artifactId} ${project.version}</windowtitle>
</configuration>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-test-sources</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
<manifestEntries>
<Automatic-Module-Name>com.google.api.client.http.apache.v5</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.9</version>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5</artifactId>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-cloudresourcemanager</artifactId>
<version>v3-rev20240310-2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-gson</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2024 Google LLC
*
* Licensed 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 com.google.api.client.http.apache.v5;

import com.google.api.client.util.Preconditions;
import com.google.api.client.util.StreamingContent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;

/**
* Translation class to make google-http-client entity conform with Apache 5.x {@link
* AbstractHttpEntity}
*/
final class Apache5ContentEntity extends AbstractHttpEntity {

/** Content length or less than zero if not known. */
private final long contentLength;

/** Streaming content. */
private final StreamingContent streamingContent;

/**
* @param contentLength content length or less than zero if not known
* @param streamingContent streaming content
*/
Apache5ContentEntity(
long contentLength,
StreamingContent streamingContent,
String contentType,
String contentEncoding) {
super(contentType, contentEncoding, contentLength == -1);
this.contentLength = contentLength;
this.streamingContent = Preconditions.checkNotNull(streamingContent);
}

@Override
public InputStream getContent() {
throw new UnsupportedOperationException();
}

@Override
public long getContentLength() {
return contentLength;
}

@Override
public boolean isRepeatable() {
return false;
}

@Override
public boolean isStreaming() {
return true;
}

@Override
public void writeTo(OutputStream out) throws IOException {
if (contentLength != 0) {
streamingContent.writeTo(out);
}
}

@Override
public void close() throws IOException {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2024 Google LLC
*
* Licensed 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 com.google.api.client.http.apache.v5;

import com.google.api.client.http.LowLevelHttpRequest;
import com.google.api.client.http.LowLevelHttpResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.apache.hc.client5.http.ClientProtocolException;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.routing.RoutingSupport;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.util.Timeout;

public final class Apache5HttpRequest extends LowLevelHttpRequest {

private final HttpUriRequestBase request;

private final RequestConfig.Builder requestConfig;

private final HttpClient httpClient;

Apache5HttpRequest(HttpClient httpClient, HttpUriRequestBase request) {
this.httpClient = httpClient;
this.request = request;
// disable redirects as google-http-client handles redirects
this.requestConfig = RequestConfig.custom().setRedirectsEnabled(false);
}

@Override
public void addHeader(String name, String value) {
request.addHeader(name, value);
}

@Override
public void setTimeout(int connectTimeout, int readTimeout) throws IOException {
requestConfig
.setConnectTimeout(Timeout.of(connectTimeout, TimeUnit.MILLISECONDS))
// ResponseTimeout behaves the same as 4.x's SocketTimeout
.setResponseTimeout(Timeout.of(readTimeout, TimeUnit.MILLISECONDS));
}

@Override
public LowLevelHttpResponse execute() throws IOException {
if (getStreamingContent() != null) {
Apache5ContentEntity entity =
new Apache5ContentEntity(
getContentLength(), getStreamingContent(), getContentType(), getContentEncoding());
request.setEntity(entity);
}
request.setConfig(requestConfig.build());
HttpHost target;
try {
target = RoutingSupport.determineHost(request);
} catch (HttpException e) {
throw new ClientProtocolException("The request's host is invalid.", e);
}
// we use a null context so the client creates the default one internally
ClassicHttpResponse httpResponse = httpClient.executeOpen(target, request, null);
return new Apache5HttpResponse(request, httpResponse);
}
}
Loading
Loading