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);
}
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();
})));
}
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();
})));
}
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();
})));
}
Aggregations