Increment code coverage for Application 96/6096/3
authorClaudio D. Gasparini <claudio.gasparini@intl.att.com>
Wed, 19 May 2021 13:14:08 +0000 (15:14 +0200)
committerClaudio David Gasparini <claudio.gasparini@intl.att.com>
Thu, 20 May 2021 05:32:41 +0000 (05:32 +0000)
Issue-ID: OAM-209
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@intl.att.com>
Change-Id: I8b40f00b022613517c4bb17bcc345f714c47fa08

13 files changed:
solution/docker-compose.yaml
ves-nf-oam-adopter/ves-nf-oam-adopter-app/pom.xml
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/LoginAttemptsLogger.java
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/config/SecurityConfiguration.java
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/controller/AdapterController.java
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/http/HttpCientFactory.java
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/properties/ServerProperties.java [moved from ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/ServerProperties.java with 96% similarity]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/properties/SslProperties.java [moved from ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/main/java/org/o/ran/oam/nf/oam/adopter/app/SslProperties.java with 95% similarity]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/test/java/org/o/ran/oam/nf/oam/adopter/app/AdapterApplicationTest.java [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/test/resources/application.yml [new file with mode: 0644]
ves-nf-oam-adopter/ves-nf-oam-adopter-mock/configuration/application.yml
ves-nf-oam-adopter/ves-nf-oam-adopter-mock/pom.xml
ves-nf-oam-adopter/ves-nf-oam-adopter-parent/pom.xml

index 9acf3e4..1490d22 100644 (file)
@@ -16,7 +16,7 @@ services:
       - "443:443/tcp"
     network_mode: host
     restart: unless-stopped
-    image: nexus3.o-ran-sc.org:10003/o-ran-sc/ves-nf-oam-adopter-ran-mock:latest
+    image: nexus3.o-ran-sc.org:10004/o-ran-sc/ves-nf-oam-adopter-ran-mock:latest
     container_name: ves-nf-oam-adopter-ran-mock
     environment:
       KEY_PASSWORD: nf-oam-adopter
@@ -29,7 +29,7 @@ services:
       - "443:444/tcp"
     network_mode: host
     restart: unless-stopped
-    image: nexus3.o-ran-sc.org:10003/o-ran-sc/ves-nf-oam-adopter:latest
+    image: nexus3.o-ran-sc.org:10004/o-ran-sc/ves-nf-oam-adopter:latest
     container_name: ves-nf-oam-adopter
     environment:
       SERVER_PORT: 444
index 25738b6..c92c564 100644 (file)
@@ -34,9 +34,6 @@
     <artifactId>ves-nf-oam-adopter-app</artifactId>
 
     <properties>
-        <minimum.coverage>0.18</minimum.coverage>
-        <!--Plugins properties-->
-        <swagger-codegen-maven-plugin.version>3.0.25</swagger-codegen-maven-plugin.version>
         <!--Image properties-->
         <image.name>ves-nf-oam-adopter</image.name>
     </properties>
             <groupId>io.swagger.core.v3</groupId>
             <artifactId>swagger-annotations</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-test</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
             <plugin>
                 <groupId>io.swagger.codegen.v3</groupId>
                 <artifactId>swagger-codegen-maven-plugin</artifactId>
-                <version>${swagger-codegen-maven-plugin.version}</version>
                 <executions>
                     <execution>
                         <goals>
index e1222f5..072fbb9 100644 (file)
@@ -40,6 +40,10 @@ public class LoginAttemptsLogger {
     public void auditEventHappened(final AuditApplicationEvent auditApplicationEvent) {
         final AuditEvent auditEvent = auditApplicationEvent.getAuditEvent();
         final WebAuthenticationDetails details = (WebAuthenticationDetails) auditEvent.getData().get("details");
+        if (details == null) {
+            LOG.info("AUDIT: User: {} Event Type: {}", auditEvent.getPrincipal(), auditEvent.getType());
+            return;
+        }
         LOG.info("AUDIT: User: {} Event Type: {} Remote IP address: {}",
                 auditEvent.getPrincipal(), auditEvent.getType(), details.getRemoteAddress());
     }
index 18101a4..2fc030f 100644 (file)
@@ -19,8 +19,8 @@
 
 package org.o.ran.oam.nf.oam.adopter.app.config;
 
-import org.o.ran.oam.nf.oam.adopter.app.ServerProperties;
-import org.o.ran.oam.nf.oam.adopter.app.SslProperties;
+import org.o.ran.oam.nf.oam.adopter.app.properties.ServerProperties;
+import org.o.ran.oam.nf.oam.adopter.app.properties.SslProperties;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
@@ -47,7 +47,10 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
         if (ssl != null && ssl.getEnabled() != null && ssl.getEnabled()) {
             http.requiresChannel().anyRequest().requiresSecure();
         }
-        http.csrf().disable().antMatcher("/adapters/**").authorizeRequests().anyRequest().hasRole(ADMIN_ROLE).and()
+        http.csrf().disable()
+                .antMatcher("/adapters/**")
+                .authorizeRequests().anyRequest()
+                .hasRole(ADMIN_ROLE).and()
                 .httpBasic();
     }
 
index 1960af7..a6fb63d 100644 (file)
@@ -57,7 +57,6 @@ public class AdapterController implements ControllerApi {
     }
 
     @Override
-    @SneakyThrows
     public ResponseEntity<List<String>> getAllAdapters() {
         LOG.info("Request triggered: getAllAdapters");
         return ResponseEntity.ok(deployer.getAll());
index 073a622..7184c28 100644 (file)
@@ -19,7 +19,6 @@
 
 package org.o.ran.oam.nf.oam.adopter.app.http;
 
-import com.google.common.base.Strings;
 import java.io.File;
 import java.io.IOException;
 import java.security.KeyManagementException;
@@ -37,10 +36,8 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
 import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
 import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
 import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
-import org.apache.hc.client5.http.ssl.TrustAllStrategy;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.ssl.SSLContextBuilder;
-import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.Timeout;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,15 +53,7 @@ public final class HttpCientFactory {
             final String trustStorePassword, final Long conectionTimeout, final Long responseTimeout)
             throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException,
             CertificateException {
-        if (Strings.isNullOrEmpty(trustStore) || Strings.isNullOrEmpty(trustStorePassword)) {
-            return trustAllCertificate(conectionTimeout, responseTimeout);
-        }
-        final File trustStoreFilePath = new File(trustStore);
-        if (!trustStoreFilePath.exists() || trustStoreFilePath.isDirectory()) {
-            return trustAllCertificate(conectionTimeout, responseTimeout);
-        }
-
-        final SSLContext sslContext = getSslContext(trustStoreFilePath, trustStorePassword);
+        final SSLContext sslContext = getSslContext(new File(trustStore), trustStorePassword);
         return trustTrustStore(sslContext, conectionTimeout, responseTimeout);
     }
 
@@ -101,23 +90,4 @@ public final class HttpCientFactory {
                 .setCookieSpec(StandardCookieSpec.STRICT)
                 .build();
     }
-
-    private static CloseableHttpAsyncClient trustAllCertificate(final Long conectionTimeout, final Long responseTimeout)
-            throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
-        LOG.info("Trust all SSL certificates");
-        final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustAllStrategy()).build();
-        final PoolingAsyncClientConnectionManager connectionManager =
-                PoolingAsyncClientConnectionManagerBuilder.create()
-                        .setTlsStrategy(ClientTlsStrategyBuilder.create()
-                                .setSslContext(sslContext)
-                                .setHostnameVerifier(NoopHostnameVerifier.INSTANCE)
-                                .build())
-                        .build();
-
-        return HttpAsyncClients.custom()
-                .setConnectionManager(connectionManager)
-                .setDefaultRequestConfig(createDefaultRequestConfig(conectionTimeout, responseTimeout))
-                .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
-                .build();
-    }
 }
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/test/java/org/o/ran/oam/nf/oam/adopter/app/AdapterApplicationTest.java b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/test/java/org/o/ran/oam/nf/oam/adopter/app/AdapterApplicationTest.java
new file mode 100644 (file)
index 0000000..3b9cdf3
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  O-RAN-SC
+ *  ================================================================================
+ *  Copyright © 2021 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.o.ran.oam.nf.oam.adopter.app;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import com.google.gson.Gson;
+import java.time.ZoneId;
+import java.util.Collections;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.o.ran.oam.nf.oam.adopter.app.controller.TimeZoneServiceProvider;
+import org.o.ran.oam.nf.oam.adopter.model.Adapter;
+import org.o.ran.oam.nf.oam.adopter.model.AdapterMechId;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.PerformanceManagementMapperConfigProvider;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.api.PerformanceManagementAdaptersDeployer;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.AlreadyPresentException;
+import org.o.ran.oam.nf.oam.adopter.pm.rest.manager.exceptions.NotFoundException;
+import org.o.ran.oam.nf.oam.adopter.snmp.manager.SnmpMappingConfigurationProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@AutoConfigureMockMvc
+class AdapterApplicationTest {
+
+    private static final Gson GSON = new Gson();
+
+    @Autowired
+    private MockMvc mockMvc;
+    @Autowired
+    private TimeZoneServiceProvider timeZoneServiceProvider;
+    @MockBean
+    private PerformanceManagementAdaptersDeployer deployer;
+    @MockBean
+    private SnmpMappingConfigurationProvider snmpProvider;
+    @MockBean
+    private PerformanceManagementMapperConfigProvider pmProvider;
+    @Autowired
+    private WebApplicationContext context;
+
+
+    @BeforeEach
+    public void applySecurity() {
+        mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
+    }
+
+    @Test
+    @WithMockUser(username = "admin", roles = "ADMIN")
+    public void testGetAllAdapters() throws Exception {
+        when(deployer.getAll()).thenReturn(Collections.singletonList("mockResult"));
+
+        mockMvc.perform(get("/adapters/").secure(true).contentType(MediaType.APPLICATION_JSON)).andDo(print())
+                .andExpect(status().isOk()).andExpect(content().string(containsString("mockResult")));
+    }
+
+    @Test
+    @WithMockUser(username = "admin", roles = "ADMIN")
+    public void testDeleteAdapter() throws Exception {
+        mockMvc.perform(delete("/adapters/adapter/172.10.55.3").secure(true).contentType(MediaType.APPLICATION_JSON))
+                .andDo(print()).andExpect(status().isOk());
+    }
+
+    @Test
+    @WithMockUser(username = "admin", roles = "ADMIN")
+    public void testNotFound() throws Exception {
+        doThrow(NotFoundException.class).when(deployer).delete(anyString());
+
+        mockMvc.perform(delete("/adapters/adapter/172.10.55.3").secure(true).contentType(MediaType.APPLICATION_JSON))
+                .andDo(print()).andExpect(status().isNotFound());
+    }
+
+    @Test
+    @WithMockUser(username = "admin", roles = "ADMIN")
+    public void testAddAdapter() throws Exception {
+
+        final Adapter adapter = new Adapter();
+        adapter.setHost("172.10.55.3");
+
+        final AdapterMechId mechId = new AdapterMechId();
+        mechId.username("admin");
+        mechId.password("somePass");
+        adapter.setMechId(mechId);
+
+        mockMvc.perform(post("/adapters/adapter").secure(true).contentType(MediaType.APPLICATION_JSON)
+                                .content(GSON.toJson(adapter))).andDo(print()).andExpect(status().isOk());
+    }
+
+    @Test
+    @WithMockUser(username = "admin", roles = "ADMIN")
+    public void testAlreadyExist() throws Exception {
+
+        final Adapter adapter = new Adapter();
+        adapter.setHost("172.10.55.3");
+
+        final AdapterMechId mechId = new AdapterMechId();
+        mechId.username("admin");
+        mechId.password("somePass");
+        adapter.setMechId(mechId);
+
+        doThrow(AlreadyPresentException.class).when(deployer).create(anyString(), anyString(), anyString());
+
+        mockMvc.perform(post("/adapters/adapter").secure(true).contentType(MediaType.APPLICATION_JSON)
+                                .content(GSON.toJson(adapter))).andDo(print()).andExpect(status().isBadRequest());
+    }
+
+    @Test
+    @WithMockUser(username = "admin", roles = "ADMIN")
+    public void testMissingArguments() throws Exception {
+
+        final Adapter adapter = new Adapter();
+        adapter.setHost("172.10.55.3");
+
+        final AdapterMechId mechId = new AdapterMechId();
+        mechId.username("admin");
+        adapter.setMechId(mechId);
+
+
+        mockMvc.perform(post("/adapters/adapter").secure(true).contentType(MediaType.APPLICATION_JSON)
+                                .content(GSON.toJson(adapter))).andDo(print()).andExpect(status().isBadRequest());
+    }
+
+    @Test
+    public void test() {
+        final ZoneId zoneId = ZoneId.of("+02:00");
+        when(deployer.getTimeZone("172.10.55.3")).thenReturn(zoneId);
+        assertEquals(zoneId, timeZoneServiceProvider.getTimeZone("172.10.55.3"));
+    }
+}
\ No newline at end of file
diff --git a/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/test/resources/application.yml b/ves-nf-oam-adopter/ves-nf-oam-adopter-app/src/test/resources/application.yml
new file mode 100644 (file)
index 0000000..27b27ff
--- /dev/null
@@ -0,0 +1,33 @@
+spring.devtools.restart.log-condition-evaluation-delta: false
+logging.config: ./configuration/log4j2.yml
+server:
+  username: admin
+  password: admin
+  ssl:
+    enabled: true
+    key-store-type: JKS
+    key-alias: nf-oam-adopter
+    key-store: ./configuration/ssl/nf-oam-adopter-keystore.jks
+    key-store-password: nf-oam-adopter
+    key-password: nf-oam-adopter
+    trust-store: ./configuration/ssl/nf-oam-adopter-truststore.jks
+    trust-store-password: nf-oam-adopter
+    enabled-protocols: TLSv1.3
+    ciphers: TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_CCM_8_SHA256, TLS_AES_128_CCM_SHA256
+ves-collector:
+  url: someUrl
+  vesEncodedAuth: someAuth
+http-client:
+  conection-timeout: 600
+  response-timeout: 600
+pm-rest-manager:
+  synchronization-time-start: 20:00:00
+  synchronization-time-frequency: 5
+  mapping-config-path: mapping-configuration/pm-ves-message-mapping.yaml
+  ran-token-endpoint: /auth/token
+  ran-pm-endpoint: /pm/files
+  ran-time-zone-offset-endpoint: /system/timeZone
+snmp-manager:
+  host: "0.0.0.0"
+  port: 10162
+  mapping-config-path: mapping-configuration/fm-ves-message-mapping.yaml
\ No newline at end of file
index 6bd01fd..c409443 100644 (file)
@@ -1,7 +1,7 @@
 spring.devtools.restart.log-condition-evaluation-delta: false
 scheduler:
-  fixedDelay: 8000
-  initialDelay: 4000
+  fixedDelay: 16000
+  initialDelay: 8000
 security:
   auth:
     username: admin
index ecf61cc..0869dc6 100644 (file)
@@ -91,7 +91,6 @@
             <plugin>
                 <groupId>io.swagger.codegen.v3</groupId>
                 <artifactId>swagger-codegen-maven-plugin</artifactId>
-                <version>${swagger-codegen-maven-plugin.version}</version>
                 <executions>
                     <execution>
                         <goals>
index 465d3db..a200391 100644 (file)
                         </execution>
                     </executions>
                 </plugin>
+                <plugin>
+                    <groupId>io.swagger.codegen.v3</groupId>
+                    <artifactId>swagger-codegen-maven-plugin</artifactId>
+                    <version>${swagger-codegen-maven-plugin.version}</version>
+                </plugin>
             </plugins>
         </pluginManagement>
         <plugins>