MapBasedDeviceConnectionService implements DeviceConnectionService { @Override public final Future<DeviceConnectionResult> setCommandHandlingAdapterInstance(final String tenantId, final String deviceId, final String protocolAdapterInstanceId, final Duration lifespan, final Span span) { Objects.requireNonNull(tenantId); Objects.requireNonNull(deviceId); Objects.requireNonNull(protocolAdapterInstanceId); final ConcurrentMap<String, ExpiringValue<JsonObject>> adapterInstancesForTenantMap = commandHandlingAdapterInstancesMap.computeIfAbsent(tenantId, k -> buildAdapterInstancesForTenantMap()); final DeviceConnectionResult result; final int currentMapSize = adapterInstancesForTenantMap.size(); if (currentMapSize < getConfig().getMaxDevicesPerTenant() || (currentMapSize == getConfig().getMaxDevicesPerTenant() && adapterInstancesForTenantMap.containsKey(deviceId))) { adapterInstancesForTenantMap.put(deviceId, new ExpiringValue<>(createAdapterInstanceIdJson(protocolAdapterInstanceId), getLifespanNanos(lifespan))); result = DeviceConnectionResult.from(HttpURLConnection.HTTP_NO_CONTENT); } else { log.debug("cannot set protocol adapter instance for handling commands of device [{}], tenant [{}]: max number of entries per tenant reached ({})", deviceId, tenantId, getConfig().getMaxDevicesPerTenant()); result = DeviceConnectionResult.from(HttpURLConnection.HTTP_FORBIDDEN); } return Future.succeededFuture(result); }  @Autowired void setConfig(final MapBasedDeviceConnectionsConfigProperties configuration); MapBasedDeviceConnectionsConfigProperties getConfig(); @Override final Future<DeviceConnectionResult> setLastKnownGatewayForDevice(final String tenantId, final String deviceId,
            final String gatewayId, final Span span); @Override final Future<DeviceConnectionResult> getLastKnownGatewayForDevice(final String tenantId, final String deviceId,
            final Span span); @Override final Future<DeviceConnectionResult> setCommandHandlingAdapterInstance(final String tenantId,
            final String deviceId, final String protocolAdapterInstanceId, final Duration lifespan, final Span span); @Override final Future<DeviceConnectionResult> removeCommandHandlingAdapterInstance(
            final String tenantId,
            final String deviceId,
            final String adapterInstanceId,
            final Span span); @Override final Future<DeviceConnectionResult> getCommandHandlingAdapterInstances(final String tenantId,
            final String deviceId, final List<String> viaGateways, final Span span);  }
@Test public void testSetCommandHandlingAdapterInstanceSucceeds(final VertxTestContext ctx) { final String deviceId = "testDevice"; final String adapterInstance = "adapterInstance"; svc.setCommandHandlingAdapterInstance(Constants.DEFAULT_TENANT, deviceId, adapterInstance, null, span) .onComplete(ctx.succeeding(result -> ctx.verify(() -> { assertEquals(HttpURLConnection.HTTP_NO_CONTENT, result.getStatus()); ctx.completeNow(); }))); }
@Test public void testSetCommandHandlingAdapterInstanceFailsIfLimitReached(final VertxTestContext ctx) { props.setMaxDevicesPerTenant(1); final String deviceId = "testDevice"; final String adapterInstance = "adapterInstance"; svc.setCommandHandlingAdapterInstance(Constants.DEFAULT_TENANT, deviceId, adapterInstance, null, span) .compose(deviceConnectionResult -> { ctx.verify(() -> { assertEquals(HttpURLConnection.HTTP_NO_CONTENT, deviceConnectionResult.getStatus()); }); return svc.setCommandHandlingAdapterInstance(Constants.DEFAULT_TENANT, "testDevice2", adapterInstance, null, span); }).onComplete(ctx.succeeding(deviceConnectionResult -> ctx.verify(() -> { assertEquals(HttpURLConnection.HTTP_FORBIDDEN, deviceConnectionResult.getStatus()); assertNull(deviceConnectionResult.getPayload()); ctx.completeNow(); }))); }