Skip to content

Commit 3d5d25b

Browse files
imotovkimchy
authored andcommitted
Add IndexAliasService
1 parent 10de33c commit 3d5d25b

File tree

10 files changed

+446
-1
lines changed

10 files changed

+446
-1
lines changed

modules/elasticsearch/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public Builder(String alias) {
7777

7878
public Builder(AliasMetaData aliasMetaData) {
7979
this(aliasMetaData.alias());
80+
filter = aliasMetaData.filter();
8081
}
8182

8283
public String alias() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.aliases;
21+
22+
import org.apache.lucene.search.Filter;
23+
import org.elasticsearch.common.Nullable;
24+
import org.elasticsearch.common.compress.CompressedString;
25+
26+
/**
27+
* @author imotov
28+
*/
29+
public class IndexAlias {
30+
31+
private String alias;
32+
33+
private CompressedString filter;
34+
35+
private Filter parsedFilter;
36+
37+
public IndexAlias(String alias, @Nullable CompressedString filter, @Nullable Filter parsedFilter) {
38+
this.alias = alias;
39+
this.filter = filter;
40+
this.parsedFilter = parsedFilter;
41+
}
42+
43+
public String alias() {
44+
return alias;
45+
}
46+
47+
@Nullable
48+
public CompressedString filter() {
49+
return filter;
50+
}
51+
52+
@Nullable
53+
public Filter parsedFilter() {
54+
return parsedFilter;
55+
}
56+
57+
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.aliases;
21+
22+
import org.apache.lucene.search.*;
23+
import org.elasticsearch.common.Nullable;
24+
import org.elasticsearch.common.collect.ImmutableMap;
25+
import org.elasticsearch.common.collect.UnmodifiableIterator;
26+
import org.elasticsearch.common.compress.CompressedString;
27+
import org.elasticsearch.common.inject.Inject;
28+
import org.elasticsearch.common.lucene.search.XBooleanFilter;
29+
import org.elasticsearch.common.settings.Settings;
30+
import org.elasticsearch.common.xcontent.XContentFactory;
31+
import org.elasticsearch.common.xcontent.XContentParser;
32+
import org.elasticsearch.index.AbstractIndexComponent;
33+
import org.elasticsearch.index.Index;
34+
import org.elasticsearch.index.query.IndexQueryParserService;
35+
import org.elasticsearch.index.query.xcontent.XContentIndexQueryParser;
36+
import org.elasticsearch.index.settings.IndexSettings;
37+
import org.elasticsearch.indices.AliasFilterParsingException;
38+
39+
import java.io.IOException;
40+
import java.util.List;
41+
42+
import static org.elasticsearch.common.collect.Lists.newArrayList;
43+
import static org.elasticsearch.common.collect.MapBuilder.newMapBuilder;
44+
45+
/**
46+
* @author imotov
47+
*/
48+
public class IndexAliasesService extends AbstractIndexComponent implements Iterable<IndexAlias> {
49+
50+
private final IndexQueryParserService indexQueryParserService;
51+
52+
private volatile ImmutableMap<String, IndexAlias> aliases = ImmutableMap.of();
53+
54+
private final Object mutex = new Object();
55+
56+
@Inject public IndexAliasesService(Index index, @IndexSettings Settings indexSettings, IndexQueryParserService indexQueryParserService) {
57+
super(index, indexSettings);
58+
this.indexQueryParserService = indexQueryParserService;
59+
}
60+
61+
public boolean hasAlias(String alias) {
62+
return aliases.containsKey(alias);
63+
}
64+
65+
public IndexAlias alias(String alias) {
66+
return aliases.get(alias);
67+
}
68+
69+
public void add(String alias, @Nullable CompressedString filter) {
70+
add(new IndexAlias(alias, filter, parse(alias, filter)));
71+
}
72+
73+
public Filter aliasFilter(String... indices) {
74+
List<Filter> filters = null;
75+
for (String alias : indices) {
76+
// The list contains the index itself - no filtering needed
77+
if (alias.equals(index.name())) {
78+
return null;
79+
}
80+
IndexAlias indexAlias = aliases.get(alias);
81+
if (indexAlias != null) {
82+
// The list contains a non-filtering alias - no filtering needed
83+
if (indexAlias.parsedFilter() == null) {
84+
return null;
85+
} else {
86+
if (filters == null) {
87+
filters = newArrayList();
88+
}
89+
filters.add(indexAlias.parsedFilter());
90+
}
91+
}
92+
}
93+
if (filters == null) {
94+
return null;
95+
}
96+
if (filters.size() == 1) {
97+
return filters.get(0);
98+
} else {
99+
XBooleanFilter combined = new XBooleanFilter();
100+
for (Filter filter : filters) {
101+
combined.add(new FilterClause(filter, BooleanClause.Occur.SHOULD));
102+
}
103+
return combined;
104+
}
105+
}
106+
107+
private void add(IndexAlias indexAlias) {
108+
synchronized (mutex) {
109+
aliases = newMapBuilder(aliases).put(indexAlias.alias(), indexAlias).immutableMap();
110+
}
111+
}
112+
113+
public void remove(String alias) {
114+
synchronized (mutex) {
115+
aliases = newMapBuilder(aliases).remove(alias).immutableMap();
116+
}
117+
}
118+
119+
private Filter parse(String alias, CompressedString filter) {
120+
if (filter == null) {
121+
return null;
122+
}
123+
XContentIndexQueryParser indexQueryParser = (XContentIndexQueryParser) indexQueryParserService.defaultIndexQueryParser();
124+
try {
125+
byte[] filterSource = filter.uncompressed();
126+
XContentParser parser = XContentFactory.xContent(filterSource).createParser(filterSource);
127+
try {
128+
return indexQueryParser.parseInnerFilter(parser);
129+
} finally {
130+
parser.close();
131+
}
132+
} catch (IOException ex) {
133+
throw new AliasFilterParsingException(index, alias, "Invalid alias filter", ex);
134+
}
135+
}
136+
137+
@Override public UnmodifiableIterator<IndexAlias> iterator() {
138+
return aliases.values().iterator();
139+
}
140+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.aliases;
21+
22+
import org.elasticsearch.common.inject.AbstractModule;
23+
24+
/**
25+
* @author imotov
26+
*/
27+
public class IndexAliasesServiceModule extends AbstractModule {
28+
29+
@Override protected void configure() {
30+
bind(IndexAliasesService.class).asEagerSingleton();
31+
}
32+
}

modules/elasticsearch/src/main/java/org/elasticsearch/index/service/IndexService.java

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.common.inject.Injector;
2525
import org.elasticsearch.index.IndexComponent;
2626
import org.elasticsearch.index.IndexShardMissingException;
27+
import org.elasticsearch.index.aliases.IndexAliasesService;
2728
import org.elasticsearch.index.analysis.AnalysisService;
2829
import org.elasticsearch.index.cache.IndexCache;
2930
import org.elasticsearch.index.engine.IndexEngine;
@@ -56,6 +57,8 @@ public interface IndexService extends IndexComponent, Iterable<IndexShard> {
5657

5758
SimilarityService similarityService();
5859

60+
IndexAliasesService aliasesService();
61+
5962
IndexEngine engine();
6063

6164
IndexStore store();

modules/elasticsearch/src/main/java/org/elasticsearch/index/service/InternalIndexService.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.elasticsearch.env.NodeEnvironment;
3535
import org.elasticsearch.gateway.none.NoneGateway;
3636
import org.elasticsearch.index.*;
37+
import org.elasticsearch.index.aliases.IndexAliasesService;
3738
import org.elasticsearch.index.analysis.AnalysisService;
3839
import org.elasticsearch.index.cache.IndexCache;
3940
import org.elasticsearch.index.deletionpolicy.DeletionPolicyModule;
@@ -103,6 +104,8 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
103104

104105
private final SimilarityService similarityService;
105106

107+
private final IndexAliasesService aliasesService;
108+
106109
private final IndexCache indexCache;
107110

108111
private final IndexEngine indexEngine;
@@ -118,7 +121,8 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
118121
private volatile boolean closed = false;
119122

120123
@Inject public InternalIndexService(Injector injector, Index index, @IndexSettings Settings indexSettings, NodeEnvironment nodeEnv, ThreadPool threadPool,
121-
PercolatorService percolatorService, AnalysisService analysisService, MapperService mapperService, IndexQueryParserService queryParserService, SimilarityService similarityService,
124+
PercolatorService percolatorService, AnalysisService analysisService, MapperService mapperService,
125+
IndexQueryParserService queryParserService, SimilarityService similarityService, IndexAliasesService aliasesService,
122126
IndexCache indexCache, IndexEngine indexEngine, IndexGateway indexGateway, IndexStore indexStore) {
123127
super(index, indexSettings);
124128
this.injector = injector;
@@ -130,6 +134,7 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
130134
this.mapperService = mapperService;
131135
this.queryParserService = queryParserService;
132136
this.similarityService = similarityService;
137+
this.aliasesService = aliasesService;
133138
this.indexCache = indexCache;
134139
this.indexEngine = indexEngine;
135140
this.indexGateway = indexGateway;
@@ -203,6 +208,10 @@ public class InternalIndexService extends AbstractIndexComponent implements Inde
203208
return similarityService;
204209
}
205210

211+
@Override public IndexAliasesService aliasesService() {
212+
return aliasesService;
213+
}
214+
206215
@Override public IndexEngine engine() {
207216
return indexEngine;
208217
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.indices;
21+
22+
import org.elasticsearch.index.Index;
23+
import org.elasticsearch.index.IndexException;
24+
25+
/**
26+
* @author imotov
27+
*/
28+
public class AliasFilterParsingException extends IndexException {
29+
30+
public AliasFilterParsingException(Index index, String name, String desc) {
31+
super(index, "[" + name + "], " + desc);
32+
}
33+
34+
public AliasFilterParsingException(Index index, String name, String desc, Throwable ex) {
35+
super(index, "[" + name + "], " + desc, ex);
36+
}
37+
38+
39+
}

modules/elasticsearch/src/main/java/org/elasticsearch/indices/InternalIndicesService.java

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.elasticsearch.env.NodeEnvironment;
3737
import org.elasticsearch.gateway.Gateway;
3838
import org.elasticsearch.index.*;
39+
import org.elasticsearch.index.aliases.IndexAliasesServiceModule;
3940
import org.elasticsearch.index.analysis.AnalysisModule;
4041
import org.elasticsearch.index.analysis.AnalysisService;
4142
import org.elasticsearch.index.cache.CacheStats;
@@ -242,6 +243,7 @@ public synchronized IndexService createIndex(String sIndexName, Settings setting
242243
modules.add(new IndexCacheModule(indexSettings));
243244
modules.add(new IndexQueryParserModule(indexSettings));
244245
modules.add(new MapperServiceModule());
246+
modules.add(new IndexAliasesServiceModule());
245247
modules.add(new IndexGatewayModule(indexSettings, injector.getInstance(Gateway.class)));
246248
modules.add(new IndexModule());
247249
modules.add(new PercolatorModule());

0 commit comments

Comments
 (0)