Skip to content

Commit 1b67511

Browse files
Move Rest5 client to a separate subproject (#1076) (#1084)
* Move Rest5 client to a separate subproject * Add README * Fix test * Fix imports * Fix CI Co-authored-by: Sylvain Wallez <[email protected]>
1 parent bdfe840 commit 1b67511

File tree

75 files changed

+304
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+304
-21
lines changed

.ci/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ RUN ./gradlew
4444

4545
COPY --chown=$BUILDER_UID:$BUILDER_GID LICENSE.txt NOTICE.txt ./
4646

47+
48+
4749
# Prefetch and cache dependencies
4850
COPY --chown=$BUILDER_UID:$BUILDER_GID build.gradle.kts settings.gradle.kts ./
4951
COPY --chown=$BUILDER_UID:$BUILDER_GID buildSrc ./buildSrc/
5052
COPY --chown=$BUILDER_UID:$BUILDER_GID config ./config/
53+
COPY --chown=$BUILDER_UID:$BUILDER_GID rest5-client ./rest5-client/
5154
COPY --chown=$BUILDER_UID:$BUILDER_GID java-client/build.gradle.kts ./java-client/
5255
RUN ./gradlew resolveDependencies
5356

java-client/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ dependencies {
179179
val jacksonVersion = "2.18.3"
180180
val openTelemetryVersion = "1.32.0"
181181

182+
api(project(":rest5-client"))
183+
182184
// Apache 2.0
183185
// https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low.html
184186
compileOnly("org.elasticsearch.client", "elasticsearch-rest-client", elasticsearchVersion)
Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,30 @@
1717
* under the License.
1818
*/
1919

20-
package co.elastic.clients.transport.rest5_client.low_level;
21-
22-
import co.elastic.clients.transport.rest5_client.SafeResponseConsumer;
20+
package co.elastic.clients.transport.rest5_client;
21+
22+
import co.elastic.clients.transport.rest5_client.low_level.BufferedByteConsumer;
23+
import co.elastic.clients.transport.rest5_client.low_level.HttpAsyncResponseConsumerFactory;
24+
import co.elastic.clients.transport.rest5_client.low_level.Request;
25+
import co.elastic.clients.transport.rest5_client.low_level.RequestOptions;
26+
import co.elastic.clients.transport.rest5_client.low_level.Response;
27+
import co.elastic.clients.transport.rest5_client.low_level.Rest5Client;
2328
import com.sun.net.httpserver.HttpServer;
29+
import org.apache.hc.core5.http.ClassicHttpResponse;
2430
import org.apache.hc.core5.http.ContentType;
31+
import org.apache.hc.core5.http.HttpException;
2532
import org.apache.hc.core5.http.HttpHost;
2633
import org.apache.hc.core5.http.HttpResponse;
2734
import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
2835
import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
29-
import org.apache.hc.core5.http.protocol.HttpContext;
36+
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
37+
import org.apache.hc.core5.http.nio.support.AbstractAsyncResponseConsumer;
3038
import org.junit.jupiter.api.AfterAll;
3139
import org.junit.jupiter.api.Assertions;
3240
import org.junit.jupiter.api.BeforeAll;
3341
import org.junit.jupiter.api.Test;
3442

43+
import java.io.IOException;
3544
import java.net.InetAddress;
3645
import java.net.InetSocketAddress;
3746
import java.nio.charset.StandardCharsets;
@@ -42,20 +51,36 @@ public class SafeResponseConsumerTest {
4251
static HttpHost ESHost;
4352

4453
// A consumer factory that throws an Error, to simulate the effect of an OOME
45-
static HttpAsyncResponseConsumerFactory FailingConsumerFactory =
46-
() -> new BasicAsyncResponseConsumer(new BufferedByteConsumer(100 * 1024 * 1024)) {
47-
@Override
48-
public void informationResponse(HttpResponse response, HttpContext context) {
49-
super.informationResponse(response, context);
50-
}
54+
static HttpAsyncResponseConsumerFactory FailingConsumerFactory = new FailingAsyncResponseConsumerFactory();
5155

52-
@Override
53-
protected BasicClassicHttpResponse buildResult(HttpResponse response, ByteArrayEntity entity,
54-
ContentType contentType) {
55-
super.buildResult(response, entity, contentType);
56-
throw new Error("Error in buildResult");
57-
}
58-
};
56+
static class FailingAsyncResponseConsumerFactory implements HttpAsyncResponseConsumerFactory {
57+
@Override
58+
public AsyncResponseConsumer<ClassicHttpResponse> createHttpAsyncResponseConsumer() {
59+
return new FailingAsyncResponseConsumer();
60+
}
61+
}
62+
63+
static class FailingAsyncResponseConsumer extends AbstractAsyncResponseConsumer<ClassicHttpResponse,
64+
ByteArrayEntity> {
65+
66+
FailingAsyncResponseConsumer() {
67+
super(new BufferedByteConsumer(100));
68+
}
69+
70+
@Override
71+
public void informationResponse(HttpResponse response, org.apache.hc.core5.http.protocol.HttpContext context)
72+
throws HttpException, IOException {
73+
throw new Error("Error in informationResponse");
74+
}
75+
76+
@Override
77+
protected BasicClassicHttpResponse buildResult(
78+
HttpResponse response, ByteArrayEntity entity,
79+
ContentType contentType
80+
) {
81+
throw new Error("Error in buildResult");
82+
}
83+
}
5984

6085
@BeforeAll
6186
public static void setup() throws Exception {

rest5-client/README.md

Lines changed: 7 additions & 0 deletions

rest5-client/build.gradle.kts

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import com.github.jk1.license.ProjectData
21+
import com.github.jk1.license.render.LicenseDataCollector
22+
import com.github.jk1.license.render.ReportRenderer
23+
import java.io.FileWriter
24+
25+
plugins {
26+
java
27+
`java-library`
28+
`maven-publish`
29+
publishing
30+
checkstyle
31+
signing
32+
id("com.github.jk1.dependency-license-report") version "2.2"
33+
}
34+
35+
checkstyle {
36+
toolVersion = "10.16.0"
37+
}
38+
39+
java {
40+
targetCompatibility = JavaVersion.VERSION_17
41+
sourceCompatibility = JavaVersion.VERSION_17
42+
43+
withJavadocJar()
44+
withSourcesJar()
45+
}
46+
47+
tasks.compileJava {
48+
options.release.set(17)
49+
}
50+
51+
tasks.withType<Test> {
52+
useJUnitPlatform()
53+
}
54+
55+
tasks.withType<Jar> {
56+
doFirst {
57+
if (rootProject.extra.has("gitHashFull")) {
58+
val jar = this as Jar
59+
jar.manifest.attributes["X-Git-Revision"] = rootProject.extra["gitHashFull"]
60+
jar.manifest.attributes["X-Git-Commit-Time"] = rootProject.extra["gitCommitTime"]
61+
} else {
62+
throw GradleException("No git information available")
63+
}
64+
}
65+
66+
manifest {
67+
attributes["Implementation-Title"] = "Elasticsearch Java client"
68+
attributes["Implementation-Vendor"] = "Elastic"
69+
attributes["Implementation-URL"] = "https://github.com/elastic/elasticsearch-java/"
70+
attributes["Build-Date"] = rootProject.extra["buildTime"]
71+
}
72+
73+
metaInf {
74+
from("../LICENSE.txt")
75+
from("../NOTICE.txt")
76+
}
77+
}
78+
79+
tasks.withType<Javadoc> {
80+
val opt = options as StandardJavadocDocletOptions
81+
// Gradle calls javadoc with a list of file and not a path. This prevents doc-files from being copied.
82+
opt.addStringOption("sourcepath", project.projectDir.path + "/src/main/java")
83+
opt.docFilesSubDirs(true)
84+
opt.addBooleanOption("Xdoclint:-missing", true)
85+
}
86+
87+
publishing {
88+
repositories {
89+
maven {
90+
// See https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry
91+
name = "ESJavaGithubPackages"
92+
url = uri("https://maven.pkg.github.com/elastic/elasticsearch-java")
93+
credentials(PasswordCredentials::class)
94+
}
95+
96+
maven {
97+
name = "Build"
98+
url = uri("${rootProject.layout.buildDirectory.get().asFile}/repository")
99+
}
100+
}
101+
102+
publications {
103+
create<MavenPublication>("maven") {
104+
from(components["java"])
105+
pom {
106+
name.set("Elasticsearch Rest5 Client")
107+
artifactId = "elasticsearch-rest5-client"
108+
description.set("Low level client based on http5")
109+
url.set("https://github.com/elastic/elasticsearch-java/")
110+
licenses {
111+
license {
112+
name.set("The Apache Software License, Version 2.0")
113+
url.set("https://www.apache.org/licenses/LICENSE-2.0.txt")
114+
}
115+
}
116+
developers {
117+
developer {
118+
name.set("Elastic")
119+
url.set("https://www.elastic.co")
120+
inceptionYear.set("2020")
121+
}
122+
}
123+
scm {
124+
connection.set("scm:git:https://github.com/elastic/elasticsearch-java.git")
125+
developerConnection.set("scm:git:ssh://[email protected]:elastic/elasticsearch-java.git")
126+
url.set("https://github.com/elastic/elasticsearch-java/")
127+
}
128+
}
129+
}
130+
}
131+
}
132+
133+
134+
signing {
135+
// Only sign if a key has been configured in gradle.properties
136+
isRequired = providers.gradleProperty("signing.keyId").isPresent
137+
sign(publishing.publications["maven"])
138+
}
139+
140+
dependencies {
141+
val jacksonVersion = "2.18.3"
142+
143+
// Apache 2.0
144+
// https://hc.apache.org/httpcomponents-client-ga/
145+
api("org.apache.httpcomponents.client5","httpclient5","5.4.4")
146+
147+
// Apache 2.0
148+
// http://commons.apache.org/logging/
149+
api("commons-logging:commons-logging:1.3.5")
150+
151+
testImplementation("org.apache.commons:commons-lang3:3.14.0")
152+
testImplementation("junit:junit:4.13.2")
153+
154+
// Apache 2.0
155+
// https://github.com/FasterXML/jackson
156+
implementation("com.fasterxml.jackson.core", "jackson-core", jacksonVersion)
157+
implementation("com.fasterxml.jackson.core", "jackson-databind", jacksonVersion)
158+
159+
// // Apache-2.0
160+
// testImplementation("commons-io:commons-io:2.17.0")
161+
162+
// EPL-2.0
163+
// https://junit.org/junit5/
164+
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
165+
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
166+
167+
// Apache-2.0
168+
// https://github.com/awaitility/awaitility
169+
testImplementation("org.awaitility", "awaitility", "4.2.0")
170+
171+
// MIT
172+
// https://github.com/mockito/mockito
173+
testImplementation("org.mockito","mockito-core","5.12.0")
174+
175+
// Apache-2.0
176+
// https://github.com/elastic/mocksocket
177+
testImplementation("org.elasticsearch","mocksocket","1.2")
178+
179+
}
180+
181+
182+
licenseReport {
183+
renderers = arrayOf(SpdxReporter(File(rootProject.layout.buildDirectory.get().asFile, "release/dependencies.csv")))
184+
excludeGroups = arrayOf("org.elasticsearch.client")
185+
}
186+
187+
class SpdxReporter(val dest: File) : ReportRenderer {
188+
// License names to their SPDX identifier
189+
val spdxIds = mapOf(
190+
"The Apache License, Version 2.0" to "Apache-2.0",
191+
"Apache License, Version 2.0" to "Apache-2.0",
192+
"The Apache Software License, Version 2.0" to "Apache-2.0",
193+
"Apache-2.0" to "Apache-2.0",
194+
"MIT License" to "MIT",
195+
"BSD Zero Clause License" to "0BSD",
196+
"Eclipse Public License 2.0" to "EPL-2.0",
197+
"Eclipse Public License v. 2.0" to "EPL-2.0",
198+
"Eclipse Public License - v 2.0" to "EPL-2.0",
199+
"GNU General Public License, version 2 with the GNU Classpath Exception" to "GPL-2.0 WITH Classpath-exception-2.0",
200+
"COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0" to "CDDL-1.0"
201+
)
202+
203+
private fun quote(str: String): String {
204+
return if (str.contains(',') || str.contains("\"")) {
205+
"\"" + str.replace("\"", "\"\"") + "\""
206+
} else {
207+
str
208+
}
209+
}
210+
211+
override fun render(data: ProjectData?) {
212+
dest.parentFile.mkdirs()
213+
FileWriter(dest).use { out ->
214+
out.append("name,url,version,revision,license\n")
215+
data?.allDependencies?.forEach { dep ->
216+
217+
val depVersion = dep.version
218+
val depName = dep.group + ":" + dep.name
219+
220+
val info = LicenseDataCollector.multiModuleLicenseInfo(dep)
221+
val depUrl = when(dep.group) {
222+
"org.apache.httpcomponents.client5" -> "https://hc.apache.org/"
223+
"org.apache.httpcomponents.core5" -> "https://hc.apache.org/"
224+
"com.fasterxml.jackson" -> "https://github.com/FasterXML/jackson"
225+
else -> if (info.moduleUrls.isEmpty()) {
226+
throw RuntimeException("No URL found for module '$depName'")
227+
} else {
228+
info.moduleUrls.first()
229+
}
230+
}
231+
232+
val licenseIds = info.licenses.mapNotNull { license ->
233+
license.name?.let {
234+
checkNotNull(spdxIds[it]) { "No SPDX identifier for $license" }
235+
}
236+
}.toSet()
237+
238+
// Combine multiple licenses.
239+
// See https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/#composite-license-expressions
240+
val licenseId = licenseIds.joinToString(" OR ")
241+
242+
out.append("${quote(depName)},${quote(depUrl)},${quote(depVersion)},,${quote(licenseId)}\n")
243+
}
244+
}
245+
}
246+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828

2929
import static co.elastic.clients.transport.rest5_client.low_level.Constants.DEFAULT_BUFFER_INITIAL_CAPACITY;
3030

31-
class BufferedByteConsumer extends AbstractBinAsyncEntityConsumer<ByteArrayEntity> {
31+
public class BufferedByteConsumer extends AbstractBinAsyncEntityConsumer<ByteArrayEntity> {
3232

3333
private volatile ByteArrayBuffer buffer;
3434
private final int limit;
3535
private ContentType contentType;
3636

37-
BufferedByteConsumer(int bufferLimit) {
37+
public BufferedByteConsumer(int bufferLimit) {
3838
super();
3939
if (bufferLimit <= 0) {
4040
throw new IllegalArgumentException("Buffer limit must be greater than 0");

0 commit comments

Comments
 (0)