Search in sources :

Example 26 with ResourceIdentifier

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

the class AbstractProtocolAdapterBaseTest method testValidateAddressUsesDeviceIdentityForAddressWithoutTenant.

/**
 * Verifies that the adapter uses an authenticated device's identity when validating an
 * address without a tenant ID.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testValidateAddressUsesDeviceIdentityForAddressWithoutTenant(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.from(TelemetryConstants.TELEMETRY_ENDPOINT, "", "4712");
    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("4712", 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)

Example 27 with ResourceIdentifier

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

the class VertxBasedAmqpProtocolAdapter method openCommandSenderLink.

private Future<CommandConsumer> openCommandSenderLink(final ProtonConnection connection, final ProtonSender sender, final ResourceIdentifier address, final Device authenticatedDevice, final Span span, final OptionalInt traceSamplingPriority) {
    return createCommandConsumer(sender, address, authenticatedDevice, span).map(consumer -> {
        final String tenantId = address.getTenantId();
        final String deviceId = address.getResourceId();
        sender.setSource(sender.getRemoteSource());
        sender.setTarget(sender.getRemoteTarget());
        sender.setQoS(ProtonQoS.AT_LEAST_ONCE);
        final Handler<AsyncResult<ProtonSender>> detachHandler = link -> {
            final Span detachHandlerSpan = newSpan("detach device command receiver link", authenticatedDevice, traceSamplingPriority);
            removeCommandSubscription(connection, address.toString());
            onLinkDetach(sender);
            closeCommandConsumer(consumer, address, authenticatedDevice, true, detachHandlerSpan).onComplete(v -> detachHandlerSpan.finish());
        };
        HonoProtonHelper.setCloseHandler(sender, detachHandler);
        HonoProtonHelper.setDetachHandler(sender, detachHandler);
        sender.open();
        // At this point, the remote peer's receiver link is successfully opened and is ready to receive
        // commands. Send "device ready for command" notification downstream.
        log.debug("established link [address: {}] for sending commands to device", address);
        sendConnectedTtdEvent(tenantId, deviceId, authenticatedDevice, span.context());
        registerCommandSubscription(connection, new CommandSubscription(consumer, address));
        return consumer;
    }).recover(t -> Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "cannot create command consumer")));
}
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) ProtonSender(io.vertx.proton.ProtonSender) Handler(io.vertx.core.Handler) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Span(io.opentracing.Span)

Example 28 with ResourceIdentifier

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

the class AbstractRequestResponseEndpointTest method getEndpoint.

private AbstractRequestResponseEndpoint<ServiceConfigProperties> getEndpoint() {
    final AbstractRequestResponseEndpoint<ServiceConfigProperties> endpoint = new AbstractRequestResponseEndpoint<>(vertx) {

        @Override
        public String getName() {
            return "test";
        }

        @Override
        protected boolean passesFormalVerification(final ResourceIdentifier targetAddress, final Message message) {
            return formalMessageVerification.apply(targetAddress, message);
        }

        @Override
        protected Future<Message> handleRequestMessage(final Message requestMessage, final ResourceIdentifier targetAddress, final SpanContext spanContext) {
            return requestMessageHandler.apply(requestMessage, targetAddress);
        }
    };
    endpoint.setConfiguration(new ServiceConfigProperties());
    endpoint.setAuthorizationService(authService);
    return endpoint;
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) SpanContext(io.opentracing.SpanContext) Message(org.apache.qpid.proton.message.Message) ServiceConfigProperties(org.eclipse.hono.config.ServiceConfigProperties)

Example 29 with ResourceIdentifier

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

the class SimpleAuthenticationServer method handleSenderOpen.

/**
 * Handles a request from a client to establish a link for receiving messages from this server.
 *
 * @param con the connection to the client.
 * @param sender the sender created for the link.
 */
@Override
protected void handleSenderOpen(final ProtonConnection con, final ProtonSender sender) {
    final Source remoteSource = sender.getRemoteSource();
    LOG.debug("client [{}] wants to open a link for receiving messages [address: {}]", con.getRemoteContainer(), remoteSource);
    if (!ResourceIdentifier.isValid(remoteSource.getAddress())) {
        handleUnknownEndpoint(con, sender, remoteSource.getAddress());
        return;
    }
    final ResourceIdentifier targetResource = ResourceIdentifier.fromString(remoteSource.getAddress());
    final AmqpEndpoint endpoint = getEndpoint(targetResource);
    if (endpoint == null) {
        handleUnknownEndpoint(con, sender, targetResource.toString());
    } else {
        final HonoUser user = Constants.getClientPrincipal(con);
        if (Constants.SUBJECT_ANONYMOUS.equals(user.getName())) {
            con.setCondition(ProtonHelper.condition(AmqpError.UNAUTHORIZED_ACCESS, "client must authenticate using SASL")).close();
        } else {
            sender.setSource(sender.getRemoteSource());
            endpoint.onLinkAttach(con, sender, targetResource);
        }
    }
}
Also used : ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) HonoUser(org.eclipse.hono.auth.HonoUser) AmqpEndpoint(org.eclipse.hono.service.amqp.AmqpEndpoint) Source(org.apache.qpid.proton.amqp.transport.Source)

Example 30 with ResourceIdentifier

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

the class AmqpServiceBaseTest method testHandleReceiverOpenRejectsUnauthorizedClient.

/**
 * Verifies that the service rejects sender links on resources that
 * the client is not authorized to write to.
 */
@Test
public void testHandleReceiverOpenRejectsUnauthorizedClient() {
    // GIVEN a server with a endpoint
    final ResourceIdentifier restrictedTargetAddress = ResourceIdentifier.from(ENDPOINT, "RESTRICTED_TENANT", null);
    final AmqpEndpoint endpoint = mock(AmqpEndpoint.class);
    when(endpoint.getName()).thenReturn(ENDPOINT);
    final AuthorizationService authService = mock(AuthorizationService.class);
    when(authService.isAuthorized(Constants.PRINCIPAL_ANONYMOUS, restrictedTargetAddress, Activity.WRITE)).thenReturn(Future.succeededFuture(Boolean.FALSE));
    final AmqpServiceBase<ServiceConfigProperties> server = createServer(endpoint);
    server.setAuthorizationService(authService);
    // WHEN a client connects to the server using a address for a tenant it is not authorized to write to
    final Target target = getTarget(restrictedTargetAddress);
    final ProtonReceiver receiver = mock(ProtonReceiver.class);
    when(receiver.getRemoteTarget()).thenReturn(target);
    when(receiver.setCondition(any())).thenReturn(receiver);
    server.handleReceiverOpen(newConnection(Constants.PRINCIPAL_ANONYMOUS), receiver);
    // THEN the server closes the link with the client
    verify(receiver).close();
}
Also used : ProtonReceiver(io.vertx.proton.ProtonReceiver) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Target(org.apache.qpid.proton.amqp.transport.Target) AuthorizationService(org.eclipse.hono.service.auth.AuthorizationService) ServiceConfigProperties(org.eclipse.hono.config.ServiceConfigProperties) 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