Create spring-boot-data-elasticsearch module
This commit is contained in:
committed by
Phillip Webb
parent
f3dd5dae72
commit
fd07ba3860
@@ -0,0 +1,32 @@
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "org.springframework.boot.auto-configuration"
|
||||
id "org.springframework.boot.configuration-properties"
|
||||
id "org.springframework.boot.deployed"
|
||||
id "org.springframework.boot.docker-test"
|
||||
id "org.springframework.boot.optional-dependencies"
|
||||
}
|
||||
|
||||
description = "Spring Boot Data Elasticsearch"
|
||||
|
||||
dependencies {
|
||||
api(project(":spring-boot-project:spring-boot-elasticsearch"))
|
||||
api("org.springframework.data:spring-data-elasticsearch")
|
||||
|
||||
optional(project(":spring-boot-project:spring-boot-autoconfigure"))
|
||||
optional("io.projectreactor:reactor-core")
|
||||
|
||||
dockerTestImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
dockerTestImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support-docker"))
|
||||
dockerTestImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure")))
|
||||
dockerTestImplementation("ch.qos.logback:logback-classic")
|
||||
dockerTestImplementation("org.junit.jupiter:junit-jupiter")
|
||||
dockerTestImplementation("org.testcontainers:elasticsearch")
|
||||
dockerTestImplementation("org.testcontainers:junit-jupiter")
|
||||
|
||||
testImplementation(project(":spring-boot-project:spring-boot-test"))
|
||||
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
|
||||
testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure")))
|
||||
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.elasticsearch.ElasticsearchContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.data.elasticsearch.domain.city.City;
|
||||
import org.springframework.boot.data.elasticsearch.domain.city.CityRepository;
|
||||
import org.springframework.boot.data.elasticsearch.domain.empty.EmptyDataPackage;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.container.TestImage;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.config.EnableElasticsearchAuditing;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class ElasticsearchRepositoriesAutoConfigurationTests {
|
||||
|
||||
@Container
|
||||
static final ElasticsearchContainer elasticsearch = TestImage.container(ElasticsearchContainer.class);
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
|
||||
ElasticsearchClientAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class))
|
||||
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress());
|
||||
|
||||
@Test
|
||||
void testDefaultRepositoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(CityRepository.class)
|
||||
.hasSingleBean(ElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoRepositoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
this.contextRunner.withUserConfiguration(CustomizedConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(CityRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuditingConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(AuditingConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
@EnableElasticsearchRepositories(basePackageClasses = CityRepository.class)
|
||||
static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
@EnableElasticsearchRepositories
|
||||
@EnableElasticsearchAuditing
|
||||
static class AuditingConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.elasticsearch.ElasticsearchContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.data.elasticsearch.domain.city.City;
|
||||
import org.springframework.boot.data.elasticsearch.domain.city.ReactiveCityRepository;
|
||||
import org.springframework.boot.data.elasticsearch.domain.empty.EmptyDataPackage;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ReactiveElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.container.TestImage;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.config.EnableElasticsearchAuditing;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReactiveElasticsearchRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
class ReactiveElasticsearchRepositoriesAutoConfigurationTests {
|
||||
|
||||
@Container
|
||||
static final ElasticsearchContainer elasticsearch = TestImage.container(ElasticsearchContainer.class);
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ElasticsearchClientAutoConfiguration.class,
|
||||
ElasticsearchRestClientAutoConfiguration.class,
|
||||
ReactiveElasticsearchRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class,
|
||||
ReactiveElasticsearchClientAutoConfiguration.class))
|
||||
.withPropertyValues(
|
||||
"spring.elasticsearch.uris=" + elasticsearch.getHost() + ":" + elasticsearch.getFirstMappedPort(),
|
||||
"spring.elasticsearch.socket-timeout=30s");
|
||||
|
||||
@Test
|
||||
void backsOffWithoutReactor() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.withClassLoader(new FilteredClassLoader(Mono.class))
|
||||
.run((context) -> assertThat(context)
|
||||
.doesNotHaveBean(ReactiveElasticsearchRepositoriesAutoConfiguration.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultRepositoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveCityRepository.class)
|
||||
.hasSingleBean(ReactiveElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNoRepositoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
this.contextRunner.withUserConfiguration(CustomizedConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveCityRepository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAuditingConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(AuditingConfiguration.class)
|
||||
.run((context) -> assertThat(context).hasSingleBean(ReactiveElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
@EnableReactiveElasticsearchRepositories(basePackageClasses = ReactiveCityRepository.class)
|
||||
static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
@EnableReactiveElasticsearchRepositories
|
||||
@EnableElasticsearchAuditing
|
||||
static class AuditingConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.domain.empty;
|
||||
|
||||
public class EmptyDataPackage {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ReactiveElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch
|
||||
* support.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
* @since 4.0.0
|
||||
* @see EnableElasticsearchRepositories
|
||||
* @see EnableReactiveElasticsearchRepositories
|
||||
*/
|
||||
@AutoConfiguration(
|
||||
after = { ElasticsearchClientAutoConfiguration.class, ReactiveElasticsearchClientAutoConfiguration.class })
|
||||
@ConditionalOnClass({ ElasticsearchTemplate.class })
|
||||
@Import({ ElasticsearchDataConfiguration.BaseConfiguration.class,
|
||||
ElasticsearchDataConfiguration.JavaClientConfiguration.class,
|
||||
ElasticsearchDataConfiguration.ReactiveRestClientConfiguration.class })
|
||||
public class ElasticsearchDataAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import co.elastic.clients.elasticsearch.ElasticsearchClient;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScanner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient;
|
||||
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
|
||||
/**
|
||||
* Configuration classes for Spring Data for Elasticsearch
|
||||
* <p>
|
||||
* Those should be {@code @Import} in a regular auto-configuration class to guarantee
|
||||
* their order of execution.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Scott Frederick
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
abstract class ElasticsearchDataConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ElasticsearchCustomConversions elasticsearchCustomConversions() {
|
||||
return new ElasticsearchCustomConversions(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SimpleElasticsearchMappingContext elasticsearchMappingContext(ApplicationContext applicationContext,
|
||||
ElasticsearchCustomConversions elasticsearchCustomConversions) throws ClassNotFoundException {
|
||||
SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext();
|
||||
mappingContext.setInitialEntitySet(new EntityScanner(applicationContext).scan(Document.class));
|
||||
mappingContext.setSimpleTypeHolder(elasticsearchCustomConversions.getSimpleTypeHolder());
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
ElasticsearchConverter elasticsearchConverter(SimpleElasticsearchMappingContext mappingContext,
|
||||
ElasticsearchCustomConversions elasticsearchCustomConversions) {
|
||||
MappingElasticsearchConverter converter = new MappingElasticsearchConverter(mappingContext);
|
||||
converter.setConversions(elasticsearchCustomConversions);
|
||||
return converter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(ElasticsearchClient.class)
|
||||
static class JavaClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ElasticsearchOperations.class, name = "elasticsearchTemplate")
|
||||
@ConditionalOnBean(ElasticsearchClient.class)
|
||||
ElasticsearchTemplate elasticsearchTemplate(ElasticsearchClient client, ElasticsearchConverter converter) {
|
||||
return new ElasticsearchTemplate(client, converter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ReactiveRestClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ReactiveElasticsearchOperations.class, name = "reactiveElasticsearchTemplate")
|
||||
@ConditionalOnBean(ReactiveElasticsearchClient.class)
|
||||
ReactiveElasticsearchTemplate reactiveElasticsearchTemplate(ReactiveElasticsearchClient client,
|
||||
ElasticsearchConverter converter) {
|
||||
return new ReactiveElasticsearchTemplate(client, converter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch
|
||||
* Repositories.
|
||||
*
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
* @since 4.0.0
|
||||
* @see EnableElasticsearchRepositories
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(ElasticsearchRepository.class)
|
||||
@ConditionalOnBooleanProperty(name = "spring.data.elasticsearch.repositories.enabled", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean(ElasticsearchRepositoryFactoryBean.class)
|
||||
@Import(ElasticsearchRepositoriesRegistrar.class)
|
||||
public class ElasticsearchRepositoriesAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.data.elasticsearch.repository.config.ElasticsearchRepositoryConfigExtension;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Elasticsearch
|
||||
* Repositories.
|
||||
*
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
*/
|
||||
class ElasticsearchRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
return EnableElasticsearchRepositories.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getConfiguration() {
|
||||
return EnableElasticsearchRepositoriesConfiguration.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
|
||||
return new ElasticsearchRepositoryConfigExtension();
|
||||
}
|
||||
|
||||
@EnableElasticsearchRepositories
|
||||
private static final class EnableElasticsearchRepositoriesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient;
|
||||
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.support.ReactiveElasticsearchRepositoryFactoryBean;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch
|
||||
* Reactive Repositories.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 4.0.0
|
||||
* @see EnableReactiveElasticsearchRepositories
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ReactiveElasticsearchClient.class, ReactiveElasticsearchRepository.class, Mono.class })
|
||||
@ConditionalOnBooleanProperty(name = "spring.data.elasticsearch.repositories.enabled", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean(ReactiveElasticsearchRepositoryFactoryBean.class)
|
||||
@Import(ReactiveElasticsearchRepositoriesRegistrar.class)
|
||||
public class ReactiveElasticsearchRepositoriesAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.config.ReactiveElasticsearchRepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Elasticsearch
|
||||
* Reactive Repositories.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
class ReactiveElasticsearchRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
return EnableReactiveElasticsearchRepositories.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getConfiguration() {
|
||||
return EnableElasticsearchRepositoriesConfiguration.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
|
||||
return new ReactiveElasticsearchRepositoryConfigurationExtension();
|
||||
}
|
||||
|
||||
@EnableReactiveElasticsearchRepositories
|
||||
private static final class EnableElasticsearchRepositoriesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Spring Data Elasticsearch.
|
||||
*/
|
||||
package org.springframework.boot.data.elasticsearch.autoconfigure;
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"groups": [],
|
||||
"properties": [
|
||||
{
|
||||
"name": "spring.data.elasticsearch.cluster-name",
|
||||
"type": "java.lang.String",
|
||||
"description": "Elasticsearch cluster name.",
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.elasticsearch.cluster-nodes",
|
||||
"type": "java.lang.String",
|
||||
"description": "Comma-separated list of cluster node addresses.",
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.elasticsearch.properties",
|
||||
"type": "java.util.Map<java.lang.String,java.lang.String>",
|
||||
"description": "Additional properties used to configure the client.",
|
||||
"deprecation": {
|
||||
"level": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spring.data.elasticsearch.repositories.enabled",
|
||||
"type": "java.lang.Boolean",
|
||||
"description": "Whether to enable Elasticsearch repositories.",
|
||||
"defaultValue": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchDataAutoConfiguration
|
||||
org.springframework.boot.data.elasticsearch.autoconfigure.ElasticsearchRepositoriesAutoConfiguration
|
||||
org.springframework.boot.data.elasticsearch.autoconfigure.ReactiveElasticsearchRepositoriesAutoConfiguration
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.autoconfigure;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.data.elasticsearch.domain.city.City;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchRestClientAutoConfiguration;
|
||||
import org.springframework.boot.elasticsearch.autoconfigure.ReactiveElasticsearchClientAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ElasticsearchDataAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Artur Konczak
|
||||
* @author Brian Clozel
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Scott Frederick
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class ElasticsearchDataAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
|
||||
ElasticsearchClientAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class,
|
||||
ReactiveElasticsearchClientAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void defaultRestBeansRegistered() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ElasticsearchTemplate.class)
|
||||
.hasSingleBean(ReactiveElasticsearchTemplate.class)
|
||||
.hasSingleBean(ElasticsearchConverter.class)
|
||||
.hasSingleBean(ElasticsearchConverter.class)
|
||||
.hasSingleBean(ElasticsearchCustomConversions.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultConversionsRegisterBigDecimalAsSimpleType() {
|
||||
this.contextRunner.run((context) -> {
|
||||
SimpleElasticsearchMappingContext mappingContext = context.getBean(SimpleElasticsearchMappingContext.class);
|
||||
assertThat(mappingContext)
|
||||
.extracting("simpleTypeHolder", InstanceOfAssertFactories.type(SimpleTypeHolder.class))
|
||||
.satisfies((simpleTypeHolder) -> assertThat(simpleTypeHolder.isSimpleType(BigDecimal.class)).isTrue());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customConversionsShouldBeUsed() {
|
||||
this.contextRunner.withUserConfiguration(CustomElasticsearchCustomConversions.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(ElasticsearchCustomConversions.class).hasBean("testCustomConversions");
|
||||
assertThat(context.getBean(ElasticsearchConverter.class)
|
||||
.getConversionService()
|
||||
.canConvert(ElasticsearchTemplate.class, Boolean.class)).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customRestTemplateShouldBeUsed() {
|
||||
this.contextRunner.withUserConfiguration(CustomRestTemplate.class)
|
||||
.run((context) -> assertThat(context).getBeanNames(ElasticsearchTemplate.class)
|
||||
.hasSize(1)
|
||||
.contains("elasticsearchTemplate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customReactiveRestTemplateShouldBeUsed() {
|
||||
this.contextRunner.withUserConfiguration(CustomReactiveElasticsearchTemplate.class)
|
||||
.run((context) -> assertThat(context).getBeanNames(ReactiveElasticsearchTemplate.class)
|
||||
.hasSize(1)
|
||||
.contains("reactiveElasticsearchTemplate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFilterInitialEntityScanWithDocumentAnnotation() {
|
||||
this.contextRunner.withUserConfiguration(EntityScanConfig.class).run((context) -> {
|
||||
SimpleElasticsearchMappingContext mappingContext = context.getBean(SimpleElasticsearchMappingContext.class);
|
||||
assertThat(mappingContext.hasPersistentEntityFor(City.class)).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomElasticsearchCustomConversions {
|
||||
|
||||
@Bean
|
||||
ElasticsearchCustomConversions testCustomConversions() {
|
||||
return new ElasticsearchCustomConversions(Collections.singletonList(new MyConverter()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomRestTemplate {
|
||||
|
||||
@Bean
|
||||
ElasticsearchTemplate elasticsearchTemplate() {
|
||||
return mock(ElasticsearchTemplate.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomReactiveElasticsearchTemplate {
|
||||
|
||||
@Bean
|
||||
ReactiveElasticsearchTemplate reactiveElasticsearchTemplate() {
|
||||
return mock(ReactiveElasticsearchTemplate.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class EntityScanConfig {
|
||||
|
||||
}
|
||||
|
||||
static class MyConverter implements Converter<ElasticsearchTemplate, Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean convert(ElasticsearchTemplate source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.domain.city;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
|
||||
@Document(indexName = "city")
|
||||
@Setting(shards = 1, replicas = 0, refreshInterval = "-1")
|
||||
public class City implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String state;
|
||||
|
||||
private String country;
|
||||
|
||||
private String map;
|
||||
|
||||
protected City() {
|
||||
}
|
||||
|
||||
public City(String name, String country) {
|
||||
this.name = name;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return this.country;
|
||||
}
|
||||
|
||||
public String getMap() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() + "," + getState() + "," + getCountry();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.domain.city;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
public interface CityRepository extends Repository<City, Long> {
|
||||
|
||||
Page<City> findAll(Pageable pageable);
|
||||
|
||||
Page<City> findByNameLikeAndCountryLikeAllIgnoringCase(String name, String country, Pageable pageable);
|
||||
|
||||
City findByNameAndCountryAllIgnoringCase(String name, String country);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.boot.data.elasticsearch.domain.city;
|
||||
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
|
||||
public interface ReactiveCityRepository extends ReactiveCrudRepository<City, String> {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user