Skip to content

Commit

Permalink
Merge pull request quarkusio#39416 from yrodiere/backend-elasticsearc…
Browse files Browse the repository at this point in the history
…h-shared

Shared extension for the Hibernate Search Elasticsearch backend
  • Loading branch information
gsmet authored Nov 29, 2024
2 parents 89bc558 + 1c43f90 commit 0f88242
Show file tree
Hide file tree
Showing 36 changed files with 1,321 additions and 1,633 deletions.
10 changes: 10 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,16 @@
<artifactId>quarkus-mongodb-panache-common-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-orm-elasticsearch</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions devtools/bom-descriptor-json/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-orm-elasticsearch</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-orm-elasticsearch-deployment</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-hibernate-search-backend-elasticsearch-common-deployment</artifactId>
<name>Quarkus - Hibernate Search - Elasticsearch - Deployment</name>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elasticsearch-rest-client-common-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.quarkus.hibernate.search.backend.elasticsearch.common.deployment;

import java.util.Map;

import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.hibernate.search.backend.elasticsearch.common.runtime.HibernateSearchBackendElasticsearchBuildTimeConfig;
import io.quarkus.hibernate.search.backend.elasticsearch.common.runtime.MapperContext;

public final class HibernateSearchBackendElasticsearchEnabledBuildItem extends MultiBuildItem {

private final MapperContext mapperContext;
private final Map<String, HibernateSearchBackendElasticsearchBuildTimeConfig> buildTimeConfig;

public HibernateSearchBackendElasticsearchEnabledBuildItem(MapperContext mapperContext,
Map<String, HibernateSearchBackendElasticsearchBuildTimeConfig> buildTimeConfig) {
this.mapperContext = mapperContext;
this.buildTimeConfig = buildTimeConfig;
}

public MapperContext getMapperContext() {
return mapperContext;
}

public Map<String, HibernateSearchBackendElasticsearchBuildTimeConfig> getBuildTimeConfig() {
return buildTimeConfig;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package io.quarkus.hibernate.search.backend.elasticsearch.common.deployment;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;

import org.hibernate.search.backend.elasticsearch.analysis.ElasticsearchAnalysisConfigurer;
import org.hibernate.search.backend.elasticsearch.gson.spi.GsonClasses;
import org.hibernate.search.backend.elasticsearch.index.layout.IndexLayoutStrategy;

import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildSteps;
import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem;
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.hibernate.search.backend.elasticsearch.common.runtime.HibernateSearchBackendElasticsearchBuildTimeConfig;
import io.quarkus.hibernate.search.backend.elasticsearch.common.runtime.MapperContext;
import io.quarkus.runtime.configuration.ConfigurationException;

@BuildSteps
class HibernateSearchBackendElasticsearchProcessor {

@BuildStep
void registerBeans(List<HibernateSearchBackendElasticsearchEnabledBuildItem> enabled,
BuildProducer<UnremovableBeanBuildItem> unremovableBean) {
if (enabled.isEmpty()) {
return;
}
// Some user-injectable beans are retrieved programmatically and shouldn't be removed
unremovableBean.produce(UnremovableBeanBuildItem.beanTypes(ElasticsearchAnalysisConfigurer.class,
IndexLayoutStrategy.class));
}

@BuildStep
void registerReflectionForGson(List<HibernateSearchBackendElasticsearchEnabledBuildItem> enabled,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
if (enabled.isEmpty()) {
return;
}
String[] reflectiveClasses = GsonClasses.typesRequiringReflection().toArray(String[]::new);
reflectiveClass.produce(ReflectiveClassBuildItem.builder(reflectiveClasses)
.reason(getClass().getName())
.methods().fields().build());
}

@BuildStep
void processBuildTimeConfig(List<HibernateSearchBackendElasticsearchEnabledBuildItem> enabled,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles) {
if (enabled.isEmpty()) {
return;
}
for (HibernateSearchBackendElasticsearchEnabledBuildItem enabledItem : enabled) {
processBuildTimeConfig(enabledItem, applicationArchivesBuildItem, nativeImageResources,
hotDeploymentWatchedFiles);
}
}

private void processBuildTimeConfig(HibernateSearchBackendElasticsearchEnabledBuildItem enabled,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles) {
Set<String> propertyKeysWithNoVersion = new LinkedHashSet<>();
var buildTimeConfig = enabled.getBuildTimeConfig();

var mapperContext = enabled.getMapperContext();
Set<String> allBackendNames = new LinkedHashSet<>(mapperContext.getBackendNamesForIndexedEntities());
allBackendNames.addAll(buildTimeConfig.keySet());
// For all backends referenced either through @Indexed(backend = ...) or configuration...
for (String backendName : allBackendNames) {
HibernateSearchBackendElasticsearchBuildTimeConfig backendConfig = buildTimeConfig.get(backendName);
// ... we validate that the backend is configured and the version is present
if (backendConfig == null || backendConfig.version().isEmpty()) {
propertyKeysWithNoVersion.add(mapperContext.backendPropertyKey(backendName, null, "version"));
}
if (backendConfig == null) {
continue;
}
// ... we register files referenced from backends configuration
registerClasspathFilesFromBackendConfig(mapperContext, backendName, backendConfig,
applicationArchivesBuildItem, nativeImageResources, hotDeploymentWatchedFiles);
}
if (!propertyKeysWithNoVersion.isEmpty()) {
throw new ConfigurationException(
"The Elasticsearch version needs to be defined via properties: "
+ String.join(", ", propertyKeysWithNoVersion) + ".",
propertyKeysWithNoVersion);
}
}

private static void registerClasspathFilesFromBackendConfig(MapperContext mapperContext, String backendName,
HibernateSearchBackendElasticsearchBuildTimeConfig backendConfig,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles) {
registerClasspathFilesFromIndexConfig(mapperContext, backendName, null, backendConfig.indexDefaults(),
applicationArchivesBuildItem, nativeImageResources, hotDeploymentWatchedFiles);
for (Entry<String, HibernateSearchBackendElasticsearchBuildTimeConfig.IndexConfig> entry : backendConfig.indexes()
.entrySet()) {
String indexName = entry.getKey();
HibernateSearchBackendElasticsearchBuildTimeConfig.IndexConfig indexConfig = entry.getValue();
registerClasspathFilesFromIndexConfig(mapperContext, backendName, indexName, indexConfig,
applicationArchivesBuildItem, nativeImageResources, hotDeploymentWatchedFiles);
}
}

private static void registerClasspathFilesFromIndexConfig(MapperContext mapperContext, String backendName, String indexName,
HibernateSearchBackendElasticsearchBuildTimeConfig.IndexConfig indexConfig,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles) {
registerClasspathFileFromConfig(mapperContext, backendName, indexName, "schema-management.settings-file",
indexConfig.schemaManagement().settingsFile(),
applicationArchivesBuildItem, nativeImageResources, hotDeploymentWatchedFiles);
registerClasspathFileFromConfig(mapperContext, backendName, indexName, "schema-management.mapping-file",
indexConfig.schemaManagement().mappingFile(),
applicationArchivesBuildItem, nativeImageResources, hotDeploymentWatchedFiles);
}

private static void registerClasspathFileFromConfig(MapperContext mapperContext, String backendName, String indexName,
String propertyKeyRadical,
Optional<String> classpathFileOptional,
ApplicationArchivesBuildItem applicationArchivesBuildItem,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
BuildProducer<HotDeploymentWatchedFileBuildItem> hotDeploymentWatchedFiles) {
if (!classpathFileOptional.isPresent()) {
return;
}
String classpathFile = classpathFileOptional.get();

Path existingPath = applicationArchivesBuildItem.getRootArchive().getChildPath(classpathFile);

if (existingPath == null || Files.isDirectory(existingPath)) {
//raise exception if explicit file is not present (i.e. not the default)
throw new ConfigurationException(
"Unable to find file referenced in '"
+ mapperContext.backendPropertyKey(backendName, indexName, propertyKeyRadical) + "="
+ classpathFile
+ "'. Remove property or add file to your path.");
}
nativeImageResources.produce(new NativeImageResourceBuildItem(classpathFile));
hotDeploymentWatchedFiles.produce(new HotDeploymentWatchedFileBuildItem(classpathFile));
}

}
20 changes: 20 additions & 0 deletions extensions/hibernate-search-backend-elasticsearch-common/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-extensions-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-hibernate-search-backend-elasticsearch-common-parent</artifactId>
<name>Quarkus - Hibernate Search - Elasticsearch</name>
<packaging>pom</packaging>
<modules>
<module>deployment</module>
<module>runtime</module>
</modules>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-hibernate-search-backend-elasticsearch-common-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-hibernate-search-backend-elasticsearch-common</artifactId>
<name>Quarkus - Hibernate Search - Elasticsearch - Runtime</name>
<description>Elasticsearch/OpenSearch backend for use in other Hibernate Search extensions</description>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elasticsearch-rest-client-common</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.search</groupId>
<artifactId>hibernate-search-backend-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-extension-processor</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.quarkus.hibernate.search.orm.elasticsearch.runtime;
package io.quarkus.hibernate.search.backend.elasticsearch.common.runtime;

import org.hibernate.search.backend.elasticsearch.ElasticsearchVersion;

Expand Down
Loading

0 comments on commit 0f88242

Please sign in to comment.