[AAI] Improve test coverage for A&AI component aai-resources 17/141617/1 master
authorakshay.khairnar@t-systems.com <akshay.khairnar@t-systems.com>
Mon, 11 Aug 2025 07:39:28 +0000 (09:39 +0200)
committerakshay.khairnar@t-systems.com <akshay.khairnar@t-systems.com>
Mon, 11 Aug 2025 07:39:38 +0000 (09:39 +0200)
"- to Improve test coverage for A&AI component aai-resources <=80%
Issue-ID: AAI-4185
Change-Id: I5048b826c112914e7752d0343ace456b39af1eb0
Signed-off-by: akshay.khairnar@t-systems.com <akshay.khairnar@t-systems.com>
aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
aai-resources/src/test/java/org/onap/aai/ResourcesAppTest.java [new file with mode: 0644]
aai-resources/src/test/java/org/onap/aai/rest/util/LogFormatToolsTest.java
aai-resources/src/test/java/org/onap/aai/util/PositiveNumValidator.java [new file with mode: 0644]

index 44dc48b..3f09248 100644 (file)
-/*
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai;
-
-import jakarta.annotation.PostConstruct;
-import jakarta.annotation.PreDestroy;
-
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.onap.aai.aailog.logs.AaiDebugLog;
-import org.onap.aai.config.SpringContextAware;
-import org.onap.aai.dbmap.AAIGraph;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.nodes.NodeIngestor;
-import org.onap.aai.util.AAIConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
-import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
-import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.core.env.Environment;
-import org.springframework.core.env.Profiles;
-
-@EnableConfigurationProperties
-@SpringBootApplication(
-        exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,
-                HibernateJpaAutoConfiguration.class, CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class})
-public class ResourcesApp {
-
-    private static final Logger logger = LoggerFactory.getLogger(ResourcesApp.class.getName());
-
-    private static final String APP_NAME = "aai-resources";
-    private static AaiDebugLog debugLog = new AaiDebugLog();
-    static {
-        debugLog.setupMDC();
-    }
-
-    @Autowired
-    private Environment env;
-
-    @Autowired
-    private NodeIngestor nodeIngestor;
-
-    @Autowired
-    private SpringContextAware context;
-
-    @Autowired
-    private SpringContextAware loaderFactory;
-
-    @PostConstruct
-    private void init() throws AAIException {
-        System.setProperty("org.onap.aai.serverStarted", "false");
-        setDefaultProps();
-        logger.info("AAI Server initialization started...");
-
-        // Setting this property to allow for encoded slash (/) in the path parameter
-        // This is only needed for tomcat keeping this as temporary
-        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
-
-        logger.info("Starting AAIGraph connections and the NodeInjestor");
-
-        // if (env.acceptsProfiles(Profiles.TWO_WAY_SSL) && env.acceptsProfiles(Profiles.ONE_WAY_SSL)) {
-        if (env.acceptsProfiles(Profiles.of(ResourcesProfiles.TWO_WAY_SSL, ResourcesProfiles.ONE_WAY_SSL))) {
-            logger.warn("You have seriously misconfigured your application");
-        }
-
-    }
-
-    @PreDestroy
-    public void cleanup() {
-        logger.info("Shutting down both realtime and cached connections");
-        AAIGraph.getInstance().graphShutdown();
-    }
-
-    public static void main(String[] args) throws AAIException {
-
-        setDefaultProps();
-
-        Environment env = null;
-        AAIConfig.init();
-        try {
-            SpringApplication app = new SpringApplication(ResourcesApp.class);
-            app.setLogStartupInfo(false);
-            app.setRegisterShutdownHook(true);
-            env = app.run(args).getEnvironment();
-        } catch (Exception ex) {
-            AAIException aai = null;
-            if (ex.getCause() instanceof AAIException) {
-                aai = (AAIException) ex.getCause();
-            } else {
-                aai = schemaServiceExceptionTranslator(ex);
-            }
-            logger.error("Problems starting the ResourcesApp due to {}", aai.getMessage());
-            ErrorLogHelper.logException(aai);
-            throw aai;
-        }
-
-        logger.info("Application '{}' is running on {}!", env.getProperty("spring.application.name"),
-                env.getProperty("server.port"));
-
-        // The main reason this was moved from the constructor is due
-        // to the SchemaGenerator needs the bean and during the constructor
-        // the Spring Context is not yet initialized
-
-        AAIConfig.init();
-        AAIGraph.getInstance();
-
-        logger.info("Resources MicroService Started");
-        logger.debug("Resources MicroService Started");
-
-    }
-
-    public static void setDefaultProps() {
-
-        if (System.getProperty("file.separator") == null) {
-            System.setProperty("file.separator", "/");
-        }
-
-        String currentDirectory = System.getProperty("user.dir");
-        System.setProperty("aai.service.name", ResourcesApp.class.getSimpleName());
-
-        if (System.getProperty("AJSC_HOME") == null) {
-            System.setProperty("AJSC_HOME", ".");
-        }
-
-        if (currentDirectory.contains(APP_NAME)) {
-            if (System.getProperty("BUNDLECONFIG_DIR") == null) {
-                System.setProperty("BUNDLECONFIG_DIR", "src/main/resources");
-            }
-        } else {
-            if (System.getProperty("BUNDLECONFIG_DIR") == null) {
-                System.setProperty("BUNDLECONFIG_DIR", "aai-resources/src/main/resources");
-            }
-        }
-    }
-
-    public static AAIException schemaServiceExceptionTranslator(Exception ex) {
-        AAIException aai = null;
-        String message = ExceptionUtils.getRootCause(ex).getMessage();
-        if (message.contains("NodeIngestor")) {
-            aai = new AAIException("AAI_3026", "Error reading OXM from SchemaService - Investigate");
-        } else if (message.contains("EdgeIngestor")) {
-            aai = new AAIException("AAI_3027", "Error reading EdgeRules from SchemaService - Investigate");
-        } else if (message.contains("Connection refused")) {
-            aai = new AAIException("AAI_3025", "Error connecting to SchemaService - Investigate");
-        } else {
-            aai = new AAIException("AAI_3025", "Unable to determine what the error is, please check external.log");
-        }
-
-        return aai;
-    }
-}
+/*\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.aai\r
+ * ================================================================================\r
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *    http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.aai;\r
+\r
+import jakarta.annotation.PostConstruct;\r
+import jakarta.annotation.PreDestroy;\r
+\r
+import org.apache.commons.lang3.exception.ExceptionUtils;\r
+import org.onap.aai.aailog.logs.AaiDebugLog;\r
+import org.onap.aai.config.SpringContextAware;\r
+import org.onap.aai.dbmap.AAIGraph;\r
+import org.onap.aai.exceptions.AAIException;\r
+import org.onap.aai.logging.ErrorLogHelper;\r
+import org.onap.aai.nodes.NodeIngestor;\r
+import org.onap.aai.util.AAIConfig;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.boot.SpringApplication;\r
+import org.springframework.boot.autoconfigure.SpringBootApplication;\r
+import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;\r
+import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;\r
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;\r
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;\r
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;\r
+import org.springframework.boot.context.properties.EnableConfigurationProperties;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.core.env.Profiles;\r
+\r
+@EnableConfigurationProperties\r
+@SpringBootApplication(\r
+        exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,\r
+                HibernateJpaAutoConfiguration.class, CassandraDataAutoConfiguration.class, CassandraAutoConfiguration.class})\r
+public class ResourcesApp {\r
+\r
+    private static final Logger logger = LoggerFactory.getLogger(ResourcesApp.class.getName());\r
+\r
+    private static final String APP_NAME = "aai-resources";\r
+    private static AaiDebugLog debugLog = new AaiDebugLog();\r
+    static {\r
+        debugLog.setupMDC();\r
+    }\r
+\r
+    @Autowired\r
+    private Environment env;\r
+\r
+    @Autowired\r
+    private NodeIngestor nodeIngestor;\r
+\r
+    @Autowired\r
+    private SpringContextAware context;\r
+\r
+    @Autowired\r
+    private SpringContextAware loaderFactory;\r
+\r
+    @PostConstruct\r
+    void init() throws AAIException {\r
+        System.setProperty("org.onap.aai.serverStarted", "false");\r
+        setDefaultProps();\r
+        logger.info("AAI Server initialization started...");\r
+\r
+        // Setting this property to allow for encoded slash (/) in the path parameter\r
+        // This is only needed for tomcat keeping this as temporary\r
+        System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");\r
+\r
+        logger.info("Starting AAIGraph connections and the NodeInjestor");\r
+\r
+        // if (env.acceptsProfiles(Profiles.TWO_WAY_SSL) && env.acceptsProfiles(Profiles.ONE_WAY_SSL)) {\r
+        if (env.acceptsProfiles(Profiles.of(ResourcesProfiles.TWO_WAY_SSL, ResourcesProfiles.ONE_WAY_SSL))) {\r
+            logger.warn("You have seriously misconfigured your application");\r
+        }\r
+\r
+    }\r
+\r
+    @PreDestroy\r
+    public void cleanup() {\r
+        logger.info("Shutting down both realtime and cached connections");\r
+        AAIGraph.getInstance().graphShutdown();\r
+    }\r
+\r
+    public static void main(String[] args) throws AAIException {\r
+\r
+        setDefaultProps();\r
+\r
+        Environment env = null;\r
+        AAIConfig.init();\r
+        try {\r
+            SpringApplication app = new SpringApplication(ResourcesApp.class);\r
+            app.setLogStartupInfo(false);\r
+            app.setRegisterShutdownHook(true);\r
+            env = app.run(args).getEnvironment();\r
+        } catch (Exception ex) {\r
+            AAIException aai = null;\r
+            if (ex.getCause() instanceof AAIException) {\r
+                aai = (AAIException) ex.getCause();\r
+            } else {\r
+                aai = schemaServiceExceptionTranslator(ex);\r
+            }\r
+            logger.error("Problems starting the ResourcesApp due to {}", aai.getMessage());\r
+            ErrorLogHelper.logException(aai);\r
+            throw aai;\r
+        }\r
+\r
+        logger.info("Application '{}' is running on {}!", env.getProperty("spring.application.name"),\r
+                env.getProperty("server.port"));\r
+\r
+        // The main reason this was moved from the constructor is due\r
+        // to the SchemaGenerator needs the bean and during the constructor\r
+        // the Spring Context is not yet initialized\r
+\r
+        AAIConfig.init();\r
+        AAIGraph.getInstance();\r
+\r
+        logger.info("Resources MicroService Started");\r
+        logger.debug("Resources MicroService Started");\r
+\r
+    }\r
+\r
+    public static void setDefaultProps() {\r
+\r
+        if (System.getProperty("file.separator") == null) {\r
+            System.setProperty("file.separator", "/");\r
+        }\r
+\r
+        String currentDirectory = System.getProperty("user.dir");\r
+        System.setProperty("aai.service.name", ResourcesApp.class.getSimpleName());\r
+\r
+        if (System.getProperty("AJSC_HOME") == null) {\r
+            System.setProperty("AJSC_HOME", ".");\r
+        }\r
+\r
+        if (currentDirectory.contains(APP_NAME)) {\r
+            if (System.getProperty("BUNDLECONFIG_DIR") == null) {\r
+                System.setProperty("BUNDLECONFIG_DIR", "src/main/resources");\r
+            }\r
+        } else {\r
+            if (System.getProperty("BUNDLECONFIG_DIR") == null) {\r
+                System.setProperty("BUNDLECONFIG_DIR", "aai-resources/src/main/resources");\r
+            }\r
+        }\r
+    }\r
+\r
+    public static AAIException schemaServiceExceptionTranslator(Exception ex) {\r
+        AAIException aai = null;\r
+        String message = ExceptionUtils.getRootCause(ex).getMessage();\r
+        if (message.contains("NodeIngestor")) {\r
+            aai = new AAIException("AAI_3026", "Error reading OXM from SchemaService - Investigate");\r
+        } else if (message.contains("EdgeIngestor")) {\r
+            aai = new AAIException("AAI_3027", "Error reading EdgeRules from SchemaService - Investigate");\r
+        } else if (message.contains("Connection refused")) {\r
+            aai = new AAIException("AAI_3025", "Error connecting to SchemaService - Investigate");\r
+        } else {\r
+            aai = new AAIException("AAI_3025", "Unable to determine what the error is, please check external.log");\r
+        }\r
+\r
+        return aai;\r
+    }\r
+}\r
diff --git a/aai-resources/src/test/java/org/onap/aai/ResourcesAppTest.java b/aai-resources/src/test/java/org/onap/aai/ResourcesAppTest.java
new file mode 100644 (file)
index 0000000..38bf8e5
--- /dev/null
@@ -0,0 +1,198 @@
+/**\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.aai\r
+ * ================================================================================\r
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *    http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+package org.onap.aai;\r
+\r
+import static org.junit.jupiter.api.Assertions.assertAll;\r
+import static org.junit.jupiter.api.Assertions.assertEquals;\r
+import static org.junit.jupiter.api.Assertions.assertNotNull;\r
+import static org.mockito.ArgumentMatchers.any;\r
+import static org.mockito.Mockito.mock;\r
+import static org.mockito.Mockito.mockStatic;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+\r
+import org.junit.jupiter.api.BeforeEach;\r
+import org.junit.jupiter.api.DisplayName;\r
+import org.junit.jupiter.api.Test;\r
+import org.junit.jupiter.api.extension.ExtendWith;\r
+import org.mockito.InjectMocks;\r
+import org.mockito.Mock;\r
+import org.mockito.MockedStatic;\r
+import org.mockito.junit.jupiter.MockitoExtension;\r
+import org.onap.aai.config.SpringContextAware;\r
+import org.onap.aai.dbmap.AAIGraph;\r
+import org.onap.aai.exceptions.AAIException;\r
+import org.onap.aai.nodes.NodeIngestor;\r
+import org.springframework.boot.test.mock.mockito.MockBean;\r
+import org.springframework.context.ConfigurableApplicationContext;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.core.env.Profiles;\r
+\r
+@ExtendWith(MockitoExtension.class)\r
+class ResourcesAppTest {\r
+\r
+       private ResourcesApp resourcesApp;\r
+\r
+       @Mock\r
+       private Environment environment;\r
+\r
+       @Mock\r
+       private NodeIngestor nodeIngestor;\r
+\r
+       @Mock\r
+       private SpringContextAware context;\r
+\r
+       @Mock\r
+       private SpringContextAware loaderFactory;\r
+\r
+       @InjectMocks\r
+       private ResourcesApp resourceApp;\r
+\r
+       @MockBean\r
+       private ConfigurableApplicationContext applicationContext;\r
+\r
+\r
+       @Mock\r
+       private Environment env;\r
+\r
+       @BeforeEach\r
+       void setUp() {\r
+               resourcesApp = new ResourcesApp();\r
+               System.setProperty("AJSC_HOME", ".");\r
+        System.setProperty("BUNDLECONFIG_DIR", "src/main/resources");\r
+       }\r
+\r
+       @Test\r
+       void testSetDefaultProps() {\r
+               // Clear any existing system properties\r
+               System.clearProperty("file.separator");\r
+               System.clearProperty("AJSC_HOME");\r
+               System.clearProperty("BUNDLECONFIG_DIR");\r
+\r
+               ResourcesApp.setDefaultProps();\r
+\r
+               assertEquals("/", System.getProperty("file.separator"));\r
+               assertEquals(".", System.getProperty("AJSC_HOME"));\r
+               assertNotNull(System.getProperty("BUNDLECONFIG_DIR"));\r
+               assertEquals("ResourcesApp", System.getProperty("aai.service.name"));\r
+       }\r
+\r
+       @Test\r
+       void init_ShouldSetupPropertiesAndConfiguration() throws AAIException {\r
+               when(env.acceptsProfiles(any(Profiles.class))).thenReturn(false);\r
+\r
+               resourceApp.init();\r
+\r
+               assertAll(\r
+                               () -> assertEquals("false", System.getProperty("org.onap.aai.serverStarted")),\r
+                               () -> assertEquals("true", System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH"))\r
+                               );\r
+       }\r
+       \r
+       @Test\r
+       void testBundleConfigDirWithAppName() {\r
+               System.clearProperty("BUNDLECONFIG_DIR");\r
+               String originalUserDir = System.getProperty("user.dir");\r
+\r
+               System.setProperty("user.dir", originalUserDir + "/aai-resources");\r
+               ResourcesApp.setDefaultProps();\r
+               assertEquals("src/main/resources", System.getProperty("BUNDLECONFIG_DIR"));\r
+\r
+               System.setProperty("user.dir", originalUserDir);\r
+       }\r
+\r
+       @Test\r
+       void testBundleConfigDirWithoutAppName() {\r
+               // Clear and set specific properties for this test\r
+               System.clearProperty("BUNDLECONFIG_DIR");\r
+               String originalUserDir = System.getProperty("user.dir");\r
+\r
+               System.setProperty("user.dir", "/different/path");\r
+               ResourcesApp.setDefaultProps();\r
+               assertEquals("aai-resources/src/main/resources", System.getProperty("BUNDLECONFIG_DIR"));\r
+\r
+               System.setProperty("user.dir", originalUserDir);\r
+       }\r
+       \r
+    @Test\r
+    void testCleanup() {\r
+        try (MockedStatic<AAIGraph> aaiGraphMock = mockStatic(AAIGraph.class)) {\r
+            AAIGraph mockGraph = mock(AAIGraph.class);\r
+            aaiGraphMock.when(AAIGraph::getInstance).thenReturn(mockGraph);\r
+\r
+           resourcesApp.cleanup();\r
+            verify(mockGraph).graphShutdown();\r
+        }\r
+    }\r
+   \r
+    @Test\r
+    @DisplayName("Should return AAI_3026 exception when NodeIngestor error occurs")\r
+    void testNodeIngestorError() {\r
+        Exception cause = new RuntimeException("Failed to process NodeIngestor data");\r
+        Exception originalException = new Exception("Wrapper", cause);\r
+        \r
+        AAIException result = ResourcesApp.schemaServiceExceptionTranslator(originalException);\r
+        \r
+        assertNotNull(result);\r
+        assertEquals("AAI_3026", result.getCode());\r
+    }\r
+\r
+    @Test\r
+    @DisplayName("Should return AAI_3027 exception when EdgeIngestor error occurs")\r
+    void testEdgeIngestorError() {\r
+        Exception cause = new RuntimeException("EdgeIngestor failed to process");\r
+        Exception originalException = new Exception("Wrapper", cause);\r
+        \r
+        AAIException result = ResourcesApp.schemaServiceExceptionTranslator(originalException);\r
+        \r
+        assertNotNull(result);\r
+        assertEquals("AAI_3027", result.getCode());\r
+    }\r
+\r
+    @Test\r
+    @DisplayName("Should return AAI_3025 exception when connection refused")\r
+    void testConnectionRefusedError() {\r
+        Exception cause = new RuntimeException("Connection refused");\r
+        Exception originalException = new Exception("Wrapper", cause);\r
+        \r
+        AAIException result = ResourcesApp.schemaServiceExceptionTranslator(originalException);\r
+        \r
+        assertNotNull(result);\r
+        assertEquals("AAI_3025", result.getCode());\r
+    }\r
+\r
+    @Test\r
+    @DisplayName("Should return default AAI_3025 exception for unknown errors")\r
+    void testUnknownError() {\r
+        Exception cause = new RuntimeException("Some unexpected error");\r
+        Exception originalException = new Exception("Wrapper", cause);\r
+        \r
+        AAIException result = ResourcesApp.schemaServiceExceptionTranslator(originalException);\r
+        \r
+        assertNotNull(result);\r
+        assertEquals("AAI_3025", result.getCode());\r
+    }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
index 3958f46..6f1a05f 100644 (file)
@@ -1,35 +1,89 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.aai.rest.util;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.junit.jupiter.api.Test;
-
-public class LogFormatToolsTest {
-
-    @Test
-    public void testLogFormatTools() {
-
-        String dateTime = LogFormatTools.getCurrentDateTime();
-        assertNotNull(dateTime);
-    }
-}
+/**\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.aai\r
+ * ================================================================================\r
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *    http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.aai.rest.util;\r
+\r
+import static org.junit.jupiter.api.Assertions.assertEquals;\r
+import static org.junit.jupiter.api.Assertions.assertFalse;\r
+import static org.junit.jupiter.api.Assertions.assertNotNull;\r
+import static org.junit.jupiter.api.Assertions.assertTrue;\r
+\r
+import java.time.ZoneOffset;\r
+import java.time.ZonedDateTime;\r
+import java.time.format.DateTimeFormatter;\r
+\r
+import org.junit.jupiter.api.Test;\r
+\r
+public class LogFormatToolsTest {\r
+\r
+       private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";\r
+    private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern(DATE_FORMAT).withZone(ZoneOffset.UTC);\r
+\r
+    @Test\r
+    void getCurrentDateTime_ShouldReturnCorrectFormat() {\r
+        String result = LogFormatTools.getCurrentDateTime();\r
+\r
+        assertTrue(isValidDateFormat(result), "DateTime string should match the expected format");\r
+    }\r
+\r
+    @Test\r
+    void getCurrentDateTime_ShouldReturnCurrentTime() {\r
+        ZonedDateTime beforeTest = ZonedDateTime.now();\r
+\r
+        String result = LogFormatTools.getCurrentDateTime();\r
+        ZonedDateTime parsedResult = ZonedDateTime.parse(result, DTF);\r
+        ZonedDateTime afterTest = ZonedDateTime.now();\r
+\r
+        assertTrue(parsedResult.isBefore(afterTest) || parsedResult.equals(afterTest),\r
+                "Returned datetime should not be after test end");\r
+    }\r
+\r
+    @Test\r
+    void getCurrentDateTime_ShouldReturnUTCTime() {\r
+        String result = LogFormatTools.getCurrentDateTime();\r
+        ZonedDateTime parsedResult = ZonedDateTime.parse(result, DTF);\r
+\r
+        assertEquals(ZoneOffset.UTC, parsedResult.getOffset(),\r
+                "DateTime should be in UTC timezone");\r
+    }\r
+\r
+    private boolean isValidDateFormat(String dateStr) {\r
+        ZonedDateTime.parse(dateStr, DTF);\r
+        return true;\r
+    }\r
+    \r
+    @Test\r
+    void testLogFormatToolsInstantiation() {\r
+        LogFormatTools logFormatTools = new LogFormatTools();\r
+\r
+        assertNotNull(logFormatTools, "Should be able to create LogFormatTools instance");\r
+        assertTrue(logFormatTools instanceof LogFormatTools, \r
+            "Created object should be instance of LogFormatTools");\r
+    }\r
+\r
+    @Test\r
+    void testLogFormatToolsClass() {\r
+        Class<?> clazz = LogFormatTools.class;\r
+\r
+        assertFalse(clazz.isInterface(), "LogFormatTools should be a class, not an interface");\r
+        assertFalse(clazz.isEnum(), "LogFormatTools should be a class, not an enum");\r
+        assertFalse(clazz.isAnnotation(), "LogFormatTools should be a class, not an annotation");\r
+    }\r
+}\r
diff --git a/aai-resources/src/test/java/org/onap/aai/util/PositiveNumValidator.java b/aai-resources/src/test/java/org/onap/aai/util/PositiveNumValidator.java
new file mode 100644 (file)
index 0000000..8e61693
--- /dev/null
@@ -0,0 +1,61 @@
+/**\r
+ * ============LICENSE_START=======================================================\r
+ * org.onap.aai\r
+ * ================================================================================\r
+ * Copyright © 2025 Deutsche Telekom. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *    http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+package org.onap.aai.util;\r
+\r
+import org.junit.jupiter.api.Test;\r
+\r
+import com.beust.jcommander.ParameterException;\r
+\r
+import org.junit.jupiter.api.DisplayName;\r
+import static org.junit.jupiter.api.Assertions.*;\r
+\r
+class PositiveNumValidatorTest {\r
+\r
+    private final PositiveNumValidator validator = new PositiveNumValidator();\r
+\r
+    @Test\r
+    @DisplayName("Should accept zero as valid input")\r
+    void validateZero() {\r
+        assertDoesNotThrow(() -> validator.validate("testParam", "0"));\r
+    }\r
+\r
+    @Test\r
+    @DisplayName("Should accept positive number as valid input")\r
+    void validatePositiveNumber() {\r
+        assertDoesNotThrow(() -> validator.validate("testParam", "42"));\r
+    }\r
+\r
+    @Test\r
+    @DisplayName("Should throw ParameterException for negative number")\r
+    void validateNegativeNumber() {\r
+        ParameterException exception = assertThrows(ParameterException.class,\r
+            () -> validator.validate("testParam", "-1"));\r
+        \r
+        assertEquals("Parameter testParam should be >= 0", exception.getMessage());\r
+    }\r
+\r
+    @Test\r
+    @DisplayName("Should throw NumberFormatException for non-numeric input")\r
+    void validateNonNumericInput() {\r
+        assertThrows(NumberFormatException.class,\r
+            () -> validator.validate("testParam", "abc"));\r
+    }\r
+}\r
+\r