use of io.vertx.core.Future in project hono by eclipse.
the class DelegatingCredentialsManagementHttpEndpoint method updateCredentials.
private void updateCredentials(final RoutingContext ctx) {
final Span span = TracingHelper.buildServerChildSpan(tracer, TracingHandler.serverSpanContext(ctx), SPAN_NAME_UPDATE_CREDENTIALS, getClass().getSimpleName()).start();
final Future<String> tenantId = getRequestParameter(ctx, PARAM_TENANT_ID, getPredicate(config.getTenantIdPattern(), false));
final Future<String> deviceId = getRequestParameter(ctx, PARAM_DEVICE_ID, getPredicate(config.getDeviceIdPattern(), false));
final Future<List<CommonCredential>> updatedCredentials = fromPayload(ctx);
CompositeFuture.all(tenantId, deviceId, updatedCredentials).compose(ok -> {
TracingHelper.setDeviceTags(span, tenantId.result(), deviceId.result());
logger.debug("updating {} credentials [tenant: {}, device-id: {}]", updatedCredentials.result().size(), tenantId.result(), deviceId.result());
final Optional<String> resourceVersion = Optional.ofNullable(ctx.get(KEY_RESOURCE_VERSION));
return getService().updateCredentials(tenantId.result(), deviceId.result(), updatedCredentials.result(), resourceVersion, span);
}).onSuccess(operationResult -> writeResponse(ctx, operationResult, span)).onFailure(t -> failRequest(ctx, t, span)).onComplete(s -> span.finish());
}
use of io.vertx.core.Future in project hono by eclipse.
the class HonoConnectionImplTest method testHandlerCallsCloseHook.
private void testHandlerCallsCloseHook(final VertxTestContext ctx, final BiConsumer<ProtonReceiver, ArgumentCaptor<Handler<AsyncResult<ProtonReceiver>>>> handlerCaptor) {
// GIVEN an established connection
final Source source = mock(Source.class);
when(source.getAddress()).thenReturn("source/address");
final ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.isOpen()).thenReturn(Boolean.TRUE);
when(receiver.getSource()).thenReturn(source);
when(receiver.getRemoteSource()).thenReturn(source);
when(session.createReceiver(anyString())).thenReturn(receiver);
final Handler<String> remoteCloseHook = VertxMockSupport.mockHandler();
final ArgumentCaptor<Handler<AsyncResult<ProtonReceiver>>> captor = VertxMockSupport.argumentCaptorHandler();
honoConnection.connect().compose(c -> {
// WHEN creating a receiver link with a close hook
final Future<ProtonReceiver> r = c.createReceiver("source", ProtonQoS.AT_LEAST_ONCE, mock(ProtonMessageHandler.class), remoteCloseHook);
// wait for peer's attach frame
final ArgumentCaptor<Handler<AsyncResult<ProtonReceiver>>> openHandlerCaptor = VertxMockSupport.argumentCaptorHandler();
ctx.verify(() -> verify(receiver).openHandler(openHandlerCaptor.capture()));
openHandlerCaptor.getValue().handle(Future.succeededFuture(receiver));
return r;
}).onComplete(ctx.succeeding(recv -> {
// WHEN the peer sends a detach frame
handlerCaptor.accept(receiver, captor);
captor.getValue().handle(Future.succeededFuture(receiver));
ctx.verify(() -> {
// THEN the close hook is called
verify(remoteCloseHook).handle(any());
// and the receiver link is closed
verify(receiver).close();
verify(receiver).free();
});
ctx.completeNow();
}));
}
use of io.vertx.core.Future in project hono by eclipse.
the class HonoConnectionImplTest method testCreateSenderFailsIfPeerDoesNotCreateTerminus.
/**
* Verifies that the attempt to create a sender fails with a
* {@code ServerErrorException} if the remote peer sends a
* {@code null} target in its attach frame.
*
* @param ctx The vert.x test context.
*/
@Test
public void testCreateSenderFailsIfPeerDoesNotCreateTerminus(final VertxTestContext ctx) {
final ProtonSender sender = mock(ProtonSender.class);
when(sender.getRemoteTarget()).thenReturn(null);
when(session.createSender(anyString())).thenReturn(sender);
final Handler<String> remoteCloseHook = VertxMockSupport.mockHandler();
// GIVEN an established connection
honoConnection.connect().compose(c -> {
// WHEN the client tries to open a sender link
final Future<ProtonSender> s = c.createSender(TelemetryConstants.TELEMETRY_ENDPOINT, ProtonQoS.AT_LEAST_ONCE, remoteCloseHook);
ctx.verify(() -> {
final ArgumentCaptor<Handler<AsyncResult<ProtonSender>>> openHandler = VertxMockSupport.argumentCaptorHandler();
verify(sender).open();
verify(sender).openHandler(openHandler.capture());
// and the peer does not allocate a local terminus for the link
openHandler.getValue().handle(Future.succeededFuture(sender));
});
return s;
}).onComplete(ctx.failing(t -> {
ctx.verify(() -> {
// THEN the link does not get established
assertThat(((ServerErrorException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_UNAVAILABLE);
// and the remote close hook does not get invoked
verify(remoteCloseHook, never()).handle(anyString());
});
ctx.completeNow();
}));
}
use of io.vertx.core.Future in project hono by eclipse.
the class HonoConnectionImplTest method testConnectFailsIfAnotherConnectAttemptIsScheduled.
/**
* Verifies that a connection attempt by the client is failed if it occurs while another connect invocation is
* waiting for the next reconnect attempt.
*
* @param ctx The test execution context.
*/
@Test
public void testConnectFailsIfAnotherConnectAttemptIsScheduled(final VertxTestContext ctx) {
final long reconnectMinDelay = 20L;
// GIVEN a client that is configured to connect to a peer
// to which the connection is only getting established on the 2nd attempt, after some delay.
// the reconnect timer handler only shall get invoked on demand (after a corresponding promise gets completed)
final AtomicBoolean reconnectTimerStarted = new AtomicBoolean();
final Promise<Void> reconnectTimerContinuePromise = Promise.promise();
when(vertx.setTimer(eq(reconnectMinDelay), any())).thenAnswer(invocation -> {
reconnectTimerStarted.set(true);
final Handler<Long> reconnectTimerHandler = invocation.getArgument(1);
reconnectTimerContinuePromise.future().onComplete(ar -> reconnectTimerHandler.handle(0L));
return 1L;
});
connectionFactory = new DisconnectHandlerProvidingConnectionFactory(con) {
@Override
public void connect(final ProtonClientOptions options, final String username, final String password, final String containerId, final Handler<AsyncResult<ProtonConnection>> closeHandler, final Handler<ProtonConnection> disconnectHandler, final Handler<AsyncResult<ProtonConnection>> connectionResultHandler) {
super.connect(options, username, password, containerId, closeHandler, disconnectHandler, connectionResultHandler);
}
};
connectionFactory.setExpectedFailingConnectionAttempts(1);
props.setReconnectMinDelay(reconnectMinDelay);
honoConnection = new HonoConnectionImpl(vertx, connectionFactory, props);
// WHEN trying to connect
final Future<HonoConnection> connectFuture = honoConnection.connect();
assertThat(reconnectTimerStarted.get()).isTrue();
// and starting another connect attempt before the connection has been established
final Future<HonoConnection> connectFuture2 = honoConnection.connect();
// and letting the first attempt finish
reconnectTimerContinuePromise.complete();
// THEN the first connect invocation succeeds and the second is failed
connectFuture.onComplete(ctx.succeeding(cause -> {
ctx.verify(() -> {
assertThat(connectFuture2.failed()).isTrue();
assertThat(connectFuture2.cause()).isInstanceOf(ClientErrorException.class);
assertThat(((ClientErrorException) connectFuture2.cause()).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_CONFLICT);
});
ctx.completeNow();
}));
}
use of io.vertx.core.Future in project hono by eclipse.
the class HonoConnectionImplTest method testCreateReceiverFails.
private void testCreateReceiverFails(final VertxTestContext ctx, final Supplier<ErrorCondition> errorSupplier, final Predicate<Throwable> failureAssertion) {
final ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.getRemoteCondition()).thenReturn(errorSupplier.get());
when(session.createReceiver(anyString())).thenReturn(receiver);
final Handler<String> remoteCloseHook = VertxMockSupport.mockHandler();
when(vertx.setTimer(anyLong(), VertxMockSupport.anyHandler())).thenAnswer(invocation -> {
// do not run timers immediately
return 0L;
});
// GIVEN an established connection
honoConnection.connect().compose(c -> {
// WHEN creating a receiver
final Future<ProtonReceiver> r = c.createReceiver("source", ProtonQoS.AT_LEAST_ONCE, (delivery, msg) -> {
}, remoteCloseHook);
ctx.verify(() -> {
// and when the peer rejects to open the link
final ArgumentCaptor<Handler<AsyncResult<ProtonReceiver>>> openHandler = VertxMockSupport.argumentCaptorHandler();
verify(receiver).openHandler(openHandler.capture());
openHandler.getValue().handle(Future.failedFuture(new IllegalStateException()));
});
return r;
}).onComplete(ctx.failing(t -> {
ctx.verify(() -> {
// THEN link establishment is failed after the configured amount of time
verify(vertx).setTimer(eq(props.getLinkEstablishmentTimeout()), VertxMockSupport.anyHandler());
// with the expected error condition
assertThat(failureAssertion.test(t)).isTrue();
verify(remoteCloseHook, never()).handle(anyString());
});
ctx.completeNow();
}));
}
Aggregations