From a20267530701ecfb9c1537e3607ed38533c2f489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stef=C3=A1n=20Freyr=20Stef=C3=A1nsson?= Date: Sat, 26 Aug 2023 02:55:10 +0000 Subject: [PATCH] Restructure modules as per PR comments --- bom/pom.xml | 16 +- caches/cache-common/pom.xml | 112 --- caches/cache-infinispan/pom.xml | 96 --- .../infinispan/BasicCache.java | 223 ------ .../infinispan/EmbeddedCache.java | 115 --- .../infinispan/HotrodCache.java | 239 ------ .../InfinispanRemoteConfigurationOptions.java | 202 ----- ...finispanRemoteConfigurationProperties.java | 189 ----- caches/cache-redis/pom.xml | 50 -- caches/pom.xml | 95 --- client-device-connection-infinispan/pom.xml | 56 +- .../client/AdapterInstanceStatusProvider.java | 51 -- .../infinispan/client/BasicCache.java | 1 + .../infinispan/client/Cache.java | 119 --- .../CacheBasedDeviceConnectionInfo.java | 693 ------------------ .../infinispan/client/CommonCacheConfig.java | 86 --- .../infinispan/client/CommonCacheOptions.java | 52 -- .../client/DeviceConnectionInfo.java | 186 ----- .../DeviceToAdapterMappingErrorListener.java | 37 - .../infinispan/client/HotrodCache.java | 1 + .../client/UnknownStatusProvider.java | 41 -- .../client/QuarkusPropertyBindingTest.java | 2 + client-device-connection-redis/pom.xml | 175 +++++ .../redis/client}/RedisCache.java | 4 +- .../native-image.properties | 15 + .../resources-config.json | 37 + .../src/main/resources/application.properties | 11 + .../test/resources/common-cache-options.yaml | 6 + .../src/test/resources/logback-test.xml | 37 + .../test/resources/remote-cache-options.yaml | 34 + client-device-connection/pom.xml | 119 ++- .../AdapterInstanceStatusProvider.java | 2 +- .../hono/deviceconnection/common}/Cache.java | 2 +- .../CacheBasedDeviceConnectionInfo.java | 3 +- .../common}/CommonCacheConfig.java | 2 +- .../common}/CommonCacheOptions.java | 2 +- .../{ => common}/DeviceConnectionInfo.java | 2 +- .../DeviceToAdapterMappingErrorListener.java | 2 +- .../{ => common}/UnknownStatusProvider.java | 2 +- .../CacheBasedDeviceConnectionInfoTest.java | 11 +- pom.xml | 6 +- services/command-router/pom.xml | 10 +- .../AdapterInstanceStatusService.java | 2 +- .../commandrouter/CommandTargetMapper.java | 2 +- .../hono/commandrouter/app/Application.java | 2 +- .../app/DeviceConnectionInfoProducer.java | 16 +- .../impl/CommandRouterServiceImpl.java | 2 +- .../impl/CommandTargetMapperImpl.java | 2 +- .../impl/CommandRouterServiceImplTest.java | 2 +- 49 files changed, 492 insertions(+), 2680 deletions(-) delete mode 100644 caches/cache-common/pom.xml delete mode 100644 caches/cache-infinispan/pom.xml delete mode 100644 caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/BasicCache.java delete mode 100644 caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/EmbeddedCache.java delete mode 100644 caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/HotrodCache.java delete mode 100644 caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationOptions.java delete mode 100644 caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationProperties.java delete mode 100644 caches/cache-redis/pom.xml delete mode 100644 caches/pom.xml delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/AdapterInstanceStatusProvider.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/Cache.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfo.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheConfig.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheOptions.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceConnectionInfo.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceToAdapterMappingErrorListener.java delete mode 100644 client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/UnknownStatusProvider.java create mode 100644 client-device-connection-redis/pom.xml rename {caches/cache-redis/src/main/java/org/eclipse/hono/deviceconnection/redis => client-device-connection-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/client}/RedisCache.java (97%) create mode 100644 client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/native-image.properties create mode 100644 client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/resources-config.json create mode 100644 client-device-connection-redis/src/main/resources/application.properties create mode 100644 client-device-connection-redis/src/test/resources/common-cache-options.yaml create mode 100644 client-device-connection-redis/src/test/resources/logback-test.xml create mode 100644 client-device-connection-redis/src/test/resources/remote-cache-options.yaml rename client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/{ => common}/AdapterInstanceStatusProvider.java (97%) rename {caches/cache-common/src/main/java/org/eclipse/hono/cache => client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common}/Cache.java (98%) rename client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/{ => common}/CacheBasedDeviceConnectionInfo.java (99%) rename {caches/cache-common/src/main/java/org/eclipse/hono/cache => client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common}/CommonCacheConfig.java (97%) rename {caches/cache-common/src/main/java/org/eclipse/hono/cache => client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common}/CommonCacheOptions.java (96%) rename client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/{ => common}/DeviceConnectionInfo.java (99%) rename client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/{ => common}/DeviceToAdapterMappingErrorListener.java (96%) rename client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/{ => common}/UnknownStatusProvider.java (95%) rename {client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client => client-device-connection/src/test/java/org/eclipse/hono/deviceconnection/common}/CacheBasedDeviceConnectionInfoTest.java (99%) diff --git a/bom/pom.xml b/bom/pom.xml index 0f055100da..851588b971 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -328,22 +328,17 @@ quarkus.vertx.max-event-loop-execute-time=${max.event-loop.execute-time:20000} org.eclipse.hono - hono-cache-common + client-device-connection ${project.version} org.eclipse.hono - hono-cache-infinispan - ${project.version} - - - org.eclipse.hono - hono-cache-redis + client-device-connection-infinispan ${project.version} org.eclipse.hono - hono-client-device-connection + client-device-connection-redis ${project.version} @@ -461,11 +456,6 @@ quarkus.vertx.max-event-loop-execute-time=${max.event-loop.execute-time:20000} hono-service-command-router ${project.version} - - org.eclipse.hono - client-device-connection-infinispan - ${project.version} - org.eclipse.hono hono-client-application diff --git a/caches/cache-common/pom.xml b/caches/cache-common/pom.xml deleted file mode 100644 index bc8282b651..0000000000 --- a/caches/cache-common/pom.xml +++ /dev/null @@ -1,112 +0,0 @@ - - - - 4.0.0 - - org.eclipse.hono - hono-caches-parent - 2.5.0-SNAPSHOT - - hono-cache-common - - Hono Cache Common - Classes required for implementing Hono caches - - - - io.vertx - vertx-core - - - org.eclipse.hono - hono-client-common - - - com.google.guava - guava - - - io.quarkus - quarkus-core - true - - - org.jboss.logmanager - jboss-logmanager-embedded - - - org.jboss.logging - jboss-logging-annotations - - - io.quarkus - quarkus-development-mode-spi - - - io.quarkus - quarkus-bootstrap-runner - - - org.jboss.slf4j - slf4j-jboss-logmanager - - - org.graalvm.sdk - graal-sdk - - - io.quarkus - quarkus-fs-util - - - - - - - - - diff --git a/caches/cache-infinispan/pom.xml b/caches/cache-infinispan/pom.xml deleted file mode 100644 index 633a7f7376..0000000000 --- a/caches/cache-infinispan/pom.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - 4.0.0 - - org.eclipse.hono - hono-caches-parent - 2.5.0-SNAPSHOT - - hono-cache-infinispan - - Hono Client Device Connection Cache using Infinispan - Infinispan implementation of Hono's Client Device Connection cache - - - - org.eclipse.hono - hono-cache-common - - - org.infinispan - infinispan-client-hotrod - - - io.netty - netty-transport-native-epoll - - - - - org.infinispan - infinispan-query-dsl - - - org.infinispan - infinispan-core - - - io.quarkus - quarkus-core - true - - - org.jboss.logmanager - jboss-logmanager-embedded - - - org.jboss.logging - jboss-logging-annotations - - - io.quarkus - quarkus-development-mode-spi - - - io.quarkus - quarkus-bootstrap-runner - - - org.jboss.slf4j - slf4j-jboss-logmanager - - - org.graalvm.sdk - graal-sdk - - - io.quarkus - quarkus-fs-util - - - - - - - - diff --git a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/BasicCache.java b/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/BasicCache.java deleted file mode 100644 index 47fe0603c7..0000000000 --- a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/BasicCache.java +++ /dev/null @@ -1,223 +0,0 @@ -/** - * Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan; - -import java.net.HttpURLConnection; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; - -import org.eclipse.hono.cache.Cache; -import org.eclipse.hono.client.ServerErrorException; -import org.eclipse.hono.util.Futures; -import org.eclipse.hono.util.Lifecycle; -import org.infinispan.commons.api.BasicCacheContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.vertx.core.AsyncResult; -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; - -/** - * An abstract base class for implementing caches based on an - * Infinispan {@link org.infinispan.commons.api.BasicCache}. - * - * @param The type of the key. - * @param The type of the value. - */ -public abstract class BasicCache implements Cache, Lifecycle { - - private static final Logger LOG = LoggerFactory.getLogger(BasicCache.class); - - protected final Vertx vertx; - private final BasicCacheContainer cacheManager; - private final AtomicBoolean stopCalled = new AtomicBoolean(); - - private org.infinispan.commons.api.BasicCache cache; - - /** - * Creates a new instance. - * - * @param vertx The vert.x instance to run on. - * @param cacheManager The cache manager. - */ - protected BasicCache(final Vertx vertx, final BasicCacheContainer cacheManager) { - this.vertx = Objects.requireNonNull(vertx); - this.cacheManager = Objects.requireNonNull(cacheManager); - } - - /** - * Called to trigger connecting the cache. - * - * @return A future tracking the progress, never returns {@code null}. - */ - protected abstract Future connectToCache(); - - /** - * Checks if the cache manager is started. - * - * @return {@code true} if the cache manager is started, {@code false} otherwise. - */ - protected abstract boolean isStarted(); - - @Override - public Future start() { - LOG.info("starting cache"); - return connectToCache(); - } - - @Override - public Future stop() { - if (!stopCalled.compareAndSet(false, true)) { - return Future.succeededFuture(); - } - LOG.info("stopping cache"); - setCache(null); - final Promise result = Promise.promise(); - vertx.executeBlocking(r -> { - try { - cacheManager.stop(); - r.complete(); - } catch (final Exception t) { - r.fail(t); - } - }, (AsyncResult stopAttempt) -> { - if (stopAttempt.succeeded()) { - LOG.info("connection(s) to cache stopped successfully"); - } else { - LOG.info("error trying to stop connection(s) to cache", stopAttempt.cause()); - } - result.handle(stopAttempt); - }); - return result.future(); - } - - protected void setCache(final org.infinispan.commons.api.BasicCache cache) { - this.cache = cache; - } - - protected org.infinispan.commons.api.BasicCache getCache() { - return this.cache; - } - - /** - * Performs a task with a connected cache. - *

- * The method checks if the cache instance has been set. If that is the case, then the - * supplier will be invoked, providing a non-null cache instance. - *

- * If the cache has not been set (yet) or it has been stopped, the supplier will not be - * called and a failed future will be returned, provided by {@link #noConnectionFailure()}. - * - * @param The type of the return value. - * @param futureSupplier The supplier, providing the operation which should be invoked. - * @return The future, tracking the result of the operation. - */ - protected final Future withCache( - final Function, CompletionStage> futureSupplier) { - - return Optional.ofNullable(cache) - .map(c -> Futures.create(() -> futureSupplier.apply(c))) - .orElseGet(BasicCache::noConnectionFailure) - .onComplete(this::postCacheAccess); - } - - /** - * Performs extra processing on the result of a cache operation returned by {@link #withCache(Function)}. - *

- * Subclasses should override this method if needed. - *

- * This default implementation does nothing. - * - * @param The type of the return value. - * @param cacheOperationResult The result of the cache operation. - */ - protected void postCacheAccess(final AsyncResult cacheOperationResult) { - // nothing done by default - } - - @Override - public Future put(final K key, final V value) { - Objects.requireNonNull(key); - Objects.requireNonNull(value); - - return withCache(aCache -> aCache.putAsync(key, value).thenApply(v -> (Void) null)); - } - - @Override - public Future put(final K key, final V value, final long lifespan, final TimeUnit lifespanUnit) { - Objects.requireNonNull(key); - Objects.requireNonNull(value); - Objects.requireNonNull(lifespanUnit); - - return withCache(aCache -> aCache.putAsync(key, value, lifespan, lifespanUnit).thenApply(v -> (Void) null)); - } - - @Override - public Future putAll(final Map data) { - Objects.requireNonNull(data); - - return withCache(aCache -> aCache.putAllAsync(data)); - } - - @Override - public Future putAll(final Map data, final long lifespan, final TimeUnit lifespanUnit) { - Objects.requireNonNull(data); - Objects.requireNonNull(lifespanUnit); - - return withCache(aCache -> aCache.putAllAsync(data, lifespan, lifespanUnit)); - } - - @Override - public Future remove(final K key, final V value) { - Objects.requireNonNull(key); - Objects.requireNonNull(value); - - return withCache(aCache -> aCache.removeAsync(key, value)); - } - - @Override - public Future get(final K key) { - Objects.requireNonNull(key); - - return withCache(aCache -> aCache.getAsync(key)); - } - - @Override - public Future> getAll(final Set keys) { - Objects.requireNonNull(keys); - - return withCache(aCache -> aCache.getAllAsync(keys)); - } - - /** - * Returns a failed future, reporting a missing connection to the cache. - * - * @param The value type of the returned future. - * @return A failed future, never returns {@code null}. - */ - protected static Future noConnectionFailure() { - - return Future.failedFuture(new ServerErrorException( - HttpURLConnection.HTTP_UNAVAILABLE, "no connection to data grid")); - } - -} diff --git a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/EmbeddedCache.java b/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/EmbeddedCache.java deleted file mode 100644 index efbfeee309..0000000000 --- a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/EmbeddedCache.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan; - -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.infinispan.manager.EmbeddedCacheManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; -import io.vertx.core.json.JsonObject; - -/** - * An embedded cache. - * - * @param The type of keys used by the cache. - * @param The type of values stored in the cache. - */ -public class EmbeddedCache extends BasicCache { - - private static final Logger LOG = LoggerFactory.getLogger(EmbeddedCache.class); - - private final AtomicBoolean connecting = new AtomicBoolean(false); - - private final EmbeddedCacheManager cacheManager; - private final String cacheName; - - /** - * Creates a new embedded cache instance. - * - * @param vertx The vert.x instance to run on. - * @param cacheManager The connection to the cache. - * @param cacheName The name of the cache. - */ - public EmbeddedCache( - final Vertx vertx, - final EmbeddedCacheManager cacheManager, - final String cacheName) { - super(vertx, cacheManager); - this.cacheManager = Objects.requireNonNull(cacheManager); - this.cacheName = Objects.requireNonNull(cacheName); - } - - @Override - protected boolean isStarted() { - return cacheManager.isRunning(cacheName) && getCache() != null; - } - - @Override - protected Future connectToCache() { - - final Promise result = Promise.promise(); - - if (connecting.compareAndSet(false, true)) { - - vertx.executeBlocking(r -> { - try { - LOG.debug("trying to start cache manager"); - cacheManager.start(); - LOG.info("started cache manager"); - LOG.debug("trying to get cache"); - setCache(cacheManager.getCache(cacheName)); - if (isStarted()) { - r.complete(getCache()); - } else { - r.fail(new IllegalStateException("cache [" + cacheName + "] is not configured")); - } - } catch (final Throwable t) { - r.fail(t); - } - }, attempt -> { - if (attempt.succeeded()) { - LOG.info("successfully connected to cache"); - result.complete(); - } else { - LOG.debug("failed to connect to cache: {}", attempt.cause().getMessage()); - result.fail(attempt.cause()); - } - connecting.set(false); - }); - } else { - LOG.info("already trying to establish connection to cache"); - result.fail("already trying to establish connection to cache"); - } - return result.future(); - } - - @Override - public Future checkForCacheAvailability() { - - if (isStarted()) { - return Future.succeededFuture(new JsonObject()); - } else { - // try to (re-)establish connection - connectToCache(); - return Future.failedFuture("not connected to cache"); - } - } - -} diff --git a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/HotrodCache.java b/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/HotrodCache.java deleted file mode 100644 index 6aebc33824..0000000000 --- a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/HotrodCache.java +++ /dev/null @@ -1,239 +0,0 @@ -/** - * Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan; - -import java.time.Duration; -import java.time.Instant; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.eclipse.hono.cache.CommonCacheConfig; -import org.infinispan.client.hotrod.RemoteCache; -import org.infinispan.client.hotrod.RemoteCacheContainer; -import org.infinispan.client.hotrod.RemoteCacheManager; -import org.infinispan.commons.marshall.ProtoStreamMarshaller; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.vertx.core.AsyncResult; -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.core.Vertx; -import io.vertx.core.json.JsonObject; - -/** - * A remote cache that connects to a data grid using the Hotrod protocol. - * - * @param The type of keys used by the cache. - * @param The type of values stored in the cache. - */ -public final class HotrodCache extends BasicCache { - - private static final Logger LOG = LoggerFactory.getLogger(HotrodCache.class); - - /** - * Maximum age for a cached connection check result to be used in {@link #checkForCacheAvailability()}. - */ - private static final Duration CACHED_CONNECTION_CHECK_RESULT_MAX_AGE = Duration.ofSeconds(30); - - private final AtomicBoolean connecting = new AtomicBoolean(false); - private final RemoteCacheContainer cacheManager; - private final String cacheName; - - private final K connectionCheckKey; - private final V connectionCheckValue; - - private ConnectionCheckResult lastConnectionCheckResult; - - /** - * Creates a new HotrodCache instance. - * - * @param vertx The vert.x instance to run on. - * @param cacheManager The connection to the remote cache. - * @param cacheName The name of the (remote) cache. - * @param connectionCheckKey The key to use for checking the connection - * to the data grid. - * @param connectionCheckValue The value to use for checking the connection - * to the data grid. - * @throws NullPointerException if any of the parameters are {@code null}. - */ - HotrodCache( - final Vertx vertx, - final RemoteCacheContainer cacheManager, - final String cacheName, - final K connectionCheckKey, - final V connectionCheckValue) { - super(vertx, cacheManager); - this.cacheManager = Objects.requireNonNull(cacheManager); - this.cacheName = Objects.requireNonNull(cacheName); - this.connectionCheckKey = Objects.requireNonNull(connectionCheckKey); - this.connectionCheckValue = Objects.requireNonNull(connectionCheckValue); - } - - /** - * Creates a new remote cache. - * - * @param vertx The vert.x instance to run on. - * @param properties The remote cache configuration. - * @param commonCacheConfig The common cache configuration. - * @return The remote cache. - * @throws NullPointerException if any of the parameters are {@code null}. - */ - public static HotrodCache from( - final Vertx vertx, - final InfinispanRemoteConfigurationProperties properties, - final CommonCacheConfig commonCacheConfig) { - - Objects.requireNonNull(vertx); - Objects.requireNonNull(properties); - Objects.requireNonNull(commonCacheConfig); - - final var configBuilder = properties.getConfigurationBuilder(); - configBuilder.marshaller(new ProtoStreamMarshaller()); - final var configuration = configBuilder.build(); - if (LOG.isInfoEnabled()) { - LOG.info("creating HotrodCache using configuration: {}", configuration); - } - return new HotrodCache<>( - vertx, - new RemoteCacheManager(configuration, false), - commonCacheConfig.getCacheName(), - commonCacheConfig.getCheckKey(), - commonCacheConfig.getCheckValue()); - } - - @Override - protected Future connectToCache() { - - final Promise result = Promise.promise(); - - if (connecting.compareAndSet(false, true)) { - - vertx.executeBlocking(r -> { - try { - if (!cacheManager.isStarted()) { - LOG.debug("trying to start cache manager"); - cacheManager.start(); - LOG.info("started cache manager, now connecting to remote cache"); - } - LOG.debug("trying to connect to remote cache"); - @SuppressWarnings("unchecked") - final var cache = (RemoteCache) cacheManager.getCache(cacheName); - if (cache == null) { - r.fail(new IllegalStateException("remote cache [" + cacheName + "] does not exist")); - } else { - cache.start(); - setCache(cache); - r.complete(cache); - } - } catch (final Exception t) { - r.fail(t); - } - }, attempt -> { - if (attempt.succeeded()) { - LOG.info("successfully connected to remote cache"); - result.complete(); - } else { - LOG.debug("failed to connect to remote cache: {}", attempt.cause().getMessage()); - result.fail(attempt.cause()); - } - connecting.set(false); - }); - } else { - LOG.info("already trying to establish connection to data grid"); - result.fail("already trying to establish connection to data grid"); - } - return result.future(); - } - - @Override - protected boolean isStarted() { - return cacheManager.isStarted() && getCache() != null; - } - - @Override - protected void postCacheAccess(final AsyncResult cacheOperationResult) { - lastConnectionCheckResult = new ConnectionCheckResult(cacheOperationResult.cause()); - } - - /** - * Checks if the cache is connected. - * - * @return A future that is completed with information about a successful check's result. - * Otherwise, the future will be failed with a {@link org.eclipse.hono.client.ServerErrorException}. - */ - @Override - public Future checkForCacheAvailability() { - - if (isStarted()) { - final ConnectionCheckResult lastResult = lastConnectionCheckResult; - if (lastResult != null && !lastResult.isOlderThan(CACHED_CONNECTION_CHECK_RESULT_MAX_AGE)) { - return lastResult.asFuture(); - } else { - final Promise result = Promise.promise(); - put(connectionCheckKey, connectionCheckValue) - .onComplete(r -> { - if (r.succeeded()) { - result.complete(new JsonObject()); - } else { - LOG.debug("failed to put test value to cache", r.cause()); - result.fail(r.cause()); - } - }); - return result.future(); - } - } else { - // try to (re-)establish connection - connectToCache(); - return Future.failedFuture("not connected to data grid"); - } - } - - /** - * Keeps the result of a connection check. - */ - private static class ConnectionCheckResult { - private final Instant creationTimestamp = Instant.now(); - private final Throwable errorResult; - - /** - * Creates a new ConnectionCheckResult. - * - * @param errorResult The error in case the check failed; use {@code null} if the check succeeded. - */ - ConnectionCheckResult(final Throwable errorResult) { - this.errorResult = errorResult; - } - - /** - * Checks if the result is older than the given time span, determined from the current point in time. - * - * @param timespan The time span. - * @return {@code true} if the result is older. - */ - public boolean isOlderThan(final Duration timespan) { - return creationTimestamp.isBefore(Instant.now().minus(timespan)); - } - - /** - * Gets a future indicating the connection check outcome. - * - * @return A succeeded future if the check succeeded, otherwise a failed future. - */ - public Future asFuture() { - return errorResult != null ? Future.failedFuture(errorResult) : Future.succeededFuture(new JsonObject()); - } - } - -} diff --git a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationOptions.java b/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationOptions.java deleted file mode 100644 index e47cdcf43d..0000000000 --- a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationOptions.java +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - - -package org.eclipse.hono.deviceconnection.infinispan; - -import java.util.Map; -import java.util.Optional; - -import io.smallrye.config.ConfigMapping; -import io.smallrye.config.ConfigMapping.NamingStrategy; -import io.smallrye.config.WithDefault; - -/** - * Options for configuring a Hotrod connection to a remote cache. - * - */ -@ConfigMapping(prefix = "hono.cache.infinispan", namingStrategy = NamingStrategy.VERBATIM) -public interface InfinispanRemoteConfigurationOptions { - - /** - * Gets the connection pool options. - * - * @return The options. - */ - Map connectionPool(); - - /** - * Gets the default executor factory options. - * - * @return The options. - */ - Map defaultExecutorFactory(); - - /** - * Gets the SASL properties. - * - * @return The properties. - */ - Map saslProperties(); - - /** - * Gets the cluster options. - * - * @return The options. - */ - Map cluster(); - - /** - * Gets the list of remote servers as a string of the form host1[:port][;host2[:port]]. - * - * @return The servers. - */ - Optional serverList(); - - /** - * Gets the auth server name. - * - * @return The server name. - */ - Optional authServerName(); - - /** - * Gets the user name to use for authentication. - * - * @return The user name. - */ - Optional authUsername(); - - /** - * Gets the password to use for authentication. - * - * @return The password. - */ - Optional authPassword(); - - /** - * Gets the auth realm (for DIGEST-MD5 authentication). - * - * @return The realm. - */ - Optional authRealm(); - - /** - * Gets the SASL mechanism to use for authentication. - * - * @return The mechanism. - */ - Optional saslMechanism(); - - /** - * Gets the socket timeout. - * - * @return The timeout. - */ - @WithDefault("60000") - int socketTimeout(); - - /** - * Gets the connect timeout. - * - * @return The timeout. - */ - @WithDefault("60000") - int connectTimeout(); - - /** - * Gets the path of the trust store. - * - * @return The path. - */ - Optional trustStorePath(); - - /** - * Gets the trust store file name. - * - * @return The file name. - */ - Optional trustStoreFileName(); - - /** - * Gets the type of the trust store (JKS, JCEKS, PCKS12 or PEM). - * - * @return The type. - */ - Optional trustStoreType(); - - /** - * Gets the password of the trust store. - * - * @return The password. - */ - Optional trustStorePassword(); - - /** - * Gets the file name of a keystore to use when using client certificate authentication. - * - * @return The file name. - */ - Optional keyStoreFileName(); - - /** - * Gets the keystore type. - * - * @return The type. - */ - Optional keyStoreType(); - - /** - * Gets the keystore password. - * - * @return The password. - */ - Optional keyStorePassword(); - - /** - * Gets the key alias. - * - * @return The alias. - */ - Optional keyAlias(); - - /** - * Gets the certificate password in the keystore. - * - * @return The password. - */ - Optional keyStoreCertificatePassword(); - - /** - * Checks whether TLS is enabled. - * - * @return {@code true} if TLS is enabled. - */ - @WithDefault("false") - boolean useSsl(); - - /** - * Gets the list of ciphers, separated with spaces and in order of preference, that are used during the TLS - * handshake. - * - * @return The ciphers. - */ - Optional sslCiphers(); - - /** - * Gets the TLS protocol to use (e.g. TLSv1.2). - * - * @return The protocol. - */ - Optional sslProtocol(); -} diff --git a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationProperties.java b/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationProperties.java deleted file mode 100644 index 0251615446..0000000000 --- a/caches/cache-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/InfinispanRemoteConfigurationProperties.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - - -package org.eclipse.hono.deviceconnection.infinispan; - -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; - -import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; -import org.infinispan.client.hotrod.impl.ConfigurationProperties; - -import com.google.common.base.CaseFormat; -import com.google.common.base.MoreObjects; - - -/** - * Configuration properties for a Hotrod connection to a remote cache. - * - */ -public class InfinispanRemoteConfigurationProperties extends ConfigurationProperties { - - private static final String DEFAULT_EXECUTOR_FACTORY_PREFIX = "infinispan.client.hotrod.default_executor_factory"; - private static final String CONNECTION_POOL_PREFIX = "infinispan.client.hotrod.connection_pool"; - - /** - * Creates properties using default values. - */ - public InfinispanRemoteConfigurationProperties() { - super(); - } - - /** - * Creates properties from existing options. - * - * @param options The options to copy. - */ - @SuppressWarnings("deprecation") - public InfinispanRemoteConfigurationProperties(final InfinispanRemoteConfigurationOptions options) { - super(); - - options.authPassword().ifPresent(this::setAuthPassword); - options.authRealm().ifPresent(this::setAuthRealm); - options.authServerName().ifPresent(this::setAuthServerName); - options.authUsername().ifPresent(this::setAuthUsername); - - setCluster(options.cluster()); - setConnectionPool(options.connectionPool()); - setConnectTimeout(options.connectTimeout()); - - setDefaultExecutorFactory(options.defaultExecutorFactory()); - - options.keyAlias().ifPresent(this::setKeyAlias); - options.keyStoreCertificatePassword().ifPresent(this::setKeyStoreCertificatePassword); - options.keyStoreFileName().ifPresent(this::setKeyStoreFileName); - options.keyStorePassword().ifPresent(this::setKeyStorePassword); - options.keyStoreType().ifPresent(this::setKeyStoreType); - - options.saslMechanism().ifPresent(this::setSaslMechanism); - setSaslProperties(options.saslProperties()); - - options.serverList().ifPresent(this::setServerList); - setSocketTimeout(options.socketTimeout()); - - options.trustStoreFileName().ifPresent(this::setTrustStoreFileName); - options.trustStorePassword().ifPresent(this::setTrustStorePassword); - options.trustStorePath().ifPresent(this::setTrustStorePath); - options.trustStoreType().ifPresent(this::setTrustStoreType); - - setUseSSL(options.useSsl()); - - options.sslCiphers().ifPresent(this::setSSLCiphers); - options.sslProtocol().ifPresent(this::setSSLProtocol); - } - - /** - * Gets a builder for this configuration. - * - * @return A builder that can be used to create a cache. - */ - public final ConfigurationBuilder getConfigurationBuilder() { - return new ConfigurationBuilder().withProperties(getProperties()); - } - - /** - * Sets the properties related to the connection pool. - *

- * Property keys may be in camel case or snake case. - * - * @param poolProperties The properties. - */ - public final void setConnectionPool(final Map poolProperties) { - setProperties(poolProperties, CONNECTION_POOL_PREFIX, this::toSnakeCase); - } - - /** - * Sets the properties related to the default executor factory. - *

- * Property keys may be in camel case or snake case. - * - * @param factoryProperties The properties. - */ - public final void setDefaultExecutorFactory(final Map factoryProperties) { - setProperties(factoryProperties, DEFAULT_EXECUTOR_FACTORY_PREFIX, this::toSnakeCase); - } - - /** - * Sets the properties related to the SASL based authentication. - * - * @param saslProperties The properties. - */ - public final void setSaslProperties(final Map saslProperties) { - setProperties(saslProperties, SASL_PROPERTIES_PREFIX, null); - } - - /** - * Sets the properties related to cluster configuration. - * - * @param clusterProperties The properties. - */ - public final void setCluster(final Map clusterProperties) { - setProperties(clusterProperties, CLUSTER_PROPERTIES_PREFIX, null); - } - - private String toSnakeCase(final String key) { - return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, key); - } - - private void setProperties( - final Map properties, - final String keyPrefix, - final Function keyConverter) { - - properties.forEach((k, v) -> { - final String keySuffix = Optional.ofNullable(keyConverter).map(f -> f.apply(k)).orElse(k); - final String key = String.format("%s.%s", keyPrefix, keySuffix); - getProperties().setProperty(key, v); - }); - } - - // ------- Getters/setters missing in the parent ConfigurationProperties class ------- - - /** - * Gets the keystore certificate password. - * - * @return The password. - */ - public String getKeyStoreCertificatePassword() { - return getProperties().getProperty(KEY_STORE_CERTIFICATE_PASSWORD); - } - - /** - * Gets the SSL ciphers. - * - * @return The ciphers. - */ - public String getSSLCiphers() { - return getProperties().getProperty(SSL_CIPHERS); - } - - /** - * Sets the SSL ciphers. - * - * @param ciphers The ciphers. - */ - public void setSSLCiphers(final String ciphers) { - getProperties().put(SSL_CIPHERS, ciphers); - } - - @Override - public String toString() { - return MoreObjects - .toStringHelper(this) - .add("serverList", this.getServerList()) - .add("authUsername", this.getAuthUsername()) - .toString(); - } -} diff --git a/caches/cache-redis/pom.xml b/caches/cache-redis/pom.xml deleted file mode 100644 index 7a6a5b04ca..0000000000 --- a/caches/cache-redis/pom.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - 4.0.0 - - org.eclipse.hono - hono-caches-parent - 2.5.0-SNAPSHOT - - hono-cache-redis - - Hono Client Device Connection Cache (Redis) - Redis implementation of Hono's Client Device Connection cache - - - - org.eclipse.hono - hono-cache-common - - - - redis.clients - jedis - 4.3.1 - - - - - - - diff --git a/caches/pom.xml b/caches/pom.xml deleted file mode 100644 index 2b25b16dd9..0000000000 --- a/caches/pom.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - 4.0.0 - - org.eclipse.hono - hono-bom - 2.5.0-SNAPSHOT - ../bom - - - hono-caches-parent - pom - - Hono Caches - Cache implementations used for Hono's client device connection (TODO: improve) - - - cache-common - cache-infinispan - cache-redis - - - - - org.eclipse.hono - hono-legal - - - - - org.mockito - mockito-core - test - - - org.junit.jupiter - junit-jupiter-engine - test - - - org.junit.jupiter - junit-jupiter-params - test - - - io.vertx - vertx-junit5 - test - - - com.google.truth - truth - test - - - org.eclipse.hono - core-test-utils - test - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - org.apache.maven.plugins - maven-dependency-plugin - - - org.jboss.jandex - jandex-maven-plugin - - - org.jacoco - jacoco-maven-plugin - - - - diff --git a/client-device-connection-infinispan/pom.xml b/client-device-connection-infinispan/pom.xml index 8af198fd9f..3abe259fe5 100644 --- a/client-device-connection-infinispan/pom.xml +++ b/client-device-connection-infinispan/pom.xml @@ -20,6 +20,7 @@ 2.5.0-SNAPSHOT ../bom + client-device-connection-infinispan Hotrod Device Connection client @@ -28,12 +29,9 @@ org.eclipse.hono - hono-legal - - - org.slf4j - slf4j-api + client-device-connection + org.infinispan infinispan-client-hotrod @@ -52,23 +50,8 @@ org.infinispan infinispan-core - - org.eclipse.hono - hono-client-common - - - io.vertx - vertx-web - - - com.google.guava - guava - - - redis.clients - jedis - 4.3.1 - + + io.quarkus quarkus-core @@ -105,6 +88,35 @@ + + + org.junit.jupiter diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/AdapterInstanceStatusProvider.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/AdapterInstanceStatusProvider.java deleted file mode 100644 index 2c98c8a2c0..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/AdapterInstanceStatusProvider.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2021, 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import java.util.Collection; -import java.util.Set; - -import org.eclipse.hono.util.AdapterInstanceStatus; - -import io.vertx.core.Future; - -/** - * Provides the status of an adapter instance. - */ -public interface AdapterInstanceStatusProvider { - - /** - * Gets the status of the adapter identified by the given identifier. - * - * @param adapterInstanceId The identifier of the adapter instance. - * @return The status of the adapter instance. - * @throws NullPointerException if adapterInstanceId is {@code null}. - */ - AdapterInstanceStatus getStatus(String adapterInstanceId); - - /** - * Gets the identifiers of the adapter instances from the given collection - * that have the {@link AdapterInstanceStatus#DEAD} status. - *

- * Compared to {@link #getStatus(String)}, extra measures may be taken here - * to resolve the status of adapter instances otherwise classified as - * {@link AdapterInstanceStatus#SUSPECTED_DEAD} before completing the result future. - * - * @param adapterInstanceIds The identifiers of the adapter instances. - * @return A succeeded future containing the identifiers of the dead adapter instances or a failed future - * indicating the reason why the operation failed. - * @throws NullPointerException if adapterInstanceIds is {@code null}. - */ - Future> getDeadAdapterInstances(Collection adapterInstanceIds); -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/BasicCache.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/BasicCache.java index ae4455aa2a..c027f729fe 100644 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/BasicCache.java +++ b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/BasicCache.java @@ -24,6 +24,7 @@ import java.util.function.Function; import org.eclipse.hono.client.ServerErrorException; +import org.eclipse.hono.deviceconnection.common.Cache; import org.eclipse.hono.util.Futures; import org.eclipse.hono.util.Lifecycle; import org.infinispan.commons.api.BasicCacheContainer; diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/Cache.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/Cache.java deleted file mode 100644 index eec68f8f7c..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/Cache.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import io.vertx.core.Future; -import io.vertx.core.json.JsonObject; - -/** - * A simple {@code Map} like interface to a data grid cache. - * - * @param The type of keys used for looking up data. - * @param The type of values stored in grid. - */ -public interface Cache { - - /** - * Checks if the cache is connected to the data grid. - *

- * If a cache is found to be not connected here, this method may trigger a connection (re)establishment. - * - * @return A future that is completed with information about a successful check's result. - * Otherwise, the future will be failed with a - * {@link org.eclipse.hono.client.ServerErrorException}. - */ - Future checkForCacheAvailability(); - - /** - * Puts a value to the cache. - * - * @param key The key. - * @param value The value. - * @return A succeeded future if the value has been stored successfully. - * A failed future if the value could not be stored in the cache. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future put(K key, V value); - - /** - * Puts a value to the cache. - * - * @param key The key. - * @param value The value. - * @param lifespan The lifespan of the entry. A negative value is interpreted as an unlimited lifespan. - * @param lifespanUnit The time unit for the lifespan. - * @return A succeeded future if the value has been stored successfully. - * A failed future if the value could not be stored in the cache. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future put(K key, V value, long lifespan, TimeUnit lifespanUnit); - - /** - * Puts all values of the given map to the cache. - * - * @param data The map with the entries to add. - * @return A succeeded future if the operation succeeded. - * A failed future if there was an error storing the entries in the cache. - * @throws NullPointerException if data is {@code null}. - */ - Future putAll(Map data); - - /** - * Puts all values of the given map to the cache. - * - * @param data The map with the entries to add. - * @param lifespan The lifespan of the entries. A negative value is interpreted as an unlimited lifespan. - * @param lifespanUnit The time unit for the lifespan. - * @return A succeeded future if the operation succeeded. - * A failed future if there was an error storing the entries in the cache. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future putAll(Map data, long lifespan, TimeUnit lifespanUnit); - - /** - * Gets a value from the cache. - * - * @param key The key. - * @return A succeeded future containing the value or {@code null} if the - * cache didn't contain the key yet. - * A failed future if the value could not be read from the cache. - * @throws NullPointerException if key is {@code null}. - */ - Future get(K key); - - /** - * Removes a key/value mapping from the cache. - * - * @param key The key. - * @param value The value. - * @return A succeeded future containing {@code true} if the key was - * mapped to the value, {@code false} otherwise. - * A failed future if the value could not be removed from the cache. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future remove(K key, V value); - - /** - * Gets the values for the specified keys from the cache. - * - * @param keys The keys. - * @return A succeeded future containing a map with key/value pairs. - * @throws NullPointerException if keys is {@code null}. - */ - Future> getAll(Set keys); -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfo.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfo.java deleted file mode 100644 index 519b29eacb..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfo.java +++ /dev/null @@ -1,693 +0,0 @@ -/** - * Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import java.net.HttpURLConnection; -import java.time.Duration; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.eclipse.hono.client.ClientErrorException; -import org.eclipse.hono.client.ServerErrorException; -import org.eclipse.hono.client.util.ServiceClient; -import org.eclipse.hono.tracing.TracingHelper; -import org.eclipse.hono.util.AdapterInstanceStatus; -import org.eclipse.hono.util.DeviceConnectionConstants; -import org.eclipse.hono.util.Lifecycle; -import org.eclipse.hono.util.MessageHelper; -import org.eclipse.hono.util.RequestResponseApiConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.opentracing.Span; -import io.opentracing.Tracer; -import io.vertx.core.CompositeFuture; -import io.vertx.core.Future; -import io.vertx.core.Promise; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.ext.healthchecks.HealthCheckHandler; -import io.vertx.ext.healthchecks.Status; - - -/** - * A client for accessing device connection information in a data grid. - */ -public final class CacheBasedDeviceConnectionInfo implements DeviceConnectionInfo, ServiceClient, Lifecycle { - - /** - * Lifespan for last-known-gateway cache entries. - */ - static final Duration LAST_KNOWN_GATEWAY_CACHE_ENTRY_LIFESPAN = Duration.ofDays(28); - - /** - * For viaGateways parameter value lower or equal to this value, the {@link #getCommandHandlingAdapterInstances(String, String, Set, Span)} - * method will use an optimized approach, potentially saving additional cache requests. - */ - static final int VIA_GATEWAYS_OPTIMIZATION_THRESHOLD = 3; - - private static final Logger LOG = LoggerFactory.getLogger(CacheBasedDeviceConnectionInfo.class); - - /** - * Key prefix for cache entries having gateway id values, concerning lastKnownGatewayForDevice - * operations. - */ - private static final String KEY_PREFIX_GATEWAY_ENTRIES_VALUE = "gw"; - /** - * Key prefix for cache entries having protocol adapter instance id values, concerning - * commandHandlingAdapterInstance operations. - */ - private static final String KEY_PREFIX_ADAPTER_INSTANCE_VALUES = "ai"; - private static final String KEY_SEPARATOR = "@@"; - - final Cache cache; - final Tracer tracer; - final AdapterInstanceStatusProvider adapterInstanceStatusProvider; - - private DeviceToAdapterMappingErrorListener deviceToAdapterMappingErrorListener; - - /** - * Creates a client for accessing device connection information. - * - * @param cache The remote cache that contains the data. - * @param tracer The tracer instance. - * @throws NullPointerException if cache or tracer is {@code null}. - */ - public CacheBasedDeviceConnectionInfo(final Cache cache, final Tracer tracer) { - this(cache, tracer, null); - } - - /** - * Creates a client for accessing device connection information. - * - * @param cache The remote cache that contains the data. - * @param tracer The tracer instance. - * @param adapterInstanceStatusProvider The provider of the adapter instance status (may be {@code null}). - * @throws NullPointerException if cache or tracer is {@code null}. - */ - public CacheBasedDeviceConnectionInfo(final Cache cache, final Tracer tracer, - final AdapterInstanceStatusProvider adapterInstanceStatusProvider) { - this.cache = Objects.requireNonNull(cache); - this.tracer = Objects.requireNonNull(tracer); - this.adapterInstanceStatusProvider = Optional.ofNullable(adapterInstanceStatusProvider) - .orElseGet(UnknownStatusProvider::new); - } - - /** - * {@inheritDoc} - * - * If this method is invoked from a vert.x Context, then the returned future will be completed on that context. - */ - @Override - public Future setLastKnownGatewayForDevice( - final String tenantId, - final String deviceId, - final String gatewayId, - final Span span) { - - Objects.requireNonNull(tenantId); - Objects.requireNonNull(deviceId); - Objects.requireNonNull(gatewayId); - Objects.requireNonNull(span); - - final long lifespanMillis = LAST_KNOWN_GATEWAY_CACHE_ENTRY_LIFESPAN.toMillis(); - return cache.put(getGatewayEntryKey(tenantId, deviceId), gatewayId, lifespanMillis, TimeUnit.MILLISECONDS) - .onSuccess(ok -> LOG.debug("set last known gateway [tenant: {}, device-id: {}, gateway: {}]", - tenantId, deviceId, gatewayId)) - .otherwise(t -> { - LOG.debug("failed to set last known gateway [tenant: {}, device-id: {}, gateway: {}]", - tenantId, deviceId, gatewayId, t); - TracingHelper.logError(span, "failed to set last known gateway", t); - throw new ServerErrorException(tenantId, HttpURLConnection.HTTP_INTERNAL_ERROR, t); - }); - } - - @Override - public Future setLastKnownGatewayForDevice( - final String tenantId, - final Map deviceIdToGatewayIdMap, - final Span span) { - - Objects.requireNonNull(tenantId); - Objects.requireNonNull(deviceIdToGatewayIdMap); - Objects.requireNonNull(span); - - if (deviceIdToGatewayIdMap.isEmpty()) { - return Future.succeededFuture(); - } - - final long lifespanMillis = LAST_KNOWN_GATEWAY_CACHE_ENTRY_LIFESPAN.toMillis(); - final Map mapToBePut = deviceIdToGatewayIdMap.entrySet().stream() - .collect(Collectors.toMap(entry -> getGatewayEntryKey(tenantId, entry.getKey()), Map.Entry::getValue)); - return cache.putAll(mapToBePut, lifespanMillis, TimeUnit.MILLISECONDS) - .onSuccess(ok -> LOG.debug("set {} last known gateway entries [tenant: {}]", - deviceIdToGatewayIdMap.size(), tenantId)) - .otherwise(t -> { - LOG.debug("failed to set {} last known gateway entries [tenant: {}]", - deviceIdToGatewayIdMap.size(), tenantId, t); - TracingHelper.logError(span, "failed to set last known gateway entries", t); - throw new ServerErrorException(tenantId, HttpURLConnection.HTTP_INTERNAL_ERROR, t); - }); - } - - @Override - public Future 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)) - .otherwise(t -> { - LOG.debug("failed to find last known gateway for device [tenant: {}, device-id: {}]", - tenantId, deviceId, t); - TracingHelper.logError(span, "failed to find last known gateway for device", t); - throw new ServerErrorException(tenantId, 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)); - } - }); - } - - @Override - public Future setCommandHandlingAdapterInstance( - final String tenantId, - final String deviceId, - final String adapterInstanceId, - final Duration lifespan, - final Span span) { - - Objects.requireNonNull(tenantId); - Objects.requireNonNull(deviceId); - Objects.requireNonNull(adapterInstanceId); - Objects.requireNonNull(span); - - // sanity check, preventing an ArithmeticException in lifespan.toMillis() - final long lifespanMillis = lifespan == null || lifespan.isNegative() - || lifespan.getSeconds() > (Long.MAX_VALUE / 1000L) ? -1 : lifespan.toMillis(); - return cache.put(getAdapterInstanceEntryKey(tenantId, deviceId), adapterInstanceId, lifespanMillis, TimeUnit.MILLISECONDS) - .onSuccess(ok -> LOG.debug( - "set command handling adapter instance [tenant: {}, device-id: {}, adapter-instance: {}, lifespan: {}ms]", - tenantId, deviceId, adapterInstanceId, lifespanMillis)) - .otherwise(t -> { - LOG.debug("failed to set command handling adapter instance [tenant: {}, device-id: {}, adapter-instance: {}, lifespan: {}ms]", - tenantId, deviceId, adapterInstanceId, lifespanMillis, t); - TracingHelper.logError(span, "failed to set command handling adapter instance cache entry", t); - throw new ServerErrorException(tenantId, HttpURLConnection.HTTP_INTERNAL_ERROR, t); - }); - } - - @Override - public Future removeCommandHandlingAdapterInstance( - final String tenantId, - final String deviceId, - final String adapterInstanceId, - final Span span) { - - Objects.requireNonNull(tenantId); - Objects.requireNonNull(deviceId); - Objects.requireNonNull(adapterInstanceId); - Objects.requireNonNull(span); - - return cache - .remove(getAdapterInstanceEntryKey(tenantId, deviceId), adapterInstanceId) - .otherwise(t -> { - LOG.debug("failed to remove the cache entry for the command handling adapter instance [tenant: {}, device-id: {}, adapter-instance: {}]", - tenantId, deviceId, adapterInstanceId, t); - TracingHelper.logError(span, "failed to remove cache entry for the command handling adapter instance", t); - throw new ServerErrorException(tenantId, HttpURLConnection.HTTP_INTERNAL_ERROR, t); - }) - .compose(removed -> { - if (!removed) { - LOG.debug("command handling adapter instance was not removed, key not mapped or value didn't match [tenant: {}, device-id: {}, adapter-instance: {}]", - tenantId, deviceId, adapterInstanceId); - return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_PRECON_FAILED)); - } else { - LOG.debug("removed command handling adapter instance [tenant: {}, device-id: {}, adapter-instance: {}]", - tenantId, deviceId, adapterInstanceId); - return Future.succeededFuture(); - } - }); - - } - - @Override - public Future getCommandHandlingAdapterInstances( - final String tenantId, - final String deviceId, - final Set viaGateways, - final Span span) { - - Objects.requireNonNull(tenantId); - Objects.requireNonNull(deviceId); - Objects.requireNonNull(viaGateways); - Objects.requireNonNull(span); - - final Future resultFuture; - if (viaGateways.isEmpty()) { - // get the command handling adapter instance for the device (no gateway involved) - resultFuture = cache.get(getAdapterInstanceEntryKey(tenantId, deviceId)) - .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t, span)) - .compose(adapterInstanceId -> checkAdapterInstanceId(adapterInstanceId, tenantId, deviceId, span)) - .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 { - // number of viaGateways is more than threshold value - reduce cache accesses by not checking *all* viaGateways, - // instead trying the last known gateway first - resultFuture = getInstancesGettingLastKnownGatewayFirst(tenantId, deviceId, viaGateways, span); - } - return resultFuture; - } - - @Override - public void setDeviceToAdapterMappingErrorListener( - final DeviceToAdapterMappingErrorListener obsoleteMappingListener) { - this.deviceToAdapterMappingErrorListener = obsoleteMappingListener; - } - - private Future getInstancesQueryingAllGatewaysFirst( - final String tenantId, - final String deviceId, - final Set viaGateways, - final Span span) { - - LOG.debug("using optimized query, retrieving {} via-gateways in one go", viaGateways.size()); - // get the command handling adapter instances for the device and *all* via-gateways in one call first - // (this saves the extra lastKnownGateway check if only one adapter instance is returned) - return cache.getAll(getAdapterInstanceEntryKeys(tenantId, deviceId, viaGateways)) - .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t, span)) - .compose(getAllMap -> checkAdapterInstanceIds(tenantId, convertAdapterInstanceEntryKeys(getAllMap), span)) - .compose(deviceToInstanceMap -> { - final Future resultFuture; - if (deviceToInstanceMap.isEmpty()) { - LOG.debug("no command handling adapter instances found [tenant: {}, device-id: {}]", - tenantId, deviceId); - span.log("no command handling adapter instances found for device or given via-gateways (" - + String.join(", ", viaGateways) + ")"); - resultFuture = Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND)); - } else if (deviceToInstanceMap.containsKey(deviceId)) { - // there is a adapter instance set for the device itself - that gets precedence - resultFuture = getAdapterInstanceFoundForDeviceItselfResult(tenantId, deviceId, - deviceToInstanceMap.get(deviceId), span); - } else if (deviceToInstanceMap.size() > 1) { - // multiple gateways found - check last known gateway - resultFuture = cache.get(getGatewayEntryKey(tenantId, deviceId)) - .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t, span)) - .compose(lastKnownGateway -> { - if (lastKnownGateway == null) { - // no last known gateway found - just return all found mapping entries - LOG.debug("returning {} command handling adapter instances for device gateways (no last known gateway found) [tenant: {}, device-id: {}]", - deviceToInstanceMap.size(), tenantId, deviceId); - span.log("no last known gateway found, returning all matching adapter instances"); - return Future.succeededFuture(getAdapterInstancesResultJson(deviceToInstanceMap)); - } else if (!viaGateways.contains(lastKnownGateway)) { - // found gateway is not valid anymore - just return all found mapping entries - LOG.debug("returning {} command handling adapter instances for device gateways (last known gateway not valid anymore) [tenant: {}, device-id: {}, lastKnownGateway: {}]", - deviceToInstanceMap.size(), tenantId, deviceId, lastKnownGateway); - span.log(String.format( - "last known gateway '%s' is not valid anymore, returning all matching adapter instances", - lastKnownGateway)); - return Future.succeededFuture(getAdapterInstancesResultJson(deviceToInstanceMap)); - } else if (!deviceToInstanceMap.containsKey(lastKnownGateway)) { - // found gateway has no command handling instance assigned - just return all found mapping entries - LOG.debug("returning {} command handling adapter instances for device gateways (last known gateway not in that list) [tenant: {}, device-id: {}, lastKnownGateway: {}]", - deviceToInstanceMap.size(), tenantId, deviceId, lastKnownGateway); - span.log(String.format( - "last known gateway '%s' has no adapter instance assigned, returning all matching adapter instances", - lastKnownGateway)); - return Future.succeededFuture(getAdapterInstancesResultJson(deviceToInstanceMap)); - } else { - LOG.debug("returning command handling adapter instance '{}' for last known gateway [tenant: {}, device-id: {}, lastKnownGateway: {}]", - deviceToInstanceMap.get(lastKnownGateway), tenantId, deviceId, lastKnownGateway); - span.log("returning adapter instance for last known gateway '" + lastKnownGateway + "'"); - setTagsForSingleResultWithGateway(span, deviceToInstanceMap.get(lastKnownGateway), lastKnownGateway); - return Future.succeededFuture(getAdapterInstancesResultJson(lastKnownGateway, - deviceToInstanceMap.get(lastKnownGateway))); - } - }); - } else { - // one command handling instance found - final Map.Entry foundEntry = deviceToInstanceMap.entrySet().iterator().next(); - LOG.debug("returning command handling adapter instance '{}' associated with gateway {} [tenant: {}, device-id: {}]", - foundEntry.getValue(), foundEntry.getKey(), tenantId, deviceId); - span.log("returning adapter instance associated with gateway '" + foundEntry.getKey() + "'"); - setTagsForSingleResultWithGateway(span, foundEntry.getValue(), foundEntry.getKey()); - resultFuture = Future.succeededFuture(getAdapterInstancesResultJson(foundEntry.getKey(), - foundEntry.getValue())); - } - return resultFuture; - }); - } - - private void setTagsForSingleResultWithGateway(final Span span, final String adapterInstanceId, final String gatewayId) { - setTagsForSingleResult(span, adapterInstanceId); - span.setTag(MessageHelper.APP_PROPERTY_GATEWAY_ID, gatewayId); - } - - private void setTagsForSingleResult(final Span span, final String adapterInstanceId) { - TracingHelper.TAG_ADAPTER_INSTANCE_ID.set(span, adapterInstanceId); - } - - private Future getInstancesGettingLastKnownGatewayFirst( - final String tenantId, - final String deviceId, - final Set viaGateways, - final Span span) { - - return cache.get(getGatewayEntryKey(tenantId, deviceId)) - .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t, span)) - .compose(lastKnownGateway -> { - if (lastKnownGateway == null) { - LOG.trace("no last known gateway found [tenant: {}, device-id: {}]", tenantId, deviceId); - span.log("no last known gateway found"); - } else if (!viaGateways.contains(lastKnownGateway)) { - LOG.trace("found gateway is not valid for the device anymore [tenant: {}, device-id: {}]", tenantId, deviceId); - span.log("found gateway '" + lastKnownGateway + "' is not valid anymore"); - } - if (lastKnownGateway != null && viaGateways.contains(lastKnownGateway)) { - // fetch command handling instances for lastKnownGateway and device - return cache.getAll(getAdapterInstanceEntryKeys(tenantId, deviceId, lastKnownGateway)) - .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t, span)) - .compose(getAllMap -> checkAdapterInstanceIds(tenantId, convertAdapterInstanceEntryKeys(getAllMap), span)) - .compose(deviceToInstanceMap -> { - if (deviceToInstanceMap.isEmpty()) { - // no adapter instances found for last-known-gateway and device - check all via gateways - span.log(String.format( - "last known gateway '%s' has no adapter instance assigned, returning all matching adapter instances", - lastKnownGateway)); - return getAdapterInstancesWithoutLastKnownGatewayCheck(tenantId, deviceId, viaGateways, span); - } else if (deviceToInstanceMap.containsKey(deviceId)) { - // there is a adapter instance set for the device itself - that gets precedence - return getAdapterInstanceFoundForDeviceItselfResult(tenantId, deviceId, deviceToInstanceMap.get(deviceId), span); - } else { - // adapter instance found for last known gateway - LOG.debug("returning command handling adapter instance '{}' for last known gateway [tenant: {}, device-id: {}, lastKnownGateway: {}]", - deviceToInstanceMap.get(lastKnownGateway), tenantId, deviceId, lastKnownGateway); - span.log("returning adapter instance for last known gateway '" + lastKnownGateway + "'"); - setTagsForSingleResultWithGateway(span, deviceToInstanceMap.get(lastKnownGateway), lastKnownGateway); - return Future.succeededFuture(getAdapterInstancesResultJson(deviceToInstanceMap)); - } - }); - } else { - // last-known-gateway not found or invalid - look for all adapter instances for device and viaGateways - return getAdapterInstancesWithoutLastKnownGatewayCheck(tenantId, deviceId, viaGateways, span); - } - }); - } - - private Future getAdapterInstancesWithoutLastKnownGatewayCheck( - final String tenantId, - final String deviceId, - final Set viaGateways, - final Span span) { - - return cache.getAll(getAdapterInstanceEntryKeys(tenantId, deviceId, viaGateways)) - .recover(t -> failedToGetEntriesWhenGettingInstances(tenantId, deviceId, t, span)) - .compose(getAllMap -> checkAdapterInstanceIds(tenantId, convertAdapterInstanceEntryKeys(getAllMap), span)) - .compose(deviceToInstanceMap -> { - final Future resultFuture; - if (deviceToInstanceMap.isEmpty()) { - LOG.debug("no command handling adapter instances found [tenant: {}, device-id: {}]", - tenantId, deviceId); - span.log("no command handling adapter instances found for device or given via-gateways (" - + String.join(", ", viaGateways) + ")"); - resultFuture = Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND)); - } else if (deviceToInstanceMap.containsKey(deviceId)) { - // there is a command handling instance set for the device itself - that gets precedence - resultFuture = getAdapterInstanceFoundForDeviceItselfResult(tenantId, deviceId, deviceToInstanceMap.get(deviceId), span); - } else { - LOG.debug("returning {} command handling adapter instance(s) (no last known gateway found) [tenant: {}, device-id: {}]", - deviceToInstanceMap.size(), tenantId, deviceId); - resultFuture = Future.succeededFuture(getAdapterInstancesResultJson(deviceToInstanceMap)); - } - return resultFuture; - }); - } - - private Future getAdapterInstanceFoundForDeviceItselfResult( - final String tenantId, - final String deviceId, - final String adapterInstanceId, - final Span span) { - - LOG.debug("returning command handling adapter instance '{}' for device itself [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)); - } - - private Future failedToGetEntriesWhenGettingInstances( - final String tenantId, - final String deviceId, - final Throwable t, - final Span span) { - - LOG.debug("failed to get cache entries when trying to get command handling adapter instances [tenant: {}, device-id: {}]", - tenantId, deviceId, t); - TracingHelper.logError(span, "failed to get cache entries when trying to get command handling adapter instances", t); - return Future.failedFuture(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR, t)); - } - - static String getGatewayEntryKey(final String tenantId, final String deviceId) { - return KEY_PREFIX_GATEWAY_ENTRIES_VALUE + KEY_SEPARATOR + tenantId + KEY_SEPARATOR + deviceId; - } - - static String getAdapterInstanceEntryKey(final String tenantId, final String deviceId) { - return KEY_PREFIX_ADAPTER_INSTANCE_VALUES + KEY_SEPARATOR + tenantId + KEY_SEPARATOR + deviceId; - } - - static Set getAdapterInstanceEntryKeys( - final String tenantId, - final String deviceIdA, - final String deviceIdB) { - - final Set keys = new HashSet<>(2); - keys.add(getAdapterInstanceEntryKey(tenantId, deviceIdA)); - keys.add(getAdapterInstanceEntryKey(tenantId, deviceIdB)); - return keys; - } - - /** - * Puts the entries from the given map, having {@link #getAdapterInstanceEntryKey(String, String)} keys, into - * a new map with just the extracted device ids as keys. - * - * @param map Map to get the entries from. - * @return New map with keys containing just the device id. - */ - private static Map convertAdapterInstanceEntryKeys(final Map map) { - return map.entrySet().stream() - .collect(Collectors.toMap(entry -> getDeviceIdFromAdapterInstanceEntryKey( - entry.getKey()), Map.Entry::getValue)); - } - - private static String getDeviceIdFromAdapterInstanceEntryKey(final String key) { - final int pos = key.lastIndexOf(KEY_SEPARATOR); - return key.substring(pos + KEY_SEPARATOR.length()); - } - - static Set getAdapterInstanceEntryKeys( - final String tenantId, - final String deviceIdA, - final Set additionalDeviceIds) { - - final Set keys = new HashSet<>(additionalDeviceIds.size() + 1); - keys.add(getAdapterInstanceEntryKey(tenantId, deviceIdA)); - additionalDeviceIds.forEach(id -> keys.add(getAdapterInstanceEntryKey(tenantId, id))); - return keys; - } - - private static JsonObject getLastKnownGatewayResultJson(final String gatewayId) { - return new JsonObject().put(DeviceConnectionConstants.FIELD_GATEWAY_ID, gatewayId); - } - - private static JsonObject getAdapterInstancesResultJson(final Map deviceToAdapterInstanceMap) { - final JsonObject jsonObject = new JsonObject(); - final JsonArray adapterInstancesArray = new JsonArray(new ArrayList<>(deviceToAdapterInstanceMap.size())); - for (final Map.Entry resultEntry : deviceToAdapterInstanceMap.entrySet()) { - final JsonObject entryJson = new JsonObject(); - entryJson.put(RequestResponseApiConstants.FIELD_PAYLOAD_DEVICE_ID, resultEntry.getKey()); - entryJson.put(DeviceConnectionConstants.FIELD_ADAPTER_INSTANCE_ID, resultEntry.getValue()); - adapterInstancesArray.add(entryJson); - } - jsonObject.put(DeviceConnectionConstants.FIELD_ADAPTER_INSTANCES, adapterInstancesArray); - return jsonObject; - } - - private static JsonObject getAdapterInstancesResultJson(final String deviceId, final String adapterInstanceId) { - return getAdapterInstancesResultJson(Map.of(deviceId, adapterInstanceId)); - } - - private Future> checkAdapterInstanceIds(final String tenantId, - final Map deviceToInstanceIdMap, final Span span) { - - @SuppressWarnings("rawtypes") - final List mappingFutures = new ArrayList<>(); - final Map deviceToInstanceIdMapResult = new HashMap<>(); - deviceToInstanceIdMap.entrySet().forEach(entry -> { - final Future mappingFuture = checkAdapterInstanceId(entry.getValue(), tenantId, entry.getKey(), span) - .map(adapterId -> { - if (adapterId != null) { - deviceToInstanceIdMapResult.put(entry.getKey(), entry.getValue()); - } - return adapterId; - }); - mappingFutures.add(mappingFuture); - }); - - return CompositeFuture.join(mappingFutures).map(deviceToInstanceIdMapResult); - } - - private Future checkAdapterInstanceId( - final String adapterInstanceId, - final String tenantId, - final String deviceId, - final Span span) { - - if (adapterInstanceId != null) { - final AdapterInstanceStatus status = adapterInstanceStatusProvider.getStatus(adapterInstanceId); - if (status == AdapterInstanceStatus.DEAD) { - LOG.debug( - "ignoring found adapter instance id, belongs to already terminated container [tenant: {}, device-id: {}, adapter-instance-id: {}]", - tenantId, deviceId, adapterInstanceId); - span.log("ignoring found adapter instance id [" + adapterInstanceId - + "], belongs to already terminated container"); - final Future listenerResult; - if (deviceToAdapterMappingErrorListener != null) { - listenerResult = deviceToAdapterMappingErrorListener.onObsoleteEntryFound(tenantId, deviceId, - adapterInstanceId, - span); - } else { - listenerResult = Future.succeededFuture(); - } - return listenerResult - .onSuccess(v -> { - if (deviceToAdapterMappingErrorListener != null) { - LOG.debug( - "called listener for obsolete adapter instance id '{}' [tenant: {}, device-id: {}]", - adapterInstanceId, tenantId, deviceId); - } - }) - .onFailure(thr -> { - LOG.debug( - "error calling listener for obsolete adapter instance id '{}' [tenant: {}, device-id: {}]", - adapterInstanceId, tenantId, deviceId, thr); - }) - .compose(s -> { - return cache.remove(getAdapterInstanceEntryKey(tenantId, deviceId), adapterInstanceId) - .onSuccess(removed -> { - if (removed) { - LOG.debug( - "removed entry with obsolete adapter instance id '{}' [tenant: {}, device-id: {}]", - adapterInstanceId, tenantId, deviceId); - } - }) - .onFailure(thr -> { - LOG.debug( - "error removing entry with obsolete adapter instance id '{}' [tenant: {}, device-id: {}]", - adapterInstanceId, tenantId, deviceId, thr); - }); - }) - .recover(thr -> { - // errors treated as not found adapter instance - return Future.succeededFuture(); - }) - .mapEmpty(); - } else if (status == AdapterInstanceStatus.SUSPECTED_DEAD) { - LOG.debug( - "ignoring found adapter instance id, belongs to container with state 'SUSPECTED_DEAD' [tenant: {}, device-id: {}, adapter-instance-id: {}]", - tenantId, deviceId, adapterInstanceId); - span.log("ignoring found adapter instance id [" + adapterInstanceId + - "], belongs to container with state 'SUSPECTED_DEAD'"); - return Future.succeededFuture(); - } - } - return Future.succeededFuture(adapterInstanceId); - } - - /** - * {@inheritDoc} - *

- * Registers a check which verifies if the underlying cache is available. - * The check times out (and fails) after 1000ms. - */ - @Override - public void registerReadinessChecks(final HealthCheckHandler readinessHandler) { - readinessHandler.register("remote-cache-connection", 1000, this::checkForCacheAvailability); - } - - private void checkForCacheAvailability(final Promise status) { - - cache.checkForCacheAvailability() - .map(Status::OK) - .otherwise(t -> Status.KO()) - .onComplete(ar -> status.tryComplete(ar.result())); - } - - @Override - public void registerLivenessChecks(final HealthCheckHandler livenessHandler) { - // nothing to register - } - - @Override - public Future start() { - if (cache instanceof Lifecycle) { - return ((Lifecycle) cache).start(); - } else { - return Future.succeededFuture(); - } - } - - @Override - public Future stop() { - if (cache instanceof Lifecycle) { - return ((Lifecycle) cache).stop(); - } else { - return Future.succeededFuture(); - } - } -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheConfig.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheConfig.java deleted file mode 100644 index ec4109424c..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheConfig.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - *******************************************************************************/ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import com.google.common.base.MoreObjects; - -/** - * Common cache configuration options. - */ -public class CommonCacheConfig { - - /** - * The default name of the (remote) cache in the data grid that is used for - * storing device connection information. - */ - public static final String DEFAULT_CACHE_NAME = "device-connection"; - - private String cacheName = DEFAULT_CACHE_NAME; - - private String checkKey = "KEY_CONNECTION_CHECK"; - private String checkValue = "VALUE_CONNECTION_CHECK"; - - /** - * Creates properties for default values. - */ - public CommonCacheConfig() { - super(); - } - - /** - * Creates properties for existing options. - * - * @param options The options to copy. - */ - public CommonCacheConfig(final CommonCacheOptions options) { - super(); - this.cacheName = options.cacheName(); - this.checkKey = options.checkKey(); - this.checkValue = options.checkValue(); - } - - public void setCacheName(final String cacheName) { - this.cacheName = cacheName; - } - - public String getCacheName() { - return cacheName; - } - - public void setCheckKey(final String checkKey) { - this.checkKey = checkKey; - } - - public String getCheckKey() { - return checkKey; - } - - public void setCheckValue(final String checkValue) { - this.checkValue = checkValue; - } - - public String getCheckValue() { - return checkValue; - } - - @Override - public String toString() { - return MoreObjects - .toStringHelper(this) - .add("cacheName", this.cacheName) - .add("checkKey", this.checkKey) - .add("checkValue", this.checkValue) - .toString(); - } -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheOptions.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheOptions.java deleted file mode 100644 index 8118a198f5..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/CommonCacheOptions.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2021 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import org.eclipse.hono.util.CommandRouterConstants; - -import io.smallrye.config.ConfigMapping; -import io.smallrye.config.ConfigMapping.NamingStrategy; -import io.smallrye.config.WithDefault; - -/** - * Common options for configuring a cache. - * - */ -@ConfigMapping(prefix = "hono.cache.common", namingStrategy = NamingStrategy.VERBATIM) -public interface CommonCacheOptions { - - /** - * Gets the name of the cache. - * - * @return The name. - */ - @WithDefault(CommandRouterConstants.DEFAULT_CACHE_NAME) - String cacheName(); - - /** - * Gets the key to use for checking the cache's availability. - * - * @return The key. - */ - @WithDefault("KEY_CONNECTION_CHECK") - String checkKey(); - - /** - * The value to use for checking the cache's availability. - * - * @return The value. - */ - @WithDefault("VALUE_CONNECTION_CHECK") - String checkValue(); -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceConnectionInfo.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceConnectionInfo.java deleted file mode 100644 index 4b7e800298..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceConnectionInfo.java +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import java.time.Duration; -import java.util.Map; -import java.util.Set; - -import io.opentracing.Span; -import io.vertx.core.Future; -import io.vertx.core.json.JsonObject; - -/** - * A repository for keeping connection information about devices. - * - */ -public interface DeviceConnectionInfo { - - /** - * Sets the gateway that last acted on behalf of a device. - *

- * If a device connects directly instead of through a gateway, the device identifier itself is to be used as value - * for the gatewayId parameter. - * - * @param tenant The tenant that the device belongs to. - * @param deviceId The device identifier. - * @param gatewayId The gateway identifier. This may be the same as the device identifier if the device is - * (currently) not connected via a gateway but directly to a protocol adapter. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! - * An implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. - *

- * The future will be succeeded if the device connection information has been updated. - * Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future setLastKnownGatewayForDevice(String tenant, String deviceId, String gatewayId, Span span); - - /** - * For a given list of device and gateway combinations, sets the gateway as the last gateway that acted on behalf - * of the device. - *

- * If a device connects directly instead of through a gateway, the device identifier itself is to be used as - * gateway value. - * - * @param tenant The tenant that the device belongs to. - * @param deviceIdToGatewayIdMap The map containing device identifiers and associated gateway identifiers. The - * gateway identifier may be the same as the device identifier if the device is - * (currently) not connected via a gateway but directly to a protocol adapter. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! - * An implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. - *

- * The future will be succeeded if the device connection information has been updated. - * Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}. - * The outcome is indeterminate if any of the entries cannot be processed by an implementation. - * In such a case, client code should assume that none of the entries have been updated. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future setLastKnownGatewayForDevice(String tenant, Map deviceIdToGatewayIdMap, Span span); - - /** - * Gets the gateway that last acted on behalf of a device. - *

- * If no last known gateway has been set for the given device yet, a failed future with status - * 404 is returned. - * - * @param tenant The tenant that the device belongs to. - * @param deviceId The device identifier. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! - * An implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. - *

- * The future will be succeeded with a JSON object containing the currently mapped gateway ID - * in the gateway-id property, if device connection information has been found for - * the given device. - * Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future getLastKnownGatewayForDevice(String tenant, String deviceId, Span span); - - /** - * Sets the protocol adapter instance that handles commands for the given device or gateway. - * - * @param tenantId The tenant id. - * @param deviceId The device id. - * @param adapterInstanceId The protocol adapter instance id. - * @param lifespan The lifespan of the mapping entry. Using a negative duration or {@code null} here is - * interpreted as an unlimited lifespan. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! - * An implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. - *

- * The future will be succeeded if the device connection information has been updated. - * Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}. - * @throws NullPointerException if any of the parameters except lifespan is {@code null}. - */ - Future setCommandHandlingAdapterInstance(String tenantId, String deviceId, String adapterInstanceId, - Duration lifespan, Span span); - - /** - * Removes the mapping information that associates the given device with the given protocol adapter instance - * that handles commands for the given device. The mapping entry is only deleted if its value - * contains the given protocol adapter instance id. - * - * @param tenantId The tenant id. - * @param deviceId The device id. - * @param adapterInstanceId The protocol adapter instance id that the entry to be removed has to contain. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! - * An implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. - *

- * The future will be succeeded if the entry was successfully removed. - * Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}. - * @throws NullPointerException if any of the parameters except context is {@code null}. - */ - Future removeCommandHandlingAdapterInstance(String tenantId, String deviceId, String adapterInstanceId, Span span); - - /** - * Gets information about the adapter instances that can handle a command for the given device. - *

- * In order to determine the adapter instances the following rules are applied (in the given order): - *

    - *
  1. If an adapter instance is associated with the given device, this adapter instance is returned as the single - * returned list entry.
  2. - *
  3. Otherwise, if there is an adapter instance registered for the last known gateway associated with the given - * device, this adapter instance is returned as the single returned list entry. The last known gateway has to be - * contained in the given list of gateways for this case.
  4. - *
  5. Otherwise, all adapter instances associated with any of the given gateway identifiers are returned.
  6. - *
- * That means that for a device communicating via a gateway, the result is reduced to a single element list - * if an adapter instance for the device itself or its last known gateway is found. The adapter instance registered - * for the device itself is given precedence in order to ensure that a gateway having subscribed to commands for - * that particular device is chosen over a gateway that has subscribed to commands for all devices of a tenant. - *

- * The resulting JSON structure looks like this, possibly containing multiple array entries: - * { - * "adapter-instances": [ - * { - * "adapter-instance-id": "adapter-1", - * "device-id": "4711" - * } - * ] - * } - * - *

- * If no adapter instances are found, the returned future is failed. - * - * @param tenantId The tenant id. - * @param deviceId The device id. - * @param viaGateways The set of gateways that may act on behalf of the given device. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! - * An implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. - *

- * If instances were found, the future will be succeeded with a JSON object containing one or more mappings - * from device id to adapter instance id. - * Otherwise the future will be failed with a {@link org.eclipse.hono.client.ServiceInvocationException}. - * @throws NullPointerException if any of the parameters is {@code null}. - */ - Future getCommandHandlingAdapterInstances(String tenantId, String deviceId, Set viaGateways, Span span); - - /** - * Sets listener to be notified when an incorrect device to adapter mapping is identified. - * - * @param deviceToAdapterMappingErrorListener The listener. - */ - void setDeviceToAdapterMappingErrorListener(DeviceToAdapterMappingErrorListener deviceToAdapterMappingErrorListener); -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceToAdapterMappingErrorListener.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceToAdapterMappingErrorListener.java deleted file mode 100644 index bdb45e069b..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/DeviceToAdapterMappingErrorListener.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import io.opentracing.Span; -import io.vertx.core.Future; - -/** - * Listener notified when an incorrect device to adapter mapping is found. - */ -public interface DeviceToAdapterMappingErrorListener { - - /** - * Called when an obsolete device to adapter mapping is found. - * - * @param tenantId The tenant identifier. - * @param deviceId The device identifier. - * @param adapterInstanceId The adapter instance identifier. - * @param span The active OpenTracing span for this operation. It is not to be closed in this method! An - * implementation should log (error) events on this span and it may set tags and use this span as the - * parent for any spans created in this method. - * @return A future indicating the outcome of the operation. The future will be succeeded if the listener is - * notified successfully. - */ - Future onObsoleteEntryFound(String tenantId, String deviceId, String adapterInstanceId, Span span); -} diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/HotrodCache.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/HotrodCache.java index 4e3b3ea9b1..754554f0c7 100644 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/HotrodCache.java +++ b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/HotrodCache.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; +import org.eclipse.hono.deviceconnection.common.CommonCacheConfig; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheContainer; import org.infinispan.client.hotrod.RemoteCacheManager; diff --git a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/UnknownStatusProvider.java b/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/UnknownStatusProvider.java deleted file mode 100644 index d52468ce44..0000000000 --- a/client-device-connection-infinispan/src/main/java/org/eclipse/hono/deviceconnection/infinispan/client/UnknownStatusProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0 - * - * SPDX-License-Identifier: EPL-2.0 - */ - - -package org.eclipse.hono.deviceconnection.infinispan.client; - -import java.util.Collection; -import java.util.Set; - -import org.eclipse.hono.util.AdapterInstanceStatus; - -import io.vertx.core.Future; - - -/** - * Status provider that always returns the {@link AdapterInstanceStatus#UNKNOWN} status. - * - */ -final class UnknownStatusProvider implements AdapterInstanceStatusProvider { - - @Override - public AdapterInstanceStatus getStatus(final String adapterInstanceId) { - return AdapterInstanceStatus.UNKNOWN; - } - - @Override - public Future> getDeadAdapterInstances( - final Collection adapterInstanceIds) { - return Future.succeededFuture(Set.of()); - } -} diff --git a/client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/QuarkusPropertyBindingTest.java b/client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/QuarkusPropertyBindingTest.java index 53fe74cf6a..9cbed5b014 100644 --- a/client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/QuarkusPropertyBindingTest.java +++ b/client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/QuarkusPropertyBindingTest.java @@ -19,6 +19,8 @@ import javax.security.sasl.Sasl; +import org.eclipse.hono.deviceconnection.common.CommonCacheConfig; +import org.eclipse.hono.deviceconnection.common.CommonCacheOptions; import org.eclipse.hono.test.ConfigMappingSupport; import org.infinispan.client.hotrod.configuration.ClusterConfiguration; import org.infinispan.client.hotrod.configuration.Configuration; diff --git a/client-device-connection-redis/pom.xml b/client-device-connection-redis/pom.xml new file mode 100644 index 0000000000..8c6be49009 --- /dev/null +++ b/client-device-connection-redis/pom.xml @@ -0,0 +1,175 @@ + + + + 4.0.0 + + org.eclipse.hono + hono-bom + 2.5.0-SNAPSHOT + ../bom + + + client-device-connection-redis + + Redis Device Connection client + A Redis based client for accessing device connection information in a Redis cluster. + + + + org.eclipse.hono + client-device-connection + + + + redis.clients + jedis + 4.3.1 + + + + + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + com.google.truth + truth + test + + + ch.qos.logback + logback-classic + test + + + org.mockito + mockito-core + test + + + io.vertx + vertx-junit5 + test + + + org.eclipse.hono + core-test-utils + test + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + org.jboss.jandex + jandex-maven-plugin + + + org.jacoco + jacoco-maven-plugin + + + + \ No newline at end of file diff --git a/caches/cache-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/RedisCache.java b/client-device-connection-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/client/RedisCache.java similarity index 97% rename from caches/cache-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/RedisCache.java rename to client-device-connection-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/client/RedisCache.java index 74809a3d0c..a7486ed1bb 100644 --- a/caches/cache-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/RedisCache.java +++ b/client-device-connection-redis/src/main/java/org/eclipse/hono/deviceconnection/redis/client/RedisCache.java @@ -11,13 +11,13 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.deviceconnection.redis; +package org.eclipse.hono.deviceconnection.redis.client; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; -import org.eclipse.hono.cache.Cache; +import org.eclipse.hono.deviceconnection.common.Cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/native-image.properties b/client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/native-image.properties new file mode 100644 index 0000000000..2879f33e15 --- /dev/null +++ b/client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/native-image.properties @@ -0,0 +1,15 @@ +# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0 +# +# SPDX-License-Identifier: EPL-2.0 +Args = -H:ResourceConfigurationResources=${.}/resources-config.json \ + -H:AdditionalSecurityProviders=org.wildfly.security.sasl.digest.WildFlyElytronSaslDigestProvider \ + -H:AdditionalSecurityProviders=org.wildfly.security.sasl.external.WildFlyElytronSaslExternalProvider \ + -H:AdditionalSecurityProviders=org.wildfly.security.sasl.plain.WildFlyElytronSaslPlainProvider \ + -H:AdditionalSecurityProviders=org.wildfly.security.sasl.scram.WildFlyElytronSaslScramProvider diff --git a/client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/resources-config.json b/client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/resources-config.json new file mode 100644 index 0000000000..ef9f0db4ab --- /dev/null +++ b/client-device-connection-redis/src/main/resources/META-INF/native-image/org.eclipse.hono/client-device-connection-infinispan/resources-config.json @@ -0,0 +1,37 @@ +{ + "resources": { + "includes": [ + { + "pattern": ".*\\.properties$" + }, + { + "pattern": ".*\\.proto$" + }, + { + "pattern": "default-configs\\/.*$" + }, + { + "pattern": "META-INF\\/services\\/java\\.security\\.Provider" + }, + { + "pattern": "META-INF\\/services\\/javax\\.security\\.sasl\\.SaslClientFactory" + }, + { + "pattern": "META-INF\\/services\\/org\\.infinispan\\.configuration\\.parsing\\.ConfigurationParser" + }, + { + "pattern": "META-INF\\/services\\/org\\.infinispan\\.factories\\.impl\\..*$" + }, + { + "pattern": "META-INF\\/services\\/org\\.infinispan\\.protostream\\..*$" + } + ], + "excludes": [ + { + "pattern": "META-INF\\/maven\\/.*$" + },{ + "pattern": "META-INF\\/native-image\\/.*$" + } + ] + } +} diff --git a/client-device-connection-redis/src/main/resources/application.properties b/client-device-connection-redis/src/main/resources/application.properties new file mode 100644 index 0000000000..7fce6fc1be --- /dev/null +++ b/client-device-connection-redis/src/main/resources/application.properties @@ -0,0 +1,11 @@ +# Create a Jandex index of beans contained in Google Guava +# This prevents warnings when building downstream modules that use for example +# the com.google.common.base.MoreObjects$ToStringHelper method. +quarkus.index-dependency.guava.group-id=com.google.guava +quarkus.index-dependency.guava.artifact-id=guava +# Create a Jandex index of beans contained in the Infinispan Hotrod client +# This is necessary in order to be able to configure the Hotrod client by +# means of the org.eclipse.hono.deviceconnection.infinispan.client.InfinispanRemoteConfigurationOptions +# class. +quarkus.index-dependency.infinispan.group-id=org.infinispan +quarkus.index-dependency.infinispan.artifact-id=infinispan-client-hotrod diff --git a/client-device-connection-redis/src/test/resources/common-cache-options.yaml b/client-device-connection-redis/src/test/resources/common-cache-options.yaml new file mode 100644 index 0000000000..edacdbfc7d --- /dev/null +++ b/client-device-connection-redis/src/test/resources/common-cache-options.yaml @@ -0,0 +1,6 @@ +hono: + cache: + common: + cacheName: "the-cache" + checkKey: "the-key" + checkValue: "the-value" diff --git a/client-device-connection-redis/src/test/resources/logback-test.xml b/client-device-connection-redis/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..0da04c2e0b --- /dev/null +++ b/client-device-connection-redis/src/test/resources/logback-test.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + diff --git a/client-device-connection-redis/src/test/resources/remote-cache-options.yaml b/client-device-connection-redis/src/test/resources/remote-cache-options.yaml new file mode 100644 index 0000000000..19b061cf42 --- /dev/null +++ b/client-device-connection-redis/src/test/resources/remote-cache-options.yaml @@ -0,0 +1,34 @@ +hono: + cache: + infinispan: + serverList: "data-grid:11222" + authServerName: "data-grid" + authUsername: "user" + authPassword: "secret" + authRealm: "ApplicationRealm" + cluster: + siteA: "hostA1:11222; hostA2:11223" + siteB: "hostB1:11222; hostB2:11223" + connectionPool: + minIdle: 10 + maxActive: 10 + maxPendingRequests: 400 + maxWait: 500 + defaultExecutorFactory: + poolSize: 200 + saslMechanism: "DIGEST-MD5" + saslProperties: + "javax.security.sasl.qop": "auth" + socketTimeout: 5000 + connectTimeout: 5000 + keyStoreFileName: "/etc/hono/key-store.p12" + keyStoreType: "PKCS12" + keyStorePassword: "key-store-secret" + keyAlias: "infinispan" + keyStoreCertificatePassword: "cert-secret" + trustStorePath: "/etc/hono/trust-store.p12" + trustStoreFileName: "/etc/hono/trust-store-file.p12" + trustStoreType: "PKCS12" + trustStorePassword: "trust-store-secret" + useSsl: true + sslCiphers: "TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256" diff --git a/client-device-connection/pom.xml b/client-device-connection/pom.xml index ce4177a6a8..73614b6cb5 100644 --- a/client-device-connection/pom.xml +++ b/client-device-connection/pom.xml @@ -1,6 +1,6 @@ - + 4.0.0 org.eclipse.hono @@ -21,43 +20,125 @@ 2.5.0-SNAPSHOT ../bom - hono-client-device-connection + + client-device-connection - Hono Client Device Connection Cache - Common classes for Hono's Client Device Connection cache + Device Connection client + Base classes for client for accessing device connection information in a remote cache / data grid. org.eclipse.hono - hono-client-common + hono-legal + + + org.slf4j + slf4j-api org.eclipse.hono - hono-cache-common + hono-client-common - + - + + org.mockito + mockito-core + test + + + io.vertx + vertx-junit5 + test + + + org.eclipse.hono + core-test-utils + test + - + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + org.jboss.jandex + jandex-maven-plugin + + + org.jacoco + jacoco-maven-plugin + + + + \ No newline at end of file diff --git a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/AdapterInstanceStatusProvider.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/AdapterInstanceStatusProvider.java similarity index 97% rename from client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/AdapterInstanceStatusProvider.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/AdapterInstanceStatusProvider.java index 7a55f28d6e..64a18cf0f6 100644 --- a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/AdapterInstanceStatusProvider.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/AdapterInstanceStatusProvider.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ -package org.eclipse.hono.deviceconnection; +package org.eclipse.hono.deviceconnection.common; import java.util.Collection; import java.util.Set; diff --git a/caches/cache-common/src/main/java/org/eclipse/hono/cache/Cache.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/Cache.java similarity index 98% rename from caches/cache-common/src/main/java/org/eclipse/hono/cache/Cache.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/Cache.java index ff48131da7..42d28a015c 100644 --- a/caches/cache-common/src/main/java/org/eclipse/hono/cache/Cache.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/Cache.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.cache; +package org.eclipse.hono.deviceconnection.common; import java.util.Map; import java.util.Set; diff --git a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/CacheBasedDeviceConnectionInfo.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CacheBasedDeviceConnectionInfo.java similarity index 99% rename from client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/CacheBasedDeviceConnectionInfo.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CacheBasedDeviceConnectionInfo.java index 9787bb5f70..b6e65f8b41 100644 --- a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/CacheBasedDeviceConnectionInfo.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CacheBasedDeviceConnectionInfo.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.deviceconnection; +package org.eclipse.hono.deviceconnection.common; import java.net.HttpURLConnection; import java.time.Duration; @@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import org.eclipse.hono.cache.Cache; import org.eclipse.hono.client.ClientErrorException; import org.eclipse.hono.client.ServerErrorException; import org.eclipse.hono.client.util.ServiceClient; diff --git a/caches/cache-common/src/main/java/org/eclipse/hono/cache/CommonCacheConfig.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CommonCacheConfig.java similarity index 97% rename from caches/cache-common/src/main/java/org/eclipse/hono/cache/CommonCacheConfig.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CommonCacheConfig.java index 573474bb12..c969ab3c49 100644 --- a/caches/cache-common/src/main/java/org/eclipse/hono/cache/CommonCacheConfig.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CommonCacheConfig.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ -package org.eclipse.hono.cache; +package org.eclipse.hono.deviceconnection.common; import com.google.common.base.MoreObjects; diff --git a/caches/cache-common/src/main/java/org/eclipse/hono/cache/CommonCacheOptions.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CommonCacheOptions.java similarity index 96% rename from caches/cache-common/src/main/java/org/eclipse/hono/cache/CommonCacheOptions.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CommonCacheOptions.java index 1820c99a06..bbd69c036d 100644 --- a/caches/cache-common/src/main/java/org/eclipse/hono/cache/CommonCacheOptions.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/CommonCacheOptions.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.cache; +package org.eclipse.hono.deviceconnection.common; import org.eclipse.hono.util.CommandRouterConstants; diff --git a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/DeviceConnectionInfo.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/DeviceConnectionInfo.java similarity index 99% rename from client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/DeviceConnectionInfo.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/DeviceConnectionInfo.java index 2bffcf8812..f3c2d2a35c 100644 --- a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/DeviceConnectionInfo.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/DeviceConnectionInfo.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.deviceconnection; +package org.eclipse.hono.deviceconnection.common; import java.time.Duration; import java.util.Map; diff --git a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/DeviceToAdapterMappingErrorListener.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/DeviceToAdapterMappingErrorListener.java similarity index 96% rename from client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/DeviceToAdapterMappingErrorListener.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/DeviceToAdapterMappingErrorListener.java index 7a4fec04f2..0fa4d7fb95 100644 --- a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/DeviceToAdapterMappingErrorListener.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/DeviceToAdapterMappingErrorListener.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.deviceconnection; +package org.eclipse.hono.deviceconnection.common; import io.opentracing.Span; import io.vertx.core.Future; diff --git a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/UnknownStatusProvider.java b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/UnknownStatusProvider.java similarity index 95% rename from client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/UnknownStatusProvider.java rename to client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/UnknownStatusProvider.java index abe7644875..861ecfda79 100644 --- a/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/UnknownStatusProvider.java +++ b/client-device-connection/src/main/java/org/eclipse/hono/deviceconnection/common/UnknownStatusProvider.java @@ -12,7 +12,7 @@ */ -package org.eclipse.hono.deviceconnection; +package org.eclipse.hono.deviceconnection.common; import java.util.Collection; import java.util.Set; diff --git a/client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfoTest.java b/client-device-connection/src/test/java/org/eclipse/hono/deviceconnection/common/CacheBasedDeviceConnectionInfoTest.java similarity index 99% rename from client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfoTest.java rename to client-device-connection/src/test/java/org/eclipse/hono/deviceconnection/common/CacheBasedDeviceConnectionInfoTest.java index 744858a2be..28f5671c6f 100644 --- a/client-device-connection-infinispan/src/test/java/org/eclipse/hono/deviceconnection/infinispan/client/CacheBasedDeviceConnectionInfoTest.java +++ b/client-device-connection/src/test/java/org/eclipse/hono/deviceconnection/common/CacheBasedDeviceConnectionInfoTest.java @@ -11,7 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hono.deviceconnection.infinispan.client; +package org.eclipse.hono.deviceconnection.common; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -50,6 +50,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mockito; import io.opentracing.Span; import io.opentracing.Tracer; @@ -396,7 +397,7 @@ public void testGetCommandHandlingAdapterInstancesWithExpiredEntry(final VertxTe @Test public void testGetCommandHandlingAdapterInstancesWithTerminatedAdapterInstance(final VertxTestContext ctx) { - final AdapterInstanceStatusProvider statusProvider = mock(AdapterInstanceStatusProvider.class); + final AdapterInstanceStatusProvider statusProvider = Mockito.mock(AdapterInstanceStatusProvider.class); info = new CacheBasedDeviceConnectionInfo(cache, tracer, statusProvider); final Promise listenerTracker = Promise.promise(); @@ -441,7 +442,7 @@ public void testGetCommandHandlingAdapterInstancesWithTerminatedAdapterInstance( @Test public void testGetCommandHandlingAdapterInstancesWithSuspectedAdapterInstance(final VertxTestContext ctx) { - final AdapterInstanceStatusProvider statusProvider = mock(AdapterInstanceStatusProvider.class); + final AdapterInstanceStatusProvider statusProvider = Mockito.mock(AdapterInstanceStatusProvider.class); info = new CacheBasedDeviceConnectionInfo(cache, tracer, statusProvider); final String deviceId = "testDevice"; @@ -761,7 +762,7 @@ public void testGetCommandHandlingAdapterInstancesWithoutLastKnownGatewayIsGivin @MethodSource("extraUnusedViaGateways") public void testGetCommandHandlingAdapterInstancesWithTerminatedAdapterInstanceContainer(final Set extraUnusedViaGateways, final VertxTestContext ctx) { - final AdapterInstanceStatusProvider statusProvider = mock(AdapterInstanceStatusProvider.class); + final AdapterInstanceStatusProvider statusProvider = Mockito.mock(AdapterInstanceStatusProvider.class); info = new CacheBasedDeviceConnectionInfo(cache, tracer, statusProvider); final String deviceId = "testDevice"; @@ -813,7 +814,7 @@ public void testGetCommandHandlingAdapterInstancesWithTerminatedAdapterInstanceC @MethodSource("extraUnusedViaGateways") public void testGetCommandHandlingAdapterInstancesWithSuspectedAdapterInstanceContainer(final Set extraUnusedViaGateways, final VertxTestContext ctx) { - final AdapterInstanceStatusProvider statusProvider = mock(AdapterInstanceStatusProvider.class); + final AdapterInstanceStatusProvider statusProvider = Mockito.mock(AdapterInstanceStatusProvider.class); info = new CacheBasedDeviceConnectionInfo(cache, tracer, statusProvider); final String deviceId = "testDevice"; diff --git a/pom.xml b/pom.xml index d88ff4516f..439212acb6 100644 --- a/pom.xml +++ b/pom.xml @@ -225,7 +225,9 @@ bom core cli - + client-device-connection + client-device-connection-infinispan + client-device-connection-redis clients demo-certs examples @@ -235,8 +237,6 @@ site test-utils tests - client-device-connection - caches diff --git a/services/command-router/pom.xml b/services/command-router/pom.xml index 1b50625bd1..d35c53eaff 100644 --- a/services/command-router/pom.xml +++ b/services/command-router/pom.xml @@ -25,22 +25,18 @@ org.eclipse.hono hono-client-device-connection + --> org.eclipse.hono - hono-cache-infinispan + client-device-connection-infinispan org.eclipse.hono - hono-cache-redis + client-device-connection-redis diff --git a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/AdapterInstanceStatusService.java b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/AdapterInstanceStatusService.java index e1e10b3588..16eb5653df 100644 --- a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/AdapterInstanceStatusService.java +++ b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/AdapterInstanceStatusService.java @@ -13,7 +13,7 @@ package org.eclipse.hono.commandrouter; -import org.eclipse.hono.deviceconnection.AdapterInstanceStatusProvider; +import org.eclipse.hono.deviceconnection.common.AdapterInstanceStatusProvider; import org.eclipse.hono.util.Lifecycle; /** diff --git a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/CommandTargetMapper.java b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/CommandTargetMapper.java index 9bfc674e5e..482efeb4da 100644 --- a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/CommandTargetMapper.java +++ b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/CommandTargetMapper.java @@ -15,7 +15,7 @@ import org.eclipse.hono.client.registry.DeviceRegistrationClient; import org.eclipse.hono.commandrouter.impl.CommandTargetMapperImpl; -import org.eclipse.hono.deviceconnection.DeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.common.DeviceConnectionInfo; import io.opentracing.SpanContext; import io.opentracing.Tracer; diff --git a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/Application.java b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/Application.java index eb389772d3..8f5654f020 100644 --- a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/Application.java +++ b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/Application.java @@ -64,7 +64,7 @@ import org.eclipse.hono.commandrouter.impl.pubsub.PubSubBasedCommandConsumerFactoryImpl; import org.eclipse.hono.config.ServiceConfigProperties; import org.eclipse.hono.config.ServiceOptions; -import org.eclipse.hono.deviceconnection.DeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.common.DeviceConnectionInfo; import org.eclipse.hono.service.HealthCheckProvider; import org.eclipse.hono.service.NotificationSupportingServiceApplication; import org.eclipse.hono.service.amqp.AmqpEndpoint; diff --git a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/DeviceConnectionInfoProducer.java b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/DeviceConnectionInfoProducer.java index 9dbc6753eb..588f43fe16 100644 --- a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/DeviceConnectionInfoProducer.java +++ b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/app/DeviceConnectionInfoProducer.java @@ -23,18 +23,18 @@ import javax.enterprise.inject.Produces; import javax.inject.Singleton; -import org.eclipse.hono.cache.Cache; -import org.eclipse.hono.cache.CommonCacheConfig; -import org.eclipse.hono.cache.CommonCacheOptions; import org.eclipse.hono.commandrouter.AdapterInstanceStatusService; import org.eclipse.hono.commandrouter.CommandRouterServiceOptions; import org.eclipse.hono.commandrouter.impl.KubernetesBasedAdapterInstanceStatusService; import org.eclipse.hono.commandrouter.impl.UnknownStatusProvidingService; -import org.eclipse.hono.deviceconnection.CacheBasedDeviceConnectionInfo; -import org.eclipse.hono.deviceconnection.DeviceConnectionInfo; -import org.eclipse.hono.deviceconnection.infinispan.InfinispanRemoteConfigurationOptions; -import org.eclipse.hono.deviceconnection.infinispan.InfinispanRemoteConfigurationProperties; -import org.eclipse.hono.deviceconnection.redis.RedisCache; +import org.eclipse.hono.deviceconnection.common.Cache; +import org.eclipse.hono.deviceconnection.common.CacheBasedDeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.common.CommonCacheConfig; +import org.eclipse.hono.deviceconnection.common.CommonCacheOptions; +import org.eclipse.hono.deviceconnection.common.DeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.infinispan.client.InfinispanRemoteConfigurationOptions; +import org.eclipse.hono.deviceconnection.infinispan.client.InfinispanRemoteConfigurationProperties; +import org.eclipse.hono.deviceconnection.redis.client.RedisCache; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.infinispan.configuration.parsing.ConfigurationBuilderHolder; import org.infinispan.configuration.parsing.ParserRegistry; diff --git a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImpl.java b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImpl.java index 0ca0b2cdce..25651125c5 100644 --- a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImpl.java +++ b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImpl.java @@ -38,7 +38,7 @@ import org.eclipse.hono.commandrouter.CommandRouterResult; import org.eclipse.hono.commandrouter.CommandRouterService; import org.eclipse.hono.config.ServiceConfigProperties; -import org.eclipse.hono.deviceconnection.DeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.common.DeviceConnectionInfo; import org.eclipse.hono.service.HealthCheckProvider; import org.eclipse.hono.tracing.TracingHelper; import org.eclipse.hono.util.CommandConstants; diff --git a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandTargetMapperImpl.java b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandTargetMapperImpl.java index bcb669597c..c85844b3de 100644 --- a/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandTargetMapperImpl.java +++ b/services/command-router/src/main/java/org/eclipse/hono/commandrouter/impl/CommandTargetMapperImpl.java @@ -23,7 +23,7 @@ import org.eclipse.hono.client.registry.DeviceDisabledOrNotRegisteredException; import org.eclipse.hono.client.registry.DeviceRegistrationClient; import org.eclipse.hono.commandrouter.CommandTargetMapper; -import org.eclipse.hono.deviceconnection.DeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.common.DeviceConnectionInfo; import org.eclipse.hono.tracing.TracingHelper; import org.eclipse.hono.util.DeviceConnectionConstants; import org.eclipse.hono.util.MessageHelper; diff --git a/services/command-router/src/test/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImplTest.java b/services/command-router/src/test/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImplTest.java index c3568cdc92..5fa82469be 100644 --- a/services/command-router/src/test/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImplTest.java +++ b/services/command-router/src/test/java/org/eclipse/hono/commandrouter/impl/CommandRouterServiceImplTest.java @@ -41,7 +41,7 @@ import org.eclipse.hono.client.util.MessagingClientProvider; import org.eclipse.hono.commandrouter.CommandConsumerFactory; import org.eclipse.hono.config.ServiceConfigProperties; -import org.eclipse.hono.deviceconnection.DeviceConnectionInfo; +import org.eclipse.hono.deviceconnection.common.DeviceConnectionInfo; import org.eclipse.hono.test.VertxMockSupport; import org.eclipse.hono.util.CommandConstants; import org.eclipse.hono.util.EventConstants;