use of io.vertx.proton.ProtonConnection in project hono by eclipse.
the class HonoMessagingTest method testServerPublishesConnectionIdOnClientDisconnect.
/**
* Verifies that Hono Messaging notifies downstream components
* about an upstream connection being closed.
*/
@Test
public void testServerPublishesConnectionIdOnClientDisconnect() {
// GIVEN a Hono server
HonoMessaging server = createServer(null);
// WHEN the server's publish close event method is called
final ProtonConnection con = newConnection(Constants.PRINCIPAL_ANONYMOUS);
server.publishConnectionClosedEvent(con);
// THEN an appropriate closed event is published on the event bus
verify(eventBus).publish(Constants.EVENT_BUS_ADDRESS_CONNECTION_CLOSED, CON_ID);
}
use of io.vertx.proton.ProtonConnection in project hono by eclipse.
the class SenderFactoryImplTest method testNewSenderIsClosedOnRemoteDetachOrClose.
@SuppressWarnings({ "unchecked", "rawtypes" })
private void testNewSenderIsClosedOnRemoteDetachOrClose(final TestContext ctx, final BiConsumer<ProtonSender, ArgumentCaptor<Handler>> handlerCaptor) {
// GIVEN a sender created by the factory
final Async senderCreation = ctx.async();
final ProtonSender sender = mock(ProtonSender.class);
when(sender.open()).then(answer -> {
senderCreation.complete();
return sender;
});
final ProtonConnection con = mock(ProtonConnection.class);
final ProtonSession session = mock(ProtonSession.class);
when(session.createSender(anyString())).thenReturn(sender);
final ResourceIdentifier address = ResourceIdentifier.from(TelemetryConstants.TELEMETRY_ENDPOINT, Constants.DEFAULT_TENANT, null);
final Handler<String> closeHook = mock(Handler.class);
final SenderFactoryImpl factory = new SenderFactoryImpl();
final ArgumentCaptor<Handler> captor = ArgumentCaptor.forClass(Handler.class);
factory.newSender(con, session, address, ProtonQoS.AT_LEAST_ONCE, drain -> {
}, closeHook);
handlerCaptor.accept(sender, captor);
// WHEN the peer detaches from the sender
captor.getValue().handle(Future.succeededFuture(sender));
// THEN the sender gets closed
verify(sender).close();
// and the close hook is called
verify(closeHook).handle(any());
}
use of io.vertx.proton.ProtonConnection in project hono by eclipse.
the class EventEndpointTest method testOnLinkAttachDisconnectsClientsUsingWrongQos.
/**
* Verifies that the endpoint rejects a client's attempt to create a link using <em>AT_MOST_ONCE</em>
* delivery mode.
*/
@Test
public void testOnLinkAttachDisconnectsClientsUsingWrongQos() {
ProtonConnection con = mock(ProtonConnection.class);
ProtonReceiver receiver = mock(ProtonReceiver.class);
when(receiver.getRemoteQoS()).thenReturn(ProtonQoS.AT_MOST_ONCE);
ResourceIdentifier targetAddress = ResourceIdentifier.from("event", "tenant", null);
endpoint.onLinkAttach(con, receiver, targetAddress);
ArgumentCaptor<ErrorCondition> errorCondition = ArgumentCaptor.forClass(ErrorCondition.class);
verify(receiver).setCondition(errorCondition.capture());
assertThat(errorCondition.getValue(), is(ErrorConditions.ERROR_UNSUPPORTED_DELIVERY_MODE));
verify(receiver).close();
}
use of io.vertx.proton.ProtonConnection in project hono by eclipse.
the class RequestResponseEndpoint method handleMessage.
/**
* Handles a request message received from a client.
* <p>
* The message gets rejected if
* <ul>
* <li>the message does not pass {@linkplain #passesFormalVerification(ResourceIdentifier, Message) formal verification}
* or</li>
* <li>the client is not {@linkplain #isAuthorized(HonoUser, ResourceIdentifier, Message) authorized to execute the operation}
* indicated by the message's <em>subject</em> or</li>
* <li>its payload cannot be parsed</li>
* </ul>
*
* @param con The connection with the client.
* @param receiver The link over which the message has been received.
* @param targetAddress The address the message is sent to.
* @param delivery The message's delivery status.
* @param message The message.
*/
protected final void handleMessage(final ProtonConnection con, final ProtonReceiver receiver, final ResourceIdentifier targetAddress, ProtonDelivery delivery, Message message) {
final Future<Void> formalCheck = Future.future();
if (passesFormalVerification(targetAddress, message)) {
formalCheck.complete();
} else {
formalCheck.fail(new AmqpErrorException(AmqpError.DECODE_ERROR, "malformed payload"));
}
final HonoUser clientPrincipal = Constants.getClientPrincipal(con);
formalCheck.compose(ok -> isAuthorized(clientPrincipal, targetAddress, message)).compose(authorized -> {
logger.debug("client [{}] is {}authorized to {}:{}", clientPrincipal.getName(), authorized ? "" : "not ", targetAddress, message.getSubject());
if (authorized) {
try {
processRequest(message, targetAddress, clientPrincipal);
ProtonHelper.accepted(delivery, true);
return Future.succeededFuture();
} catch (DecodeException e) {
return Future.failedFuture(new AmqpErrorException(AmqpError.DECODE_ERROR, "malformed payload"));
}
} else {
return Future.failedFuture(new AmqpErrorException(AmqpError.UNAUTHORIZED_ACCESS, "unauthorized"));
}
}).otherwise(t -> {
if (t instanceof AmqpErrorException) {
AmqpErrorException cause = (AmqpErrorException) t;
MessageHelper.rejected(delivery, cause.asErrorCondition());
} else {
logger.debug("error processing request [resource: {}, op: {}]: {}", targetAddress, message.getSubject(), t.getMessage());
MessageHelper.rejected(delivery, ProtonHelper.condition(AmqpError.INTERNAL_ERROR, "internal error"));
}
return null;
});
}
use of io.vertx.proton.ProtonConnection in project hono by eclipse.
the class AuthenticationServerClient method getToken.
private void getToken(final ProtonConnection openCon, final Future<HonoUser> authResult) {
final ProtonMessageHandler messageHandler = (delivery, message) -> {
String type = MessageHelper.getApplicationProperty(message.getApplicationProperties(), AuthenticationConstants.APPLICATION_PROPERTY_TYPE, String.class);
if (AuthenticationConstants.TYPE_AMQP_JWT.equals(type)) {
Section body = message.getBody();
if (body instanceof AmqpValue) {
final String token = ((AmqpValue) body).getValue().toString();
HonoUser user = new HonoUserAdapter() {
@Override
public String getToken() {
return token;
}
};
LOG.debug("successfully retrieved token from Authentication service");
authResult.complete(user);
} else {
authResult.fail("message from Authentication service contains no body");
}
} else {
authResult.fail("Authentication service issued unsupported token [type: " + type + "]");
}
};
openReceiver(openCon, messageHandler).compose(openReceiver -> {
LOG.debug("opened receiver link to Authentication service, waiting for token ...");
}, authResult);
}
Aggregations