/** * This handles the login form submission for the Web IDE. * * @return The result of rendering the page. */ @AddCSRFToken @RequireCSRFCheck @Transactional public CompletionStage<Result> login() { Form<LoginForm> userForm = myFormFactory.form(LoginForm.class).bindFromRequest(); // Perform the basic validation checks. if (userForm.hasErrors()) { // Render the page with the login form with the errors fields String token = CSRF.getToken(request()).map(t -> t.value()).orElse("no token"); return CompletableFuture.supplyAsync( () -> badRequest(index.render(userForm, token)), myHttpExecutionContext.current()); } else { LoginForm form = userForm.get(); // Check for a registered user with the same email. // Note that "connect" expects a JPA entity manager, // which is not present if we don't wrap the call using // "withTransaction()". User user = myJpaApi.withTransaction(() -> User.connect(form.getEmail(), form.getPassword())); if (user != null) { // Check to see if this account has been authenticated or not. boolean hasAuthenticated = myJpaApi.withTransaction(() -> User.hasAuthenticated(form.getEmail())); if (hasAuthenticated) { // Update the login date final User updatedUser = myJpaApi.withTransaction(() -> User.lastLogin(form.getEmail())); // Add a new user event myJpaApi.withTransaction(() -> UserEvent.addRegularEvent("login", "", updatedUser)); // Stores the email as session value session("connected", form.getEmail()); // Obtain the http context from the configuration file String context = myConfiguration.getString("play.http.context"); if (context == null) { context = ""; } // Redirect back to the home page final String finalContext = context; return CompletableFuture.supplyAsync( () -> redirect(finalContext + "/"), myHttpExecutionContext.current()); } else { // Render the not authenticated page return CompletableFuture.supplyAsync( () -> ok(notAuthenticated.render(form.getEmail())), myHttpExecutionContext.current()); } } else { // The email and/or password does not match, so we add a new validation error. userForm.reject(new ValidationError("loginError", "Could not login.")); // Render the page with the login form with the errors fields String token = CSRF.getToken(request()).map(t -> t.value()).orElse("no token"); return CompletableFuture.supplyAsync( () -> badRequest(index.render(userForm, token)), myHttpExecutionContext.current()); } } }
@SuppressWarnings("unchecked") public <T extends UaResponseMessage> CompletableFuture<T> sendRequest(UaRequestMessage request) { return channelManager .getChannel() .thenCompose( ch -> { CompletableFuture<T> future = new CompletableFuture<>(); RequestHeader requestHeader = request.getRequestHeader(); pending.put( requestHeader.getRequestHandle(), (CompletableFuture<UaResponseMessage>) future); scheduleRequestTimeout(requestHeader); ch.writeAndFlush(request) .addListener( f -> { if (!f.isSuccess()) { UInteger requestHandle = request.getRequestHeader().getRequestHandle(); pending.remove(requestHandle); future.completeExceptionally(f.cause()); logger.debug("Write failed, requestHandle={}", requestHandle, f.cause()); } }); return future; }); }
/** * Connects to an RS world. * * @param world the world, as a string. For RS3, use a numeric string. For oldschool, use * "oldschool[world]". * @return A future for the connection task. */ public CompletableFuture<Void> connect(String world) { if (connectionTask != null && !connectionTask.isDone()) { connectionTask.cancel(true); } disconnect(); String host; int port; if (world.startsWith("oldschool")) { host = world + HOST_SUFFIX; port = OLDSCHOOL_PORT; } else { host = "world" + world + HOST_SUFFIX; port = RS3_PORT; } connectionTask = new CompletableFuture<>(); CompletableFuture.runAsync( () -> { try { synchronized (this) { socket = new Socket(host, port); } connectionTask.complete(null); } catch (IOException e) { connectionTask.completeExceptionally(e); } }); return connectionTask; }
@Override public void notifyTopologyInstalled(int topologyId) { if (topologyId < this.topologyId) { throw new IllegalStateException( "Cannot set a topology id (" + topologyId + ") that is lower than the current one (" + this.topologyId + ")"); } if (trace) { log.tracef("Signalling topology %d is installed", topologyId); } this.topologyId = topologyId; CompletableFuture<Void> oldFuture = null; try { synchronized (this) { oldFuture = topologyFuture; topologyFuture = new CompletableFuture(); } } finally { if (oldFuture != null) { oldFuture.complete(null); } } }
private static TestResponse callTestService(TestService.AsyncIface client) throws Exception { final CompletableFuture<TestResponse> result = new CompletableFuture<>(); client.process( request(), new AsyncMethodCallback<TestService.AsyncClient.process_call>() { @Override public void onComplete(TestService.AsyncClient.process_call response) { extract(response); } @Override public void onError(Exception e) { logger.error("RPC call failed ", e); } private void extract(TestService.AsyncClient.process_call response) { try { result.complete(response.getResult()); } catch (Exception e) { logger.error("Failed to extract response from: " + response, e); } } }); return result.get(5, TimeUnit.SECONDS); }
@Override public void notifyTransactionDataReceived(int topologyId) { if (topologyId < transactionDataTopologyId) { throw new IllegalStateException( "Cannot set a topology id (" + topologyId + ") that is lower than the current one (" + transactionDataTopologyId + ")"); } if (trace) { log.tracef("Signalling transaction data received for topology %d", topologyId); } transactionDataTopologyId = topologyId; CompletableFuture<Void> oldFuture = null; try { synchronized (this) { oldFuture = transactionDataFuture; transactionDataFuture = new CompletableFuture<>(); } } finally { if (oldFuture != null) { oldFuture.complete(null); } } }
private void scheduleRequestTimeout(RequestHeader requestHeader) { UInteger requestHandle = requestHeader.getRequestHandle(); long timeoutHint = requestHeader.getTimeoutHint() != null ? requestHeader.getTimeoutHint().longValue() : DEFAULT_TIMEOUT_MS; Timeout timeout = wheelTimer.newTimeout( t -> { timeouts.remove(requestHandle); if (!t.isCancelled()) { CompletableFuture<UaResponseMessage> f = pending.remove(requestHandle); if (f != null) { String message = "request timed out after " + timeoutHint + "ms"; f.completeExceptionally(new UaException(StatusCodes.Bad_Timeout, message)); } } }, timeoutHint, TimeUnit.MILLISECONDS); timeouts.put(requestHandle, timeout); }
static void checkCompletedNormally(CompletableFuture<?> cf, Object[] values) { try { equalAnyOf(cf.join(), values); } catch (Throwable x) { unexpected(x); } try { equalAnyOf(cf.getNow(null), values); } catch (Throwable x) { unexpected(x); } try { equalAnyOf(cf.get(), values); } catch (Throwable x) { unexpected(x); } try { equalAnyOf(cf.get(0L, SECONDS), values); } catch (Throwable x) { unexpected(x); } check(cf.isDone(), "Expected isDone to be true, got:" + cf); check(!cf.isCancelled(), "Expected isCancelled to be false"); check(!cf.cancel(true), "Expected cancel to return false"); check(cf.toString().contains("[Completed normally]")); check(cf.complete(null) == false, "Expected complete() to fail"); check( cf.completeExceptionally(new Throwable()) == false, "Expected completeExceptionally() to fail"); }
@Before public void setUp() throws Exception { final InputStream stream = getSettingsInputStream(); final Settings settings = Settings.read(stream); final CompletableFuture<Void> serverReadyFuture = new CompletableFuture<>(); thread = new Thread( () -> { try { final Settings overridenSettings = overrideSettings(settings); new GremlinServer(overridenSettings, serverReadyFuture).run(); } catch (InterruptedException ie) { logger.info("Shutting down Gremlin Server"); } catch (Exception ex) { logger.error("Could not start Gremlin Server for integration tests", ex); } }); thread.start(); // make sure gremlin server gets off the ground - longer than 30 seconds means that this didn't // work somehow try { serverReadyFuture.get(30000, TimeUnit.MILLISECONDS); } catch (Exception ex) { logger.error("Server did not start in the expected time or was otherwise interrupted.", ex); return; } host = System.getProperty("host", "localhost"); port = System.getProperty("port", "8182"); }
public CompletableFuture<ExecutionInfo> executeAsyncWithStats() { meta.triggerInterceptorsForEvent(PRE_INSERT, instance); validatePrimaryKey(instance, meta); final StatementWrapper statementWrapper = getInternalBoundStatementWrapper(); final String queryString = statementWrapper.getBoundStatement().preparedStatement().getQueryString(); if (LOGGER.isTraceEnabled()) { LOGGER.trace(format("Insert async with execution info : %s", queryString)); } CompletableFuture<ResultSet> cfutureRS = rte.execute(statementWrapper); return cfutureRS .thenApply(options::resultSetAsyncListener) .thenApply(statementWrapper::logReturnResults) .thenApply(statementWrapper::logTrace) .thenApply(x -> triggerLWTListeners(lwtResultListeners, x, queryString)) .thenApply(x -> x.getExecutionInfo()) .thenApply( x -> { meta.triggerInterceptorsForEvent(POST_INSERT, instance); return x; }); }
private CompletableFuture<Void> waitForEnvironmentInitialization( BuildExecutionSession buildExecutionSession, StartedEnvironment startedEnvironment) { CompletableFuture<Void> waitToCompleteFuture = new CompletableFuture<>(); try { Consumer<RunningEnvironment> onComplete = (runningEnvironment) -> { buildExecutionSession.setRunningEnvironment(runningEnvironment); buildExecutionSession.setStatus(BuildExecutionStatus.BUILD_ENV_SETUP_COMPLETE_SUCCESS); waitToCompleteFuture.complete(null); }; Consumer<Exception> onError = (e) -> { buildExecutionSession.setStatus( BuildExecutionStatus.BUILD_ENV_SETUP_COMPLETE_WITH_ERROR); waitToCompleteFuture.completeExceptionally( new BuildProcessException(e, startedEnvironment)); }; buildExecutionSession.setStatus(BuildExecutionStatus.BUILD_ENV_WAITING); startedEnvironment.monitorInitialization(onComplete, onError); } catch (Throwable e) { waitToCompleteFuture.completeExceptionally(new BuildProcessException(e, startedEnvironment)); } return waitToCompleteFuture; }
private void connect(boolean initialAttempt, CompletableFuture<ClientSecureChannel> future) { UaTcpStackClient.bootstrap(client, Optional.empty()) .whenCompleteAsync( (sc, ex) -> { if (sc != null) { logger.debug( "Channel bootstrap succeeded: localAddress={}, remoteAddress={}", sc.getChannel().localAddress(), sc.getChannel().remoteAddress()); future.complete(sc); } else { logger.debug("Channel bootstrap failed: {}", ex.getMessage(), ex); StatusCode statusCode = UaException.extract(ex).map(UaException::getStatusCode).orElse(StatusCode.BAD); boolean secureChannelError = statusCode.getValue() == StatusCodes.Bad_SecureChannelIdInvalid || statusCode.getValue() == StatusCodes.Bad_SecurityChecksFailed || statusCode.getValue() == StatusCodes.Bad_TcpSecureChannelUnknown; if (initialAttempt && secureChannelError) { // Try again if bootstrapping failed because we couldn't re-open the previous // channel. logger.debug("Previous channel unusable, retrying..."); connect(false, future); } else { future.completeExceptionally(ex); } } }); }
private void reconnect(Reconnecting reconnectState, long delaySeconds) { logger.debug("Scheduling reconnect for +{} seconds...", delaySeconds); Stack.sharedScheduledExecutor() .schedule( () -> { logger.debug("{} seconds elapsed; reconnecting...", delaySeconds); CompletableFuture<ClientSecureChannel> reconnected = reconnectState.reconnected; connect(true, reconnected); reconnected.whenCompleteAsync( (sc, ex) -> { if (sc != null) { logger.debug("Reconnect succeeded, channelId={}", sc.getChannelId()); if (state.compareAndSet(reconnectState, new Connected(reconnected))) { sc.getChannel().pipeline().addLast(new InactivityHandler()); } } else { logger.debug("Reconnect failed: {}", ex.getMessage(), ex); Reconnecting nextState = new Reconnecting(); if (state.compareAndSet(reconnectState, nextState)) { reconnect(nextState, nextDelay(delaySeconds)); } } }); }, delaySeconds, TimeUnit.SECONDS); }
/** * @param collector to perform aggregation / reduction operation on the results from active stage * (e.g. to Collect into a List or String) * @param fn Function that receives the results of all currently active tasks as input * @return A new builder object that can be used to define the next stage in the dataflow */ @SuppressWarnings({"unchecked", "rawtypes"}) default <T, R> SimpleReactStream<R> allOf(final Collector collector, final Function<T, R> fn) { CompletableFuture[] array = lastActiveArray(getLastActive()); CompletableFuture cf = CompletableFuture.allOf(array); Function<Exception, T> f = (Exception e) -> { BlockingStreamHelper.capture(e, getErrorHandler()); return BlockingStreamHelper.block( this, Collectors.toList(), new StreamWrapper(Stream.of(array), true)); }; CompletableFuture onFail = cf.exceptionally(f); CompletableFuture onSuccess = onFail.thenApplyAsync( (result) -> { return new StageWithResults(this.getTaskExecutor(), null, result) .submit( () -> (R) fn.apply( BlockingStreamHelper.aggregateResults( collector, Stream.of(array).collect(Collectors.toList()), getErrorHandler()))); }, getTaskExecutor()); return (SimpleReactStream<R>) withLastActive(new StreamWrapper(onSuccess, isEager())); }
/** * React to the completion of any of the events in the previous stage. Will not work reliably with * Streams where filter has been applied in earlier stages. (As Filter completes the Stream for * events that are filtered out, they potentially shortcircuit the completion of the stage). * * @param fn Function to apply when any of the previous events complete * @return Next stage in the stream */ default <R> SimpleReactStream<R> anyOf(final Function<U, R> fn) { CompletableFuture[] array = lastActiveArray(getLastActive()); CompletableFuture cf = CompletableFuture.anyOf(array); CompletableFuture onSuccess = cf.thenApplyAsync(fn, getTaskExecutor()); return (SimpleReactStream<R>) withLastActive(new StreamWrapper(onSuccess, isEager())); }
public void receiveResponse(UaResponseMessage response) { ResponseHeader header = response.getResponseHeader(); UInteger requestHandle = header.getRequestHandle(); CompletableFuture<UaResponseMessage> future = pending.remove(requestHandle); if (future != null) { if (header.getServiceResult().isGood()) { future.complete(response); } else { ServiceFault serviceFault; if (response instanceof ServiceFault) { serviceFault = (ServiceFault) response; } else { serviceFault = new ServiceFault(header); } future.completeExceptionally(new UaServiceFaultException(serviceFault)); } Timeout timeout = timeouts.remove(requestHandle); if (timeout != null) timeout.cancel(); } else { logger.debug( "Received {} for unknown requestHandle: {}", response.getClass().getSimpleName(), requestHandle); } }
private byte[] getFromCache(int site) { int blockNumber = site / myNumLinesPerInterval; byte[][] result = myGenoCache.getIfPresent(blockNumber); if (result == null) { CompletableFuture<byte[]> future = new CompletableFuture<>(); CompletableFuture<byte[]> temp = myFutureQueue.putIfAbsent(site, future); if (temp != null) { future = temp; } if (myCurrentlyProcessingBlocks.add(blockNumber)) { myThreadPool.submit(new ProcessLines(site)); } try { result = myGenoCache.getIfPresent(blockNumber); if (result != null) { myFutureQueue.remove(site); future.complete(result[site % myNumLinesPerInterval]); return result[site % myNumLinesPerInterval]; } else { return future.get(); } } catch (Exception e) { myLogger.error(e.getMessage(), e); } } return result[site % myNumLinesPerInterval]; }
@Override public CompletableFuture<Void> close() { CompletableFuture<Void> future = new CompletableFuture<>(); lock.lock() .thenCompose(v -> balancer.replace(server.server().cluster())) .whenComplete( (r1, e1) -> { balancer.close(); lock.unlock() .whenComplete( (r2, e2) -> { super.close() .whenComplete( (r3, e3) -> { server .close() .whenComplete( (r4, e4) -> { if (e4 == null) { future.complete(null); } else { future.completeExceptionally(e4); } }); }); }); }); return future; }
@Test @SuppressWarnings("unchecked") public void modificationDuringTransactionCausesAbort() throws Exception { Map<String, String> testMap = getRuntime().getObjectsView().open(CorfuRuntime.getStreamID("A"), SMRMap.class); assertThat(testMap.put("a", "z")); getRuntime().getObjectsView().TXBegin(); assertThat(testMap.put("a", "a")).isEqualTo("z"); assertThat(testMap.put("a", "b")).isEqualTo("a"); assertThat(testMap.get("a")).isEqualTo("b"); CompletableFuture cf = CompletableFuture.runAsync( () -> { Map<String, String> testMap2 = getRuntime() .getObjectsView() .open( UUID.nameUUIDFromBytes("A".getBytes()), SMRMap.class, null, EnumSet.of(ObjectOpenOptions.NO_CACHE), SerializerType.JSON); testMap2.put("a", "f"); }); cf.join(); assertThatThrownBy(() -> getRuntime().getObjectsView().TXEnd()) .isInstanceOf(TransactionAbortedException.class); }
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException { ExecutorService executor = Executors.newFixedThreadPool(5); CompletableFuture<String> task1 = CompletableFuture.supplyAsync( () -> { try { System.out.println(Thread.currentThread().getName() + ": firstTask"); TimeUnit.SECONDS.sleep(2); } catch (Exception e) { } return "1"; }); CompletableFuture<String> task2 = CompletableFuture.supplyAsync( () -> { try { System.out.println(Thread.currentThread().getName() + ": secondTask"); TimeUnit.SECONDS.sleep(3); } catch (Exception e) { } return "2"; }); // a new thread from the supplied executor will execute third task task1.acceptEitherAsync( task2, (x) -> { System.out.println(Thread.currentThread().getName() + ": thirdTask " + x); }, executor); TimeUnit.SECONDS.sleep(5); System.out.println(Thread.currentThread().getName() + ": " + task1.get()); executor.shutdown(); }
/* * @param t Result type * @see java.util.function.Consumer#accept(java.lang.Object) */ @Override public void accept(FastFuture<T> t) { active.add(t); if (active.size() > maxActive.getMaxActive()) { while (active.size() > maxActive.getReduceTo()) { List<FastFuture> toRemove = active .stream() .filter(cf -> cf.isDone()) .peek(this::handleExceptions) .collect(Collectors.toList()); active.removeAll(toRemove); if (active.size() > maxActive.getReduceTo()) { CompletableFuture promise = new CompletableFuture(); FastFuture.xOf( active.size() - maxActive.getReduceTo(), () -> promise.complete(true), active.toArray(new FastFuture[0])); promise.join(); } } } }
// Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_046: [The function shall open the Sender (Proton) // link.] // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_047: [The function shall return a new // CompletableFuture for the sent message.] // Tests_SRS_AMQPSIOTHUBCONNECTIONBASEHANDLER_14_048: [The function shall lock sending on the // AmqpsIotHubConnection.] @Test public void createBinaryMessageOpensSenderAndLocksSending( @Mocked final CompletableFuture<Integer> mockFuture) { final String hostName = "test.host.name"; final String deviceId = "test-deviceId"; final String userName = "******"; final String sasToken = "test-token"; final byte[] msgBody = {0x61, 0x62, 0x63}; final Object messageId = "123"; new NonStrictExpectations() { { new CompletableFuture<Integer>(); result = mockFuture; } }; AmqpsIotHubConnectionBaseHandler handler = new AmqpsIotHubConnectionBaseHandler( hostName, userName, sasToken, deviceId, mockIotHubConnection); Deencapsulation.setField(handler, "sender", mockSender); CompletableFuture<Integer> actualFuture = handler.createBinaryMessage(msgBody, messageId); assertEquals(CompletableFuture.class, actualFuture.getClass()); new Verifications() { { Deencapsulation.invoke(mockIotHubConnection, "lockSending"); mockSender.open(); } }; }
/** * Handles a publish request. * * @param request The publish request to handle. * @return A completable future to be completed with the publish response. */ @SuppressWarnings("unchecked") private CompletableFuture<PublishResponse> handlePublish(PublishRequest request) { if (request.session() != id) return Futures.exceptionalFuture(new UnknownSessionException("incorrect session ID")); if (request.previousVersion() != eventVersion) { return CompletableFuture.completedFuture( PublishResponse.builder() .withStatus(Response.Status.ERROR) .withError(RaftError.Type.INTERNAL_ERROR) .withVersion(eventVersion) .build()); } eventVersion = request.eventVersion(); List<CompletableFuture<Void>> futures = new ArrayList<>(request.events().size()); for (Event<?> event : request.events()) { Listeners<Object> listeners = eventListeners.get(event.name()); if (listeners != null) { futures.add(listeners.accept(event.message())); } } return CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[futures.size()])) .handleAsync( (result, error) -> { completeVersion = Math.max(completeVersion, request.eventVersion()); return PublishResponse.builder() .withStatus(Response.Status.OK) .withVersion(eventVersion) .build(); }, context.executor()); }
/** Registers the session. */ private CompletableFuture<Void> register() { context.checkThread(); CompletableFuture<Void> future = new CompletableFuture<>(); RegisterRequest request = RegisterRequest.builder().withClient(clientId).build(); this.<RegisterRequest, RegisterResponse>request(request, new CompletableFuture<>(), false, true) .whenComplete( (response, error) -> { if (error == null) { if (response.status() == Response.Status.OK) { setMembers(response.members()); setTimeout(response.timeout()); onOpen(response.session()); setupConnection(connection) .whenComplete((setupResult, setupError) -> future.complete(null)); resetMembers() .keepAlive( Duration.ofMillis(Math.round(response.timeout() * KEEP_ALIVE_RATIO))); } else { future.completeExceptionally(response.error().createException()); } } else { future.completeExceptionally(error); } }); return future; }
/** Recursively submits a command. */ @SuppressWarnings("unchecked") private <T> CompletableFuture<T> submit(CommandRequest request, CompletableFuture<T> future) { if (!isOpen()) { future.completeExceptionally(new IllegalStateException("session not open")); return future; } long sequence = ++requestSequence; this.<CommandRequest, CommandResponse>request(request) .whenComplete( (response, error) -> { if (error == null) { long responseSequence = request.sequence(); sequenceResponse( sequence, () -> { commandResponse = responseSequence; completeResponse(response, future); }); } else { future.completeExceptionally(error); } }); return future; }
@SuppressWarnings("unchecked") public void sendRequests( List<? extends UaRequestMessage> requests, List<CompletableFuture<? extends UaResponseMessage>> futures) { Preconditions.checkArgument( requests.size() == futures.size(), "requests and futures parameters must be same size"); channelManager .getChannel() .whenComplete( (ch, ex) -> { if (ch != null) { Iterator<? extends UaRequestMessage> requestIterator = requests.iterator(); Iterator<CompletableFuture<? extends UaResponseMessage>> futureIterator = futures.iterator(); while (requestIterator.hasNext() && futureIterator.hasNext()) { UaRequestMessage request = requestIterator.next(); CompletableFuture<UaResponseMessage> future = (CompletableFuture<UaResponseMessage>) futureIterator.next(); RequestHeader requestHeader = request.getRequestHeader(); pending.put(requestHeader.getRequestHandle(), future); scheduleRequestTimeout(requestHeader); } ch.eventLoop() .execute( () -> { for (UaRequestMessage request : requests) { ch.write(request) .addListener( f -> { if (!f.isSuccess()) { UInteger requestHandle = request.getRequestHeader().getRequestHandle(); CompletableFuture<?> future = pending.remove(requestHandle); if (future != null) future.completeExceptionally(f.cause()); logger.debug( "Write failed, requestHandle={}", requestHandle, f.cause()); } }); } ch.flush(); }); } else { futures.forEach(f -> f.completeExceptionally(ex)); } }); }
@Test public void testLongParam() throws IllegalAccessException, InstantiationException { PrimitiveUser2 a = new PrimitiveUser2(); CompletableFuture<String> blocker = new CompletableFuture<>(); final CompletableFuture<Object> res = a.longTest(blocker, 10000000000L); blocker.complete("x"); assertEquals(":10000000000:x", res.join()); }
public static <T> CompletableFuture<T> toCompletableFuture(final Supplier<T> supplier) { CompletableFuture<T> future = new CompletableFuture<T>(); try { future.complete(supplier.get()); } catch (RuntimeException e) { future.completeExceptionally(e); } return future; }
/** Completes the given operation response. */ @SuppressWarnings("unchecked") private void completeResponse(OperationResponse response, CompletableFuture future) { if (response.status() == Response.Status.OK) { future.complete(response.result()); resetMembers(); } else { future.completeExceptionally(response.error().createException()); } }
@Test public void testAddOnChatUserQuitListener() throws Exception { CompletableFuture<Boolean> quitFuture = new CompletableFuture<>(); instance.addOnChatUserQuitListener((username) -> quitFuture.complete(true)); instance.onEvent(new QuitEvent(pircBotX, daoSnapshot, userHostMask, userSnapshot, "reason")); assertThat(quitFuture.get(TIMEOUT, TIMEOUT_UNIT), is(true)); }