// TODO: This can be moved to IndexNameExpressionResolver too, but this means that we will support // wildcards and other expressions // in the index,bulk,update and delete apis. public String resolveIndexRouting( @Nullable String parent, @Nullable String routing, String aliasOrIndex) { if (aliasOrIndex == null) { if (routing == null) { return parent; } return routing; } AliasOrIndex result = getAliasAndIndexLookup().get(aliasOrIndex); if (result == null || result.isAlias() == false) { if (routing == null) { return parent; } return routing; } AliasOrIndex.Alias alias = (AliasOrIndex.Alias) result; if (result.getIndices().size() > 1) { String[] indexNames = new String[result.getIndices().size()]; int i = 0; for (IndexMetaData indexMetaData : result.getIndices()) { indexNames[i++] = indexMetaData.getIndex().getName(); } throw new IllegalArgumentException( "Alias [" + aliasOrIndex + "] has more than one index associated with it [" + Arrays.toString(indexNames) + "], can't execute a single index op"); } AliasMetaData aliasMd = alias.getFirstAliasMetaData(); if (aliasMd.indexRouting() != null) { if (aliasMd.indexRouting().indexOf(',') != -1) { throw new IllegalArgumentException( "index/alias [" + aliasOrIndex + "] provided with routing value [" + aliasMd.getIndexRouting() + "] that resolved to several routing values, rejecting operation"); } if (routing != null) { if (!routing.equals(aliasMd.indexRouting())) { throw new IllegalArgumentException( "Alias [" + aliasOrIndex + "] has index routing associated with it [" + aliasMd.indexRouting() + "], and was provided with routing value [" + routing + "], rejecting operation"); } } // Alias routing overrides the parent routing (if any). return aliasMd.indexRouting(); } if (routing == null) { return parent; } return routing; }
public MetaData build() { // TODO: We should move these datastructures to IndexNameExpressionResolver, this will give // the following benefits: // 1) The datastructures will only be rebuilded when needed. Now during serializing we rebuild // these datastructures // while these datastructures aren't even used. // 2) The aliasAndIndexLookup can be updated instead of rebuilding it all the time. // build all concrete indices arrays: // TODO: I think we can remove these arrays. it isn't worth the effort, for operations on all // indices. // When doing an operation across all indices, most of the time is spent on actually going to // all shards and // do the required operations, the bottleneck isn't resolving expressions into concrete // indices. List<String> allIndicesLst = new ArrayList<>(); for (ObjectCursor<IndexMetaData> cursor : indices.values()) { allIndicesLst.add(cursor.value.getIndex().getName()); } String[] allIndices = allIndicesLst.toArray(new String[allIndicesLst.size()]); List<String> allOpenIndicesLst = new ArrayList<>(); List<String> allClosedIndicesLst = new ArrayList<>(); for (ObjectCursor<IndexMetaData> cursor : indices.values()) { IndexMetaData indexMetaData = cursor.value; if (indexMetaData.getState() == IndexMetaData.State.OPEN) { allOpenIndicesLst.add(indexMetaData.getIndex().getName()); } else if (indexMetaData.getState() == IndexMetaData.State.CLOSE) { allClosedIndicesLst.add(indexMetaData.getIndex().getName()); } } String[] allOpenIndices = allOpenIndicesLst.toArray(new String[allOpenIndicesLst.size()]); String[] allClosedIndices = allClosedIndicesLst.toArray(new String[allClosedIndicesLst.size()]); // build all indices map SortedMap<String, AliasOrIndex> aliasAndIndexLookup = new TreeMap<>(); for (ObjectCursor<IndexMetaData> cursor : indices.values()) { IndexMetaData indexMetaData = cursor.value; aliasAndIndexLookup.put( indexMetaData.getIndex().getName(), new AliasOrIndex.Index(indexMetaData)); for (ObjectObjectCursor<String, AliasMetaData> aliasCursor : indexMetaData.getAliases()) { AliasMetaData aliasMetaData = aliasCursor.value; AliasOrIndex aliasOrIndex = aliasAndIndexLookup.get(aliasMetaData.getAlias()); if (aliasOrIndex == null) { aliasOrIndex = new AliasOrIndex.Alias(aliasMetaData, indexMetaData); aliasAndIndexLookup.put(aliasMetaData.getAlias(), aliasOrIndex); } else if (aliasOrIndex instanceof AliasOrIndex.Alias) { AliasOrIndex.Alias alias = (AliasOrIndex.Alias) aliasOrIndex; alias.addIndex(indexMetaData); } else if (aliasOrIndex instanceof AliasOrIndex.Index) { AliasOrIndex.Index index = (AliasOrIndex.Index) aliasOrIndex; throw new IllegalStateException( "index and alias names need to be unique, but alias [" + aliasMetaData.getAlias() + "] and index " + index.getIndex().getIndex() + " have the same name"); } else { throw new IllegalStateException( "unexpected alias [" + aliasMetaData.getAlias() + "][" + aliasOrIndex + "]"); } } } aliasAndIndexLookup = Collections.unmodifiableSortedMap(aliasAndIndexLookup); return new MetaData( clusterUUID, version, transientSettings, persistentSettings, indices.build(), templates.build(), customs.build(), allIndices, allOpenIndices, allClosedIndices, aliasAndIndexLookup); }