use of io.vertx.core.Future in project vert.x by eclipse.
the class HttpTest method drainingServer.
private void drainingServer(Consumer<Future<Void>> consumer) {
Promise<Void> resumeFuture = Promise.promise();
server.requestHandler(req -> {
req.response().setChunked(true);
assertFalse(req.response().writeQueueFull());
req.response().setWriteQueueMaxSize(1000);
Buffer buff = TestUtils.randomBuffer(10000);
// Send data until the buffer is full
vertx.setPeriodic(1, id -> {
req.response().write(buff);
if (req.response().writeQueueFull()) {
vertx.cancelTimer(id);
req.response().drainHandler(v -> {
assertFalse(req.response().writeQueueFull());
testComplete();
});
// Tell the client to resume
resumeFuture.complete();
}
});
});
server.listen(testAddress, onSuccess(s -> consumer.accept(resumeFuture.future())));
}
use of io.vertx.core.Future in project vert.x by eclipse.
the class ConnectionPoolTest method testConnectResultAfterClose.
private void testConnectResultAfterClose(boolean success) {
ConnectionManager mgr = new ConnectionManager();
ConnectionPool<Connection> pool = ConnectionPool.pool(mgr, new int[] { 1 });
EventLoopContext ctx = vertx.createEventLoopContext();
AtomicInteger acquired = new AtomicInteger();
pool.acquire(ctx, 0, ar -> {
assertEquals(0, acquired.getAndIncrement());
});
assertEquals(1, pool.size());
ConnectionRequest request = mgr.assertRequest();
Promise<List<Future<Connection>>> closeResult = Promise.promise();
pool.close(closeResult);
Throwable cause = new Throwable();
Connection expected = new Connection();
if (success) {
request.connect(expected, 0);
} else {
request.fail(cause);
}
assertTrue(closeResult.future().isComplete());
List<Future<Connection>> connections = closeResult.future().result();
assertEquals(1, connections.size());
assertEquals(success, connections.get(0).succeeded());
assertEquals(0, pool.size());
if (success) {
assertEquals(expected, connections.get(0).result());
} else {
assertEquals(cause, connections.get(0).cause());
}
waitUntil(() -> acquired.get() == 1);
}
use of io.vertx.core.Future in project java-chassis by ServiceComb.
the class MockForRestServerVerticle method mockRestServerVerticle.
public void mockRestServerVerticle() {
final HttpServer server = Mockito.mock(HttpServer.class);
new MockUp<RestServerVerticle>() {
@Mock
private void startListen(HttpServer server, IpPort ipPort, Future<Void> startFuture) {
}
@Mock
private HttpServer createHttpServer(boolean isHttp_2) {
return server;
}
};
}
use of io.vertx.core.Future in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapter method uploadMessage.
private Future<Void> uploadMessage(final MqttContext ctx, final TenantObject tenantObject, final String deviceId, final Buffer payload, final MetricsTags.EndpointType endpoint) {
if (!isPayloadOfIndicatedType(payload, ctx.contentType())) {
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, String.format("Content-Type %s does not match payload", ctx.contentType())));
}
final Span currentSpan = TracingHelper.buildChildSpan(tracer, ctx.getTracingContext(), "upload " + endpoint, getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, tenantObject.getTenantId()).withTag(TracingHelper.TAG_DEVICE_ID, deviceId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), ctx.authenticatedDevice() != null).start();
final Future<RegistrationAssertion> tokenTracker = getRegistrationAssertion(tenantObject.getTenantId(), deviceId, ctx.authenticatedDevice(), currentSpan.context());
final Future<TenantObject> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantObject), checkMessageLimit(tenantObject, payload.length(), currentSpan.context())).map(tenantObject);
return CompositeFuture.all(tokenTracker, tenantValidationTracker).compose(ok -> {
final Map<String, Object> props = getDownstreamMessageProperties(ctx);
props.put(MessageHelper.APP_PROPERTY_QOS, ctx.getRequestedQos().ordinal());
addRetainAnnotation(ctx, props, currentSpan);
customizeDownstreamMessageProperties(props, ctx);
if (endpoint == EndpointType.EVENT) {
return getEventSender(tenantObject).sendEvent(tenantObject, tokenTracker.result(), ctx.contentType(), payload, props, currentSpan.context());
} else {
return getTelemetrySender(tenantObject).sendTelemetry(tenantObject, tokenTracker.result(), ctx.getRequestedQos(), ctx.contentType(), payload, props, currentSpan.context());
}
}).map(ok -> {
log.trace("successfully processed message [topic: {}, QoS: {}] from device [tenantId: {}, deviceId: {}]", ctx.message().topicName(), ctx.message().qosLevel(), tenantObject.getTenantId(), deviceId);
// check that the remote MQTT client is still connected before sending PUBACK
if (ctx.isAtLeastOnce() && ctx.deviceEndpoint().isConnected()) {
currentSpan.log(EVENT_SENDING_PUBACK);
ctx.acknowledge();
}
currentSpan.finish();
return ok;
}).recover(t -> {
if (ClientErrorException.class.isInstance(t)) {
final ClientErrorException e = (ClientErrorException) t;
log.debug("cannot process message [endpoint: {}] from device [tenantId: {}, deviceId: {}]: {} - {}", endpoint, tenantObject.getTenantId(), deviceId, e.getErrorCode(), e.getMessage());
} else {
log.debug("cannot process message [endpoint: {}] from device [tenantId: {}, deviceId: {}]", endpoint, tenantObject.getTenantId(), deviceId, t);
}
TracingHelper.logError(currentSpan, t);
currentSpan.finish();
return Future.failedFuture(t);
});
}
use of io.vertx.core.Future in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapter method uploadCommandResponseMessage.
/**
* Uploads a command response message.
*
* @param ctx The context in which the MQTT message has been published.
* @param targetAddress The address that the response should be forwarded to.
* @return A future indicating the outcome of the operation.
* <p>
* The future will succeed if the message has been uploaded successfully.
* Otherwise, the future will fail with a {@link ServiceInvocationException}.
* @throws NullPointerException if any of the parameters are {@code null}.
*/
public final Future<Void> uploadCommandResponseMessage(final MqttContext ctx, final ResourceIdentifier targetAddress) {
Objects.requireNonNull(ctx);
Objects.requireNonNull(targetAddress);
final String[] addressPath = targetAddress.getResourcePath();
Integer status = null;
String reqId = null;
final Future<CommandResponse> commandResponseTracker;
if (addressPath.length <= CommandConstants.TOPIC_POSITION_RESPONSE_STATUS) {
commandResponseTracker = Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "command response topic has too few segments"));
} else {
try {
status = Integer.parseInt(addressPath[CommandConstants.TOPIC_POSITION_RESPONSE_STATUS]);
} catch (final NumberFormatException e) {
log.trace("got invalid status code [{}] [tenant-id: {}, device-id: {}]", addressPath[CommandConstants.TOPIC_POSITION_RESPONSE_STATUS], targetAddress.getTenantId(), targetAddress.getResourceId());
}
if (status != null) {
reqId = addressPath[CommandConstants.TOPIC_POSITION_RESPONSE_REQ_ID];
final CommandResponse commandResponse = CommandResponse.fromRequestId(reqId, targetAddress.getTenantId(), targetAddress.getResourceId(), ctx.message().payload(), ctx.contentType(), status);
commandResponseTracker = commandResponse != null ? Future.succeededFuture(commandResponse) : Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "command response topic contains invalid data"));
} else {
// status code could not be parsed
commandResponseTracker = Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "invalid status code"));
}
}
final Span currentSpan = TracingHelper.buildChildSpan(tracer, ctx.getTracingContext(), "upload Command response", getTypeName()).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).withTag(TracingHelper.TAG_TENANT_ID, targetAddress.getTenantId()).withTag(TracingHelper.TAG_DEVICE_ID, targetAddress.getResourceId()).withTag(Constants.HEADER_COMMAND_RESPONSE_STATUS, status).withTag(Constants.HEADER_COMMAND_REQUEST_ID, reqId).withTag(TracingHelper.TAG_AUTHENTICATED.getKey(), ctx.authenticatedDevice() != null).start();
final int payloadSize = Optional.ofNullable(ctx.message().payload()).map(Buffer::length).orElse(0);
final Future<TenantObject> tenantTracker = getTenantConfiguration(targetAddress.getTenantId(), ctx.getTracingContext());
return CompositeFuture.all(tenantTracker, commandResponseTracker).compose(success -> {
final Future<RegistrationAssertion> deviceRegistrationTracker = getRegistrationAssertion(targetAddress.getTenantId(), targetAddress.getResourceId(), ctx.authenticatedDevice(), currentSpan.context());
final Future<Void> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantTracker.result()), checkMessageLimit(tenantTracker.result(), payloadSize, currentSpan.context())).mapEmpty();
return CompositeFuture.all(deviceRegistrationTracker, tenantValidationTracker).compose(ok -> sendCommandResponse(tenantTracker.result(), deviceRegistrationTracker.result(), commandResponseTracker.result(), currentSpan.context()));
}).compose(delivery -> {
log.trace("successfully forwarded command response from device [tenant-id: {}, device-id: {}]", targetAddress.getTenantId(), targetAddress.getResourceId());
metrics.reportCommand(Direction.RESPONSE, targetAddress.getTenantId(), tenantTracker.result(), ProcessingOutcome.FORWARDED, payloadSize, ctx.getTimer());
// check that the remote MQTT client is still connected before sending PUBACK
if (ctx.isAtLeastOnce() && ctx.deviceEndpoint().isConnected()) {
currentSpan.log(EVENT_SENDING_PUBACK);
ctx.acknowledge();
}
currentSpan.finish();
return Future.<Void>succeededFuture();
}).recover(t -> {
TracingHelper.logError(currentSpan, t);
currentSpan.finish();
metrics.reportCommand(Direction.RESPONSE, targetAddress.getTenantId(), tenantTracker.result(), ProcessingOutcome.from(t), payloadSize, ctx.getTimer());
return Future.failedFuture(t);
});
}
Aggregations