org.elasticsearch.action.ActionListener Java Examples

The following examples show how to use org.elasticsearch.action.ActionListener. 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
Source File: TransportBulkCreateIndicesAction.java    From Elasticsearch with Apache License 2.0 6 votes vote down vote up
@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 File: MockInternalClusterInfoService.java    From crate with 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 #3
Source File: IndexAnomalyDetectorActionHandler.java    From anomaly-detection with Apache License 2.0 6 votes vote down vote up
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 #4
Source File: ModelManager.java    From anomaly-detection with 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 File: TransportCreateUserAction.java    From crate with 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 #6
Source File: AnomalyDetectorProfileRunnerTests.java    From anomaly-detection with Apache License 2.0 6 votes vote down vote up
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 #7
Source File: NodeStatsTest.java    From crate with 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 #8
Source File: AnomalyDetectorActionHandler.java    From anomaly-detection with Apache License 2.0 6 votes vote down vote up
/**
 * 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 #9
Source File: TransportDeleteAction.java    From Elasticsearch with 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 #10
Source File: ModelManager.java    From anomaly-detection with 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 #11
Source File: ReloadRestAction.java    From elasticsearch-auth with 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
Source File: RCFResultTransportAction.java    From anomaly-detection with Apache License 2.0 5 votes vote down vote up
@Override
protected void doExecute(Task task, RCFResultRequest request, ActionListener<RCFResultResponse> listener) {

    if (adCircuitBreakerService.isOpen()) {
        listener.onFailure(new LimitExceededException(request.getAdID(), CommonErrorMessages.MEMORY_CIRCUIT_BROKEN_ERR_MSG));
        return;
    }

    try {
        LOG.info("Serve rcf request for {}", request.getModelID());
        manager
            .getRcfResult(
                request.getAdID(),
                request.getModelID(),
                request.getFeatures(),
                ActionListener
                    .wrap(
                        result -> listener
                            .onResponse(new RCFResultResponse(result.getScore(), result.getConfidence(), result.getForestSize())),
                        exception -> {
                            LOG.warn(exception);
                            listener.onFailure(exception);
                        }
                    )
            );
    } catch (Exception e) {
        LOG.error(e);
        listener.onFailure(e);
    }

}
 
Example #13
Source File: StopDetectorTransportAction.java    From anomaly-detection with Apache License 2.0 5 votes vote down vote up
@Override
protected void doExecute(Task task, ActionRequest actionRequest, ActionListener<StopDetectorResponse> listener) {
    StopDetectorRequest request = StopDetectorRequest.fromActionRequest(actionRequest);
    String adID = request.getAdID();
    try {
        DiscoveryNode[] dataNodes = nodeFilter.getEligibleDataNodes();
        DeleteModelRequest modelDeleteRequest = new DeleteModelRequest(adID, dataNodes);
        client.execute(DeleteModelAction.INSTANCE, modelDeleteRequest, ActionListener.wrap(response -> {
            if (response.hasFailures()) {
                LOG.warn("Cannot delete all models of detector {}", adID);
                for (FailedNodeException failedNodeException : response.failures()) {
                    LOG.warn("Deleting models of node has exception", failedNodeException);
                }
                // if customers are using an updated detector and we haven't deleted old
                // checkpoints, customer would have trouble
                listener.onResponse(new StopDetectorResponse(false));
            } else {
                LOG.info("models of detector {} get deleted", adID);
                listener.onResponse(new StopDetectorResponse(true));
            }
        }, exception -> {
            LOG.error(new ParameterizedMessage("Deletion of detector [{}] has exception.", adID), exception);
            listener.onResponse(new StopDetectorResponse(false));
        }));
    } catch (Exception e) {
        LOG.error("Fail to stop detector " + adID, e);
        Throwable cause = ExceptionsHelper.unwrapCause(e);
        listener.onFailure(new InternalFailure(adID, cause));
    }
}
 
Example #14
Source File: ListAlgorithmsAction.java    From elasticsearch-carrot2 with Apache License 2.0 5 votes vote down vote up
@Override
protected void doExecute(Task task,
                         ListAlgorithmsActionRequest request,
                         ActionListener<ListAlgorithmsActionResponse> listener) {
    listener.onResponse(new ListAlgorithmsActionResponse(
        new ArrayList<>(controllerSingleton.getAlgorithms().keySet())));
}
 
Example #15
Source File: ContentFilter.java    From elasticsearch-auth with Apache License 2.0 5 votes vote down vote up
protected void init(final RestRequest request, final RestChannel channel,
        final RestFilterChain filterChain) {
    if (logger.isDebugEnabled()) {
        logger.debug("initializing: {0}", initializing);
    }
    if (!initializing.getAndSet(true)) {
        authService.init(new ActionListener<Void>() {
            @Override
            public void onResponse(final Void response) {
                initializing.set(false);
                if (constraints == null) {
                    sendServiceUnavailable(request, channel);
                } else {
                    processNext(request, channel, filterChain);
                }
            }

            @Override
            public void onFailure(final Throwable e) {
                initializing.set(false);
                logger.warn("Failed to reload AuthService.", e);
                sendServiceUnavailable(request, channel);
            }
        });
    } else {
        sendServiceUnavailable(request, channel);
    }
}
 
Example #16
Source File: KerberizedClient.java    From elasticsearch-shield-kerberos-realm with Apache License 2.0 5 votes vote down vote up
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 #17
Source File: ActionListeners.java    From crate with 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 #18
Source File: SearchFeatureDao.java    From anomaly-detection with 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 #19
Source File: IndexAnomalyDetectorActionHandler.java    From anomaly-detection with Apache License 2.0 5 votes vote down vote up
private void createAnomalyDetector() {
    try {
        QueryBuilder query = QueryBuilders.matchAllQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(query).size(0).timeout(requestTimeout);

        SearchRequest searchRequest = new SearchRequest(ANOMALY_DETECTORS_INDEX).source(searchSourceBuilder);

        client.search(searchRequest, ActionListener.wrap(response -> onSearchAdResponse(response), exception -> onFailure(exception)));
    } catch (Exception e) {
        onFailure(e);
    }
}
 
Example #20
Source File: ClientUtil.java    From anomaly-detection with 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 #21
Source File: TransportFetchNodeAction.java    From crate with 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 #22
Source File: TransportsTest.java    From crate with 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 #23
Source File: TransportUpgradeAction.java    From Elasticsearch with 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 #24
Source File: SearchDfsQueryThenFetchAsyncAction.java    From Elasticsearch with Apache License 2.0 5 votes vote down vote up
SearchDfsQueryThenFetchAsyncAction(ESLogger logger, SearchServiceTransportAction searchService,
                                           ClusterService clusterService, IndexNameExpressionResolver indexNameExpressionResolver,
                                           SearchPhaseController searchPhaseController, ThreadPool threadPool,
                                           SearchRequest request, ActionListener<SearchResponse> listener) {
    super(logger, searchService, clusterService, indexNameExpressionResolver, searchPhaseController, threadPool, request, listener);
    queryResults = new AtomicArray<>(firstResults.length());
    fetchResults = new AtomicArray<>(firstResults.length());
    docIdsToLoad = new AtomicArray<>(firstResults.length());
}
 
Example #25
Source File: Search.java    From elasticsearch-rest-command with 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 #26
Source File: ClientUtil.java    From anomaly-detection with 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 #27
Source File: TransportPendingClusterTasksAction.java    From crate with Apache License 2.0 5 votes vote down vote up
@Override
protected void masterOperation(PendingClusterTasksRequest request, ClusterState state, ActionListener<PendingClusterTasksResponse> listener) {
    logger.trace("fetching pending tasks from cluster service");
    final List<PendingClusterTask> pendingTasks = clusterService.getMasterService().pendingTasks();
    logger.trace("done fetching pending tasks from cluster service");
    listener.onResponse(new PendingClusterTasksResponse(pendingTasks));
}
 
Example #28
Source File: RecoverySourceHandler.java    From crate with 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);
                }
            });
        }
    });
}
 
Example #29
Source File: TransportMasterNodeAction.java    From crate with Apache License 2.0 5 votes vote down vote up
AsyncSingleAction(Task task, Request request, ActionListener<Response> listener) {
    this.task = task;
    this.request = request;
    if (task != null) {
        request.setParentTask(clusterService.localNode().getId(), task.getId());
    }
    this.listener = listener;
}
 
Example #30
Source File: MultiActionListener.java    From Elasticsearch with Apache License 2.0 5 votes vote down vote up
public MultiActionListener(int numResponses,
                           Function<List<SingleResponse>, FinalResponse> mergeFunction,
                           ActionListener<? super FinalResponse> actionListener) {
    this.mergeFunction = mergeFunction;
    this.actionListener = actionListener;
    results = new ArrayList<>(numResponses);
    counter = new AtomicInteger(numResponses);
}