/** * Throws an ActionRequestValidationException if the request tries to index back into the same * index or into an index that points to two indexes. This cannot be done during request * validation because the cluster state isn't available then. Package private for testing. */ static void validateAgainstAliases( SearchRequest source, IndexRequest destination, RemoteInfo remoteInfo, IndexNameExpressionResolver indexNameExpressionResolver, AutoCreateIndex autoCreateIndex, ClusterState clusterState) { if (remoteInfo != null) { return; } String target = destination.index(); if (false == autoCreateIndex.shouldAutoCreate(target, clusterState)) { /* * If we're going to autocreate the index we don't need to resolve * it. This is the same sort of dance that TransportIndexRequest * uses to decide to autocreate the index. */ target = indexNameExpressionResolver.concreteIndexNames(clusterState, destination)[0]; } for (String sourceIndex : indexNameExpressionResolver.concreteIndexNames(clusterState, source)) { if (sourceIndex.equals(target)) { ActionRequestValidationException e = new ActionRequestValidationException(); e.addValidationError( "reindex cannot write into an index its reading from [" + target + ']'); throw e; } } }
@Override protected void doExecute( final UpdateRequest request, final ActionListener<UpdateResponse> listener) { // if we don't have a master, we don't have metadata, that's fine, let it find a master using // create index API if (autoCreateIndex.shouldAutoCreate(request.index(), clusterService.state())) { request.beforeLocalFork(); // we fork on another thread... createIndexAction.execute( new CreateIndexRequest(request.index()) .cause("auto(update api)") .masterNodeTimeout(request.timeout()), new ActionListener<CreateIndexResponse>() { @Override public void onResponse(CreateIndexResponse result) { innerExecute(request, listener); } @Override public void onFailure(Throwable e) { if (ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException) { // we have the index, do it try { innerExecute(request, listener); } catch (Exception e1) { listener.onFailure(e1); } } else { listener.onFailure(e); } } }); } else { innerExecute(request, listener); } }
@Override protected void doExecute( final IndexRequest request, final ActionListener<IndexResponse> listener) { // if we don't have a master, we don't have metadata, that's fine, let it find a master using // create index API ClusterState state = clusterService.state(); if (autoCreateIndex.shouldAutoCreate(request.index(), state)) { CreateIndexRequest createIndexRequest = new CreateIndexRequest(request); createIndexRequest.index(request.index()); createIndexRequest.mapping(request.type()); createIndexRequest.cause("auto(index api)"); createIndexRequest.masterNodeTimeout(request.timeout()); createIndexAction.execute( createIndexRequest, new ActionListener<CreateIndexResponse>() { @Override public void onResponse(CreateIndexResponse result) { innerExecute(request, listener); } @Override public void onFailure(Throwable e) { if (ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException) { // we have the index, do it try { innerExecute(request, listener); } catch (Throwable e1) { listener.onFailure(e1); } } else { listener.onFailure(e); } } }); } else { innerExecute(request, listener); } }
@Override protected void doExecute( final BulkRequest bulkRequest, final ActionListener<BulkResponse> listener) { final long startTime = System.currentTimeMillis(); final AtomicArray<BulkItemResponse> responses = new AtomicArray<>(bulkRequest.requests.size()); if (autoCreateIndex.needToCheck()) { // Keep track of all unique indices and all unique types per index for the create index // requests: final Map<String, Set<String>> indicesAndTypes = new HashMap<>(); for (ActionRequest request : bulkRequest.requests) { if (request instanceof DocumentRequest) { DocumentRequest req = (DocumentRequest) request; Set<String> types = indicesAndTypes.get(req.index()); if (types == null) { indicesAndTypes.put(req.index(), types = new HashSet<>()); } types.add(req.type()); } else { throw new ElasticsearchException( "Parsed unknown request in bulk actions: " + request.getClass().getSimpleName()); } } final AtomicInteger counter = new AtomicInteger(indicesAndTypes.size()); ClusterState state = clusterService.state(); for (Map.Entry<String, Set<String>> entry : indicesAndTypes.entrySet()) { final String index = entry.getKey(); if (autoCreateIndex.shouldAutoCreate(index, state)) { CreateIndexRequest createIndexRequest = new CreateIndexRequest(); createIndexRequest.index(index); for (String type : entry.getValue()) { createIndexRequest.mapping(type); } createIndexRequest.cause("auto(bulk api)"); createIndexRequest.masterNodeTimeout(bulkRequest.timeout()); createIndexAction.execute( createIndexRequest, new ActionListener<CreateIndexResponse>() { @Override public void onResponse(CreateIndexResponse result) { if (counter.decrementAndGet() == 0) { try { executeBulk(bulkRequest, startTime, listener, responses); } catch (Throwable t) { listener.onFailure(t); } } } @Override public void onFailure(Throwable e) { if (!(ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException)) { // fail all requests involving this index, if create didnt work for (int i = 0; i < bulkRequest.requests.size(); i++) { ActionRequest request = bulkRequest.requests.get(i); if (request != null && setResponseFailureIfIndexMatches(responses, i, request, index, e)) { bulkRequest.requests.set(i, null); } } } if (counter.decrementAndGet() == 0) { try { executeBulk(bulkRequest, startTime, listener, responses); } catch (Throwable t) { listener.onFailure(t); } } } }); } else { if (counter.decrementAndGet() == 0) { executeBulk(bulkRequest, startTime, listener, responses); } } } } else { executeBulk(bulkRequest, startTime, listener, responses); } }