-
-
Notifications
You must be signed in to change notification settings - Fork 246
HSEARCH-5482 Simple Elasticsearch client based on java.net.http.HttpClient #4896
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
base: main
Are you sure you want to change the base?
Conversation
a4bd553 to
473746a
Compare
c407d26 to
4a3dd9e
Compare
4a3dd9e to
90873f6
Compare
marko-bekhta
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if someone wants to have a look 😉 🙂
This one adds a new JDK based http client.
| import org.hibernate.search.util.common.impl.Closer; | ||
|
|
||
| @Incubating | ||
| public class RestJdkClient implements AutoCloseable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put the client and node provider into the SPI package only because we usually say that "you can pass your own instance of the rest client to us" and if the client is in the impl package.. then it somewhat defeats that point
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why wouldn't users/frameworks just pass the HttpClient instance in that case, instead of a Hibernate Search-specific interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* An external Elasticsearch client instance that Hibernate Search should use for all requests to Elasticsearch.
* <p>
* If this is set, Hibernate Search will not attempt to create its own Elasticsearch,
* and all other client-related configuration properties
* (hosts/uris, authentication, discovery, timeouts, max connections, configurer, ...)
* will be ignored.
I wanted to go with that option of HttpClient ... this (HttpClient) client on its own won't know about the hosts/uris and maybe more ? So I was looking at it from this prespective: for other clients we expect the wrapper client around the apache one and not the apache client itself... and I was trying to follow the same pattern here 🫣.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user passed a HttpClient, it would be primarily to share the connection pool (if any) with other uses of the client elsewhere, IMO. It'd be fine to still have the uris and more configured through Hibernate Search -- after all, the user passed the client, they can pass more.
But I can understand your view as well. +0 from me I guess :)
| if ( httpClient != null ) { | ||
| try ( Closer<Exception> closer = new Closer<>() ) { | ||
| Optional<Executor> executor = httpClient.executor(); | ||
| // May look a bit silly ... but close was only added in JDK 21: | ||
| if ( ( (Object) httpClient ) instanceof AutoCloseable closeable ) { | ||
| closer.push( AutoCloseable::close, closeable ); | ||
| } | ||
| if ( executor.isPresent() && executor.get() instanceof AutoCloseable closeable ) { | ||
| closer.push( AutoCloseable::close, closeable ); | ||
| } | ||
| } | ||
| finally { | ||
| httpClient = null; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the closing look as it does ? well .....
Prior to JDK 21, this client does not expose a way to close it.... and it starts a thread and an executor (unless provided, which we do here), which are supposedly stopped and cleaned up once the client is not referenced from anywhere ...
But TBH .. I'd rather limit the use of this client to JDK 21+ 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But TBH .. I'd rather limit the use of this client to JDK 21+ 🙂
+1 that's a perfectly reasonable limitation.
...earch/src/main/java/org/hibernate/search/backend/elasticsearch/client/impl/NodeProvider.java
Show resolved
Hide resolved
|
|
||
| public ClientJdkGsonHttpEntity(Gson gson, List<JsonObject> bodyParts) throws IOException { | ||
| super( gson, bodyParts ); | ||
| delegate = HttpRequest.BodyPublishers.ofInputStream( this::getContent ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HttpRequest.BodyPublisher didn't fit the abstract gson entity that easily so I thought I'll just delegate to the existing one instead.
| // https://docs.oracle.com/en/java/javase/25/docs/api/java.net.http/module-summary.html | ||
| // | ||
| // Host header is one of the restricted ^ so we skip it here: | ||
| private static final Set<String> HEADERS_TO_IGNORE = Set.of( "host" ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some of those JDK client properties can only be set as system properties ... and what "restricted" headers to allow is one of those configs.
I've tested the aws signing with the host header skipped and it seems to work ok, so I'll leave it as this for now.
| <version>8.2.0-SNAPSHOT</version> | ||
| <relativePath>../../../build/parents/public</relativePath> | ||
| </parent> | ||
| <artifactId>hibernate-search-backend-elasticsearch-client-jdk</artifactId> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to confirm the new artifact name/package:
(org.hibernate.search.backend.elasticsearch.client.jdk)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't the plan to include this client directly in the Elasticsearch backend, because it doesn't require any additional dependency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was the original idea, yes ... but I hesitated about doing so in the end 🙂
Reason ? well ... we already have a dependency on the rest4 based client and if we add the jdk one, with the current logic we'll end up using the JDK one, and user wouldn't be able to force the use of rest4 one Then adding one of the apache 5 based ones won't work at all without excludes.. all of that because we'll have too many clients on the classpath and we wouldn't know which one to pick...
hence I thought .. make this one as another module, then in the next version replace the rest4 dependency with this one and move the rest4 code out of the backend into the client while move this one back in ...
otherwise we need to rethink how we determine which client factory to select + probably have a config property on the API side to specify it instead of the SPI (
Line 30 in 6e8a388
| public static final String BACKEND_WORK_EXECUTOR_PROVIDER = PREFIX + Radicals.BACKEND_WORK_EXECUTOR_PROVIDER; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
otherwise we need to rethink how we determine which client factory to select + probably have a config property on the API side to specify it instead of the SPI (
That's what I expected TBH. Ignore the JDK one by default (because the rest4 one must remain the default for backwards compatibility) and allow passing a config property to switch to the JDK one.
90873f6 to
8429125
Compare
…assing a reference to the HttpClient instead
b26b28f to
b9bee13
Compare
|


https://hibernate.atlassian.net/browse/HSEARCH-5482
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.