CacheBasedDeviceConnectionInfo implements DeviceConnectionInfo, HealthCheckProvider { @Override public Future<JsonObject> getCommandHandlingAdapterInstances(final String tenantId, final String deviceId, final Set<String> viaGateways, final Span span) { Objects.requireNonNull(tenantId); Objects.requireNonNull(deviceId); Objects.requireNonNull(viaGateways); Objects.requireNonNull(span); final Future<JsonObject> resultFuture; if (viaGateways.isEmpty()) { resultFuture = cache.get(getAdapterInstanceEntryKey(tenantId, deviceId)) .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t)) .compose(adapterInstanceId -> { if (adapterInstanceId == null) { LOG.debug("no command handling adapter instances found [tenant: {}, device-id: {}]", tenantId, deviceId); span.log("no command handling adapter instances found for device (no via-gateways given)"); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND)); } else { LOG.debug("found command handling adapter instance '{}' [tenant: {}, device-id: {}]", adapterInstanceId, tenantId, deviceId); span.log("returning command handling adapter instance for device itself"); setTagsForSingleResult(span, adapterInstanceId); return Future.succeededFuture(getAdapterInstancesResultJson(deviceId, adapterInstanceId)); } }); } else if (viaGateways.size() <= VIA_GATEWAYS_OPTIMIZATION_THRESHOLD) { resultFuture = getInstancesQueryingAllGatewaysFirst(tenantId, deviceId, viaGateways, span); } else { resultFuture = getInstancesGettingLastKnownGatewayFirst(tenantId, deviceId, viaGateways, span); } return resultFuture; } 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 public void testGetCommandHandlingAdapterInstancesFails(final VertxTestContext ctx) { final String deviceId = "testDevice"; final Set<String> viaGateways = Collections.emptySet(); info.getCommandHandlingAdapterInstances(Constants.DEFAULT_TENANT, deviceId, viaGateways, span) .onComplete(ctx.failing(t -> ctx.verify(() -> { assertThat(t).isInstanceOf(ServiceInvocationException.class); assertThat(((ServiceInvocationException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_NOT_FOUND); ctx.completeNow(); }))); }