Search in sources :

Example 31 with ProtonDelivery

use of io.vertx.proton.ProtonDelivery in project hono by eclipse.

the class ForwardingTelemetryDownstreamAdapterTest method testProcessMessageDiscardsMessageIfNoCreditIsAvailable.

/**
 * Verifies that telemetry data is discarded if no downstream credit is available.
 *
 * @param ctx The test context.
 */
@SuppressWarnings("unchecked")
@Test
public void testProcessMessageDiscardsMessageIfNoCreditIsAvailable(final TestContext ctx) {
    final UpstreamReceiver client = TestSupport.newClient();
    final ProtonDelivery upstreamDelivery = mock(ProtonDelivery.class);
    when(upstreamDelivery.remotelySettled()).thenReturn(Boolean.FALSE);
    // GIVEN an adapter with a connection to a downstream container
    ProtonSender sender = TestSupport.newMockSender(false);
    when(sender.sendQueueFull()).thenReturn(true);
    final ForwardingEventDownstreamAdapter adapter = new ForwardingEventDownstreamAdapter(vertx, newMockSenderFactory(sender));
    adapter.setMetrics(mock(MessagingMetrics.class));
    adapter.setDownstreamConnectionFactory(TestSupport.newMockConnectionFactory(false));
    adapter.start(Future.future());
    adapter.addSender(client, sender);
    // WHEN processing an event
    final Message msg = ProtonHelper.message(TELEMETRY_MSG_CONTENT);
    MessageHelper.addDeviceId(msg, DEVICE_ID);
    adapter.processMessage(client, upstreamDelivery, msg);
    // THEN the the message is accepted
    verify(upstreamDelivery).disposition(any(Released.class), eq(Boolean.TRUE));
    // but is not delivered to the downstream container
    verify(sender, never()).send(any(Message.class), any(Handler.class));
}
Also used : ProtonSender(io.vertx.proton.ProtonSender) Released(org.apache.qpid.proton.amqp.messaging.Released) ProtonDelivery(io.vertx.proton.ProtonDelivery) Message(org.apache.qpid.proton.message.Message) ForwardingEventDownstreamAdapter(org.eclipse.hono.event.impl.ForwardingEventDownstreamAdapter) Handler(io.vertx.core.Handler) UpstreamReceiver(org.eclipse.hono.messaging.UpstreamReceiver) MessagingMetrics(org.eclipse.hono.messaging.MessagingMetrics) Test(org.junit.Test)

Example 32 with ProtonDelivery

use of io.vertx.proton.ProtonDelivery in project hono by eclipse.

the class RegistrationClientImplTest method testAssertRegistrationInvokesServiceIfNoCacheConfigured.

/**
 * Verifies that the client retrieves registration information from the
 * Device Registration service if no cache is configured.
 *
 * @param ctx The vert.x test context.
 */
@SuppressWarnings("unchecked")
@Test
public void testAssertRegistrationInvokesServiceIfNoCacheConfigured(final TestContext ctx) {
    // GIVEN an adapter with no cache configured
    final JsonObject registrationAssertion = newRegistrationAssertionResult();
    final Message response = ProtonHelper.message(registrationAssertion.encode());
    MessageHelper.addProperty(response, MessageHelper.APP_PROPERTY_STATUS, HttpURLConnection.HTTP_OK);
    // WHEN getting registration information
    final Async assertion = ctx.async();
    client.assertRegistration("device").setHandler(ctx.asyncAssertSuccess(result -> assertion.complete()));
    final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
    verify(sender).send(messageCaptor.capture(), any(Handler.class));
    response.setCorrelationId(messageCaptor.getValue().getMessageId());
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    client.handleResponse(delivery, response);
    // THEN the registration information has been retrieved from the service
    assertion.await();
    // and not been put to the cache
    verify(cache, never()).put(any(), any(RegistrationResult.class), any(Duration.class));
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) HttpURLConnection(java.net.HttpURLConnection) CacheDirective(org.eclipse.hono.util.CacheDirective) TestContext(io.vertx.ext.unit.TestContext) ProtonReceiver(io.vertx.proton.ProtonReceiver) Async(io.vertx.ext.unit.Async) ProtonDelivery(io.vertx.proton.ProtonDelivery) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) RunWith(org.junit.runner.RunWith) ExpiringValueCache(org.eclipse.hono.cache.ExpiringValueCache) Context(io.vertx.core.Context) Assert.assertThat(org.junit.Assert.assertThat) ArgumentCaptor(org.mockito.ArgumentCaptor) Duration(java.time.Duration) RegistrationResult(org.eclipse.hono.util.RegistrationResult) Timeout(org.junit.rules.Timeout) SignatureAlgorithm(io.jsonwebtoken.SignatureAlgorithm) Message(org.apache.qpid.proton.message.Message) JsonObject(io.vertx.core.json.JsonObject) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Before(org.junit.Before) TriTuple(org.eclipse.hono.util.TriTuple) Vertx(io.vertx.core.Vertx) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) Test(org.junit.Test) ProtonHelper(io.vertx.proton.ProtonHelper) VertxUnitRunner(io.vertx.ext.unit.junit.VertxUnitRunner) Instant(java.time.Instant) MessageHelper(org.eclipse.hono.util.MessageHelper) Date(java.sql.Date) Mockito(org.mockito.Mockito) Rule(org.junit.Rule) Jwts(io.jsonwebtoken.Jwts) ProtonSender(io.vertx.proton.ProtonSender) Handler(io.vertx.core.Handler) Message(org.apache.qpid.proton.message.Message) ProtonDelivery(io.vertx.proton.ProtonDelivery) Async(io.vertx.ext.unit.Async) JsonObject(io.vertx.core.json.JsonObject) Handler(io.vertx.core.Handler) Duration(java.time.Duration) RegistrationResult(org.eclipse.hono.util.RegistrationResult) Test(org.junit.Test)

Example 33 with ProtonDelivery

use of io.vertx.proton.ProtonDelivery in project hono by eclipse.

the class TelemetrySenderImplTest method testSendMessageFailsOnLackOfCredit.

/**
 * Verifies that the sender fails if no credit is available.
 *
 * @param ctx The vert.x test context.
 */
@SuppressWarnings("unchecked")
@Test
public void testSendMessageFailsOnLackOfCredit(final TestContext ctx) {
    // GIVEN a sender that has no credit
    when(sender.sendQueueFull()).thenReturn(Boolean.TRUE);
    MessageSender messageSender = new TelemetrySenderImpl(config, sender, "tenant", "telemetry/tenant", context);
    // WHEN trying to send a message
    final Future<ProtonDelivery> result = messageSender.send("device", "some payload", "application/text", "token");
    // THEN the message is not sent
    assertFalse(result.succeeded());
    verify(sender, never()).send(any(Message.class), any(Handler.class));
}
Also used : ProtonDelivery(io.vertx.proton.ProtonDelivery) Message(org.apache.qpid.proton.message.Message) MessageSender(org.eclipse.hono.client.MessageSender) Handler(io.vertx.core.Handler) Test(org.junit.Test)

Example 34 with ProtonDelivery

use of io.vertx.proton.ProtonDelivery in project hono by eclipse.

the class TenantClientImplTest method testGetTenantAddsInfoToCacheOnCacheMiss.

/**
 * Verifies that on a cache miss the adapter retrieves tenant information
 * from the Tenant service and puts it to the cache.
 *
 * @param ctx The vert.x test context.
 */
@SuppressWarnings("unchecked")
@Test
public void testGetTenantAddsInfoToCacheOnCacheMiss(final TestContext ctx) {
    // GIVEN an adapter with an empty cache
    client.setResponseCache(cache);
    final JsonObject tenantResult = newTenantResult("tenant");
    // WHEN getting tenant information
    final Async get = ctx.async();
    client.get("tenant").setHandler(ctx.asyncAssertSuccess(tenant -> get.complete()));
    final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
    verify(sender).send(messageCaptor.capture(), any(Handler.class));
    final Message response = ProtonHelper.message(tenantResult.encode());
    MessageHelper.addProperty(response, MessageHelper.APP_PROPERTY_STATUS, HttpURLConnection.HTTP_OK);
    MessageHelper.addCacheDirective(response, CacheDirective.maxAgeDirective(60));
    response.setCorrelationId(messageCaptor.getValue().getMessageId());
    final ProtonDelivery delivery = mock(ProtonDelivery.class);
    client.handleResponse(delivery, response);
    // THEN the tenant result has been added to the cache
    get.await();
    verify(cache).put(eq(TriTuple.of(TenantAction.get, "tenant", null)), any(TenantResult.class), any(Duration.class));
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) HttpURLConnection(java.net.HttpURLConnection) CacheDirective(org.eclipse.hono.util.CacheDirective) TestContext(io.vertx.ext.unit.TestContext) ProtonReceiver(io.vertx.proton.ProtonReceiver) Async(io.vertx.ext.unit.Async) ProtonDelivery(io.vertx.proton.ProtonDelivery) TenantConstants(org.eclipse.hono.util.TenantConstants) RunWith(org.junit.runner.RunWith) CoreMatchers.startsWith(org.hamcrest.CoreMatchers.startsWith) ExpiringValueCache(org.eclipse.hono.cache.ExpiringValueCache) Context(io.vertx.core.Context) Assert.assertThat(org.junit.Assert.assertThat) ArgumentCaptor(org.mockito.ArgumentCaptor) TenantAction(org.eclipse.hono.util.TenantConstants.TenantAction) Duration(java.time.Duration) Timeout(org.junit.rules.Timeout) Message(org.apache.qpid.proton.message.Message) JsonObject(io.vertx.core.json.JsonObject) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Before(org.junit.Before) TenantResult(org.eclipse.hono.util.TenantResult) TriTuple(org.eclipse.hono.util.TriTuple) Vertx(io.vertx.core.Vertx) Test(org.junit.Test) ProtonHelper(io.vertx.proton.ProtonHelper) VertxUnitRunner(io.vertx.ext.unit.junit.VertxUnitRunner) MessageHelper(org.eclipse.hono.util.MessageHelper) TenantObject(org.eclipse.hono.util.TenantObject) Mockito(org.mockito.Mockito) Rule(org.junit.Rule) ProtonSender(io.vertx.proton.ProtonSender) Handler(io.vertx.core.Handler) Message(org.apache.qpid.proton.message.Message) ProtonDelivery(io.vertx.proton.ProtonDelivery) Async(io.vertx.ext.unit.Async) JsonObject(io.vertx.core.json.JsonObject) Handler(io.vertx.core.Handler) Duration(java.time.Duration) TenantResult(org.eclipse.hono.util.TenantResult) Test(org.junit.Test)

Example 35 with ProtonDelivery

use of io.vertx.proton.ProtonDelivery 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)

Aggregations

ProtonDelivery (io.vertx.proton.ProtonDelivery)38 Test (org.junit.Test)31 Message (org.apache.qpid.proton.message.Message)29 Handler (io.vertx.core.Handler)21 ProtonSender (io.vertx.proton.ProtonSender)15 Rejected (org.apache.qpid.proton.amqp.messaging.Rejected)15 ProtonReceiver (io.vertx.proton.ProtonReceiver)13 Async (io.vertx.ext.unit.Async)12 Vertx (io.vertx.core.Vertx)11 ProtonHelper (io.vertx.proton.ProtonHelper)11 JsonObject (io.vertx.core.json.JsonObject)10 TestContext (io.vertx.ext.unit.TestContext)10 VertxUnitRunner (io.vertx.ext.unit.junit.VertxUnitRunner)10 Before (org.junit.Before)10 Rule (org.junit.Rule)10 RunWith (org.junit.runner.RunWith)10 ArgumentCaptor (org.mockito.ArgumentCaptor)10 Mockito (org.mockito.Mockito)10 Context (io.vertx.core.Context)9 HttpURLConnection (java.net.HttpURLConnection)9