use of org.eclipse.hono.client.ServerErrorException in project hono by eclipse.
the class AbstractRequestResponseClientTest method testCreateAndSendRequestFailsWithServerErrorExceptionIfSendQueueFull.
/**
* Verifies that the client fails the handler for sending a request message
* with a {@link ServerErrorException} if the link to the peer has no credit left.
*
* @param ctx The vert.x test context.
*/
@Test
public void testCreateAndSendRequestFailsWithServerErrorExceptionIfSendQueueFull(final TestContext ctx) {
// GIVEN a request-response client with a full send queue
when(sender.sendQueueFull()).thenReturn(Boolean.TRUE);
// WHEN sending a request message
final Async sendFailure = ctx.async();
client.createAndSendRequest("get", null, ctx.asyncAssertFailure(t -> {
ctx.assertTrue(ServerErrorException.class.isInstance(t));
sendFailure.complete();
}));
// THEN the message is not sent and the request result handler is failed
sendFailure.await();
verify(sender, never()).send(any(Message.class));
}
use of org.eclipse.hono.client.ServerErrorException in project hono by eclipse.
the class AbstractRequestResponseClientTest method testCreateAndSendRequestFailsIfReceiverIsNotOpen.
/**
* Verifies that a response handler is immediately failed with a
* {@link ServerErrorException} when the receiver link is not open (yet).
*
* @param ctx The vert.x test context.
*/
@Test
public void testCreateAndSendRequestFailsIfReceiverIsNotOpen(final TestContext ctx) {
// GIVEN a client whose sender and receiver are not open
when(receiver.isOpen()).thenReturn(Boolean.FALSE);
// WHEN sending a request
Async requestFailure = ctx.async();
client.createAndSendRequest("get", null, ctx.asyncAssertFailure(t -> {
ctx.assertTrue(ServerErrorException.class.isInstance(t));
requestFailure.complete();
}));
// THEN the request fails immediately
requestFailure.await();
}
use of org.eclipse.hono.client.ServerErrorException in project hono by eclipse.
the class AbstractRequestResponseClientTest method testCreateAndSendRequestFailsIfSenderIsNotOpen.
/**
* Verifies that a response handler is immediately failed with a
* {@link ServerErrorException} when the sender link is not open (yet).
*
* @param ctx The vert.x test context.
*/
@Test
public void testCreateAndSendRequestFailsIfSenderIsNotOpen(final TestContext ctx) {
// GIVEN a client whose sender and receiver are not open
when(sender.isOpen()).thenReturn(Boolean.FALSE);
// WHEN sending a request
Async requestFailure = ctx.async();
client.createAndSendRequest("get", null, ctx.asyncAssertFailure(t -> {
ctx.assertTrue(ServerErrorException.class.isInstance(t));
requestFailure.complete();
}));
// THEN the request fails immediately
requestFailure.await();
}
use of org.eclipse.hono.client.ServerErrorException in project hono by eclipse.
the class AbstractRequestResponseClient method sendRequest.
/**
* Sends a request message via this client's sender link to the peer.
* <p>
* This method first checks if the sender has any credit left. If not, the result handler is failed immediately.
* Otherwise, the request message is sent and a timer is started which fails the result handler,
* if no response is received within <em>requestTimeoutMillis</em> milliseconds.
*
* @param request The message to send.
* @param resultHandler The handler to notify about the outcome of the request.
* @param cacheKey The key to use for caching the response (if the service allows caching).
*/
private final void sendRequest(final Message request, final Handler<AsyncResult<R>> resultHandler, final Object cacheKey) {
context.runOnContext(req -> {
if (sender.sendQueueFull()) {
LOG.debug("cannot send request to peer, no credit left for link [target: {}]", targetAddress);
resultHandler.handle(Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "no credit available for sending request")));
} else {
final Object correlationId = Optional.ofNullable(request.getCorrelationId()).orElse(request.getMessageId());
final TriTuple<Handler<AsyncResult<R>>, Object, Object> handler = TriTuple.of(resultHandler, cacheKey, null);
replyMap.put(correlationId, handler);
sender.send(request, deliveryUpdated -> {
if (Rejected.class.isInstance(deliveryUpdated.getRemoteState())) {
final Rejected rejected = (Rejected) deliveryUpdated.getRemoteState();
if (rejected.getError() != null) {
LOG.debug("service did not accept request [target address: {}, subject: {}, correlation ID: {}]: {}", targetAddress, request.getSubject(), correlationId, rejected.getError());
cancelRequest(correlationId, Future.failedFuture(StatusCodeMapper.from(rejected.getError())));
} else {
LOG.debug("service did not accept request [target address: {}, subject: {}, correlation ID: {}]", targetAddress, request.getSubject(), correlationId);
cancelRequest(correlationId, Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)));
}
} else if (Accepted.class.isInstance(deliveryUpdated.getRemoteState())) {
LOG.trace("service has accepted request [target address: {}, subject: {}, correlation ID: {}]", targetAddress, request.getSubject(), correlationId);
} else {
LOG.debug("service did not accept request [target address: {}, subject: {}, correlation ID: {}]: {}", targetAddress, request.getSubject(), correlationId, deliveryUpdated.getRemoteState());
cancelRequest(correlationId, Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE)));
}
});
if (requestTimeoutMillis > 0) {
context.owner().setTimer(requestTimeoutMillis, tid -> {
cancelRequest(correlationId, Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "request timed out after " + requestTimeoutMillis + "ms")));
});
}
if (LOG.isDebugEnabled()) {
final String deviceId = MessageHelper.getDeviceId(request);
if (deviceId == null) {
LOG.debug("sent request [target address: {}, subject: {}, correlation ID: {}] to service", targetAddress, request.getSubject(), correlationId);
} else {
LOG.debug("sent request [target address: {}, subject: {}, correlation ID: {}, device ID: {}] to service", targetAddress, request.getSubject(), correlationId, deviceId);
}
}
}
});
}
use of org.eclipse.hono.client.ServerErrorException 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")));
}
});
}
Aggregations