@SneakyThrows(InterruptedException.class)
    public static void trigger(final Collection<CompletableFuture<?>> futures, final ExecuteCallback executeCallback) {
        BlockingQueue<CompletableFuture<?>> futureQueue = new LinkedBlockingQueue<>();
        for (CompletableFuture<?> each : futures) {
            each.whenCompleteAsync(new BiConsumer<Object, Throwable>() {
                
                @SneakyThrows(InterruptedException.class)
                @Override
                public void accept(final Object unused, final Throwable throwable) {
                    futureQueue.put(each);
                }
            }, CALLBACK_EXECUTOR);
        }
        for (int i = 1, count = futures.size(); i <= count; i++) {
            CompletableFuture<?> future = futureQueue.take();
            try {
                future.get();
            } catch (final ExecutionException ex) {
                Throwable cause = ex.getCause();
                executeCallback.onFailure(null != cause ? cause : ex);
                throw new PipelineInternalException(ex);
            }
        }
        executeCallback.onSuccess();
    }
@Test
    void assertTriggerPartSuccessFailure() {
        CompletableFuture<?> future1 = CompletableFuture.runAsync(new FixtureRunnable(true));
        CompletableFuture<?> future2 = CompletableFuture.runAsync(new FixtureRunnable(false));
        FixtureExecuteCallback executeCallback = new FixtureExecuteCallback();
        try {
            ExecuteEngine.trigger(Arrays.asList(future1, future2), executeCallback);
            // CHECKSTYLE:OFF
        } catch (final RuntimeException ignored) {
            // CHECKSTYLE:ON
        }
        assertThat(executeCallback.successCount.get(), is(0));
        assertThat(executeCallback.failureCount.get(), is(1));
    }