From 8b45732980236bd0f3a381a63b1ac9ed5d720dda Mon Sep 17 00:00:00 2001
From: dseurotech <davide.salvador@eurotech.com>
Date: Wed, 6 Sep 2023 09:55:40 +0200
Subject: [PATCH] :enh: Injectable ClientIdGenerator

Signed-off-by: dseurotech <davide.salvador@eurotech.com>
---
 .../kapua/commons/util/RandomUtils.java       |  1 +
 .../app/web/src/main/resources/locator.xml    |  1 +
 rest-api/web/src/main/resources/locator.xml   |  1 +
 service/security/shiro/pom.xml                |  5 +++
 .../shiro/utils/AuthenticationUtils.java      |  1 +
 .../service/authentication/TestModule.java    | 31 ++++++++++++++++++
 .../shiro/src/test/resources/locator.xml      | 22 +++++++++++++
 .../kapua/transport/TransportModule.java      | 32 +++++++++++++++++++
 .../transport/utils/ClientIdGenerator.java    | 31 ++++--------------
 .../utils/ClientIdGeneratorTest.java          | 24 +++++---------
 .../mqtt/pooling/PooledMqttClientFactory.java |  4 ++-
 11 files changed, 112 insertions(+), 41 deletions(-)
 create mode 100644 service/security/shiro/src/test/java/org/eclipse/kapua/service/authentication/TestModule.java
 create mode 100644 service/security/shiro/src/test/resources/locator.xml
 create mode 100644 transport/api/src/main/java/org/eclipse/kapua/transport/TransportModule.java

diff --git a/commons/src/main/java/org/eclipse/kapua/commons/util/RandomUtils.java b/commons/src/main/java/org/eclipse/kapua/commons/util/RandomUtils.java
index b8af06afa73..6bcbc29d7cc 100644
--- a/commons/src/main/java/org/eclipse/kapua/commons/util/RandomUtils.java
+++ b/commons/src/main/java/org/eclipse/kapua/commons/util/RandomUtils.java
@@ -28,6 +28,7 @@
  *
  * @since 1.2.0
  */
+//TODO: FIXME: promote from static utility to injectable collaborator
 public class RandomUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(RandomUtils.class);
diff --git a/job-engine/app/web/src/main/resources/locator.xml b/job-engine/app/web/src/main/resources/locator.xml
index 97ce9f1d7c9..271dd5f6341 100644
--- a/job-engine/app/web/src/main/resources/locator.xml
+++ b/job-engine/app/web/src/main/resources/locator.xml
@@ -18,6 +18,7 @@
 
     <packages>
         <package>org.eclipse.kapua.job.engine.app.web</package>
+        <package>org.eclipse.kapua.plugin</package>
         <package>org.eclipse.kapua.commons</package>
         <package>org.eclipse.kapua.job.engine.jbatch</package>
         <package>org.eclipse.kapua.job.engine.queue.jbatch</package>
diff --git a/rest-api/web/src/main/resources/locator.xml b/rest-api/web/src/main/resources/locator.xml
index 9f07c64f510..683be053395 100644
--- a/rest-api/web/src/main/resources/locator.xml
+++ b/rest-api/web/src/main/resources/locator.xml
@@ -17,6 +17,7 @@
     </provided>
     <packages>
         <package>org.eclipse.kapua.app.api.web</package>
+        <package>org.eclipse.kapua.plugin</package>
         <package>org.eclipse.kapua.commons</package>
         <package>org.eclipse.kapua.job.engine.client</package>
         <package>org.eclipse.kapua.message</package>
diff --git a/service/security/shiro/pom.xml b/service/security/shiro/pom.xml
index c8a60816463..9c259706b33 100644
--- a/service/security/shiro/pom.xml
+++ b/service/security/shiro/pom.xml
@@ -62,6 +62,11 @@
             <groupId>org.eclipse.kapua</groupId>
             <artifactId>kapua-security-certificate-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.eclipse.kapua</groupId>
+            <artifactId>kapua-security-certificate-internal</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.eclipse.kapua</groupId>
             <artifactId>kapua-user-internal</artifactId>
diff --git a/service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/shiro/utils/AuthenticationUtils.java b/service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/shiro/utils/AuthenticationUtils.java
index 9bb24ac7968..3efbec64bc1 100644
--- a/service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/shiro/utils/AuthenticationUtils.java
+++ b/service/security/shiro/src/main/java/org/eclipse/kapua/service/authentication/shiro/utils/AuthenticationUtils.java
@@ -40,6 +40,7 @@
  *
  * @since 1.0
  */
+//TODO: FIXME: promote from static utility to injectable collaborator
 public class AuthenticationUtils {
 
     private static final String CIPHER_ALGORITHM = "AES";
diff --git a/service/security/shiro/src/test/java/org/eclipse/kapua/service/authentication/TestModule.java b/service/security/shiro/src/test/java/org/eclipse/kapua/service/authentication/TestModule.java
new file mode 100644
index 00000000000..1cdecd96a66
--- /dev/null
+++ b/service/security/shiro/src/test/java/org/eclipse/kapua/service/authentication/TestModule.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 Eurotech and/or its affiliates and others
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Eurotech - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.kapua.service.authentication;
+
+import com.google.inject.Provides;
+import org.eclipse.kapua.commons.core.AbstractKapuaModule;
+
+import javax.inject.Named;
+
+public class TestModule extends AbstractKapuaModule {
+    @Override
+    protected void configureModule() {
+
+    }
+
+    @Provides
+    @Named(value = "metricModuleName")
+    String metricModuleName() {
+        return "test";
+    }
+}
diff --git a/service/security/shiro/src/test/resources/locator.xml b/service/security/shiro/src/test/resources/locator.xml
new file mode 100644
index 00000000000..b594a2be143
--- /dev/null
+++ b/service/security/shiro/src/test/resources/locator.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
+
+    This program and the accompanying materials are made
+    available under the terms of the Eclipse Public License 2.0
+    which is available at https://www.eclipse.org/legal/epl-2.0/
+
+    SPDX-License-Identifier: EPL-2.0
+
+    Contributors:
+        Eurotech - initial API and implementation
+ -->
+<!DOCTYPE xml>
+<locator-config>
+    <provided>
+    </provided>
+
+    <packages>
+        <package>org.eclipse.kapua</package>
+    </packages>
+</locator-config>
diff --git a/transport/api/src/main/java/org/eclipse/kapua/transport/TransportModule.java b/transport/api/src/main/java/org/eclipse/kapua/transport/TransportModule.java
new file mode 100644
index 00000000000..27a1c3f989e
--- /dev/null
+++ b/transport/api/src/main/java/org/eclipse/kapua/transport/TransportModule.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
+ *
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Eurotech - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.kapua.transport;
+
+import com.google.inject.Provides;
+import org.eclipse.kapua.commons.core.AbstractKapuaModule;
+import org.eclipse.kapua.commons.util.RandomUtils;
+import org.eclipse.kapua.transport.utils.ClientIdGenerator;
+
+import javax.inject.Singleton;
+
+public class TransportModule extends AbstractKapuaModule {
+    @Override
+    protected void configureModule() {
+    }
+
+    @Provides
+    @Singleton
+    ClientIdGenerator clientIdGenerator() {
+        return new ClientIdGenerator(RandomUtils.getInstance());
+    }
+}
diff --git a/transport/api/src/main/java/org/eclipse/kapua/transport/utils/ClientIdGenerator.java b/transport/api/src/main/java/org/eclipse/kapua/transport/utils/ClientIdGenerator.java
index 178eb92bbc3..eb1bf62030d 100644
--- a/transport/api/src/main/java/org/eclipse/kapua/transport/utils/ClientIdGenerator.java
+++ b/transport/api/src/main/java/org/eclipse/kapua/transport/utils/ClientIdGenerator.java
@@ -13,8 +13,7 @@
 package org.eclipse.kapua.transport.utils;
 
 
-import org.eclipse.kapua.commons.util.RandomUtils;
-
+import javax.inject.Inject;
 import java.util.Random;
 
 /**
@@ -23,7 +22,6 @@
  * @author alberto.codutti
  * @since 1.0.0
  */
-//TODO: FIXME: singletons should not be handled manually, we have DI for that
 public class ClientIdGenerator {
 
     /**
@@ -38,31 +36,16 @@ public class ClientIdGenerator {
      *
      * @since 1.2.0
      */
-    private static final Random RANDOM = RandomUtils.getInstance();
-
-    /**
-     * {@code static} instance singleton reference
-     *
-     * @since 1.0.0
-     */
-    private static final ClientIdGenerator INSTANCE = new ClientIdGenerator();
-
-    /**
-     * Private default constructor. To obtain an instance of {@link ClientIdGenerator} use {@link ClientIdGenerator#getInstance()}.
-     *
-     * @since 1.0.0
-     */
-    private ClientIdGenerator() {
-    }
+    private final Random random;
 
     /**
-     * Returns a {@code static} instance of the {@link ClientIdGenerator}.
+     * Default constructor.
      *
-     * @return The singleton instance of {@link ClientIdGenerator}
      * @since 1.0.0
      */
-    public static ClientIdGenerator getInstance() {
-        return INSTANCE;
+    @Inject
+    public ClientIdGenerator(Random random) {
+        this.random = random;
     }
 
     /**
@@ -87,7 +70,7 @@ public String next() {
      */
     public String next(String prefix) {
         long timestamp = System.currentTimeMillis();
-        long randomNumber = RANDOM.nextLong();
+        long randomNumber = random.nextLong();
 
         return String.format(GENERATED_ID_STRING_FORMAT,
                 prefix,
diff --git a/transport/api/src/test/java/org/eclipse/kapua/transport/utils/ClientIdGeneratorTest.java b/transport/api/src/test/java/org/eclipse/kapua/transport/utils/ClientIdGeneratorTest.java
index c71e874fe0d..f70cca82d96 100644
--- a/transport/api/src/test/java/org/eclipse/kapua/transport/utils/ClientIdGeneratorTest.java
+++ b/transport/api/src/test/java/org/eclipse/kapua/transport/utils/ClientIdGeneratorTest.java
@@ -20,7 +20,10 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Random;
+import java.util.Set;
 
 /**
  * {@link ClientIdGenerator} tests.
@@ -32,20 +35,9 @@ public class ClientIdGeneratorTest {
 
     private static final Logger LOG = LoggerFactory.getLogger(ClientIdGeneratorTest.class);
 
-    @Test
-    public void getInstanceTest() {
-        ClientIdGenerator clientIdGenerator1 = ClientIdGenerator.getInstance();
-        Assert.assertNotNull(clientIdGenerator1);
-
-        ClientIdGenerator clientIdGenerator2 = ClientIdGenerator.getInstance();
-        Assert.assertNotNull(clientIdGenerator2);
-
-        Assert.assertEquals(clientIdGenerator1, clientIdGenerator2);
-    }
-
     @Test
     public void nextTest() {
-        ClientIdGenerator clientIdGenerator = ClientIdGenerator.getInstance();
+        ClientIdGenerator clientIdGenerator = new ClientIdGenerator(new Random());
 
         String nextId = clientIdGenerator.next();
 
@@ -56,9 +48,9 @@ public void nextTest() {
 
     @Test
     public void nextGenerationTest() {
-        ClientIdGenerator clientIdGenerator = ClientIdGenerator.getInstance();
+        ClientIdGenerator clientIdGenerator = new ClientIdGenerator(new Random());
 
-        List<String> generatedIds = new ArrayList<>();
+        Set<String> generatedIds = new HashSet<>();
         for (int i = 0; i < 10000; i++) {
             String nextId = clientIdGenerator.next();
             LOG.trace("Generated Id: {}", nextId);
@@ -72,7 +64,7 @@ public void nextGenerationTest() {
 
     @Test
     public void nextWithPrefixTest() {
-        ClientIdGenerator clientIdGenerator = ClientIdGenerator.getInstance();
+        ClientIdGenerator clientIdGenerator = new ClientIdGenerator(new Random());
 
         String nextId = clientIdGenerator.next("MyPrefix");
 
@@ -83,7 +75,7 @@ public void nextWithPrefixTest() {
 
     @Test
     public void nextWithPrefixGenerationTest() {
-        ClientIdGenerator clientIdGenerator = ClientIdGenerator.getInstance();
+        ClientIdGenerator clientIdGenerator = new ClientIdGenerator(new Random());
 
         List<String> generatedIds = new ArrayList<>();
         for (int i = 0; i < 10000; i++) {
diff --git a/transport/mqtt/src/main/java/org/eclipse/kapua/transport/mqtt/pooling/PooledMqttClientFactory.java b/transport/mqtt/src/main/java/org/eclipse/kapua/transport/mqtt/pooling/PooledMqttClientFactory.java
index 5cbe88b61ac..95b2d071e8f 100644
--- a/transport/mqtt/src/main/java/org/eclipse/kapua/transport/mqtt/pooling/PooledMqttClientFactory.java
+++ b/transport/mqtt/src/main/java/org/eclipse/kapua/transport/mqtt/pooling/PooledMqttClientFactory.java
@@ -15,6 +15,7 @@
 import org.apache.commons.pool2.BasePooledObjectFactory;
 import org.apache.commons.pool2.PooledObject;
 import org.apache.commons.pool2.impl.DefaultPooledObject;
+import org.eclipse.kapua.locator.KapuaLocator;
 import org.eclipse.kapua.transport.mqtt.MqttClient;
 import org.eclipse.kapua.transport.mqtt.MqttClientConnectionOptions;
 import org.eclipse.kapua.transport.mqtt.exception.MqttClientException;
@@ -37,7 +38,8 @@
 public class PooledMqttClientFactory extends BasePooledObjectFactory<MqttClient> {
 
     private static final Logger LOG = LoggerFactory.getLogger(PooledMqttClientFactory.class);
-    private final ClientIdGenerator clientIdGenerator = ClientIdGenerator.getInstance();
+    //TODO: Inject if possible
+    private final ClientIdGenerator clientIdGenerator = KapuaLocator.getInstance().getComponent(ClientIdGenerator.class);
 
     private final String serverURI;