Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions docs/src/main/asciidoc/hibernate-search-elasticsearch.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,9 @@ quarkus.hibernate-orm.sql-load-script=import.sql <4>

quarkus.hibernate-search.elasticsearch.version=7 <5>
quarkus.hibernate-search.elasticsearch.analysis.configurer=org.acme.hibernate.search.elasticsearch.config.AnalysisConfigurer <6>
quarkus.hibernate-search.elasticsearch.automatic-indexing.synchronization.strategy=searchable <7>
quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.strategy=drop-and-create <8>
quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status=yellow <9>
quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.strategy=drop-and-create <7>
quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status=yellow <8>
quarkus.hibernate-search.automatic-indexing.synchronization.strategy=searchable <9>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I'm not totally sold on this change. It makes the configuration all weird.

I'm also surprised it's not something you can configure per backend in Search.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Synchronization is about:

  1. Whether to force a refresh on the backend side before considering indexing "done" (committed vs. searchable).
  2. Whether we wait for indexing to be "done" after a transaction, or we just proceed without one works are queued (queued vs. committed/searchable).

Number 1 could theoretically be configured per backend, or even per index, though I don't really see the point.
Number 2 definitely cannot.

Maybe at some point we could split that into two separate configuration options, number 1 being configurable per backend while number 2 would not. However, that would introduce nonsensical combinations (do not wait for indexing to be "done", but force a refresh before considering it's "done"...). I also think it would make it even harder to explain the whole concept, but maybe that's just me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What bugs me a bit tbh is having this property outside of the elasticsearch context.

The other ones we had there were for advanced configurations. Here the default configuration looks a bit asymmetrical.

----
<1> We won't use SSL so we disable it to have a more compact native executable.
<2> Let's create a PostgreSQL datasource.
Expand All @@ -543,12 +543,12 @@ quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.required-status=
It is important because there are significant differences between Elasticsearch mapping syntax depending on the version.
Since the mapping is created at build time to reduce startup time, Hibernate Search cannot connect to the cluster to automatically detect the version.
<6> We point to the custom `AnalysisConfigurer` which defines the configuration of our analyzers and normalizers.
<7> This means that we wait for the entities to be searchable before considering a write complete.
While, on a production setup, the `committed` default might be a suitable value, using `searchable` is especially important when testing as you need the entities to be searchable immediately.
<8> Obviously, this is not for production: we drop and recreate the index every time we start the application.
<9> We consider the `yellow` status is sufficient to connect to the Elasticsearch cluster.
<7> Obviously, this is not for production: we drop and recreate the index every time we start the application.
<8> We consider the `yellow` status is sufficient to connect to the Elasticsearch cluster.
This is for testing purposes with the Elasticsearch Docker container.
It should not be used in production.
<9> This means that we wait for the entities to be searchable before considering a write complete.
While, on a production setup, the `committed` default might be a suitable value, using `searchable` is especially important when testing as you need the entities to be searchable immediately.

[TIP]
For more information about the Hibernate Search extension configuration please refer to the <<configuration-reference, Configuration Reference>>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,29 @@ void setRuntimeConfig(HibernateSearchElasticsearchRecorder recorder,
}

private static void checkConfig(HibernateSearchElasticsearchBuildTimeConfig buildTimeConfig) {
if (buildTimeConfig.defaultBackend.isPresent()) {
if (buildTimeConfig.additionalBackends.defaultBackend.isPresent()) {
String defaultBackend = buildTimeConfig.additionalBackends.defaultBackend.get();
// we have a default named backend
if (buildTimeConfig.elasticsearch.version.isPresent()) {
if (buildTimeConfig.defaultBackend.version.isPresent()) {
throw new ConfigurationError(
"quarkus.hibernate-search.elasticsearch.default-backend cannot be used in conjunction with a default backend configuration.");
}
if (!buildTimeConfig.additionalBackends.containsKey(buildTimeConfig.defaultBackend.get())) {
if (!buildTimeConfig.additionalBackends.backends.containsKey(defaultBackend)) {
throw new ConfigurationError(
"The default backend defined does not exist: " + buildTimeConfig.defaultBackend.get());
"The default backend defined does not exist: " + defaultBackend);
}
} else {
// we are in the default backend case
if (!buildTimeConfig.elasticsearch.version.isPresent()) {
if (!buildTimeConfig.defaultBackend.version.isPresent()) {
throw new ConfigurationError(
"The Elasticsearch version needs to be defined via the quarkus.hibernate-search.elasticsearch.version property.");
}
}

// we validate that the version is present for all the additional backends
if (!buildTimeConfig.additionalBackends.isEmpty()) {
if (!buildTimeConfig.additionalBackends.backends.isEmpty()) {
List<String> additionalBackendsWithNoVersion = new ArrayList<>();
for (Entry<String, ElasticsearchBackendBuildTimeConfig> additionalBackendEntry : buildTimeConfig.additionalBackends
for (Entry<String, ElasticsearchBackendBuildTimeConfig> additionalBackendEntry : buildTimeConfig.additionalBackends.backends
.entrySet()) {
if (!additionalBackendEntry.getValue().version.isPresent()) {
additionalBackendsWithNoVersion.add(additionalBackendEntry.getKey());
Expand All @@ -131,9 +132,9 @@ private void registerReflection(IndexView index, BuildProducer<ReflectiveClassBu
Set<DotName> reflectiveClassCollector = new HashSet<>();
Set<DotName> reflectiveTypeCollector = new HashSet<>();

if (buildTimeConfig.elasticsearch.analysis.configurer.isPresent()) {
if (buildTimeConfig.defaultBackend.analysis.configurer.isPresent()) {
reflectiveClass.produce(
new ReflectiveClassBuildItem(true, false, buildTimeConfig.elasticsearch.analysis.configurer.get()));
new ReflectiveClassBuildItem(true, false, buildTimeConfig.defaultBackend.analysis.configurer.get()));
}

if (buildTimeConfig.backgroundFailureHandler.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,18 @@
public class HibernateSearchElasticsearchBuildTimeConfig {

/**
* Configuration of the default backend.
* Default backend
*/
public ElasticsearchBackendBuildTimeConfig elasticsearch;

/**
* If not using the default backend configuration, the name of the default backend that is part of the
* {@link #additionalBackends}.
*/
@ConfigItem
public Optional<String> defaultBackend;
@ConfigItem(name = "elasticsearch")
@ConfigDocSection
public ElasticsearchBackendBuildTimeConfig defaultBackend;

/**
* Additional backends
*/
@ConfigItem(name = "elasticsearch.backends")
@ConfigItem(name = "elasticsearch")
@ConfigDocSection
@ConfigDocMapKey("backend-name")
public Map<String, ElasticsearchBackendBuildTimeConfig> additionalBackends;
public ElasticsearchAdditionalBackendsBuildTimeConfig additionalBackends;

/**
* The class or the name of the bean that should be notified of any failure occurring in a background process
Expand All @@ -44,6 +38,26 @@ public class HibernateSearchElasticsearchBuildTimeConfig {
@ConfigItem
public Optional<Class<?>> backgroundFailureHandler;

@ConfigGroup
public static class ElasticsearchAdditionalBackendsBuildTimeConfig {

/**
* Only useful when defining {@link #backends additional backends}:
* the name of the default backend,
* i.e. the backend that will be assigned to {@code @Indexed} entities
* that do not specify a backend explicitly through {@code @Indexed(backend = ...)}.
*/
@ConfigItem
public Optional<String> defaultBackend;

/**
* Additional backends
*/
@ConfigDocMapKey("backend-name")
public Map<String, ElasticsearchBackendBuildTimeConfig> backends;

}

@ConfigGroup
public static class ElasticsearchBackendBuildTimeConfig {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,20 @@ public void contributeBootProperties(BiConsumer<String, Object> propertyCollecto
EngineSettings.BACKGROUND_FAILURE_HANDLER,
buildTimeConfig.backgroundFailureHandler);

if (buildTimeConfig.defaultBackend.isPresent()) {
if (buildTimeConfig.additionalBackends.defaultBackend.isPresent()) {
// we have a named default backend
addConfig(propertyCollector, EngineSettings.DEFAULT_BACKEND,
buildTimeConfig.defaultBackend.get());
} else if (buildTimeConfig.elasticsearch.version.isPresent()) {
buildTimeConfig.additionalBackends.defaultBackend.get());
} else if (buildTimeConfig.defaultBackend.version.isPresent()) {
// we use the default backend configuration
addConfig(propertyCollector, EngineSettings.DEFAULT_BACKEND,
HibernateSearchElasticsearchRecorder.DEFAULT_BACKEND);
}

contributeBackendBuildTimeProperties(propertyCollector, HibernateSearchElasticsearchRecorder.DEFAULT_BACKEND,
buildTimeConfig.elasticsearch);
buildTimeConfig.defaultBackend);

for (Entry<String, ElasticsearchBackendBuildTimeConfig> backendEntry : buildTimeConfig.additionalBackends
for (Entry<String, ElasticsearchBackendBuildTimeConfig> backendEntry : buildTimeConfig.additionalBackends.backends
.entrySet()) {
contributeBackendBuildTimeProperties(propertyCollector, backendEntry.getKey(), backendEntry.getValue());
}
Expand Down Expand Up @@ -103,7 +103,8 @@ public void contributeRuntimeProperties(BiConsumer<String, Object> propertyColle

contributeBackendRuntimeProperties(propertyCollector, DEFAULT_BACKEND, runtimeConfig.defaultBackend);

for (Entry<String, ElasticsearchBackendRuntimeConfig> backendEntry : runtimeConfig.additionalBackends.entrySet()) {
for (Entry<String, ElasticsearchBackendRuntimeConfig> backendEntry : runtimeConfig.additionalBackends.backends
.entrySet()) {
contributeBackendRuntimeProperties(propertyCollector, backendEntry.getKey(), backendEntry.getValue());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;

@ConfigRoot(name = "hibernate-search.elasticsearch", phase = ConfigPhase.RUN_TIME)
@ConfigRoot(name = "hibernate-search", phase = ConfigPhase.RUN_TIME)
public class HibernateSearchElasticsearchRuntimeConfig {

/**
* Configuration of the default backend.
* Default backend
*/
@ConfigItem(name = ConfigItem.PARENT)
@ConfigItem(name = "elasticsearch")
@ConfigDocSection
ElasticsearchBackendRuntimeConfig defaultBackend;

/**
* Additional backends
*/
@ConfigItem(name = "backends")
@ConfigItem(name = "elasticsearch")
@ConfigDocSection
@ConfigDocMapKey("backend-name")
Map<String, ElasticsearchBackendRuntimeConfig> additionalBackends;
public ElasticsearchAdditionalBackendsRuntimeConfig additionalBackends;

/**
* Configuration for how entities are loaded by a search query.
Expand All @@ -46,6 +46,17 @@ public class HibernateSearchElasticsearchRuntimeConfig {
@ConfigItem
AutomaticIndexingConfig automaticIndexing;

@ConfigGroup
public static class ElasticsearchAdditionalBackendsRuntimeConfig {

/**
* Additional backends
*/
@ConfigDocMapKey("backend-name")
public Map<String, ElasticsearchBackendRuntimeConfig> backends;

}

@ConfigGroup
public static class ElasticsearchBackendRuntimeConfig {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ quarkus.hibernate-orm.database.generation=drop-and-create

quarkus.hibernate-search.elasticsearch.version=7
quarkus.hibernate-search.elasticsearch.analysis.configurer=io.quarkus.it.hibernate.search.elasticsearch.search.DefaultITAnalysisConfigurer
quarkus.hibernate-search.elasticsearch.automatic-indexing.synchronization.strategy=searchable
quarkus.hibernate-search.elasticsearch.index-defaults.lifecycle.strategy=drop-and-create-and-drop
quarkus.hibernate-search.automatic-indexing.synchronization.strategy=searchable