use of io.vertx.core.AsyncResult in project vert.x by eclipse.
the class VertxHttp2NetSocket method sendFile.
@Override
public NetSocket sendFile(String filename, long offset, long length, Handler<AsyncResult<Void>> resultHandler) {
synchronized (conn) {
Context resultCtx = resultHandler != null ? vertx.getOrCreateContext() : null;
File file = vertx.resolveFile(filename);
if (!file.exists()) {
if (resultHandler != null) {
resultCtx.runOnContext((v) -> resultHandler.handle(Future.failedFuture(new FileNotFoundException())));
} else {
// log.error("File not found: " + filename);
}
return this;
}
RandomAccessFile raf;
try {
raf = new RandomAccessFile(file, "r");
} catch (IOException e) {
if (resultHandler != null) {
resultCtx.runOnContext((v) -> resultHandler.handle(Future.failedFuture(e)));
} else {
//log.error("Failed to send file", e);
}
return this;
}
long contentLength = Math.min(length, file.length() - offset);
FileStreamChannel fileChannel = new FileStreamChannel(ar -> {
if (resultHandler != null) {
resultCtx.runOnContext(v -> {
resultHandler.handle(Future.succeededFuture());
});
}
}, this, offset, contentLength);
drainHandler(fileChannel.drainHandler);
handlerContext.channel().eventLoop().register(fileChannel);
fileChannel.pipeline().fireUserEventTriggered(raf);
}
return this;
}
use of io.vertx.core.AsyncResult in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testAuthenticatedMqttAdapterCreatesMessageHandlersForAuthenticatedDevices.
/**
* Verifies that on successful authentication the adapter sets appropriate message and close
* handlers on the client endpoint.
*/
@SuppressWarnings({ "unchecked" })
@Test
public void testAuthenticatedMqttAdapterCreatesMessageHandlersForAuthenticatedDevices() {
// GIVEN an adapter
final MqttServer server = getMqttServer(false);
final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
forceClientMocksToConnected();
doAnswer(invocation -> {
Handler<AsyncResult<Device>> resultHandler = invocation.getArgument(1);
resultHandler.handle(Future.succeededFuture(new Device("DEFAULT_TENANT", "4711")));
return null;
}).when(credentialsAuthProvider).authenticate(any(DeviceCredentials.class), any(Handler.class));
// WHEN a device tries to connect with valid credentials
final MqttEndpoint endpoint = getMqttEndpointAuthenticated();
adapter.handleEndpointConnection(endpoint);
// THEN the device's logical ID is successfully established and corresponding handlers
// are registered
final ArgumentCaptor<DeviceCredentials> credentialsCaptor = ArgumentCaptor.forClass(DeviceCredentials.class);
verify(credentialsAuthProvider).authenticate(credentialsCaptor.capture(), any(Handler.class));
assertThat(credentialsCaptor.getValue().getAuthId(), is("sensor1"));
verify(endpoint).accept(false);
verify(endpoint).publishHandler(any(Handler.class));
verify(endpoint).closeHandler(any(Handler.class));
}
use of io.vertx.core.AsyncResult in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method getMqttServer.
@SuppressWarnings("unchecked")
private static MqttServer getMqttServer(final boolean startupShouldFail) {
final MqttServer server = mock(MqttServer.class);
when(server.actualPort()).thenReturn(0, 1883);
when(server.endpointHandler(any(Handler.class))).thenReturn(server);
when(server.listen(any(Handler.class))).then(invocation -> {
Handler<AsyncResult<MqttServer>> handler = (Handler<AsyncResult<MqttServer>>) invocation.getArgument(0);
if (startupShouldFail) {
handler.handle(Future.failedFuture("MQTT server intentionally failed to start"));
} else {
handler.handle(Future.succeededFuture(server));
}
return server;
});
return server;
}
use of io.vertx.core.AsyncResult in project hono by eclipse.
the class HonoClientImpl method getOrCreateRequestResponseClient.
/**
* Gets an existing or creates a new request-response client for a particular service.
*
* @param key The key to look-up the client by.
* @param clientSupplier A consumer for an attempt to create a new client.
* @param resultHandler The handler to inform about the outcome of the operation.
*/
void getOrCreateRequestResponseClient(final String key, final Supplier<Future<RequestResponseClient>> clientSupplier, final Handler<AsyncResult<RequestResponseClient>> resultHandler) {
context.runOnContext(get -> {
final RequestResponseClient client = activeRequestResponseClients.get(key);
if (client != null && client.isOpen()) {
LOG.debug("reusing existing client [target: {}]", key);
resultHandler.handle(Future.succeededFuture(client));
} else if (!creationLocks.computeIfAbsent(key, k -> Boolean.FALSE)) {
// register a handler to be notified if the underlying connection to the server fails
// so that we can fail the result handler passed in
final Handler<Void> connectionFailureHandler = connectionLost -> {
// remove lock so that next attempt to open a sender doesn't fail
creationLocks.remove(key);
resultHandler.handle(Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "no connection to service")));
};
creationRequests.add(connectionFailureHandler);
creationLocks.put(key, Boolean.TRUE);
LOG.debug("creating new client for {}", key);
clientSupplier.get().setHandler(creationAttempt -> {
if (creationAttempt.succeeded()) {
LOG.debug("successfully created new client for {}", key);
activeRequestResponseClients.put(key, creationAttempt.result());
} else {
LOG.debug("failed to create new client for {}", key, creationAttempt.cause());
activeRequestResponseClients.remove(key);
}
creationLocks.remove(key);
creationRequests.remove(connectionFailureHandler);
resultHandler.handle(creationAttempt);
});
} else {
LOG.debug("already trying to create a client for {}", key);
resultHandler.handle(Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "no connection to service")));
}
});
}
use of io.vertx.core.AsyncResult in project hono by eclipse.
the class HonoClientImpl method connect.
private void connect(final ProtonClientOptions options, final Handler<AsyncResult<HonoClient>> connectionHandler, final Handler<ProtonConnection> disconnectHandler) {
context.runOnContext(connect -> {
if (isConnectedInternal()) {
LOG.debug("already connected to server [{}:{}]", connectionFactory.getHost(), connectionFactory.getPort());
connectionHandler.handle(Future.succeededFuture(this));
} else if (connecting.compareAndSet(false, true)) {
if (options == null) {
// by default, try to re-connect forever
clientOptions = new ProtonClientOptions().setConnectTimeout(200).setReconnectAttempts(-1).setReconnectInterval(Constants.DEFAULT_RECONNECT_INTERVAL_MILLIS);
} else {
clientOptions = options;
}
connectionFactory.connect(clientOptions, remoteClose -> onRemoteClose(remoteClose, disconnectHandler), failedConnection -> onRemoteDisconnect(failedConnection, disconnectHandler), conAttempt -> {
connecting.compareAndSet(true, false);
if (conAttempt.failed()) {
if (conAttempt.cause() instanceof SecurityException) {
// SASL handshake has failed
connectionHandler.handle(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_UNAUTHORIZED, "failed to authenticate with server")));
} else {
reconnect(conAttempt.cause(), connectionHandler, disconnectHandler);
}
} else {
// make sure we try to re-connect as often as we tried to connect initially
reconnectAttempts = new AtomicInteger(0);
final ProtonConnection newConnection = conAttempt.result();
if (shuttingDown.get()) {
// if client was shut down in the meantime, we need to immediately
// close again the newly created connection
newConnection.closeHandler(null);
newConnection.disconnectHandler(null);
newConnection.close();
connectionHandler.handle(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_CONFLICT, "client is already shut down")));
} else {
setConnection(newConnection);
connectionHandler.handle(Future.succeededFuture(this));
}
}
});
} else {
LOG.debug("already trying to connect to server ...");
connectionHandler.handle(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_CONFLICT, "already connecting to server")));
}
});
}
Aggregations