Adapt xml-namespace setup to the new Elasticsearch client.

Original Pull Request #2295
Closes #21294
This commit is contained in:
Peter-Josef Meisch 2022-09-10 17:05:32 +02:00 committed by GitHub
parent ccf136c8e2
commit b3a7a44db1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 231 additions and 21 deletions

View File

@ -0,0 +1,47 @@
/*
* Copyright 2022 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;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* @author Peter-Josef Meisch
* @since 5.0
*/
public class ElasticsearchClientBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ElasticsearchClientFactoryBean.class);
setConfigurations(element, builder);
return getSourcedBeanDefinition(builder, element, parserContext);
}
private void setConfigurations(Element element, BeanDefinitionBuilder builder) {
builder.addPropertyValue("hosts", element.getAttribute("hosts"));
}
private AbstractBeanDefinition getSourcedBeanDefinition(BeanDefinitionBuilder builder, Element source,
ParserContext context) {
AbstractBeanDefinition definition = builder.getBeanDefinition();
definition.setSource(context.extractSource(source));
return definition;
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright 2022 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;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.FactoryBeanNotInitializedException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* ElasticsearchClientFactoryBean
*
* @author Peter-Josef Meisch
* @since 5.0
*/
public class ElasticsearchClientFactoryBean
implements FactoryBean<ElasticsearchClient>, InitializingBean, DisposableBean {
private static final Log LOGGER = LogFactory.getLog(ElasticsearchClientFactoryBean.class);
private @Nullable AutoCloseableElasticsearchClient client;
private String hosts = "http://localhost:9200";
static final String COMMA = ",";
@Override
public void destroy() {
try {
LOGGER.info("Closing elasticSearch client");
if (client != null) {
client.close();
}
} catch (final Exception e) {
LOGGER.error("Error closing ElasticSearch client: ", e);
}
}
@Override
public void afterPropertiesSet() throws Exception {
buildClient();
}
@Override
public ElasticsearchClient getObject() {
if (client == null) {
throw new FactoryBeanNotInitializedException();
}
return client;
}
@Override
public Class<?> getObjectType() {
return ElasticsearchClient.class;
}
@Override
public boolean isSingleton() {
return false;
}
protected void buildClient() throws Exception {
Assert.hasText(hosts, "[Assertion Failed] At least one host must be set.");
var clientConfiguration = ClientConfiguration.builder().connectedTo(hosts).build();
client = (AutoCloseableElasticsearchClient) ElasticsearchClients.createImperative(clientConfiguration);
}
public void setHosts(String hosts) {
this.hosts = hosts;
}
public String getHosts() {
return this.hosts;
}
}

View File

@ -13,23 +13,24 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.data.elasticsearch.config; package org.springframework.data.elasticsearch.client.erhlc;
import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext; import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.elasticsearch.client.erhlc.RestClientFactoryBean;
import org.w3c.dom.Element; import org.w3c.dom.Element;
/** /**
* @author Don Wellington * @author Don Wellington
* @deprecated since 5.0
*/ */
public class RestClientBeanDefinitionParser extends AbstractBeanDefinitionParser { @Deprecated
public class RestHighLevelClientBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override @Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(RestClientFactoryBean.class); BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(RestHighLevelClientFactoryBean.class);
setConfigurations(element, builder); setConfigurations(element, builder);
return getSourcedBeanDefinition(builder, element, parserContext); return getSourcedBeanDefinition(builder, element, parserContext);
} }

View File

@ -31,16 +31,17 @@ import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* RestClientFactoryBean * RestHighLevelClientFactoryBean
* *
* @author Don Wellington * @author Don Wellington
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
* @deprecated since 5.0 * @deprecated since 5.0
*/ */
@Deprecated @Deprecated
public class RestClientFactoryBean implements FactoryBean<RestHighLevelClient>, InitializingBean, DisposableBean { public class RestHighLevelClientFactoryBean
implements FactoryBean<RestHighLevelClient>, InitializingBean, DisposableBean {
private static final Log LOGGER = LogFactory.getLog(RestClientFactoryBean.class); private static final Log LOGGER = LogFactory.getLog(RestHighLevelClientFactoryBean.class);
private @Nullable RestHighLevelClient client; private @Nullable RestHighLevelClient client;
private String hosts = "http://localhost:9200"; private String hosts = "http://localhost:9200";

View File

@ -16,6 +16,7 @@
package org.springframework.data.elasticsearch.config; package org.springframework.data.elasticsearch.config;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchClientBeanDefinitionParser;
import org.springframework.data.elasticsearch.repository.config.ElasticsearchRepositoryConfigExtension; import org.springframework.data.elasticsearch.repository.config.ElasticsearchRepositoryConfigExtension;
import org.springframework.data.repository.config.RepositoryBeanDefinitionParser; import org.springframework.data.repository.config.RepositoryBeanDefinitionParser;
import org.springframework.data.repository.config.RepositoryConfigurationExtension; import org.springframework.data.repository.config.RepositoryConfigurationExtension;
@ -35,6 +36,6 @@ public class ElasticsearchNamespaceHandler extends NamespaceHandlerSupport {
RepositoryBeanDefinitionParser parser = new RepositoryBeanDefinitionParser(extension); RepositoryBeanDefinitionParser parser = new RepositoryBeanDefinitionParser(extension);
registerBeanDefinitionParser("repositories", parser); registerBeanDefinitionParser("repositories", parser);
registerBeanDefinitionParser("rest-client", new RestClientBeanDefinitionParser()); registerBeanDefinitionParser("elasticsearch-client", new ElasticsearchClientBeanDefinitionParser());
} }
} }

View File

@ -1,8 +1,10 @@
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-4.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-4.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-5.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-5.0.xsd
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-4.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-4.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-4.0.xsd https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-5.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-5.0.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-5.0.xsd

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.springframework.org/schema/data/elasticsearch"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:repository="http://www.springframework.org/schema/data/repository"
targetNamespace="http://www.springframework.org/schema/data/elasticsearch"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
schemaLocation="https://www.springframework.org/schema/data/repository/spring-repository.xsd"/>
<xsd:element name="repositories">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="repository:repositories">
<xsd:attributeGroup ref="repository:repository-attributes"/>
<xsd:attribute name="elasticsearch-template-ref" type="elasticsearchTemplateRef"
default="elasticsearchTemplate"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="elasticsearchTemplateRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:element name="elasticsearch-client">
<xsd:annotation>
<xsd:documentation/>
<xsd:appinfo>
<tool:assignable-to type="co.elastic.clients.elasticsearch.ElasticsearchClient"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="hosts" type="xsd:string" default="http://127.0.0.1:9200">
<xsd:annotation>
<xsd:documentation>
<![CDATA[The comma delimited list of host:port entries to use for elasticsearch cluster.]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.client.erhlc.RestClientFactoryBean; import org.springframework.data.elasticsearch.client.elc.ElasticsearchClientFactoryBean;
import org.springframework.data.elasticsearch.junit.jupiter.Tags; import org.springframework.data.elasticsearch.junit.jupiter.Tags;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
@ -50,10 +50,11 @@ public class ElasticsearchNamespaceHandlerTests {
} }
@Test @Test
public void shouldCreateRestClient() { public void shouldCreateElasticsearchClient() {
assertThat(context.getBean(RestClientFactoryBean.class)).isNotNull(); assertThat(context.getBean(ElasticsearchClientFactoryBean.class)).isNotNull();
assertThat(context.getBean(RestClientFactoryBean.class)).isInstanceOf(RestClientFactoryBean.class); assertThat(context.getBean(ElasticsearchClientFactoryBean.class))
.isInstanceOf(ElasticsearchClientFactoryBean.class);
} }
@Document(indexName = "test-index-config-namespace", createIndex = false) @Document(indexName = "test-index-config-namespace", createIndex = false)

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch https://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch https://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="elasticsearchTemplate" <bean name="elasticsearchTemplate"
class="org.springframework.data.elasticsearch.client.erhlc.ElasticsearchRestTemplate"> class="org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate">
<constructor-arg name="client" ref="restClient"/> <constructor-arg name="client" ref="elasticsearchClient"/>
</bean> </bean>
<elasticsearch:repositories <elasticsearch:repositories
base-package="org.springframework.data.elasticsearch.config.namespace" base-package="org.springframework.data.elasticsearch.config.namespace"
consider-nested-repositories="true"/> consider-nested-repositories="true"/>
<elasticsearch:rest-client id="restClient"/> <elasticsearch:elasticsearch-client id="elasticsearchClient"/>
</beans> </beans>