Search in sources :

Example 66 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class RegistrationMessageFilterTest method testVerifyDetectsMissingAction.

/**
 * Verifies that a request that does not contain a subject
 * does not pass the filter.
 */
@Test
public void testVerifyDetectsMissingAction() {
    // GIVEN a registration message lacking a valid subject
    final Message msg = givenAMessageHavingProperties(MY_DEVICE, null);
    // WHEN receiving the message via a link
    final ResourceIdentifier linkTarget = getResourceIdentifier(MY_TENANT);
    // THEN message validation fails
    assertFalse(RegistrationMessageFilter.verify(linkTarget, msg));
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Message(org.apache.qpid.proton.message.Message) Test(org.junit.jupiter.api.Test)

Example 67 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class VertxBasedAmqpProtocolAdapter method doUploadCommandResponseMessage.

private Future<Void> doUploadCommandResponseMessage(final AmqpContext context, final ResourceIdentifier resource, final Span currentSpan) {
    final Future<CommandResponse> responseTracker = Optional.ofNullable(getCommandResponse(context.getMessage())).map(Future::succeededFuture).orElseGet(() -> {
        TracingHelper.logError(currentSpan, String.format("invalid message (correlationId: %s, address: %s, status: %s)", context.getMessage().getCorrelationId(), context.getMessage().getAddress(), MessageHelper.getStatus(context.getMessage())));
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed command response message"));
    });
    final Future<TenantObject> tenantTracker = getTenantConfiguration(resource.getTenantId(), currentSpan.context());
    return CompositeFuture.all(tenantTracker, responseTracker).compose(ok -> {
        final CommandResponse commandResponse = responseTracker.result();
        log.trace("sending command response [device-id: {}, status: {}, correlation-id: {}, reply-to: {}]", resource.getResourceId(), commandResponse.getStatus(), commandResponse.getCorrelationId(), commandResponse.getReplyToId());
        final Map<String, Object> items = new HashMap<>(3);
        items.put(Fields.EVENT, "sending command response");
        items.put(TracingHelper.TAG_CORRELATION_ID.getKey(), commandResponse.getCorrelationId());
        items.put(MessageHelper.APP_PROPERTY_STATUS, commandResponse.getStatus());
        currentSpan.log(items);
        final Future<RegistrationAssertion> tokenFuture = getRegistrationAssertion(resource.getTenantId(), resource.getResourceId(), context.getAuthenticatedDevice(), currentSpan.context());
        final Future<TenantObject> tenantValidationTracker = CompositeFuture.all(isAdapterEnabled(tenantTracker.result()), checkMessageLimit(tenantTracker.result(), context.getPayloadSize(), currentSpan.context())).map(success -> tenantTracker.result());
        return CompositeFuture.all(tenantValidationTracker, tokenFuture).compose(success -> sendCommandResponse(tenantTracker.result(), tokenFuture.result(), commandResponse, currentSpan.context()));
    }).map(delivery -> {
        log.trace("forwarded command response from device [tenant: {}, device-id: {}]", resource.getTenantId(), resource.getResourceId());
        metrics.reportCommand(Direction.RESPONSE, resource.getTenantId(), tenantTracker.result(), ProcessingOutcome.FORWARDED, context.getPayloadSize(), context.getTimer());
        return delivery;
    }).recover(t -> {
        log.debug("cannot process command response from device [tenant: {}, device-id: {}]", resource.getTenantId(), resource.getResourceId(), t);
        metrics.reportCommand(Direction.RESPONSE, resource.getTenantId(), tenantTracker.result(), ProcessingOutcome.from(t), context.getPayloadSize(), context.getTimer());
        return Future.failedFuture(t);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Tags(io.opentracing.tag.Tags) ProtonServer(io.vertx.proton.ProtonServer) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) ProcessingOutcome(org.eclipse.hono.service.metric.MetricsTags.ProcessingOutcome) EndpointType(org.eclipse.hono.service.metric.MetricsTags.EndpointType) Modified(org.apache.qpid.proton.amqp.messaging.Modified) DeviceCredentials(org.eclipse.hono.adapter.auth.device.DeviceCredentials) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) AuthorizationException(org.eclipse.hono.adapter.AuthorizationException) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Fields(io.opentracing.log.Fields) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) TracingHelper(org.eclipse.hono.tracing.TracingHelper) ProtonSaslAuthenticatorFactory(io.vertx.proton.sasl.ProtonSaslAuthenticatorFactory) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) TenantServiceBasedX509Authentication(org.eclipse.hono.adapter.auth.device.TenantServiceBasedX509Authentication) Predicate(java.util.function.Predicate) Collection(java.util.Collection) CommandContext(org.eclipse.hono.client.command.CommandContext) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) Objects(java.util.Objects) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) List(java.util.List) QoS(org.eclipse.hono.service.metric.MetricsTags.QoS) TenantTraceSamplingHelper(org.eclipse.hono.tracing.TenantTraceSamplingHelper) CommandConsumer(org.eclipse.hono.client.command.CommandConsumer) Optional(java.util.Optional) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) ProtonLink(io.vertx.proton.ProtonLink) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) ProtonServerOptions(io.vertx.proton.ProtonServerOptions) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) ConnectionLimitManager(org.eclipse.hono.adapter.limiting.ConnectionLimitManager) Command(org.eclipse.hono.client.command.Command) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) AdapterDisabledException(org.eclipse.hono.adapter.AdapterDisabledException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Commands(org.eclipse.hono.client.command.Commands) Constants(org.eclipse.hono.util.Constants) CompositeFuture(io.vertx.core.CompositeFuture) ProtonSession(io.vertx.proton.ProtonSession) Symbol(org.apache.qpid.proton.amqp.Symbol) AdapterConnectionsExceededException(org.eclipse.hono.adapter.AdapterConnectionsExceededException) Target(org.apache.qpid.proton.amqp.transport.Target) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) Message(org.apache.qpid.proton.message.Message) HttpUtils(org.eclipse.hono.service.http.HttpUtils) AsyncResult(io.vertx.core.AsyncResult) CommandConstants(org.eclipse.hono.util.CommandConstants) TenantChangeNotification(org.eclipse.hono.notification.deviceregistry.TenantChangeNotification) Strings(org.eclipse.hono.util.Strings) UsernamePasswordAuthProvider(org.eclipse.hono.adapter.auth.device.UsernamePasswordAuthProvider) CredentialsApiAuthProvider(org.eclipse.hono.adapter.auth.device.CredentialsApiAuthProvider) AbstractProtocolAdapterBase(org.eclipse.hono.adapter.AbstractProtocolAdapterBase) Direction(org.eclipse.hono.service.metric.MetricsTags.Direction) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) Sample(io.micrometer.core.instrument.Timer.Sample) Released(org.apache.qpid.proton.amqp.messaging.Released) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) Source(org.apache.qpid.proton.amqp.transport.Source) ConnectionAttemptOutcome(org.eclipse.hono.service.metric.MetricsTags.ConnectionAttemptOutcome) MemoryBasedConnectionLimitStrategy(org.eclipse.hono.adapter.limiting.MemoryBasedConnectionLimitStrategy) X509AuthProvider(org.eclipse.hono.adapter.auth.device.X509AuthProvider) Handler(io.vertx.core.Handler) Collections(java.util.Collections) DefaultConnectionLimitManager(org.eclipse.hono.adapter.limiting.DefaultConnectionLimitManager) TenantObject(org.eclipse.hono.util.TenantObject) HashMap(java.util.HashMap) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) ClientErrorException(org.eclipse.hono.client.ClientErrorException) TenantObject(org.eclipse.hono.util.TenantObject) CommandResponse(org.eclipse.hono.client.command.CommandResponse)

Example 68 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class AbstractHonoResource method getPutRequestDeviceAndAuth.

/**
 * Gets a device identity for a CoAP PUT request which contains a tenant and device id in its URI.
 *
 * @param exchange The CoAP exchange with URI and/or peer's principal.
 * @return A future indicating the outcome of the operation.
 *         The future will be succeeded if the device can be determined from the CoAP exchange,
 *         otherwise the future will be failed with a {@link ClientErrorException}.
 */
public Future<RequestDeviceAndAuth> getPutRequestDeviceAndAuth(final CoapExchange exchange) {
    final List<String> pathList = exchange.getRequestOptions().getUriPath();
    if (pathList.isEmpty()) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "missing request URI"));
    } else if (pathList.size() == 1) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "missing tenant and device ID in URI"));
    } else if (pathList.size() == 2) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "missing device ID in URI"));
    }
    try {
        final String[] path = pathList.toArray(new String[pathList.size()]);
        final ResourceIdentifier identifier = ResourceIdentifier.fromPath(path);
        final Device device = new Device(identifier.getTenantId(), identifier.getResourceId());
        final Principal peer = exchange.advanced().getRequest().getSourceContext().getPeerIdentity();
        if (peer == null) {
            // unauthenticated device request
            return Future.succeededFuture(new RequestDeviceAndAuth(device, null, null));
        } else {
            return TracingSupportingHonoResource.getAuthenticatedDevice(exchange).map(authenticatedDevice -> new RequestDeviceAndAuth(device, TracingSupportingHonoResource.getAuthId(exchange), authenticatedDevice));
        }
    } catch (final IllegalArgumentException cause) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "invalid request URI"));
    }
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Device(org.eclipse.hono.auth.Device) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Principal(java.security.Principal)

Example 69 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class VertxBasedAmqpProtocolAdapterTest method testAdapterAcceptsAnonymousRelayReceiverOnly.

/**
 * Verifies that the AMQP Adapter rejects (closes) AMQP links that contains a target address.
 */
@Test
public void testAdapterAcceptsAnonymousRelayReceiverOnly() {
    // GIVEN an AMQP adapter with a configured server.
    givenAnAdapter(properties);
    // WHEN the adapter receives a link that contains a target address
    final ResourceIdentifier targetAddress = ResourceIdentifier.from(TelemetryConstants.TELEMETRY_ENDPOINT, TEST_TENANT_ID, TEST_DEVICE);
    final ProtonReceiver link = getReceiver(ProtonQoS.AT_LEAST_ONCE, getTarget(targetAddress));
    adapter.handleRemoteReceiverOpen(getConnection(null), link);
    // THEN the adapter closes the link.
    verify(link).close();
}
Also used : ProtonReceiver(io.vertx.proton.ProtonReceiver) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Test(org.junit.jupiter.api.Test)

Example 70 with ResourceIdentifier

use of org.eclipse.hono.util.ResourceIdentifier in project hono by eclipse.

the class AbstractProtocolAdapterBaseTest method testValidateAddressUsesDeviceIdentityForAddressWithoutTenantAndDevice.

/**
 * Verifies that the adapter uses an authenticated device's identity when validating an
 * address without a tenant ID and device ID.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testValidateAddressUsesDeviceIdentityForAddressWithoutTenantAndDevice(final VertxTestContext ctx) {
    // WHEN an authenticated device publishes a message to an address that does not contain a tenant ID
    final Device authenticatedDevice = new Device("my-tenant", "4711");
    final ResourceIdentifier address = ResourceIdentifier.fromString(TelemetryConstants.TELEMETRY_ENDPOINT);
    adapter.validateAddress(address, authenticatedDevice).onComplete(ctx.succeeding(r -> ctx.verify(() -> {
        // THEN the validated address contains the authenticated device's tenant and device ID
        assertEquals("my-tenant", r.getTenantId());
        assertEquals("4711", r.getResourceId());
        ctx.completeNow();
    })));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) TenantConstants(org.eclipse.hono.util.TenantConstants) Context(io.vertx.core.Context) TelemetrySender(org.eclipse.hono.client.telemetry.TelemetrySender) MessagingType(org.eclipse.hono.util.MessagingType) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Map(java.util.Map) CredentialsClient(org.eclipse.hono.client.registry.CredentialsClient) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) EventSender(org.eclipse.hono.client.telemetry.EventSender) RegistrationAssertion(org.eclipse.hono.util.RegistrationAssertion) TenantClient(org.eclipse.hono.client.registry.TenantClient) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) Test(org.junit.jupiter.api.Test) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) CommandRouterClient(org.eclipse.hono.client.command.CommandRouterClient) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Optional(java.util.Optional) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ConnectionEventProducer(org.eclipse.hono.adapter.monitoring.ConnectionEventProducer) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) CommandResponseSender(org.eclipse.hono.client.command.CommandResponseSender) Commands(org.eclipse.hono.client.command.Commands) Constants(org.eclipse.hono.util.Constants) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) ArgumentCaptor(org.mockito.ArgumentCaptor) DeviceRegistrationClient(org.eclipse.hono.client.registry.DeviceRegistrationClient) TelemetryExecutionContext(org.eclipse.hono.util.TelemetryExecutionContext) HttpUtils(org.eclipse.hono.service.http.HttpUtils) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) MessagingClient(org.eclipse.hono.util.MessagingClient) ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) MessagingClientProvider(org.eclipse.hono.client.util.MessagingClientProvider) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) CommandResponse(org.eclipse.hono.client.command.CommandResponse) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) CommandConsumerFactory(org.eclipse.hono.client.command.CommandConsumerFactory) Mockito.never(org.mockito.Mockito.never) ResourceLimitChecks(org.eclipse.hono.adapter.resourcelimits.ResourceLimitChecks) HonoEventConnectionEventProducer(org.eclipse.hono.adapter.monitoring.HonoEventConnectionEventProducer) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Device(org.eclipse.hono.auth.Device) Test(org.junit.jupiter.api.Test)

Aggregations

ResourceIdentifier (org.eclipse.hono.util.ResourceIdentifier)82 Message (org.apache.qpid.proton.message.Message)30 Future (io.vertx.core.Future)24 HttpURLConnection (java.net.HttpURLConnection)22 MessageHelper (org.eclipse.hono.util.MessageHelper)22 ClientErrorException (org.eclipse.hono.client.ClientErrorException)20 Test (org.junit.Test)20 Test (org.junit.jupiter.api.Test)19 Handler (io.vertx.core.Handler)18 Map (java.util.Map)18 Span (io.opentracing.Span)17 Buffer (io.vertx.core.buffer.Buffer)17 SpanContext (io.opentracing.SpanContext)16 Constants (org.eclipse.hono.util.Constants)16 Promise (io.vertx.core.Promise)15 Objects (java.util.Objects)14 AsyncResult (io.vertx.core.AsyncResult)13 Vertx (io.vertx.core.Vertx)13 ProtonConnection (io.vertx.proton.ProtonConnection)13 ProtonReceiver (io.vertx.proton.ProtonReceiver)13