CacheBasedDeviceConnectionInfo implements DeviceConnectionInfo, HealthCheckProvider { @Override public Future<JsonObject> getLastKnownGatewayForDevice(final String tenantId, final String deviceId, final Span span) { Objects.requireNonNull(tenantId); Objects.requireNonNull(deviceId); Objects.requireNonNull(span); return cache.get(getGatewayEntryKey(tenantId, deviceId)) .recover(t -> { LOG.debug("failed to find last known gateway for device [tenant: {}, device-id: {}]", tenantId, deviceId, t); return Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR, t)); }) .compose(gatewayId -> { if (gatewayId == null) { LOG.debug("could not find last known gateway for device [tenant: {}, device-id: {}]", tenantId, deviceId); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND)); } else { LOG.debug("found last known gateway for device [tenant: {}, device-id: {}]: {}", tenantId, deviceId, gatewayId); return Future.succeededFuture(getLastKnownGatewayResultJson(gatewayId)); } }); } CacheBasedDeviceConnectionInfo(final Cache<String, String> cache, final Tracer tracer); @Override Future<Void> setLastKnownGatewayForDevice(final String tenantId, final String deviceId,
            final String gatewayId, final Span span); @Override Future<JsonObject> getLastKnownGatewayForDevice(final String tenantId, final String deviceId, final Span span); @Override Future<Void> setCommandHandlingAdapterInstance(final String tenantId, final String deviceId,
            final String adapterInstanceId, final Duration lifespan, final Span span); @Override Future<Boolean> removeCommandHandlingAdapterInstance(final String tenantId, final String deviceId,
            final String adapterInstanceId, final Span span); @Override Future<JsonObject> getCommandHandlingAdapterInstances(final String tenantId, final String deviceId,
            final Set<String> viaGateways, final Span span); @Override void registerReadinessChecks(final HealthCheckHandler readinessHandler); @Override void registerLivenessChecks(final HealthCheckHandler livenessHandler);  }
@Test void testGetLastKnownGatewaySucceeds(final VertxTestContext ctx) { final Cache<String, String> mockedCache = mockCache(); info = new CacheBasedDeviceConnectionInfo(mockedCache, tracer); when(mockedCache.get(anyString())).thenReturn(Future.succeededFuture("gw-id")); info.getLastKnownGatewayForDevice(Constants.DEFAULT_TENANT, "device-id", mock(Span.class)) .onComplete(ctx.succeeding(value -> { ctx.verify(() -> { assertThat(value.getString(DeviceConnectionConstants.FIELD_GATEWAY_ID)).isEqualTo("gw-id"); }); ctx.completeNow(); })); }
@Test void testGetLastKnownGatewayFailsForCacheAccessException(final VertxTestContext ctx) { final Cache<String, String> mockedCache = mockCache(); info = new CacheBasedDeviceConnectionInfo(mockedCache, tracer); when(mockedCache.get(anyString())).thenReturn(Future.failedFuture(new IOException("not available"))); info.getLastKnownGatewayForDevice(Constants.DEFAULT_TENANT, "device-id", mock(Span.class)) .onComplete(ctx.failing(t -> { ctx.verify(() -> { assertThat(t).isInstanceOf(ServiceInvocationException.class); assertThat(((ServiceInvocationException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_INTERNAL_ERROR); }); ctx.completeNow(); })); }
@Test void testGetLastKnownGatewayFailsForNonExistingEntry(final VertxTestContext ctx) { final Cache<String, String> mockedCache = mockCache(); info = new CacheBasedDeviceConnectionInfo(mockedCache, tracer); when(mockedCache.get(anyString())).thenReturn(Future.succeededFuture(null)); info.getLastKnownGatewayForDevice(Constants.DEFAULT_TENANT, "device-id", mock(Span.class)) .onComplete(ctx.failing(t -> { ctx.verify(() -> { assertThat(t).isInstanceOf(ClientErrorException.class); assertThat(((ServiceInvocationException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_NOT_FOUND); }); ctx.completeNow(); })); }