diff --git a/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java b/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java new file mode 100644 index 000000000..4d301a583 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchAotPredicates.java @@ -0,0 +1,35 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.elasticsearch.aot; + +import java.util.function.Predicate; + +import org.springframework.data.util.ReactiveWrappers; + +/** + * @author Peter-Josef Meisch + * @since 5.1 + */ +public class ElasticsearchAotPredicates { + + public static final Predicate IS_REACTIVE_LIBARARY_AVAILABLE = ( + lib) -> ReactiveWrappers.isAvailable(lib); + + public static boolean isReactorPresent() { + return IS_REACTIVE_LIBARARY_AVAILABLE.test(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR); + } + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchRuntimeHints.java b/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchRuntimeHints.java new file mode 100644 index 000000000..049901421 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/aot/ElasticsearchRuntimeHints.java @@ -0,0 +1,75 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.elasticsearch.aot; + +import static org.springframework.data.elasticsearch.aot.ElasticsearchAotPredicates.*; + +import java.util.Arrays; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.data.elasticsearch.client.elc.EntityAsMap; +import org.springframework.data.elasticsearch.core.event.AfterConvertCallback; +import org.springframework.data.elasticsearch.core.event.AfterLoadCallback; +import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; +import org.springframework.data.elasticsearch.core.event.AuditingEntityCallback; +import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterLoadCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveAuditingEntityCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.lang.Nullable; + +/** + * @author Peter-Josef Meisch + * @since 5.1 + */ +public class ElasticsearchRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { + hints.reflection().registerTypes( // + Arrays.asList( // + TypeReference.of(AfterConvertCallback.class), // + TypeReference.of(AfterLoadCallback.class), // + TypeReference.of(AfterSaveCallback.class), // + TypeReference.of(BeforeConvertCallback.class), // + TypeReference.of(EntityAsMap.class) // + ), // + builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_PUBLIC_METHODS)); + + if (isReactorPresent()) { + hints.reflection().registerTypes( // + Arrays.asList( // + TypeReference.of(ReactiveAfterConvertCallback.class), // + TypeReference.of(ReactiveAfterLoadCallback.class), // + TypeReference.of(ReactiveAfterSaveCallback.class), // + TypeReference.of(ReactiveBeforeConvertCallback.class) // + ), // + builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_PUBLIC_METHODS)); + } + + // properties needed to log the different versions + hints.resources().registerPattern("versions.properties"); + hints.resources().registerPattern("co/elastic/clients/version.properties"); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java b/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java new file mode 100644 index 000000000..292bf8a1a --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/aot/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.aot; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java index 9f0026c02..11c4c6a9c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/ElasticsearchTemplate.java @@ -298,7 +298,7 @@ public String getVendor() { @Override public String getRuntimeLibraryVersion() { - return Version.VERSION.toString(); + return Version.VERSION != null ? Version.VERSION.toString() : "0.0.0.?"; } // region search operations diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/aot/ElasticsearchClientRuntimeHints.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/aot/ElasticsearchClientRuntimeHints.java new file mode 100644 index 000000000..48a5be5aa --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/aot/ElasticsearchClientRuntimeHints.java @@ -0,0 +1,39 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.elasticsearch.client.elc.aot; + +import java.util.Arrays; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.lang.Nullable; + +/** + * @author Peter-Josef Meisch + * @since 5.1 + */ +public class ElasticsearchClientRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { + // needed for the http client used by the Elasticsearch client + hints.serialization().registerType(org.apache.http.impl.auth.BasicScheme.class); + hints.serialization().registerType(org.apache.http.impl.auth.RFC2617Scheme.class); + hints.serialization().registerType(java.util.HashMap.class); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/aot/package-info.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/aot/package-info.java new file mode 100644 index 000000000..7d6be368b --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/aot/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.client.elc.aot; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java b/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java new file mode 100644 index 000000000..8de8ca009 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/aot/RepositoryRuntimeHints.java @@ -0,0 +1,50 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.elasticsearch.repository.aot; + +import static org.springframework.data.elasticsearch.aot.ElasticsearchAotPredicates.*; + +import java.util.Arrays; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.lang.Nullable; + +/** + * @author Peter-Josef Meisch + * @since 5.1 + */ +public class RepositoryRuntimeHints implements RuntimeHintsRegistrar { + @Override + public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { + hints.reflection().registerTypes( + Arrays.asList(TypeReference + .of("org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository")), + builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_PUBLIC_METHODS)); + + if (isReactorPresent()) { + hints.reflection().registerTypes( + Arrays.asList(TypeReference + .of("org.springframework.data.elasticsearch.repository.support.SimpleReactiveElasticsearchRepository")), + builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_PUBLIC_METHODS)); + + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java new file mode 100644 index 000000000..1a7c898aa --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/aot/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.repository.aot; diff --git a/src/main/resources/META-INF/spring/aot.factories b/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000..086bf3ef4 --- /dev/null +++ b/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,4 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ + org.springframework.data.elasticsearch.aot.ElasticsearchRuntimeHints,\ + org.springframework.data.elasticsearch.client.elc.aot.ElasticsearchClientRuntimeHints, \ + org.springframework.data.elasticsearch.repository.aot.RepositoryRuntimeHints