Java Code Examples for org.elasticsearch.action.ActionListener

The following examples show how to use org.elasticsearch.action.ActionListener. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
@Override
protected void masterOperation(final BulkCreateIndicesRequest request,
                               final ClusterState state,
                               final ActionListener<BulkCreateIndicesResponse> listener) throws ElasticsearchException {

    if (request.indices().isEmpty()) {
        listener.onResponse(new BulkCreateIndicesResponse(true));
        return;
    }

    final ActionListener<ClusterStateUpdateResponse> stateUpdateListener = new ActionListener<ClusterStateUpdateResponse>() {
        @Override
        public void onResponse(ClusterStateUpdateResponse clusterStateUpdateResponse) {
                listener.onResponse(new BulkCreateIndicesResponse(true));
        }

        @Override
        public void onFailure(Throwable e) {
            listener.onFailure(e);
        }
    };
    createIndices(request, stateUpdateListener);
}
 
Example 2
Source Project: Elasticsearch   Source File: TransportDeleteAction.java    License: Apache License 2.0 6 votes vote down vote up
@Override
protected void doExecute(final Task task, final DeleteRequest request, final ActionListener<DeleteResponse> listener) {
    ClusterState state = clusterService.state();
    if (autoCreateIndex.shouldAutoCreate(request.index(), state)) {
        createIndexAction.execute(task, new CreateIndexRequest(request).index(request.index()).cause("auto(delete api)")
            .masterNodeTimeout(request.timeout()), new ActionListener<CreateIndexResponse>() {
            @Override
            public void onResponse(CreateIndexResponse result) {
                innerExecute(task, request, listener);
            }

            @Override
            public void onFailure(Throwable e) {
                if (ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException) {
                    // we have the index, do it
                    innerExecute(task, request, listener);
                } else {
                    listener.onFailure(e);
                }
            }
        });
    } else {
        innerExecute(task, request, listener);
    }
}
 
Example 3
Source Project: crate   Source File: TransportCreateUserAction.java    License: Apache License 2.0 6 votes vote down vote up
@Override
protected void masterOperation(CreateUserRequest request, ClusterState state, ActionListener<WriteUserResponse> listener) throws Exception {
    clusterService.submitStateUpdateTask("create_user [" + request.userName() + "]",
        new AckedClusterStateUpdateTask<WriteUserResponse>(Priority.URGENT, request, listener) {

            private boolean alreadyExists = false;

            @Override
            public ClusterState execute(ClusterState currentState) throws Exception {
                MetaData currentMetaData = currentState.metaData();
                MetaData.Builder mdBuilder = MetaData.builder(currentMetaData);
                alreadyExists = putUser(mdBuilder, request.userName(), request.secureHash());
                return ClusterState.builder(currentState).metaData(mdBuilder).build();
            }

            @Override
            protected WriteUserResponse newResponse(boolean acknowledged) {
                return new WriteUserResponse(acknowledged, alreadyExists);
            }
        });
}
 
Example 4
Source Project: anomaly-detection   Source File: ModelManager.java    License: Apache License 2.0 6 votes vote down vote up
private void processThresholdCheckpoint(
    Optional<String> thresholdCheckpoint,
    String modelId,
    String detectorId,
    double score,
    ActionListener<ThresholdingResult> listener
) {

    Optional<ModelState<ThresholdingModel>> model = thresholdCheckpoint
        .map(
            checkpoint -> AccessController
                .doPrivileged((PrivilegedAction<ThresholdingModel>) () -> gson.fromJson(checkpoint, thresholdingModelClass))
        )
        .map(threshold -> new ModelState<>(threshold, modelId, detectorId, ModelType.THRESHOLD.getName(), clock.instant()));
    if (model.isPresent()) {
        thresholds.put(modelId, model.get());
        getThresholdingResult(model.get(), score, listener);
    } else {
        throw new ResourceNotFoundException(detectorId, CommonErrorMessages.NO_CHECKPOINT_ERR_MSG + modelId);
    }
}
 
Example 5
Source Project: anomaly-detection   Source File: ModelManager.java    License: Apache License 2.0 6 votes vote down vote up
private void clearModelForIterator(String detectorId, Map<String, ?> models, Iterator<String> idIter, ActionListener<Void> listener) {
    if (idIter.hasNext()) {
        String modelId = idIter.next();
        if (getDetectorIdForModelId(modelId).equals(detectorId)) {
            models.remove(modelId);
            checkpointDao
                .deleteModelCheckpoint(
                    modelId,
                    ActionListener.wrap(r -> clearModelForIterator(detectorId, models, idIter, listener), listener::onFailure)
                );
        } else {
            clearModelForIterator(detectorId, models, idIter, listener);
        }
    } else {
        listener.onResponse(null);
    }
}
 
Example 6
/**
 * Get detector job for update/delete AD job.
 * If AD job exist, will return error message; otherwise, execute function.
 *
 * @param clusterService ES cluster service
 * @param client ES node client
 * @param detectorId detector identifier
 * @param channel ES rest channel
 * @param function AD function
 */
public void getDetectorJob(
    ClusterService clusterService,
    NodeClient client,
    String detectorId,
    RestChannel channel,
    AnomalyDetectorFunction function
) {
    if (clusterService.state().metadata().indices().containsKey(ANOMALY_DETECTOR_JOB_INDEX)) {
        GetRequest request = new GetRequest(ANOMALY_DETECTOR_JOB_INDEX).id(detectorId);
        client.get(request, ActionListener.wrap(response -> onGetAdJobResponseForWrite(response, channel, function), exception -> {
            logger.error("Fail to get anomaly detector job: " + detectorId, exception);
            try {
                channel.sendResponse(new BytesRestResponse(channel, exception));
            } catch (IOException e) {
                logger.error("Fail to send exception" + detectorId, e);
            }
        }));
    } else {
        function.execute();
    }
}
 
Example 7
public void testInitOrRunningStateTemplate(InittedEverResultStatus status, DetectorState expectedState) throws IOException,
    InterruptedException {
    setUpClientGet(true, JobStatus.ENABLED);
    setUpClientSearch(status, ErrorResultStatus.NO_ERROR);
    DetectorProfile expectedProfile = new DetectorProfile();
    expectedProfile.setState(expectedState);
    final CountDownLatch inProgressLatch = new CountDownLatch(1);

    runner.profile(detector.getDetectorId(), ActionListener.wrap(response -> {
        assertEquals(expectedProfile, response);
        inProgressLatch.countDown();
    }, exception -> {
        assertTrue("Should not reach here ", false);
        inProgressLatch.countDown();
    }), stateOnly);
    assertTrue(inProgressLatch.await(100, TimeUnit.SECONDS));
}
 
Example 8
private void checkADNameExists(String detectorId) throws IOException {
    BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
    // src/main/resources/mappings/anomaly-detectors.json#L14
    boolQueryBuilder.must(QueryBuilders.termQuery("name.keyword", anomalyDetector.getName()));
    if (StringUtils.isNotBlank(detectorId)) {
        boolQueryBuilder.mustNot(QueryBuilders.termQuery(RestHandlerUtils._ID, detectorId));
    }
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(boolQueryBuilder).timeout(requestTimeout);
    SearchRequest searchRequest = new SearchRequest(ANOMALY_DETECTORS_INDEX).source(searchSourceBuilder);

    client
        .search(
            searchRequest,
            ActionListener
                .wrap(
                    searchResponse -> onSearchADNameResponse(searchResponse, detectorId, anomalyDetector.getName()),
                    exception -> onFailure(exception)
                )
        );
}
 
Example 9
Source Project: crate   Source File: MockInternalClusterInfoService.java    License: Apache License 2.0 6 votes vote down vote up
@Override
protected CountDownLatch updateNodeStats(ActionListener<NodesStatsResponse> listener) {
    return super.updateNodeStats(new ActionListener<>() {
        @Override
        public void onResponse(NodesStatsResponse nodesStatsResponse) {
            ImmutableOpenMap.Builder<String, DiskUsage> leastAvailableUsagesBuilder = ImmutableOpenMap.builder();
            ImmutableOpenMap.Builder<String, DiskUsage> mostAvailableUsagesBuilder = ImmutableOpenMap.builder();
            fillDiskUsagePerNode(
                LOGGER,
                adjustNodesStats(nodesStatsResponse.getNodes()),
                leastAvailableUsagesBuilder,
                mostAvailableUsagesBuilder
            );
            leastAvailableSpaceUsages = leastAvailableUsagesBuilder.build();
            mostAvailableSpaceUsages = mostAvailableUsagesBuilder.build();
        }

        @Override
        public void onFailure(Exception e) {
        }
    });
}
 
Example 10
Source Project: crate   Source File: NodeStatsTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void testRequestsIfRequired() throws Exception {
    List<Symbol> toCollect = new ArrayList<>();
    toCollect.add(idRef);
    toCollect.add(hostnameRef);

    when(collectPhase.toCollect()).thenReturn(toCollect);

    BatchIterator iterator = NodeStats.newInstance(
        transportNodeStatsAction,
        collectPhase,
        nodes,
        txnCtx,
        new InputFactory(getFunctions())
    );
    iterator.loadNextBatch();

    // Hostnames needs to be collected so requests need to be performed
    verify(transportNodeStatsAction).execute(eq("nodeOne"), any(NodeStatsRequest.class), any(ActionListener.class),
        eq(TimeValue.timeValueMillis(3000L)));
    verify(transportNodeStatsAction).execute(eq("nodeTwo"), any(NodeStatsRequest.class), any(ActionListener.class),
        eq(TimeValue.timeValueMillis(3000L)));
    verifyNoMoreInteractions(transportNodeStatsAction);
}
 
Example 11
Source Project: elasticsearch-auth   Source File: ReloadRestAction.java    License: Apache License 2.0 6 votes vote down vote up
@Override
protected void handleRequest(final RestRequest request,
        final RestChannel channel, final Client client) {

    authService.reload(new ActionListener<Void>() {
        @Override
        public void onResponse(final Void response) {
            ResponseUtil.send(request, channel, RestStatus.OK);
        }

        @Override
        public void onFailure(final Throwable e) {
            ResponseUtil.send(request, channel,
                    RestStatus.INTERNAL_SERVER_ERROR, "message",
                    "Failed to reload AuthService.");
        }
    });
}
 
Example 12
@Override
protected void doExecute(final SearchRequest request, final ActionListener<SearchResponse> listener) {
  logger.debug("{}: Execute coordinated search action", Thread.currentThread().getName());

  // A reference to the listener that will be used - can be overwritten to reference a CoordinateSearchListener
  ActionListener<SearchResponse> actionListener = listener;

  // Retrieve the singleton instance of the filterjoin cache
  FilterJoinCache cache = cacheService.getCacheInstance();

  // Parse query source
  Tuple<XContentType, Map<String, Object>> parsedSource = this.parseSource(request.source());
  if (parsedSource != null) { // can be null if this is a uri search (query parameter in extraSource)
    Map<String, Object> map = parsedSource.v2();

    // Unwrap "wrapper" queries
    WrapperQueryVisitor wrapperVisitor = new WrapperQueryVisitor(map);
    wrapperVisitor.traverse();

    // Query planning and execution of filter joins
    SourceMapVisitor mapVisitor = new SourceMapVisitor(map);
    mapVisitor.traverse();
    FilterJoinVisitor joinVisitor = new FilterJoinVisitor(client, mapVisitor.getFilterJoinTree(), cache, request);
    joinVisitor.traverse();

    // Wraps the listener with our own to inject metadata information in the response
    CoordinateSearchListener coordinateSearchListener = new CoordinateSearchListener(listener);
    coordinateSearchListener.setMetadata(joinVisitor.getMetadata());
    actionListener = coordinateSearchListener;

    // Filter joins have been replaced by a binary terms filter
    // Rebuild the query source, and delegate the execution of the search action
    request.source(this.buildSource(parsedSource.v1().xContent(), map));
  }

  // Delegate the execution of the request to the original search action
  this.searchAction.execute(request, actionListener);

  logger.debug("{}: Coordinated search action completed", Thread.currentThread().getName());
}
 
Example 13
Source Project: heroic   Source File: TransportConnection.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void execute(
    @NotNull IndexRequest request,
    @NotNull ActionListener<IndexResponse> listener
) {
    client.index(request, listener);
}
 
Example 14
Source Project: crate   Source File: ActionListeners.java    License: Apache License 2.0 5 votes vote down vote up
public static <T extends AcknowledgedResponse> ActionListener<T> waitForShards(ActionListener<T> delegate,
                                                                               ActiveShardsObserver observer,
                                                                               TimeValue timeout,
                                                                               Runnable onShardsNotAcknowledged,
                                                                               Supplier<String[]> indices) {

    return ActionListener.wrap(
        resp -> {
            if (resp.isAcknowledged()) {
                observer.waitForActiveShards(
                    indices.get(),
                    ActiveShardCount.DEFAULT,
                    timeout,
                    shardsAcknowledged -> {
                        if (!shardsAcknowledged) {
                            onShardsNotAcknowledged.run();
                        }
                        delegate.onResponse(resp);
                    },
                    delegate::onFailure
                );
            } else {
                delegate.onResponse(resp);
            }
        },
        delegate::onFailure
    );
}
 
Example 15
Source Project: crate   Source File: TransportDeleteIndexTemplateAction.java    License: Apache License 2.0 5 votes vote down vote up
@Override
protected void masterOperation(final DeleteIndexTemplateRequest request, final ClusterState state, final ActionListener<AcknowledgedResponse> listener) {
    indexTemplateService.removeTemplates(new MetaDataIndexTemplateService.RemoveRequest(request.name()).masterTimeout(request.masterNodeTimeout()), new MetaDataIndexTemplateService.RemoveListener() {
        @Override
        public void onResponse(MetaDataIndexTemplateService.RemoveResponse response) {
            listener.onResponse(new AcknowledgedResponse(response.acknowledged()));
        }

        @Override
        public void onFailure(Exception e) {
            logger.debug(() -> new ParameterizedMessage("failed to delete templates [{}]", request.name()), e);
            listener.onFailure(e);
        }
    });
}
 
Example 16
public void testDisabledJobIndexTemplate(JobStatus status) throws IOException, InterruptedException {
    setUpClientGet(true, status);
    DetectorProfile expectedProfile = new DetectorProfile();
    expectedProfile.setState(DetectorState.DISABLED);
    final CountDownLatch inProgressLatch = new CountDownLatch(1);

    runner.profile(detector.getDetectorId(), ActionListener.wrap(response -> {
        assertEquals(expectedProfile, response);
        inProgressLatch.countDown();
    }, exception -> {
        assertTrue("Should not reach here ", false);
        inProgressLatch.countDown();
    }), stateOnly);
    assertTrue(inProgressLatch.await(100, TimeUnit.SECONDS));
}
 
Example 17
Source Project: elasticsearch-dynarank   Source File: SearchActionFilter.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public <Request extends ActionRequest, Response extends ActionResponse> void apply(final Task task, final String action,
        final Request request, final ActionListener<Response> listener, final ActionFilterChain<Request, Response> chain) {
    if (!SearchAction.INSTANCE.name().equals(action)) {
        chain.proceed(task, action, request, listener);
        return;
    }

    final SearchRequest searchRequest = (SearchRequest) request;
    final ActionListener<Response> wrappedListener = DynamicRanker.getInstance().wrapActionListener(action, searchRequest, listener);
    chain.proceed(task, action, request, wrappedListener == null ? listener : wrappedListener);
}
 
Example 18
Source Project: Elasticsearch   Source File: TransportShowTenantsAction.java    License: Apache License 2.0 5 votes vote down vote up
@Override
protected void masterOperation(final ShowTenantsRequest request, ClusterState state, final ActionListener<ShowTenantsResponse> listener) {

    ShowTenantsResponse response = new ShowTenantsResponse();
    List<TenantProperty> tenantProperties = new ArrayList<TenantProperty>();
    ImmutableMap<Long, TenantProperty> allTenants = state.metaData().getTenantMetadata().tenantProperties();
    for (Long tenantId : allTenants.keySet()) {
        tenantProperties.add(allTenants.get(tenantId));
    }
    response.setTenantProperty(tenantProperties);
    listener.onResponse(response);
}
 
Example 19
Source Project: crate   Source File: PeerRecoveryTargetService.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void messageReceived(RecoveryFinalizeRecoveryRequest request, TransportChannel channel, Task task) throws Exception {
    try (RecoveryRef recoveryRef = onGoingRecoveries.getRecoverySafe(request.recoveryId(), request.shardId())) {
        final ActionListener<TransportResponse> listener =
            new HandledTransportAction.ChannelActionListener<>(channel, Actions.FINALIZE, request);
        recoveryRef.target().finalizeRecovery(
            request.globalCheckpoint(),
            ActionListener.wrap(
                nullVal -> listener.onResponse(TransportResponse.Empty.INSTANCE),
                listener::onFailure
            )
        );
    }
}
 
Example 20
Source Project: anomaly-detection   Source File: AnomalyDetectorRunner.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * run anomaly detector and return anomaly result.
 *
 * @param detector  anomaly detector instance
 * @param startTime detection period start time
 * @param endTime   detection period end time
 * @param listener handle anomaly result
 * @throws IOException - if a user gives wrong query input when defining a detector
 */
public void executeDetector(AnomalyDetector detector, Instant startTime, Instant endTime, ActionListener<List<AnomalyResult>> listener)
    throws IOException {
    featureManager.getPreviewFeatures(detector, startTime.toEpochMilli(), endTime.toEpochMilli(), ActionListener.wrap(features -> {
        try {
            List<ThresholdingResult> results = modelManager.getPreviewResults(features.getProcessedFeatures());
            listener.onResponse(sample(parsePreviewResult(detector, features, results), maxPreviewResults));
        } catch (Exception e) {
            onFailure(e, listener, detector.getDetectorId());
        }
    }, e -> onFailure(e, listener, detector.getDetectorId())));

}
 
Example 21
Source Project: anomaly-detection   Source File: FeatureManager.java    License: Apache License 2.0 5 votes vote down vote up
private void processColdStartSamples(Optional<Entry<double[][], Integer>> samples, ActionListener<Optional<double[][]>> listener) {
    listener
        .onResponse(
            samples
                .map(
                    results -> transpose(
                        interpolator.interpolate(transpose(results.getKey()), results.getValue() * (results.getKey().length - 1) + 1)
                    )
                )
                .map(points -> batchShingle(points, shingleSize))
        );
}
 
Example 22
private KerberosActionListener(final ActionListener inner, final Action action, final ActionRequest<ActionRequest> request,
        final GSSContext context) {
    super();
    this.inner = inner;
    this.action = action;
    this.request = request;
    this.context = context;
}
 
Example 23
Source Project: anomaly-detection   Source File: SearchFeatureDao.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Returns to listener features for the given time period.
 *
 * @param detector info about indices, feature query
 * @param startTime epoch milliseconds at the beginning of the period
 * @param endTime epoch milliseconds at the end of the period
 * @param listener onResponse is called with features for the given time period.
 */
public void getFeaturesForPeriod(AnomalyDetector detector, long startTime, long endTime, ActionListener<Optional<double[]>> listener) {
    SearchRequest searchRequest = createFeatureSearchRequest(detector, startTime, endTime, Optional.empty());
    client
        .search(
            searchRequest,
            ActionListener
                .wrap(response -> listener.onResponse(parseResponse(response, detector.getEnabledFeatureIds())), listener::onFailure)
        );
}
 
Example 24
Source Project: anomaly-detection   Source File: ClientUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Send an asynchronous request and handle response with the provided listener.
 * @param <Request> ActionRequest
 * @param <Response> ActionResponse
 * @param request request body
 * @param consumer request method, functional interface to operate as a client request like client::get
 * @param listener needed to handle response
 */
public <Request extends ActionRequest, Response extends ActionResponse> void asyncRequest(
    Request request,
    BiConsumer<Request, ActionListener<Response>> consumer,
    ActionListener<Response> listener
) {
    consumer
        .accept(
            request,
            ActionListener.wrap(response -> { listener.onResponse(response); }, exception -> { listener.onFailure(exception); })
        );
}
 
Example 25
Source Project: crate   Source File: TransportFetchNodeAction.java    License: Apache License 2.0 5 votes vote down vote up
public void execute(String targetNode,
                    final IntObjectMap<Streamer[]> streamers,
                    final NodeFetchRequest request,
                    RamAccounting ramAccounting,
                    ActionListener<NodeFetchResponse> listener) {
    transports.sendRequest(TRANSPORT_ACTION, targetNode, request, listener,
        new ActionListenerResponseHandler<>(listener, in -> new NodeFetchResponse(in, streamers, ramAccounting)));
}
 
Example 26
Source Project: crate   Source File: TransportsTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void testOnFailureOnListenerIsCalledIfNodeIsNotInClusterState() throws Exception {
    Transports transports = new Transports(clusterService, mock(TransportService.class));
    ActionListener actionListener = mock(ActionListener.class);
    transports.sendRequest("actionName",
        "invalid", mock(TransportRequest.class), actionListener, mock(TransportResponseHandler.class));

    verify(actionListener, times(1)).onFailure(any(ConnectTransportException.class));
}
 
Example 27
Source Project: Elasticsearch   Source File: TransportUpgradeAction.java    License: Apache License 2.0 5 votes vote down vote up
private void updateSettings(final UpgradeResponse upgradeResponse, final ActionListener<UpgradeResponse> listener) {
    UpgradeSettingsRequest upgradeSettingsRequest = new UpgradeSettingsRequest(upgradeResponse.versions());
    upgradeSettingsAction.execute(upgradeSettingsRequest, new ActionListener<UpgradeSettingsResponse>() {
        @Override
        public void onResponse(UpgradeSettingsResponse updateSettingsResponse) {
            listener.onResponse(upgradeResponse);
        }

        @Override
        public void onFailure(Throwable e) {
            listener.onFailure(e);
        }
    });
}
 
Example 28
Source Project: elasticsearch-rest-command   Source File: Search.java    License: The Unlicense 5 votes vote down vote up
public void executeQueryWithNonJoin(ActionListener<SearchResponse> listener,
		int from, final int size, String[] sortFields) {

	// jobHandler,执行期才知道要排序
	for (String field : sortFields) {
		if(field != null)addSortToQuery(field);
	}
	querySearch.setSearchType(SearchType.QUERY_THEN_FETCH).setFrom(from).setSize(size);
	dumpSearchScript(querySearch, logger);
	
	querySearch.execute(listener);
}
 
Example 29
Source Project: anomaly-detection   Source File: ClientUtil.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Execute a transport action and handle response with the provided listener.
 * @param <Request> ActionRequest
 * @param <Response> ActionResponse
 * @param action transport action
 * @param request request body
 * @param listener needed to handle response
 */
public <Request extends ActionRequest, Response extends ActionResponse> void execute(
    ActionType<Response> action,
    Request request,
    ActionListener<Response> listener
) {
    client
        .execute(
            action,
            request,
            ActionListener.wrap(response -> { listener.onResponse(response); }, exception -> { listener.onFailure(exception); })
        );
}
 
Example 30
Source Project: crate   Source File: RecoverySourceHandler.java    License: Apache License 2.0 5 votes vote down vote up
static void runUnderPrimaryPermit(CancellableThreads.Interruptable runnable, String reason,
                                  IndexShard primary, CancellableThreads cancellableThreads, Logger logger) {
    cancellableThreads.execute(() -> {
        CompletableFuture<Releasable> permit = new CompletableFuture<>();
        final ActionListener<Releasable> onAcquired = new ActionListener<>() {
            @Override
            public void onResponse(Releasable releasable) {
                if (permit.complete(releasable) == false) {
                    releasable.close();
                }
            }

            @Override
            public void onFailure(Exception e) {
                permit.completeExceptionally(e);
            }
        };
        primary.acquirePrimaryOperationPermit(onAcquired, ThreadPool.Names.SAME, reason);
        try (Releasable ignored = FutureUtils.get(permit)) {
            // check that the IndexShard still has the primary authority. This needs to be checked under operation permit to prevent
            // races, as IndexShard will switch its authority only when it holds all operation permits, see IndexShard.relocated()
            if (primary.isRelocatedPrimary()) {
                throw new IndexShardRelocatedException(primary.shardId());
            }
            runnable.run();
        } finally {
            // just in case we got an exception (likely interrupted) while waiting for the get
            permit.whenComplete((r, e) -> {
                if (r != null) {
                    r.close();
                }
                if (e != null) {
                    logger.trace("suppressing exception on completion (it was already bubbled up or the operation was aborted)", e);
                }
            });
        }
    });
}