Improve tests/issues found in Sonar report - A1 Oslo/NewDelhi/Montreal/London-Part3... 62/138862/3
authorraviteja.karumuri <raviteja.karumuri@est.tech>
Tue, 20 Aug 2024 16:22:15 +0000 (17:22 +0100)
committerRAVITEJA KARUMURI <raviteja.karumuri@est.tech>
Fri, 30 Aug 2024 10:37:09 +0000 (10:37 +0000)
Issue-ID: CCSDK-4037
Change-Id: I0b330deeced3e50a494e5f00962358d90195a37b
Signed-off-by: Raviteja Karumuri <raviteja.karumuri@est.tech>
20 files changed:
a1-policy-management/pom.xml
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1AdapterJsonHelper.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactory.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/CcsdkA1AdapterClient.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/OscA1Client.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion1.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/StdA1ClientVersion2.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationResult.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/PolicyAuthorizationRequest.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStore.java
a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/service/v3/ErrorHandlingService.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/clients/A1ClientFactoryTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ApplicationTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConcurrencyTestRunnable.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ConfigurationControllerTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStoreTest.java [new file with mode: 0644]
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/LockTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/tasks/RefreshConfigTaskTest.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1Client.java
a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/utils/MockA1ClientFactory.java

index 87cc897..10c788a 100644 (file)
         <java.version.target>17</java.version.target>
         <gson.version>2.10.1</gson.version>
         <json.version>20240303</json.version>
+        <localstack.version>1.20.1</localstack.version>
+        <junit.jupiter.version>1.20.1</junit.jupiter.version>
+        <javax.annotation-api.version>1.3.2</javax.annotation-api.version>
+        <everit-json-schema.version>1.14.4</everit-json-schema.version>
+        <jackson-databind-nullable.version>0.2.6</jackson-databind-nullable.version>
+        <validation-api.version>2.0.1.Final</validation-api.version>
+        <swagger-annotations.version>2.2.15</swagger-annotations.version>
+        <spring-boot-actuator-autoconfigure.version>3.3.2</spring-boot-actuator-autoconfigure.version>
         <formatter-maven-plugin.version>2.22.0</formatter-maven-plugin.version>
         <spotless-maven-plugin.version>2.35.0</spotless-maven-plugin.version>
         <commons-io.version>2.16.1</commons-io.version>
         <dependency>
             <groupId>javax.validation</groupId>
             <artifactId>validation-api</artifactId>
-            <version>2.0.1.Final</version>
+            <version>${validation-api.version}</version>
         </dependency>
         <dependency>
             <groupId>javax.annotation</groupId>
             <artifactId>javax.annotation-api</artifactId>
-            <version>1.3.2</version>
+            <version>${javax.annotation-api.version}</version>
         </dependency>
         <dependency>
             <groupId>io.swagger.core.v3</groupId>
             <artifactId>swagger-annotations</artifactId>
-            <version>2.2.15</version>
+            <version>${swagger-annotations.version}</version>
         </dependency>
         <dependency>
             <groupId>org.openapitools</groupId>
             <artifactId>jackson-databind-nullable</artifactId>
-            <version>0.2.6</version>
+            <version>${jackson-databind-nullable.version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <optional>true</optional>
             <scope>runtime</scope>
         </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>${junit.jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>localstack</artifactId>
+            <version>${localstack.version}</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
         <dependency>
             <groupId>com.github.erosb</groupId>
             <artifactId>everit-json-schema</artifactId>
-            <version>1.14.4</version>
+            <version>${everit-json-schema.version}</version>
         </dependency>
         <!-- For Tracing -->
         <dependency>
index ab93ea3..66d3211 100644 (file)
@@ -92,26 +92,4 @@ class A1AdapterJsonHelper {
             return Mono.error(ex);
         }
     }
-
-    public static Mono<String> getValueFromResponse(String response, String key) {
-        return getOutput(response) //
-                .map(responseParams -> {
-                    if (!responseParams.has(key)) {
-                        return "";
-                    }
-                    return responseParams.get(key).toString();
-                });
-    }
-
-    public static Mono<String> extractPolicySchema(String inputString) {
-        try {
-            JSONObject jsonObject = new JSONObject(inputString);
-            JSONObject schemaObject = jsonObject.getJSONObject("policySchema");
-            String schemaString = schemaObject.toString();
-            return Mono.just(schemaString);
-        } catch (Exception ex) { // invalid json
-            logger.debug("Invalid json {}", ex.getMessage());
-            return Mono.error(ex);
-        }
-    }
 }
index 01891e9..947c50d 100644 (file)
 
 package org.onap.ccsdk.oran.a1policymanagementservice.clients;
 
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Constructor;
-
 import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1Client.A1ProtocolType;
 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
-import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ControllerConfig;
 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig;
 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import reactor.core.publisher.Mono;
 
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Constructor;
+
 /**
  * Factory for A1 clients that supports four different protocol versions of the
  * A1 api.
@@ -92,28 +90,19 @@ public class A1ClientFactory {
         }
     }
 
-    private ControllerConfig getControllerConfig(Ric ric) throws ServiceException {
-        ControllerConfig controllerConfig = ric.getConfig().getControllerConfig();
-        if (controllerConfig == null) {
-            ric.setProtocolVersion(A1ProtocolType.UNKNOWN);
-            throw new ServiceException("No controller configured for Near-RT RIC: " + ric.id());
-        }
-        return controllerConfig;
-    }
-
     private A1Client createCustomAdapter(Ric ric) throws ServiceException {
         try {
             if (ric.getConfig().getCustomAdapterClass() != null && !ric.getConfig().getCustomAdapterClass().isEmpty()) {
                 Class<?> clazz = Class.forName(ric.getConfig().getCustomAdapterClass());
                 if (A1Client.class.isAssignableFrom(clazz)) {
                     Constructor<?> constructor = clazz.getConstructor(RicConfig.class, AsyncRestClientFactory.class);
-                    logger.debug("A1Client (" + clazz.getTypeName() + ") being created for ric: {}",
-                            ric.getConfig().getRicId());
+                    logger.debug("A1Client \"{}\" being created for ric: {}",
+                            clazz.getTypeName(), ric.getConfig().getRicId());
                     return (A1Client) constructor.newInstance(ric.getConfig(), this.restClientFactory);
                 } else if (A1Client.Factory.class.isAssignableFrom(clazz)) {
                     A1Client.Factory factory = (A1Client.Factory) clazz.getDeclaredConstructor().newInstance();
-                    logger.debug("A1Client (" + clazz.getTypeName() + ") factory creating client for ric: {}",
-                            ric.getConfig().getRicId());
+                    logger.debug("A1Client \"{}\" factory creating client for ric: {}",
+                            clazz.getTypeName(), ric.getConfig().getRicId());
                     return factory.create(ric.getConfig(), this.restClientFactory);
                 } else {
                     throw new ServiceException("The custom class must either implement A1Client.Factory or A1Client");
index 04ecf04..f62d080 100644 (file)
@@ -100,7 +100,6 @@ public class CcsdkA1AdapterClient implements A1Client {
      *                         CCSDK_A1_ADAPTER_STD_V2_0_0 with
      * @param ricConfig        the configuration of the Near-RT RIC to communicate
      *                         with
-     * @param controllerConfig the configuration of the CCSDK A1 Adapter to use
      *
      * @throws IllegalArgumentException when the protocolType is wrong.
      */
@@ -119,7 +118,6 @@ public class CcsdkA1AdapterClient implements A1Client {
      *                         CCSDK_A1_ADAPTER_STD_V2_0_0 with
      * @param ricConfig        the configuration of the Near-RT RIC to communicate
      *                         with
-     * @param controllerConfig the configuration of the CCSDK A1 Adapter to use
      * @param restClient       the REST client to use
      *
      * @throws IllegalArgumentException when the protocolType is illegal.
@@ -131,8 +129,8 @@ public class CcsdkA1AdapterClient implements A1Client {
             this.restClient = restClient;
             this.ricConfig = ricConfig;
             this.protocolType = protocolType;
-            logger.debug("A1Client (" + getClass().getTypeName() + ") created for ric: {}, a1Controller: {}",
-                    ricConfig.getRicId(), ricConfig.getControllerConfig());
+            logger.debug("A1Client \"{}\" created for ric: {}, a1Controller: {}",
+                    getClass().getTypeName(), ricConfig.getRicId(), ricConfig.getControllerConfig());
 
         } else {
             logger.error("Not supported protocoltype: {}", protocolType);
index 17681cb..f536076 100644 (file)
@@ -143,7 +143,7 @@ public class OscA1Client implements A1Client {
     public OscA1Client(RicConfig ricConfig, AsyncRestClient restClient) {
         this.restClient = restClient;
         uri = new UriBuilder(ricConfig);
-        logger.debug("A1Client (" + getClass().getTypeName() + ") created for ric: {}", ricConfig.getRicId());
+        logger.debug("A1Client \"{}\" created for ric: {}", getClass().getTypeName(), ricConfig.getRicId());
     }
 
     public static Mono<String> extractCreateSchema(String policyTypeResponse, String policyTypeId) {
index 2f06b6a..b033aea 100644 (file)
@@ -109,7 +109,7 @@ public class StdA1ClientVersion1 implements A1Client {
     public StdA1ClientVersion1(AsyncRestClient restClient, RicConfig ricConfig) {
         this.restClient = restClient;
         this.uri = new UriBuilder(ricConfig);
-        logger.debug("A1Client (" + getClass().getTypeName() + ") created for ric: {}", ricConfig.getRicId());
+        logger.debug("A1Client \"{}\" created for ric: {}", getClass().getTypeName(), ricConfig.getRicId());
     }
 
     @Override
index 6f90753..3362b79 100644 (file)
@@ -138,7 +138,7 @@ public class StdA1ClientVersion2 implements A1Client {
     public StdA1ClientVersion2(RicConfig ricConfig, AsyncRestClient restClient) {
         this.restClient = restClient;
         uriBuiler = new OranV2UriBuilder(ricConfig);
-        logger.debug("A1Client (" + getClass().getTypeName() + ") created for ric: {}", ricConfig.getRicId());
+        logger.debug("A1Client \"{}\"  created for ric: {}", getClass().getTypeName(), ricConfig.getRicId());
     }
 
     public static Mono<String> extractPolicySchema(String policyTypeResponse, String policyTypeId) {
index 796c44e..dc717d3 100644 (file)
@@ -32,7 +32,7 @@ import lombok.Getter;
 @Builder
 public class AuthorizationResult {
 
-    @Schema(name = "result", description = "If true, the access is granted", required = true)
+    @Schema(name = "result", description = "If true, the access is granted", requiredMode = Schema.RequiredMode.REQUIRED)
     @JsonProperty(value = "result", required = true)
     @SerializedName("result")
     @Getter
index 8dd4e7b..cb93006 100644 (file)
@@ -51,25 +51,25 @@ public class PolicyAuthorizationRequest {
             READ, WRITE, DELETE
         }
 
-        @Schema(name = "access_type", description = "Access type", required = true)
+        @Schema(name = "access_type", description = "Access type", requiredMode = Schema.RequiredMode.REQUIRED)
         @JsonProperty(value = "access_type", required = true)
         @SerializedName("access_type")
         @Getter
         private AccessType accessType;
 
-        @Schema(name = "policy_type_id", description = "Policy type identifier", required = true)
+        @Schema(name = "policy_type_id", description = "Policy type identifier", requiredMode = Schema.RequiredMode.REQUIRED)
         @SerializedName("policy_type_id")
         @JsonProperty(value = "policy_type_id", required = true)
         private String policyTypeId;
 
-        @Schema(name = "auth_token", description = "Authorization token", required = true)
+        @Schema(name = "auth_token", description = "Authorization token", requiredMode = Schema.RequiredMode.REQUIRED)
         @SerializedName("auth_token")
         @JsonProperty(value = "auth_token", required = true)
         private String authToken;
 
     }
 
-    @Schema(name = "input", description = "Input", required = true)
+    @Schema(name = "input", description = "Input", requiredMode = Schema.RequiredMode.REQUIRED)
     @JsonProperty(value = "input", required = true)
     @SerializedName("input")
     private Input input;
index 1c67ff7..d014ad5 100644 (file)
@@ -141,7 +141,7 @@ class S3ObjectStore implements DataStore {
         return Mono.fromFuture(future) //
                 .map(f -> s3Bucket) //
                 .doOnError(t -> logger.debug("Could not create S3 bucket: {}", t.getMessage()))
-                .onErrorResume(t -> Mono.just(s3Bucket));
+                .onErrorResume(t -> Mono.just("Not Created"));
     }
 
     @Override
index 693ae51..b445150 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.onap.ccsdk.oran.a1policymanagementservice.service.v3;
 
-import org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2.PolicyController;
 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
 import org.onap.ccsdk.oran.a1policymanagementservice.models.v3.ProblemDetails;
 import org.slf4j.Logger;
index b3c7735..ca0622c 100644 (file)
@@ -21,8 +21,7 @@
 
 package org.onap.ccsdk.oran.a1policymanagementservice.clients;
 
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -144,20 +143,20 @@ class A1ClientFactoryTest {
     @DisplayName("test Custom Adapter Creation")
     void testCustomAdapterCreation() {
 
-        Ric ric = new Ric(ricConfig("", CustomA1AdapterFactory.class.getName()));
-        A1Client client = factoryUnderTest.createA1Client(ric).block();
-
+        Ric ricLocal = new Ric(ricConfig("", CustomA1AdapterFactory.class.getName()));
+        A1Client client = factoryUnderTest.createA1Client(ricLocal).block();
+        assertNotNull(client);
         assertEquals(client.getClass(), StdA1ClientVersion2.class);
 
-        ric = new Ric(ricConfig("", "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2"));
-        client = factoryUnderTest.createA1Client(ric).block();
-
+        ricLocal = new Ric(ricConfig("", "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2"));
+        client = factoryUnderTest.createA1Client(ricLocal).block();
+        assertNotNull(client);
         assertEquals(client.getClass(), StdA1ClientVersion2.class);
 
-        ric = new Ric(
+        ricLocal = new Ric(
                 ricConfig("", "org.onap.ccsdk.oran.a1policymanagementservice.clients.StdA1ClientVersion2$Factory"));
-        client = factoryUnderTest.createA1Client(ric).block();
-
+        client = factoryUnderTest.createA1Client(ricLocal).block();
+        assertNotNull(client);
         assertEquals(client.getClass(), StdA1ClientVersion2.class);
 
         Exception e = Assertions.assertThrows(Exception.class, () -> {
index be6d43f..3a7bc79 100644 (file)
@@ -263,16 +263,16 @@ class ApplicationTest {
         waitforS3();
 
         {
-            Policies policies = new Policies(this.applicationConfig);
-            policies.restoreFromDatabase(ric, this.policyTypes).blockLast();
-            assertThat(policies.size()).isEqualTo(noOfPolicies);
+            Policies policiesLocal = new Policies(this.applicationConfig);
+            policiesLocal.restoreFromDatabase(ric, this.policyTypes).blockLast();
+            assertThat(policiesLocal.size()).isEqualTo(noOfPolicies);
         }
 
         {
             restClient().delete("/policies/id2").block();
-            Policies policies = new Policies(this.applicationConfig);
-            policies.restoreFromDatabase(ric, this.policyTypes).blockLast();
-            assertThat(policies.size()).isEqualTo(noOfPolicies - 1);
+            Policies policiesAfterDelete = new Policies(this.applicationConfig);
+            policiesAfterDelete.restoreFromDatabase(ric, this.policyTypes).blockLast();
+            assertThat(policiesAfterDelete.size()).isEqualTo(noOfPolicies - 1);
         }
     }
 
@@ -387,7 +387,7 @@ class ApplicationTest {
 
     @Test
     @DisplayName("test Get Rics")
-    void testGetRics() throws Exception {
+    void testGetRics() throws JsonProcessingException {
         addRic("ric1");
         this.addPolicyType("type1", "ric1");
         String url = "/rics?policytype_id=type1";
@@ -779,7 +779,7 @@ class ApplicationTest {
 
     @Test
     @DisplayName("test Get Policy Types")
-    void testGetPolicyTypes() throws Exception {
+    void testGetPolicyTypes() throws JsonProcessingException {
         String TYPE_ID_1 = "A_type1_1.9.0";
         String TYPE_ID_2 = "A_type1_2.0.0";
         String TYPE_ID_3 = "A_type1_1.5.0";
@@ -993,7 +993,7 @@ class ApplicationTest {
 
     @Test
     @DisplayName("test Service Supervision")
-    void testServiceSupervision() throws Exception {
+    void testServiceSupervision() throws JsonProcessingException {
         putService("service1", 2, HttpStatus.CREATED);
         addPolicyType("type1", "ric1");
 
@@ -1166,7 +1166,7 @@ class ApplicationTest {
             assertThat(test.isFailed()).isFalse();
         }
         assertThat(policies.size()).isZero();
-        logger.info("Concurrency test took " + Duration.between(startTime, Instant.now()));
+        logger.info("Concurrency test took: {}", Duration.between(startTime, Instant.now()));
 
         assertThat(nonRespondingRic.getState()).isEqualTo(RicState.UNAVAILABLE);
         nonRespondingRic.setState(RicState.AVAILABLE);
index 888325b..a42d034 100644 (file)
@@ -86,7 +86,7 @@ class ConcurrencyTestRunnable implements Runnable {
             System.out.println(Thread.currentThread() + result.getBody());
 
         } catch (Exception e) {
-            logger.error(Thread.currentThread() + "Concurrency test printStatusInfo exception " + e.toString());
+            logger.error("{} Concurrency test printStatusInfo exception {}", Thread.currentThread(), e.toString());
         }
     }
 
@@ -107,7 +107,7 @@ class ConcurrencyTestRunnable implements Runnable {
                 deletePolicy(name + "-");
             }
         } catch (Exception e) {
-            logger.error("Concurrency test exception " + e.toString());
+            logger.error("Concurrency test exception {}", e.toString());
             printStatusInfo();
             failed = true;
         }
index 42e3b0c..e46b836 100644 (file)
@@ -134,14 +134,14 @@ class ConfigurationControllerTest {
     }
 
     private String configAsString() throws Exception {
-        File configFile =
+        File configFileLocal =
                 new File(getClass().getClassLoader().getResource("test_application_configuration.json").getFile());
-        return FileUtils.readFileToString(configFile, "UTF-8");
+        return FileUtils.readFileToString(configFileLocal, "UTF-8");
     }
 
     @Test
     @DisplayName("put Invalid Configuration should Return Error 400")
-    void putInvalidConfiguration_shouldReturnError400() throws Exception {
+    void putInvalidConfiguration_shouldReturnError400() {
         String url = "a1-policy/v2/configuration";
 
         // Valid JSON but invalid configuration.
diff --git a/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStoreTest.java b/a1-policy-management/src/test/java/org/onap/ccsdk/oran/a1policymanagementservice/datastore/S3ObjectStoreTest.java
new file mode 100644 (file)
index 0000000..941b777
--- /dev/null
@@ -0,0 +1,134 @@
+/*-
+ * ========================LICENSE_START=================================
+ * ONAP : ccsdk oran
+ * ======================================================================
+ * Copyright (C) 2024 OpenInfra Foundation Europe. 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.ccsdk.oran.a1policymanagementservice.datastore;
+
+import org.junit.jupiter.api.*;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
+import org.reactivestreams.Publisher;
+import org.springframework.boot.test.system.CapturedOutput;
+import org.springframework.boot.test.system.OutputCaptureExtension;
+import org.testcontainers.containers.localstack.LocalStackContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.utility.DockerImageName;
+import reactor.test.StepVerifier;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.function.Predicate;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@Testcontainers
+@ExtendWith({MockitoExtension.class, OutputCaptureExtension.class})
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+class S3ObjectStoreTest {
+
+    static ApplicationConfig appConfig;
+    private static S3ObjectStore s3ObjectStore;
+    private static final String bucketName = "s3bucket";
+
+    @Container
+    private static final LocalStackContainer localstack =
+            new LocalStackContainer(DockerImageName.parse("localstack/localstack:0.11.3"))
+                    .withServices(LocalStackContainer.Service.S3);
+
+    @BeforeAll
+    static void init() {
+        appConfig = mock(ApplicationConfig.class);
+        when(appConfig.isS3Enabled()).thenReturn(Boolean.TRUE);
+        when(appConfig.getS3EndpointOverride()).thenReturn(localstack.getEndpoint().toString());
+        when(appConfig.getS3AccessKeyId()).thenReturn(localstack.getAccessKey());
+        when(appConfig.getS3SecretAccessKey()).thenReturn(localstack.getSecretKey());
+        when(appConfig.getS3Bucket()).thenReturn(bucketName);
+        s3ObjectStore = new S3ObjectStore(appConfig, "location");
+    }
+    @Test
+    @Order(1)
+    void testGetS3AsynchClient() {
+        assertNotNull(s3ObjectStore);
+    }
+
+    @Test
+    @Order(2)
+    void testCreateAndDeleteS3BucketSuccess(CapturedOutput capturedOutput) {
+
+        testSuccess(s3ObjectStore.createDataStore(), actual -> actual.equals(bucketName));
+        assertFalse(capturedOutput.getOut().contains("Could not create S3 bucket:"));
+
+        testSuccess(s3ObjectStore.deleteBucket(), actual -> actual.equals(bucketName));
+    }
+
+    @Test
+    @Order(3)
+    void testWriteAndReadAndDeleteObjectSuccess(CapturedOutput capturedOutput) {
+
+        testSuccess(s3ObjectStore.createDataStore(), actual -> actual.equals(bucketName));
+        byte[] fileData = "testData".getBytes(StandardCharsets.UTF_8);
+        new String(fileData);
+        testSuccess(s3ObjectStore.writeObject("test", fileData),
+                actual -> Arrays.equals(actual, fileData));
+        assertFalse(capturedOutput.getOut().contains("Failed to store object"));
+        testSuccess(s3ObjectStore.readObject("test"),
+                actual -> Arrays.equals(actual, fileData));
+        testSuccess(s3ObjectStore.deleteAllObjects(), actual -> actual.equals("OK"));
+    }
+
+    @Test
+    @Order(4)
+    void testListObjectsSuccess() {
+
+        s3ObjectStore.createDataStore().block();
+        String objectName = "test";
+        byte[] fileData = "testData".getBytes(StandardCharsets.UTF_8);
+        testSuccess(s3ObjectStore.writeObject(objectName, fileData),
+                actual -> Arrays.equals(actual, fileData));
+        testSuccess(s3ObjectStore.listObjects(""), actual -> actual.equals(objectName));
+    }
+
+    @Test
+    @Order(5)
+    void testCreateAndDeleteS3BucketError(CapturedOutput capturedOutput) {
+
+        when(appConfig.getS3Bucket()).thenReturn("S3Bucket");
+
+        testFailure(s3ObjectStore.createDataStore(), actual -> actual.equals("Not Created"));
+
+        testFailure(s3ObjectStore.deleteBucket(), actual -> actual.equals("NOK"));
+        assertTrue(capturedOutput.getOut().contains("Could not delete bucket:"));
+    }
+
+    <T> void testSuccess(Publisher<T> publisher, Predicate<T> equalityCheck) {
+        StepVerifier.create(publisher)
+                .expectNextMatches(equalityCheck)
+                .verifyComplete();
+    }
+
+    <T> void testFailure(Publisher<T> publisher, Predicate<T> equalityCheck) {
+        StepVerifier.create(publisher)
+                .expectNextMatches(equalityCheck)
+                .verifyComplete();
+    }
+}
index e4d7859..ff818ca 100644 (file)
 
 package org.onap.ccsdk.oran.a1policymanagementservice.repository;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.awaitility.Awaitility.await;
-
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.junit.jupiter.MockitoExtension;
-import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
 import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock.LockType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
 
+import java.lang.invoke.MethodHandles;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
 @ExtendWith(MockitoExtension.class)
 class LockTest {
 
@@ -66,7 +63,7 @@ class LockTest {
 
     @Test
     @DisplayName("test Lock")
-    void testLock() throws IOException, ServiceException {
+    void testLock() {
         Lock lock = new Lock("l1");
         Lock.Grant grant = lock.lockBlocking(LockType.SHARED, "test");
         grant.unlockBlocking();
index 3b1ee8f..c2db815 100644 (file)
 
 package org.onap.ccsdk.oran.a1policymanagementservice.tasks;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 import com.google.common.base.Charsets;
 import com.google.common.io.Resources;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
-
-import java.io.IOException;
-import java.net.URL;
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.Optional;
-import java.util.Properties;
-
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -55,14 +38,20 @@ import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationCo
 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfigParser.ConfigParserResult;
 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ConfigurationFile;
 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.RicConfig;
-import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies;
-import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyTypes;
-import org.onap.ccsdk.oran.a1policymanagementservice.repository.Ric;
-import org.onap.ccsdk.oran.a1policymanagementservice.repository.Rics;
-import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services;
-
+import org.onap.ccsdk.oran.a1policymanagementservice.repository.*;
 import reactor.test.StepVerifier;
 
+import java.io.IOException;
+import java.net.URL;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
 @ExtendWith(MockitoExtension.class)
 class RefreshConfigTaskTest {
 
@@ -74,11 +63,11 @@ class RefreshConfigTaskTest {
     @Mock
     ConfigurationFile configurationFileMock;
 
-    private RefreshConfigTask createTestObject(boolean configFileExists) {
-        return createTestObject(configFileExists, spy(new Rics()), new Policies(appConfig), true);
+    private RefreshConfigTask createTestObject(boolean stubConfigFileExists) {
+        return createTestObject(spy(new Rics()), new Policies(appConfig), stubConfigFileExists);
     }
 
-    private RefreshConfigTask createTestObject(boolean configFileExists, Rics rics, Policies policies,
+    private RefreshConfigTask createTestObject(Rics rics, Policies policies,
             boolean stubConfigFileExists) {
         SecurityContext secContext = new SecurityContext("");
 
@@ -117,9 +106,31 @@ class RefreshConfigTaskTest {
         assertThat(ricConfigs).isNotNull().hasSize(2);
     }
 
+    @Test
+    @DisplayName("test handle updated ric config method with type removed")
+    void testHandleUpdatedRicConfigRemoved() {
+
+        String ricId = "ric1";
+        refreshTaskUnderTest = this.createTestObject(false);
+        refreshTaskUnderTest.handleUpdatedRicConfig(buildRicConfigUpdate(ricId, "ric_baseurl_removed",
+                Type.REMOVED));
+        verify(refreshTaskUnderTest.rics, times(1)).remove(anyString());
+    }
+
+    @Test
+    @DisplayName("test handle updated ric config method with type changed and no ric available before")
+    void testHandleUpdatedRicConfigNullRicChanged() {
+
+        String ricId = "ric1";
+        refreshTaskUnderTest = this.createTestObject(false);
+        refreshTaskUnderTest.handleUpdatedRicConfig(buildRicConfigUpdate(ricId, "ric_baseurl_changed",
+                Type.CHANGED));
+        verify(refreshTaskUnderTest.rics, times(1)).put(any(Ric.class));
+    }
+
     @Test
     @DisplayName("test when File Exists But Json Is Incorrect then No Rics Are Put In Repository")
-    void whenFileExistsButJsonIsIncorrect_thenNoRicsArePutInRepository() throws Exception {
+    void whenFileExistsButJsonIsIncorrect_thenNoRicsArePutInRepository() {
         refreshTaskUnderTest = this.createTestObject(true);
 
         // When
@@ -148,4 +159,16 @@ class RefreshConfigTaskTest {
         String string = Resources.toString(url, Charsets.UTF_8);
         return Optional.of(JsonParser.parseString(string).getAsJsonObject());
     }
+
+    private ApplicationConfig.RicConfigUpdate buildRicConfigUpdate(String ricID, String baseUrl,
+                                                                   Type event) {
+        return new ApplicationConfig.RicConfigUpdate(buildRicConfig(ricID, baseUrl), event);
+    }
+
+    private RicConfig buildRicConfig(String ricID, String baseUrl) {
+        return RicConfig.builder()
+                .ricId(ricID)
+                .baseUrl(baseUrl)
+                .build();
+    }
 }
index 91b762c..0cd9db2 100644 (file)
@@ -54,7 +54,7 @@ public class MockA1Client implements A1Client {
     @Setter
     private String errorInject;
 
-    public MockA1Client(String ricId, ApplicationConfig appConfig, PolicyTypes policyTypes, Duration asynchDelay) {
+    public MockA1Client(ApplicationConfig appConfig, PolicyTypes policyTypes, Duration asynchDelay) {
         this.policyTypes = policyTypes;
         this.asynchDelay = asynchDelay;
         ApplicationConfig cfg = spy(appConfig);
index be7dfcb..974c3b0 100644 (file)
@@ -59,7 +59,7 @@ public class MockA1ClientFactory extends A1ClientFactory {
     public MockA1Client getOrCreateA1Client(String ricId) {
         if (!clients.containsKey(ricId)) {
             logger.debug("Creating client for RIC: {}", ricId);
-            MockA1Client client = spy(new MockA1Client(ricId, appConfig, policyTypes, asynchDelay));
+            MockA1Client client = spy(new MockA1Client(appConfig, policyTypes, asynchDelay));
             clients.put(ricId, client);
         }
         return clients.get(ricId);