Search in sources :

Example 36 with ProtonConnection

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);
}
Also used : ProtonConnection(io.vertx.proton.ProtonConnection) Test(org.junit.Test)

Example 37 with ProtonConnection

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());
}
Also used : ProtonSender(io.vertx.proton.ProtonSender) ProtonConnection(io.vertx.proton.ProtonConnection) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) ProtonSession(io.vertx.proton.ProtonSession) Async(io.vertx.ext.unit.Async) Handler(io.vertx.core.Handler)

Example 38 with ProtonConnection

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();
}
Also used : ProtonReceiver(io.vertx.proton.ProtonReceiver) ProtonConnection(io.vertx.proton.ProtonConnection) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Test(org.junit.Test)

Example 39 with ProtonConnection

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;
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) AmqpErrorException(org.eclipse.hono.util.AmqpErrorException) ProtonDelivery(io.vertx.proton.ProtonDelivery) DecodeException(io.vertx.core.json.DecodeException) Autowired(org.springframework.beans.factory.annotation.Autowired) EventBusMessage(org.eclipse.hono.util.EventBusMessage) HonoUser(org.eclipse.hono.auth.HonoUser) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) ServiceConfigProperties(org.eclipse.hono.config.ServiceConfigProperties) Constants(org.eclipse.hono.util.Constants) Message(org.apache.qpid.proton.message.Message) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) JsonObject(io.vertx.core.json.JsonObject) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) Vertx(io.vertx.core.Vertx) ProtonHelper(io.vertx.proton.ProtonHelper) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) Objects(java.util.Objects) Optional(java.util.Optional) ProtonSender(io.vertx.proton.ProtonSender) ClaimsBasedAuthorizationService(org.eclipse.hono.service.auth.ClaimsBasedAuthorizationService) MessageConsumer(io.vertx.core.eventbus.MessageConsumer) AuthorizationService(org.eclipse.hono.service.auth.AuthorizationService) HonoUser(org.eclipse.hono.auth.HonoUser) AmqpErrorException(org.eclipse.hono.util.AmqpErrorException) DecodeException(io.vertx.core.json.DecodeException)

Example 40 with ProtonConnection

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);
}
Also used : ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) HonoUserAdapter(org.eclipse.hono.auth.HonoUserAdapter) Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) Vertx(io.vertx.core.Vertx) Autowired(org.springframework.beans.factory.annotation.Autowired) HonoUser(org.eclipse.hono.auth.HonoUser) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) AuthenticationConstants(org.eclipse.hono.service.auth.AuthenticationConstants) Objects(java.util.Objects) ConnectionFactory(org.eclipse.hono.connection.ConnectionFactory) Section(org.apache.qpid.proton.amqp.messaging.Section) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) AmqpValue(org.apache.qpid.proton.amqp.messaging.AmqpValue) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) Qualifier(org.springframework.beans.factory.annotation.Qualifier) AsyncResult(io.vertx.core.AsyncResult) Handler(io.vertx.core.Handler) HonoUser(org.eclipse.hono.auth.HonoUser) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) HonoUserAdapter(org.eclipse.hono.auth.HonoUserAdapter) Section(org.apache.qpid.proton.amqp.messaging.Section) AmqpValue(org.apache.qpid.proton.amqp.messaging.AmqpValue)

Aggregations

ProtonConnection (io.vertx.proton.ProtonConnection)63 ProtonClient (io.vertx.proton.ProtonClient)37 Message (org.apache.qpid.proton.message.Message)36 Handler (io.vertx.core.Handler)35 Test (org.junit.Test)33 Async (io.vertx.ext.unit.Async)27 ProtonServer (io.vertx.proton.ProtonServer)25 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)25 AmqpValue (org.apache.qpid.proton.amqp.messaging.AmqpValue)25 AsyncResult (io.vertx.core.AsyncResult)24 TestContext (io.vertx.ext.unit.TestContext)24 VertxUnitRunner (io.vertx.ext.unit.junit.VertxUnitRunner)24 RunWith (org.junit.runner.RunWith)24 Section (org.apache.qpid.proton.amqp.messaging.Section)23 ProtonHelper.message (io.vertx.proton.ProtonHelper.message)21 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)21 ProtonStreams (io.vertx.proton.streams.ProtonStreams)20 Vertx (io.vertx.core.Vertx)19 Symbol (org.apache.qpid.proton.amqp.Symbol)19 Accepted (org.apache.qpid.proton.amqp.messaging.Accepted)19