Search in sources :

Example 21 with ErrorCondition

use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project vertx-proton by vert-x3.

the class MessageSubscriberWhiteboxVerificationTckTest method createServer.

private TestServer createServer() throws Exception {
    return new TestServer(vertx, (connection) -> {
        connection.openHandler(res -> {
            LOG.trace("Client connected: " + connection.getRemoteContainer());
            connection.open();
        }).closeHandler(c -> {
            LOG.trace("Client closing amqp connection: " + connection.getRemoteContainer());
            connection.close();
            connection.disconnect();
        }).disconnectHandler(c -> {
            LOG.trace("Client socket disconnected: " + connection.getRemoteContainer());
            connection.disconnect();
        }).sessionOpenHandler(session -> session.open());
        connection.receiverOpenHandler(receiver -> {
            if (!server.getDetachLink()) {
                LOG.trace("Receiving from client to: " + receiver.getRemoteTarget().getAddress());
                // This is rather naive, for example use only, proper
                receiver.setTarget(receiver.getRemoteTarget());
                // servers should ensure that they advertise their own
                // Target settings that actually reflect what is in place.
                // The request may have also been for a dynamic address.
                receiver.handler((delivery, msg) -> {
                    String address = msg.getAddress();
                    if (address == null) {
                        address = receiver.getRemoteTarget().getAddress();
                    }
                    Section body = msg.getBody();
                    String content = "unknown";
                    if (body instanceof AmqpValue) {
                        content = (String) ((AmqpValue) body).getValue();
                    }
                    LOG.trace("message to:" + address + ", body: " + content);
                });
                receiver.closeHandler(s -> {
                    s.result().close();
                });
            }
            receiver.open();
            if (server.getDetachLink()) {
                receiver.setCondition(new ErrorCondition(Symbol.getSymbol("Failed Subscriber Requested"), ""));
                receiver.close();
            }
        });
    });
}
Also used : ProtonConnection(io.vertx.proton.ProtonConnection) SubscriberWhiteboxVerification(org.reactivestreams.tck.SubscriberWhiteboxVerification) LoggerFactory(io.vertx.core.impl.logging.LoggerFactory) MockServer(io.vertx.proton.MockServer) ProtonSubscriberImpl(io.vertx.proton.streams.impl.ProtonSubscriberImpl) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AfterMethod(org.testng.annotations.AfterMethod) AtomicReference(java.util.concurrent.atomic.AtomicReference) Symbol(org.apache.qpid.proton.amqp.Symbol) AmqpValue(org.apache.qpid.proton.amqp.messaging.AmqpValue) Message(org.apache.qpid.proton.message.Message) Subscriber(org.reactivestreams.Subscriber) Logger(io.vertx.core.impl.logging.Logger) ProtonSubscriberWrapperImpl(io.vertx.proton.streams.impl.ProtonSubscriberWrapperImpl) BeforeMethod(org.testng.annotations.BeforeMethod) Vertx(io.vertx.core.Vertx) ProtonClient(io.vertx.proton.ProtonClient) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Proton(org.apache.qpid.proton.Proton) CountDownLatch(java.util.concurrent.CountDownLatch) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Section(org.apache.qpid.proton.amqp.messaging.Section) ProtonSubscriber(io.vertx.proton.streams.ProtonSubscriber) TestEnvironment(org.reactivestreams.tck.TestEnvironment) Subscription(org.reactivestreams.Subscription) ProtonConnectionImpl(io.vertx.proton.impl.ProtonConnectionImpl) Handler(io.vertx.core.Handler) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) Section(org.apache.qpid.proton.amqp.messaging.Section) AmqpValue(org.apache.qpid.proton.amqp.messaging.AmqpValue)

Example 22 with ErrorCondition

use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project hono by eclipse.

the class AbstractHonoClient method createReceiver.

/**
 * Creates a receiver link.
 * <p>
 * The receiver will be created with its <em>autoAccept</em> property set to {@code true}.
 *
 * @param ctx The vert.x context to use for establishing the link.
 * @param clientConfig The configuration properties to use.
 * @param con The connection to create the link for.
 * @param sourceAddress The address to receive messages from.
 * @param qos The quality of service to use for the link.
 * @param messageHandler The handler to invoke with every message received.
 * @param closeHook The handler to invoke when the link is closed by the peer (may be {@code null}).
 * @return A future for the created link. The future will be completed once the link is open.
 *         The future will fail with a {@link ServiceInvocationException} if the link cannot be opened.
 * @throws NullPointerException if any of the arguments other than close hook is {@code null}.
 */
protected static final Future<ProtonReceiver> createReceiver(final Context ctx, final ClientConfigProperties clientConfig, final ProtonConnection con, final String sourceAddress, final ProtonQoS qos, final ProtonMessageHandler messageHandler, final Handler<String> closeHook) {
    Objects.requireNonNull(ctx);
    Objects.requireNonNull(clientConfig);
    Objects.requireNonNull(con);
    Objects.requireNonNull(sourceAddress);
    Objects.requireNonNull(qos);
    Objects.requireNonNull(messageHandler);
    final Future<ProtonReceiver> result = Future.future();
    ctx.runOnContext(go -> {
        final ProtonReceiver receiver = con.createReceiver(sourceAddress);
        receiver.attachments().set(KEY_LINK_ESTABLISHED, Boolean.class, Boolean.FALSE);
        receiver.setAutoAccept(true);
        receiver.setQoS(qos);
        receiver.setPrefetch(clientConfig.getInitialCredits());
        receiver.handler((delivery, message) -> {
            messageHandler.handle(delivery, message);
            if (LOG.isTraceEnabled()) {
                int remainingCredits = receiver.getCredit() - receiver.getQueued();
                LOG.trace("handling message [remotely settled: {}, queued messages: {}, remaining credit: {}]", delivery.remotelySettled(), receiver.getQueued(), remainingCredits);
            }
        });
        receiver.openHandler(recvOpen -> {
            if (recvOpen.succeeded()) {
                LOG.debug("receiver open [source: {}]", sourceAddress);
                receiver.attachments().set(KEY_LINK_ESTABLISHED, Boolean.class, Boolean.TRUE);
                result.complete(recvOpen.result());
            } else {
                final ErrorCondition error = receiver.getRemoteCondition();
                if (error == null) {
                    LOG.debug("opening receiver [{}] failed", sourceAddress, recvOpen.cause());
                    result.fail(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot open receiver", recvOpen.cause()));
                } else {
                    LOG.debug("opening receiver [{}] failed: {} - {}", sourceAddress, error.getCondition(), error.getDescription());
                    result.fail(StatusCodeMapper.from(error));
                }
            }
        });
        receiver.detachHandler(remoteDetached -> onRemoteDetach(receiver, con.getRemoteContainer(), false, closeHook));
        receiver.closeHandler(remoteClosed -> onRemoteDetach(receiver, con.getRemoteContainer(), true, closeHook));
        receiver.open();
    });
    return result;
}
Also used : ProtonReceiver(io.vertx.proton.ProtonReceiver) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ClientErrorException(org.eclipse.hono.client.ClientErrorException)

Example 23 with ErrorCondition

use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project hono by eclipse.

the class AbstractHonoClient method onRemoteDetach.

private static void onRemoteDetach(final ProtonReceiver receiver, final String remoteContainer, final boolean closed, final Handler<String> closeHook) {
    final ErrorCondition error = receiver.getRemoteCondition();
    if (error == null) {
        LOG.debug("receiver [{}] detached (with closed={}) by peer [{}]", receiver.getSource().getAddress(), closed, remoteContainer);
    } else {
        LOG.debug("receiver [{}] detached (with closed={}) by peer [{}]: {} - {}", receiver.getSource().getAddress(), closed, remoteContainer, error.getCondition(), error.getDescription());
    }
    receiver.close();
    final boolean linkEstablished = receiver.attachments().get(KEY_LINK_ESTABLISHED, Boolean.class);
    if (linkEstablished && closeHook != null) {
        closeHook.handle(receiver.getSource().getAddress());
    }
}
Also used : ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition)

Example 24 with ErrorCondition

use of org.apache.qpid.proton.amqp.transport.ErrorCondition in project hono by eclipse.

the class AbstractHonoClient method createSender.

/**
 * Creates a sender link.
 *
 * @param ctx The vert.x context to use for establishing the link.
 * @param clientConfig The configuration properties to use.
 * @param con The connection to create the link for.
 * @param targetAddress The target address of the link.
 * @param qos The quality of service to use for the link.
 * @param closeHook The handler to invoke when the link is closed by the peer (may be {@code null}).
 * @return A future for the created link. The future will be completed once the link is open.
 *         The future will fail with a {@link ServiceInvocationException} if the link cannot be opened.
 * @throws NullPointerException if any of the arguments other than close hook is {@code null}.
 */
protected static final Future<ProtonSender> createSender(final Context ctx, final ClientConfigProperties clientConfig, final ProtonConnection con, final String targetAddress, final ProtonQoS qos, final Handler<String> closeHook) {
    Objects.requireNonNull(ctx);
    Objects.requireNonNull(clientConfig);
    Objects.requireNonNull(con);
    Objects.requireNonNull(targetAddress);
    Objects.requireNonNull(qos);
    final Future<ProtonSender> result = Future.future();
    ctx.runOnContext(create -> {
        final ProtonSender sender = con.createSender(targetAddress);
        sender.attachments().set(KEY_LINK_ESTABLISHED, Boolean.class, Boolean.FALSE);
        sender.setQoS(qos);
        sender.setAutoSettle(true);
        sender.openHandler(senderOpen -> {
            if (senderOpen.succeeded()) {
                LOG.debug("sender open [target: {}, sendQueueFull: {}]", targetAddress, sender.sendQueueFull());
                sender.attachments().set(KEY_LINK_ESTABLISHED, Boolean.class, Boolean.TRUE);
                // wait on credits a little time, if not already given
                if (sender.sendQueueFull()) {
                    ctx.owner().setTimer(clientConfig.getFlowLatency(), timerID -> {
                        LOG.debug("sender [target: {}] has {} credits after grace period of {}ms", targetAddress, sender.getCredit(), clientConfig.getFlowLatency());
                        result.complete(sender);
                    });
                } else {
                    result.complete(sender);
                }
            } else {
                final ErrorCondition error = sender.getRemoteCondition();
                if (error == null) {
                    LOG.debug("opening sender [{}] failed", targetAddress, senderOpen.cause());
                    result.fail(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot open sender", senderOpen.cause()));
                } else {
                    LOG.debug("opening sender [{}] failed: {} - {}", targetAddress, error.getCondition(), error.getDescription());
                    result.fail(StatusCodeMapper.from(error));
                }
            }
        });
        sender.detachHandler(remoteDetached -> onRemoteDetach(sender, con.getRemoteContainer(), false, closeHook));
        sender.closeHandler(remoteClosed -> onRemoteDetach(sender, con.getRemoteContainer(), true, closeHook));
        sender.open();
    });
    return result;
}
Also used : ProtonSender(io.vertx.proton.ProtonSender) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ClientErrorException(org.eclipse.hono.client.ClientErrorException)

Example 25 with ErrorCondition

use of org.apache.qpid.proton.amqp.transport.ErrorCondition 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)

Aggregations

ErrorCondition (org.apache.qpid.proton.amqp.transport.ErrorCondition)45 Symbol (org.apache.qpid.proton.amqp.Symbol)13 Test (org.junit.Test)11 Handler (io.vertx.core.Handler)10 ProtonConnection (io.vertx.proton.ProtonConnection)10 DeliveryState (org.apache.qpid.proton.amqp.transport.DeliveryState)10 Message (org.apache.qpid.proton.message.Message)10 Vertx (io.vertx.core.Vertx)8 Logger (io.vertx.core.impl.logging.Logger)8 LoggerFactory (io.vertx.core.impl.logging.LoggerFactory)8 ExecutionException (java.util.concurrent.ExecutionException)8 TimeUnit (java.util.concurrent.TimeUnit)8 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)8 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)8 ProtonClient (io.vertx.proton.ProtonClient)7 Map (java.util.Map)7 CountDownLatch (java.util.concurrent.CountDownLatch)7 MockServer (io.vertx.proton.MockServer)6 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 Proton (org.apache.qpid.proton.Proton)6