Search in sources :

Example 11 with AnnotatedCacheKey

use of org.eclipse.hono.client.util.AnnotatedCacheKey in project hono by eclipse.

the class ProtonBasedCredentialsClient method get.

@Override
public Future<CredentialsObject> get(final String tenantId, final String type, final String authId, final JsonObject clientContext, final SpanContext spanContext) {
    Objects.requireNonNull(tenantId);
    Objects.requireNonNull(type);
    Objects.requireNonNull(authId);
    Objects.requireNonNull(clientContext);
    final int clientContextHashCode;
    if (clientContext.isEmpty()) {
        clientContextHashCode = clientContext.hashCode();
    } else {
        // "normalize" JSON so that binary valued properties always
        // contain the value's Base64 encoding instead of the raw byte array
        // and thus always result in the same hash code
        clientContextHashCode = new JsonObject(clientContext.encode()).hashCode();
    }
    final AnnotatedCacheKey<CacheKey> responseCacheKey = new AnnotatedCacheKey<>(new CacheKey(tenantId, type, authId, clientContextHashCode));
    final Span span = newChildSpan(spanContext, "get Credentials");
    span.setTag(MessageHelper.APP_PROPERTY_TENANT_ID, tenantId);
    span.setTag(TAG_CREDENTIALS_TYPE, type);
    span.setTag(TAG_AUTH_ID, authId);
    final Future<CredentialsResult<CredentialsObject>> resultTracker = getResponseFromCache(responseCacheKey, span).recover(cacheMiss -> getOrCreateClient(tenantId).compose(client -> {
        final JsonObject specification = CredentialsConstants.getSearchCriteria(type, authId).mergeIn(clientContext);
        if (LOG.isTraceEnabled()) {
            LOG.trace("getting credentials using spec:{}{}", System.lineSeparator(), specification.encodePrettily());
        }
        return client.createAndSendRequest(CredentialsConstants.CredentialsAction.get.toString(), null, specification.toBuffer(), RequestResponseApiConstants.CONTENT_TYPE_APPLICATION_JSON, this::getRequestResponseResult, span);
    }).map(credentialsResult -> {
        addResultToCache(responseCacheKey, credentialsResult);
        return credentialsResult;
    }));
    return mapResultAndFinishSpan(resultTracker, result -> {
        switch(result.getStatus()) {
            case HttpURLConnection.HTTP_OK:
            case HttpURLConnection.HTTP_CREATED:
                return result.getPayload();
            case HttpURLConnection.HTTP_NOT_FOUND:
                throw new ClientErrorException(result.getStatus(), "no such credentials");
            default:
                throw StatusCodeMapper.from(result);
        }
    }, span);
}
Also used : HttpURLConnection(java.net.HttpURLConnection) CacheDirective(org.eclipse.hono.util.CacheDirective) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) Json(io.vertx.core.json.Json) DecodeException(io.vertx.core.json.DecodeException) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) LoggerFactory(org.slf4j.LoggerFactory) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Cache(com.github.benmanes.caffeine.cache.Cache) Constants(org.eclipse.hono.util.Constants) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) CredentialsClient(org.eclipse.hono.client.registry.CredentialsClient) JsonObject(io.vertx.core.json.JsonObject) HonoConnection(org.eclipse.hono.client.HonoConnection) AbstractRequestResponseServiceClient(org.eclipse.hono.client.amqp.AbstractRequestResponseServiceClient) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) CredentialsChangeNotification(org.eclipse.hono.notification.deviceregistry.CredentialsChangeNotification) Logger(org.slf4j.Logger) CredentialsResult(org.eclipse.hono.util.CredentialsResult) RequestResponseClient(org.eclipse.hono.client.amqp.RequestResponseClient) CachingClientFactory(org.eclipse.hono.client.impl.CachingClientFactory) MessageHelper(org.eclipse.hono.util.MessageHelper) RequestResponseApiConstants(org.eclipse.hono.util.RequestResponseApiConstants) Future(io.vertx.core.Future) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) ApplicationProperties(org.apache.qpid.proton.amqp.messaging.ApplicationProperties) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) Buffer(io.vertx.core.buffer.Buffer) Span(io.opentracing.Span) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) CredentialsObject(org.eclipse.hono.util.CredentialsObject) JsonObject(io.vertx.core.json.JsonObject) CredentialsResult(org.eclipse.hono.util.CredentialsResult) ClientErrorException(org.eclipse.hono.client.ClientErrorException) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) Span(io.opentracing.Span) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey)

Example 12 with AnnotatedCacheKey

use of org.eclipse.hono.client.util.AnnotatedCacheKey in project hono by eclipse.

the class ProtonBasedDeviceRegistrationClientTest method testDeviceChangeNotificationRemovesValueFromCache.

/**
 * Verifies that the client removes registrations of a device from the cache if it receives a notification about a
 * change in that device.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testDeviceChangeNotificationRemovesValueFromCache(final VertxTestContext ctx) {
    final String tenantId = "the-tenant-id";
    final String deviceId = "the-device-id";
    givenAClient(cache);
    final var notificationHandlerCaptor = getEventBusConsumerHandlerArgumentCaptor(DeviceChangeNotification.TYPE);
    final Set<AnnotatedCacheKey<?>> expectedCacheRemovals = new HashSet<>();
    // GIVEN a client with a cache containing device registrations of two tenants
    client.start().compose(v -> addResultToCache("other-tenant", deviceId, "gateway-id")).compose(v -> addResultToCache(tenantId, "other-device", "gateway-id")).compose(v -> addResultToCache(tenantId, deviceId, "gateway-id")).map(expectedCacheRemovals::add).compose(v -> addResultToCache(tenantId, deviceId, "other-gateway")).map(expectedCacheRemovals::add).onComplete(ctx.succeeding(ok -> ctx.verify(() -> {
        // WHEN receiving a notification about a change on the device
        sendViaEventBusMock(new DeviceChangeNotification(LifecycleChange.UPDATE, tenantId, deviceId, Instant.now(), false), notificationHandlerCaptor.getValue());
        // THEN the cache is invalidated for registrations of the changed device and not for other devices
        ctx.verify(() -> verify(cache).invalidateAll(expectedCacheRemovals));
        ctx.completeNow();
    })));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Timeout(io.vertx.junit5.Timeout) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Mockito.verifyNoMoreInteractions(org.mockito.Mockito.verifyNoMoreInteractions) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) RegistrationResult(org.eclipse.hono.util.RegistrationResult) NotificationType(org.eclipse.hono.notification.NotificationType) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) ProtonQoS(io.vertx.proton.ProtonQoS) Instant(java.time.Instant) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AbstractNotification(org.eclipse.hono.notification.AbstractNotification) CacheDirective(org.eclipse.hono.util.CacheDirective) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) AmqpClientUnitTestHelper(org.eclipse.hono.client.amqp.test.AmqpClientUnitTestHelper) Cache(com.github.benmanes.caffeine.cache.Cache) Constants(org.eclipse.hono.util.Constants) ConcurrentMap(java.util.concurrent.ConcurrentMap) HashSet(java.util.HashSet) ArgumentCaptor(org.mockito.ArgumentCaptor) Message(org.apache.qpid.proton.message.Message) HonoConnection(org.eclipse.hono.client.HonoConnection) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Tracer(io.opentracing.Tracer) Vertx(io.vertx.core.Vertx) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) ProtonHelper(io.vertx.proton.ProtonHelper) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Mockito.never(org.mockito.Mockito.never) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Example 13 with AnnotatedCacheKey

use of org.eclipse.hono.client.util.AnnotatedCacheKey in project hono by eclipse.

the class ProtonBasedDeviceRegistrationClientTest method testDeviceChangeNotificationRemovesGatewaysFromCache.

/**
 * Verifies that the client removes registrations of a gateway from the cache if it receives a notification about a
 * change in that gateway.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testDeviceChangeNotificationRemovesGatewaysFromCache(final VertxTestContext ctx) {
    final String tenantId = "the-tenant-id";
    final String deviceId = "the-device-id";
    final String gatewayId = "the-device-id";
    givenAClient(cache);
    final var notificationHandlerCaptor = getEventBusConsumerHandlerArgumentCaptor(DeviceChangeNotification.TYPE);
    final Set<AnnotatedCacheKey<?>> expectedCacheRemovals = new HashSet<>();
    // GIVEN a client with a cache containing device registrations of two tenants
    client.start().compose(v -> addResultToCache("other-tenant", deviceId, "gateway-id")).compose(v -> addResultToCache(tenantId, "other-device", "gateway-id")).compose(v -> addResultToCache(tenantId, deviceId, gatewayId)).map(expectedCacheRemovals::add).compose(v -> addResultToCache(tenantId, gatewayId, "other-gateway")).map(expectedCacheRemovals::add).onComplete(ctx.succeeding(ok -> ctx.verify(() -> {
        // WHEN receiving a notification about a change on the gateway device
        sendViaEventBusMock(new DeviceChangeNotification(LifecycleChange.UPDATE, tenantId, gatewayId, Instant.now(), false), notificationHandlerCaptor.getValue());
        // THEN the cache is invalidated for registrations where the device id matches the gateway id or the
        // device id and no other registrations
        ctx.verify(() -> verify(cache).invalidateAll(expectedCacheRemovals));
        ctx.completeNow();
    })));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Timeout(io.vertx.junit5.Timeout) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Mockito.verifyNoMoreInteractions(org.mockito.Mockito.verifyNoMoreInteractions) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) RegistrationResult(org.eclipse.hono.util.RegistrationResult) NotificationType(org.eclipse.hono.notification.NotificationType) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) ProtonQoS(io.vertx.proton.ProtonQoS) Instant(java.time.Instant) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AbstractNotification(org.eclipse.hono.notification.AbstractNotification) CacheDirective(org.eclipse.hono.util.CacheDirective) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) AmqpClientUnitTestHelper(org.eclipse.hono.client.amqp.test.AmqpClientUnitTestHelper) Cache(com.github.benmanes.caffeine.cache.Cache) Constants(org.eclipse.hono.util.Constants) ConcurrentMap(java.util.concurrent.ConcurrentMap) HashSet(java.util.HashSet) ArgumentCaptor(org.mockito.ArgumentCaptor) Message(org.apache.qpid.proton.message.Message) HonoConnection(org.eclipse.hono.client.HonoConnection) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Tracer(io.opentracing.Tracer) Vertx(io.vertx.core.Vertx) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) ProtonHelper(io.vertx.proton.ProtonHelper) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Mockito.never(org.mockito.Mockito.never) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Example 14 with AnnotatedCacheKey

use of org.eclipse.hono.client.util.AnnotatedCacheKey in project hono by eclipse.

the class ProtonBasedDeviceRegistrationClientTest method testAllDevicesOfTenantDeletedNotificationRemovesValueFromCache.

/**
 * Verifies that the client removes all registrations of a tenant from the cache if it receives a notification that
 * tenant all devices of the tenant have been deleted.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testAllDevicesOfTenantDeletedNotificationRemovesValueFromCache(final VertxTestContext ctx) {
    final String tenantId = "the-tenant-id";
    givenAClient(cache);
    final var notificationHandlerCaptor = getEventBusConsumerHandlerArgumentCaptor(AllDevicesOfTenantDeletedNotification.TYPE);
    final Set<AnnotatedCacheKey<?>> expectedCacheRemovals = new HashSet<>();
    // GIVEN a client with a cache containing device registrations of two tenants
    client.start().compose(v -> addResultToCache("other-tenant", "device-id1", "gateway-id")).compose(v -> addResultToCache(tenantId, "device-id1", "gateway-id")).map(expectedCacheRemovals::add).compose(v -> addResultToCache(tenantId, "device-id2", "gateway-id")).map(expectedCacheRemovals::add).onComplete(ctx.succeeding(ok -> ctx.verify(() -> {
        // WHEN receiving a notification that all devices of a tenant have been deleted
        sendViaEventBusMock(new AllDevicesOfTenantDeletedNotification(tenantId, Instant.now()), notificationHandlerCaptor.getValue());
        // THEN the cache is invalidated for all registrations of the tenant
        ctx.verify(() -> verify(cache).invalidateAll(expectedCacheRemovals));
        ctx.completeNow();
    })));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) LifecycleChange(org.eclipse.hono.notification.deviceregistry.LifecycleChange) ArgumentMatchers.argThat(org.mockito.ArgumentMatchers.argThat) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) DeviceChangeNotification(org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification) Timeout(io.vertx.junit5.Timeout) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Mockito.verifyNoMoreInteractions(org.mockito.Mockito.verifyNoMoreInteractions) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) RegistrationResult(org.eclipse.hono.util.RegistrationResult) NotificationType(org.eclipse.hono.notification.NotificationType) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) ProtonQoS(io.vertx.proton.ProtonQoS) Instant(java.time.Instant) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) NotificationEventBusSupport(org.eclipse.hono.notification.NotificationEventBusSupport) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AbstractNotification(org.eclipse.hono.notification.AbstractNotification) CacheDirective(org.eclipse.hono.util.CacheDirective) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) AmqpClientUnitTestHelper(org.eclipse.hono.client.amqp.test.AmqpClientUnitTestHelper) Cache(com.github.benmanes.caffeine.cache.Cache) Constants(org.eclipse.hono.util.Constants) ConcurrentMap(java.util.concurrent.ConcurrentMap) HashSet(java.util.HashSet) ArgumentCaptor(org.mockito.ArgumentCaptor) Message(org.apache.qpid.proton.message.Message) HonoConnection(org.eclipse.hono.client.HonoConnection) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Tracer(io.opentracing.Tracer) Vertx(io.vertx.core.Vertx) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) ProtonHelper(io.vertx.proton.ProtonHelper) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Mockito.never(org.mockito.Mockito.never) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AllDevicesOfTenantDeletedNotification(org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AnnotatedCacheKey(org.eclipse.hono.client.util.AnnotatedCacheKey) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Aggregations

AnnotatedCacheKey (org.eclipse.hono.client.util.AnnotatedCacheKey)14 JsonObject (io.vertx.core.json.JsonObject)12 Span (io.opentracing.Span)10 Cache (com.github.benmanes.caffeine.cache.Cache)8 Future (io.vertx.core.Future)8 HttpURLConnection (java.net.HttpURLConnection)8 HonoConnection (org.eclipse.hono.client.HonoConnection)8 SendMessageSampler (org.eclipse.hono.client.SendMessageSampler)8 NotificationEventBusSupport (org.eclipse.hono.notification.NotificationEventBusSupport)8 AllDevicesOfTenantDeletedNotification (org.eclipse.hono.notification.deviceregistry.AllDevicesOfTenantDeletedNotification)8 DeviceChangeNotification (org.eclipse.hono.notification.deviceregistry.DeviceChangeNotification)7 LifecycleChange (org.eclipse.hono.notification.deviceregistry.LifecycleChange)7 CacheDirective (org.eclipse.hono.util.CacheDirective)7 Constants (org.eclipse.hono.util.Constants)7 MessageHelper (org.eclipse.hono.util.MessageHelper)7 Truth.assertThat (com.google.common.truth.Truth.assertThat)6 Tracer (io.opentracing.Tracer)6 Handler (io.vertx.core.Handler)6 Vertx (io.vertx.core.Vertx)6 EventBus (io.vertx.core.eventbus.EventBus)6