From f824f4f1e9e22c064719800c6b8fb60367938f66 Mon Sep 17 00:00:00 2001 From: "mohsin.husen" Date: Sat, 23 Nov 2013 11:31:40 +0000 Subject: [PATCH] DATAES-38 : Add/Remove/Get Alias Support --- .../core/ElasticsearchOperations.java | 24 +++++++ .../core/ElasticsearchTemplate.java | 32 ++++++++++ .../core/query/AliasBuilder.java | 60 ++++++++++++++++++ .../elasticsearch/core/query/AliasQuery.java | 62 +++++++++++++++++++ .../EnableElasticsearchRepositoriesTests.java | 2 +- .../core/ElasticsearchTemplateTests.java | 37 +++++++++++ 6 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 54f403cde..7996ec864 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -21,6 +21,7 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverte import org.springframework.data.elasticsearch.core.query.*; import java.util.List; +import java.util.Set; /** * ElasticsearchOperations @@ -319,4 +320,27 @@ public interface ElasticsearchOperations { */ Page moreLikeThis(MoreLikeThisQuery query, Class clazz); + /** + * adding new alias + * + * @param query + * @return + */ + Boolean addAlias(AliasQuery query); + + /** + * removing previously created alias + * + * @param query + * @return + */ + Boolean removeAlias(AliasQuery query); + + /** + * get all the alias pointing to specified index + * + * @param indexName + * @return + */ + Set queryForAlias(String indexName); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index a4cc3e0ef..e53e4ea23 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -16,6 +16,8 @@ package org.springframework.data.elasticsearch.core; import org.apache.commons.collections.CollectionUtils; +import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.mapping.delete.DeleteMappingRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; @@ -59,6 +61,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.lang.StringUtils.isBlank; @@ -544,6 +547,35 @@ public class ElasticsearchTemplate implements ElasticsearchOperations { .refresh(refreshRequest(persistentEntity.getIndexName()).force(waitForOperation)).actionGet(); } + public Boolean addAlias(AliasQuery query) { + Assert.notNull(query.getIndexName(), "No index defined for Alias"); + Assert.notNull(query.getAliasName(), "No alias defined"); + IndicesAliasesRequestBuilder indicesAliasesRequestBuilder = null; + if(query.getFilterBuilder() != null) { + indicesAliasesRequestBuilder = client.admin().indices().prepareAliases().addAlias(query.getIndexName(), query.getAliasName(), query.getFilterBuilder()); + } else if(query.getFilter() != null) { + indicesAliasesRequestBuilder = client.admin().indices().prepareAliases().addAlias(query.getIndexName(), query.getAliasName(), query.getFilter()); + } else { + indicesAliasesRequestBuilder = client.admin().indices().prepareAliases().addAlias(query.getIndexName(), query.getAliasName()); + } + return indicesAliasesRequestBuilder.execute().actionGet().isAcknowledged(); + } + + public Boolean removeAlias(AliasQuery query) { + Assert.notNull(query.getIndexName(), "No index defined for Alias"); + Assert.notNull(query.getAliasName(), "No alias defined"); + return client.admin().indices().prepareAliases().removeAlias(query.getIndexName(), query.getAliasName()) + .execute().actionGet().isAcknowledged(); + } + + public Set queryForAlias(String indexName) { + ClusterStateRequest clusterStateRequest = Requests.clusterStateRequest() + .filterRoutingTable(true) + .filterNodes(true) + .filteredIndices(indexName); + return client.admin().cluster().state(clusterStateRequest).actionGet().getState().getMetaData().aliases().keySet(); + } + private ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) { Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName() + " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java new file mode 100644 index 000000000..ab6b1460b --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013 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 + * + * http://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.core.query; + +import org.elasticsearch.index.query.FilterBuilder; + +import java.util.Map; +/** + * + * @author Mohsin Husen + */ +public class AliasBuilder { + + private String indexName; + private String aliasName; + private FilterBuilder filterBuilder; + private Map filter; + + public AliasBuilder withIndexName(String indexName){ + this.indexName = indexName; + return this; + } + + public AliasBuilder withAliasName(String aliasName){ + this.aliasName = aliasName; + return this; + } + + public AliasBuilder withFilterBuilder(FilterBuilder filterBuilder){ + this.filterBuilder = filterBuilder; + return this; + } + + public AliasBuilder withFilter(Map filter){ + this.filter = filter; + return this; + } + + public AliasQuery build(){ + AliasQuery aliasQuery = new AliasQuery(); + aliasQuery.setIndexName(indexName); + aliasQuery.setAliasName(aliasName); + aliasQuery.setFilterBuilder(filterBuilder); + aliasQuery.setFilter(filter); + return aliasQuery; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java new file mode 100644 index 000000000..3f5c52448 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java @@ -0,0 +1,62 @@ +/* + * Copyright 2013 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 + * + * http://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.core.query; +import org.elasticsearch.index.query.FilterBuilder; +import java.util.Map; +/** + * AliasQuery is useful for creating new alias or deleting existing ones + * + * @author Mohsin Husen + */ +public class AliasQuery { + + private String indexName; + private String aliasName; + private FilterBuilder filterBuilder; + private Map filter; + + public String getIndexName() { + return indexName; + } + + public void setIndexName(String indexName) { + this.indexName = indexName; + } + + public String getAliasName() { + return aliasName; + } + + public void setAliasName(String aliasName) { + this.aliasName = aliasName; + } + + public FilterBuilder getFilterBuilder() { + return filterBuilder; + } + + public void setFilterBuilder(FilterBuilder filterBuilder) { + this.filterBuilder = filterBuilder; + } + + public Map getFilter() { + return filter; + } + + public void setFilter(Map filter) { + this.filter = filter; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/EnableElasticsearchRepositoriesTests.java index ec9b0fbcf..2e5e881db 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/EnableElasticsearchRepositoriesTests.java @@ -46,7 +46,7 @@ public class EnableElasticsearchRepositoriesTests { @Bean public ElasticsearchOperations elasticsearchTemplate() { - return new ElasticsearchTemplate(nodeBuilder().local(true).clusterName("testCluster").node().client()); + return new ElasticsearchTemplate(nodeBuilder().local(true).clusterName("testCluster2").node().client()); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 592c610d2..5247816c9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -39,6 +39,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.ArrayList; import java.util.List; +import java.util.Set; import static org.apache.commons.lang.RandomStringUtils.randomNumeric; import static org.elasticsearch.index.query.FilterBuilders.boolFilter; @@ -858,4 +859,40 @@ public class ElasticsearchTemplateTests { assertThat(sampleEntities.getTotalElements(), equalTo(0L)); } + @Test + public void shouldAddAlias(){ + // given + elasticsearchTemplate.createIndex(SampleEntity.class); + AliasQuery aliasQuery = new AliasBuilder() + .withIndexName("test-index") + .withAliasName("test-alias").build(); + // when + elasticsearchTemplate.addAlias(aliasQuery); + // then + Set aliases = elasticsearchTemplate.queryForAlias("test-index"); + assertThat(aliases, is(notNullValue())); + assertThat(aliases.contains("test-alias"), is(true)); + } + + @Test + public void shouldRemoveAlias(){ + // given + elasticsearchTemplate.createIndex(SampleEntity.class); + String indexName = "test-index"; + String aliasName = "test-alias"; + AliasQuery aliasQuery = new AliasBuilder() + .withIndexName(indexName) + .withAliasName(aliasName).build(); + // when + elasticsearchTemplate.addAlias(aliasQuery); + Set aliases = elasticsearchTemplate.queryForAlias(indexName); + assertThat(aliases, is(notNullValue())); + assertThat(aliases.contains(aliasName), is(true)); + // then + elasticsearchTemplate.removeAlias(aliasQuery); + aliases = elasticsearchTemplate.queryForAlias(indexName); + assertThat(aliases, is(notNullValue())); + assertThat(aliases.size(), is(0)); + } + }