[reindex] Implement CompositeIndicesRequest

Implements CompositeIndicesRequest on UpdateByQueryRequest and
ReindexRequest so that plugins can reason about the request. In both cases
this implementation is imperfect but useful because instead of listing
all requests that make up the request it instead attempts to make dummy
requests that represent the requests that it will later make.
This commit is contained in:
Nik Everett 2016-03-09 10:08:58 -05:00
parent 12a6f36a34
commit 38241a5d8b
3 changed files with 114 additions and 5 deletions

View File

@ -19,19 +19,31 @@
package org.elasticsearch.index.reindex; package org.elasticsearch.index.reindex;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.CompositeIndicesRequest;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.uid.Versions; import org.elasticsearch.common.lucene.uid.Versions;
import java.io.IOException; import static java.util.Collections.unmodifiableList;
import static org.elasticsearch.action.ValidateActions.addValidationError; import static org.elasticsearch.action.ValidateActions.addValidationError;
import static org.elasticsearch.index.VersionType.INTERNAL; import static org.elasticsearch.index.VersionType.INTERNAL;
public class ReindexRequest extends AbstractBulkIndexByScrollRequest<ReindexRequest> { /**
* Request to reindex some documents from one index to another. This implements CompositeIndicesRequest but in a misleading way. Rather than
* returning all the subrequests that it will make it tries to return a representative set of subrequests. This is best-effort for a bunch
* of reasons, not least of which that scripts are allowed to change the destination request in drastic ways, including changing the index
* to which documents are written.
*/
public class ReindexRequest extends AbstractBulkIndexByScrollRequest<ReindexRequest> implements CompositeIndicesRequest {
/** /**
* Prototype for index requests. * Prototype for index requests.
*/ */
@ -123,4 +135,20 @@ public class ReindexRequest extends AbstractBulkIndexByScrollRequest<ReindexRequ
} }
return b.toString(); return b.toString();
} }
// CompositeIndicesRequest implementation so plugins can reason about the request. This is really just a best effort thing.
/**
* Accessor to get the underlying {@link IndicesRequest}s that this request wraps. Note that this method is <strong>not
* accurate</strong> since it returns a prototype {@link IndexRequest} and not the actual requests that will be issued as part of the
* execution of this request. Additionally, scripts can modify the underlying {@link IndexRequest} and change values such as the index,
* type, {@link org.elasticsearch.action.support.IndicesOptions}. In short - only use this for very course reasoning about the request.
*
* @return a list comprising of the {@link SearchRequest} and the prototype {@link IndexRequest}
*/
@Override
public List<? extends IndicesRequest> subRequests() {
assert getSearchRequest() != null;
assert getDestination() != null;
return unmodifiableList(Arrays.asList(getSearchRequest(), getDestination()));
}
} }

View File

@ -19,13 +19,23 @@
package org.elasticsearch.index.reindex; package org.elasticsearch.index.reindex;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.action.CompositeIndicesRequest;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
import static java.util.Collections.unmodifiableList;
/** /**
* Request to reindex a set of documents where they are without changing their * Request to update some documents. That means you can't change their type, id, index, or anything like that. This implements
* locations or IDs. * CompositeIndicesRequest but in a misleading way. Rather than returning all the subrequests that it will make it tries to return a
* representative set of subrequests. This is best-effort but better than {@linkplain ReindexRequest} because scripts can't change the
* destination index and things.
*/ */
public class UpdateByQueryRequest extends AbstractBulkIndexByScrollRequest<UpdateByQueryRequest> { public class UpdateByQueryRequest extends AbstractBulkIndexByScrollRequest<UpdateByQueryRequest> implements CompositeIndicesRequest {
/** /**
* Ingest pipeline to set on index requests made by this action. * Ingest pipeline to set on index requests made by this action.
*/ */
@ -64,4 +74,26 @@ public class UpdateByQueryRequest extends AbstractBulkIndexByScrollRequest<Updat
searchToString(b); searchToString(b);
return b.toString(); return b.toString();
} }
// CompositeIndicesRequest implementation so plugins can reason about the request. This is really just a best effort thing.
/**
* Accessor to get the underlying {@link IndicesRequest}s that this request wraps. Note that this method is <strong>not
* accurate</strong> since it returns dummy {@link IndexRequest}s and not the actual requests that will be issued as part of the
* execution of this request.
*
* @return a list comprising of the {@link SearchRequest} and dummy {@link IndexRequest}s
*/
@Override
public List<? extends IndicesRequest> subRequests() {
assert getSearchRequest() != null;
List<IndicesRequest> subRequests = new ArrayList<>();
// One dummy IndexRequest per destination index.
for (String index : getSearchRequest().indices()) {
IndexRequest request = new IndexRequest();
request.index(index);
subRequests.add(request);
}
subRequests.add(getSearchRequest());
return unmodifiableList(subRequests);
};
} }

View File

@ -0,0 +1,49 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you 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.elasticsearch.index.reindex;
import java.util.List;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.test.ESTestCase;
import static org.apache.lucene.util.TestUtil.randomSimpleString;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.sameInstance;
public class UpdateByQueryRequestTests extends ESTestCase {
public void testUpdateByQueryRequestImplementsCompositeIndicesRequestWithDummies() {
int numIndices = between(1, 100);
String[] indices = new String[numIndices];
for (int i = 0; i < numIndices; i++) {
indices[i] = randomSimpleString(random(), 1, 30);
}
UpdateByQueryRequest request = new UpdateByQueryRequest(new SearchRequest(indices));
List<? extends IndicesRequest> subRequests = request.subRequests();
assertThat(subRequests, hasSize(numIndices + 1));
for (int i = 0; i < numIndices; i++) {
assertThat(subRequests.get(i).indices(), arrayWithSize(1));
assertEquals(indices[i], subRequests.get(i).indices()[0]);
}
assertThat(subRequests.get(numIndices), sameInstance(request.getSearchRequest()));
}
}