-
-
Notifications
You must be signed in to change notification settings - Fork 246
HSEARCH-5464 Pluggable rest clients in the elasticsearch backend #4798
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
aac26ce to
1d41060
Compare
3da3726 to
610c554
Compare
e91fd98 to
ae10272
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.
Hey @yrodiere @lucamolteni 🙂 👋🏻
I've added some comments here and there in this PR in places that may be of interest.
Otherwise there's a lot of "noise", from moving packages and renaming.
This PR doesn't include the docs+migration guide updates. I was thinking about sending that separately, as this already has a lot of changes 🙂.
| private final JsonObject body; | ||
|
|
||
| public ElasticsearchResponse(HttpHost host, int statusCode, String statusMessage, JsonObject body) { | ||
| public ElasticsearchResponse(String host, int statusCode, String statusMessage, JsonObject body) { |
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.
This one is pretty straightforward, we only use the host to log the response, and it's an SPI ... so removing the apache class here should be "safe"
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 you're breaking this, it might be a good idea to rename it as well? In particular I see this string includes the port, so it would be more "hostAndPort"
| * https://github.com/google/gson/issues/764 is supposedly fixed. | ||
| * Hence, we may not need the workaround anymore. | ||
| * This version will be used in the test so we'll notice if things are still broken, for the main code | ||
| * the workaround is in place through the GsonProviderHelper. |
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.
This GSON issue was fixed, but I kept the workaround for the main code "just in case".
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 it's fixed and we have a non-regression test, I'd say just remove the workaround?
...bernate/search/backend/elasticsearch/client/ElasticsearchHttpClientConfigurationContext.java
Show resolved
Hide resolved
...tiontest/backend/elasticsearch/client/ElasticsearchClientFactoryImplElasticsearchJavaIT.java
Show resolved
Hide resolved
| @SuppressJQAssistant( | ||
| reason = "Apache HTTP Client 5 uses a lot of classes/interfaces in the impl packages to create builders/instances etc. " | ||
| + "So while it is bad to expose impl types ... in this case it's what Apache Client expects users to do?") | ||
| public interface ElasticsearchHttpClientConfigurationContext { |
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.
More of an FYI 🙈
org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder
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.
Maybe ignore Apache HTTP Client 5 classes in the JQAssistant rules instead? If it's really their package naming convention which is at fault.
...search/backend/elasticsearch/client/common/cfg/ElasticsearchBackendClientCommonSettings.java
Outdated
Show resolved
Hide resolved
...e/search/backend/elasticsearch/client/common/spi/ElasticsearchRequestInterceptorContext.java
Show resolved
Hide resolved
| if ( entity instanceof AsyncEntityProducer producer ) { | ||
| if ( !producer.isRepeatable() ) { | ||
| throw new AssertionFailure( "Cannot sign AWS requests with non-repeatable entities" ); | ||
| } | ||
| return new HttpAsyncEntityProducerInputStream( producer, 1024 ); | ||
| } |
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.
This one is a bit annoying as there seems to be no easier/simpler way to get the entity out of the request, but well ... it is what it is 🙂 🤷🏻
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.
IIUC you copy-pasted the old HttpAsyncContentProducerInputStream two times where you needed it? And possibly other related classes?
This makes me uneasy, because this is very fragile code, and my memories of working with it are... not pleasant ones.
Would it make sense to abstract over the various HTTPD classes (content encoder, ...) and move this code to a single implementation in -utils instead?
| * | ||
| * @author Sanne Grinovero (C) 2017 Red Hat Inc. | ||
| */ | ||
| final class GsonHttpEntity implements HttpEntity, AsyncEntityProducer { |
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.
the apache client 5 apis changed a bit so these gson entities were updated a bit 🙂
the tests are passing and all seems good, but if anyone would want to have an extra look, that would be nice 🙂
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 honestly doubt anyone can spot mistakes in this code just by reading it. Not a reproach, just an opinion: I've had to deal with this code in the past...
I hope the tests are good :)
...ava/org/hibernate/search/backend/elasticsearch/client/ElasticsearchHttpClientConfigurer.java
Show resolved
Hide resolved
e347a5f to
2e6dca2
Compare
yrodiere
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.
I can't review it all but I went through your comments and a bit more, here's what I have to say :)
It's really a shame we can't have a dependency from clients to backend...
This PR doesn't include the docs+migration guide updates. I was thinking about sending that separately, as this already has a lot of changes 🙂.
Since the docs changes would be in very isolated files, you might as well add these changes here :)
| * https://github.com/google/gson/issues/764 is supposedly fixed. | ||
| * Hence, we may not need the workaround anymore. | ||
| * This version will be used in the test so we'll notice if things are still broken, for the main code | ||
| * the workaround is in place through the GsonProviderHelper. |
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 it's fixed and we have a non-regression test, I'd say just remove the workaround?
| <artifactId>hibernate-search-backend-elasticsearch-client-java</artifactId> | ||
|
|
||
| <name>Hibernate Search Backend - Elasticsearch client based on the low-level Elasticsearch java client</name> | ||
| <description>Hibernate Search Elasticsearch client based on the low-level Elasticsearch java client</description> |
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.
You should probably rename this, and change the description and dependency, to use that new separate artifact instead?
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.
+1 yes, that's the plan, was just waiting for it to get released 👍🏻 🤞🏻 🙂
| @SuppressJQAssistant( | ||
| reason = "Apache HTTP Client 5 uses a lot of classes/interfaces in the impl packages to create builders/instances etc. " | ||
| + "So while it is bad to expose impl types ... in this case it's what Apache Client expects users to do?") | ||
| public interface ElasticsearchHttpClientConfigurationContext { |
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.
Maybe ignore Apache HTTP Client 5 classes in the JQAssistant rules instead? If it's really their package naming convention which is at fault.
| <artifactId>hibernate-search-backend-elasticsearch-client-rest</artifactId> | ||
|
|
||
| <name>Hibernate Search Backend - Elasticsearch client based on the low-level Elasticsearch client</name> | ||
| <description>Hibernate Search Elasticsearch client based on the low-level Elasticsearch client</description> |
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.
Since you know this will disappear at some point, maybe pick a more descriptive name that wouldn't imply "that's how you do rest"? E.g. -rest4 or -rest-apache-http-4?
Good idea for other clients as well, BTW...
| private final JsonObject body; | ||
|
|
||
| public ElasticsearchResponse(HttpHost host, int statusCode, String statusMessage, JsonObject body) { | ||
| public ElasticsearchResponse(String host, int statusCode, String statusMessage, JsonObject body) { |
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 you're breaking this, it might be a good idea to rename it as well? In particular I see this string includes the port, so it would be more "hostAndPort"
| ); | ||
| } | ||
| } | ||
| ConfigurationLog.INSTANCE.backendClientFactory( clientFactoryHolder, eventContext.render() ); |
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.
Maybe pass the eventContext instead of calling render explicitly? That way there's no rendering happening if the log level is filtered out.
See for example
Lines 60 to 62 in c9c39e3
| @Message(id = ID_OFFSET_LEGACY_ENGINE + 52, | |
| value = "An index writer operation failed. Resetting the index writer and forcing release of locks. %1$s") | |
| void indexWriterResetAfterFailure(@FormatWith(EventContextFormatter.class) EventContext context); |
| throw ConfigurationLog.INSTANCE.backendClientFactoryMultipleConfigured( | ||
| clientFactoryReferences.stream().map( ref -> ref.resolve( beanResolver ) ) | ||
| .toList(), | ||
| eventContext.render() |
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.
You can pass the event context directly as a parameter to the exception's constructor, it will behave better.
See for example
Lines 56 to 59 in 2efc2d6
| @Message(id = ID_OFFSET + 16, | |
| value = "Invalid tenant identifiers: '%1$s'." | |
| + " No tenant identifier is expected, because multi-tenancy is disabled for this backend.") | |
| SearchException tenantIdProvidedButMultiTenancyDisabled(Set<String> tenantIds, @Param EventContext context); |
...search/backend/elasticsearch/client/common/cfg/ElasticsearchBackendClientCommonSettings.java
Outdated
Show resolved
Hide resolved
| <version>8.2.0-SNAPSHOT</version> | ||
| <relativePath>../../../build/parents/public</relativePath> | ||
| </parent> | ||
| <artifactId>hibernate-search-backend-elasticsearch-client-opensearch</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.
Shouldn't new clients be marked as incubating? "To be safe"? :)
Meaning @Inbucating in APIs/SPIs and an admonition in the docs.
| <version>8.2.0-SNAPSHOT</version> | ||
| <relativePath>../../../build/parents/public</relativePath> | ||
| </parent> | ||
| <artifactId>hibernate-search-backend-elasticsearch-client-common</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.
This module even existing feels very wrong... So we really don't have a solution to break circular dependencies between backend and clients?
Some hack to add the dependency from backend to the default client manually, directly in the POM, perhaps?
|
Thanks for having a look!
ohh I already did 🫣 🙂 here: at the time I didn't want to prevent anyone from looking at the PR waiting for the docs, but as I had some "free time" since then 😁 I managed to push the change here 😄 |
I envy your time management skills. Honestly. |
yrodiere
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.
Some more comments on the docs. Looks great :)
| The https://hibernate.org/community/compatibility-policy/#code-categorization[API] | ||
| in Hibernate Search {hibernateSearchVersion} | ||
| is, in general, backward-compatible with Hibernate Search {hibernateSearchPreviousStableVersionShort}. | ||
| But, there are some deprecations: |
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, there are some deprecations: | |
| However, some elements are now deprecated: |
| * `org.hibernate.search.backend.elasticsearch.client.ElasticsearchHttpClientConfigurer` is deprecated for removal. | ||
| With introduction of the pluggable Elasticsearch backend clients, configurers are a part of the particular client | ||
| and expose client-specific configuration knobs. | ||
| * `org.hibernate.search.backend.elasticsearch.client.ElasticsearchHttpClientConfigurationContext` is also up for removal, | ||
| as it's a part of the configurer API. |
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.
Maybe suggest which interface to use for people sticking to the same client? I.e. the simplest migration path.
|
|
||
| An Elasticsearch backend communicates with an Elasticsearch cluster through a REST client. | ||
| Below are the options that affect this client. | ||
| Hibernate Search comes with a range of pluggable Elasticsearch REST clients that the user can pick from: |
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.
"User" means something different for us and for... our users.
| Hibernate Search comes with a range of pluggable Elasticsearch REST clients that the user can pick from: | |
| Hibernate Search comes with a range of pluggable Elasticsearch REST clients that you can pick from: |
or
| Hibernate Search comes with a range of pluggable Elasticsearch REST clients that the user can pick from: | |
| Hibernate Search comes with a range of pluggable Elasticsearch REST clients that applications can pick from: |
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.
Maybe add something to the "Artifacts" section, mentioning that applications should explicitly depend on the client they want to use, if they do care about which client is used?
since the behavior of this client is slightly different
…plement the clients as dependencies
…he backend and remove the client-common
12e8879 to
d4e3fce
Compare
d4e3fce to
b805101
Compare
|


https://hibernate.atlassian.net/browse/HSEARCH-5464
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.