summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorawudzins <adam.wudzinski@nokia.com>2020-02-19 13:34:32 +0100
committerawudzins <adam.wudzinski@nokia.com>2020-02-20 12:43:59 +0100
commitd54223e7cd3026e260e06df39dd52c4368e7053d (patch)
tree8501ab3942fa88201f468a05bf84b600e24c7740
parente93c679bc9c22e034ba93a48460830716e1f7457 (diff)
Load CMP Servers config from volume
Create Kubernetes secret to store Cmp Server config file and mount it to container as volume Issue-ID: AAF-997 Signed-off-by: Adam Wudzinski <adam.wudzinski@nokia.com> Change-Id: I163b720ce14729328af34dd61e6eb0108c76d58b
-rw-r--r--certService/README.md175
-rw-r--r--certService/helm/aaf-cert-service/resources/cmpServers.json (renamed from certService/src/main/resources/cmpServers.json)0
-rw-r--r--certService/helm/aaf-cert-service/templates/deployment.yaml8
-rw-r--r--certService/helm/aaf-cert-service/templates/secret.yaml7
-rw-r--r--certService/helm/aaf-cert-service/values.yaml8
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java21
-rw-r--r--certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java26
-rw-r--r--certService/src/main/resources/application.properties9
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java85
-rw-r--r--certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java40
10 files changed, 255 insertions, 124 deletions
diff --git a/certService/README.md b/certService/README.md
index 5a650f1c..f9478bed 100644
--- a/certService/README.md
+++ b/certService/README.md
@@ -13,138 +13,129 @@ More information about the project and all its functionalities you can find unde
For IntelliJ use [https://plugins.jetbrains.com/plugin/8527-google-java-format]
For other IDEs use []https://github.com/google/google-java-format]
-### Running Locally
- ```
- mvn spring-boot:run
+### Local project configuration
+ * Create directory on your system /etc/onap/aaf/certservice
+ * Copy sample configuration test/resources/cmpServers.json to that directory
- ```
-
+### Running Locally
+MANDATORY SEE 'Local project configuration' section
+```
+mvn spring-boot:run
+```
+
### Running Locally with Developer Tools
- ```
- mvn spring-boot:run -Pdev
-
- ```
+MANDATORY SEE 'Local project configuration' section
+```
+mvn spring-boot:run -Pdev
+```
### Project building
- ```
- mvn clean package
-
- ```
+```
+mvn clean package
+```
### Building Docker image manually
Go to the certService subfolder and execute following statement (1.0.0-SNAPSHOT is related to a current project.version parameter):
- ```
- docker build --build-arg VERSION=1.0.0-SNAPSHOT -t onap/org.onap.aaf.certservice.aaf-certservice-api .
- ```
+```
+docker build --build-arg VERSION=1.0.0-SNAPSHOT -t onap/org.onap.aaf.certservice.aaf-certservice-api .
+```
### Install the package into the local repository
- ```
- mvn clean install
-
- ```
+```
+mvn clean install
+```
### Building Docker image and install the package into the local repository
- ```
- mvn clean install -P docker
-
- ```
+```
+mvn clean install -P docker
+```
### Running Docker container local
- ```
- docker run -p 8080:8080 --name aaf-certservice-api onap/org.onap.aaf.certservice.aaf-certservice-api
-
- ```
+```
+docker run -p 8080:8080 --name aaf-certservice-api onap/org.onap.aaf.certservice.aaf-certservice-api
+```
### Running Docker container from nexus
- ```
- docker run -p 8080:8080 --name aaf-certservice-api nexus3.onap.org:10001/onap/org.onap.aaf.certservice.aaf-certservice-api:1.0.0
-
- ```
+```
+docker run -p 8080:8080 --name aaf-certservice-api nexus3.onap.org:10001/onap/org.onap.aaf.certservice.aaf-certservice-api:1.0.0
+```
### Running Docker container from docker-compose with EJBCA
- Docker-compose uses nexus image of certservice.
-
- ```
- docker-compose up
-
- ```
+Docker-compose uses nexus image of certservice.
+```
+docker-compose up
+```
+
+### Running with Helm
+1. Use environment/server with installed kubernetes and helm.
+2. Copy helm/aaf-cert-service directory to that environment.
+3. Enter that environment
+4. Run ```helm install ./aaf-cert-service```
### Health Check
- Browser:
-
- ```
- http://<localhost>:8080/actuator/health
+Browser:
+```
+http://<localhost>:8080/actuator/health
+```
- ```
-
- Curl:
-
- ```
- curl localhost:8080/actuator/health
-
- ```
+Curl:
+```
+curl localhost:8080/actuator/health
+```
Should return {"status":"UP"}
### Running CSITs
Pull csit repository
-
- ```
- https://gerrit.onap.org/r/admin/repos/integration/csit
-
- ```
+```
+https://gerrit.onap.org/r/admin/repos/integration/csit
+```
Go to created directory and run
-
- ```
- sudo ./run-csit.sh plans/aaf/cert-service
-
- ```
+```
+sudo ./run-csit.sh plans/aaf/cert-service
+```
### Logs locally
path:
-
- ```
- var/log/onap/aaf/certservice/
- ```
+```
+var/log/onap/aaf/certservice/
+```
### Logs in Docker container
- ```
- docker exec -it aaf-certservice-api bash
- ```
+```
+docker exec -it aaf-certservice-api bash
+```
path:
-
- ```
- cd /var/log/onap/aaf/certservice
- ```
+```
+cd /var/log/onap/aaf/certservice
+```
You should see:
audit.log error.log trace.log
### Sonar results
- ```
- https://sonarcloud.io/dashboard?id=onap_aaf-certservice
- ```
+```
+https://sonarcloud.io/dashboard?id=onap_aaf-certservice
+```
- ### Maven artifacts
- All maven artifacts are deployed under nexus uri:
- ```
- https://nexus.onap.org/content/repositories/snapshots/org/onap/aaf/certservice/
- ```
+### Maven artifacts
+All maven artifacts are deployed under nexus uri:
+```
+https://nexus.onap.org/content/repositories/snapshots/org/onap/aaf/certservice/
+```
- ### Docker artifacts
- All docker images are hosted under nexus3 uri:
- ```
- https://nexus3.onap.org/repository/docker.snapshot/v2/onap/org.onap.aaf.certservice.aaf-certservice-api/
- ```
+### Docker artifacts
+All docker images are hosted under nexus3 uri:
+```
+https://nexus3.onap.org/repository/docker.snapshot/v2/onap/org.onap.aaf.certservice.aaf-certservice-api/
+```
### RestAPI
API is described by Swagger ( OpenAPI 3.0 ) on endpoint /docs
( endpoint is defined in properties as springdoc.swagger-ui.path )
-
- ```
- http://localchost:8080/docs
-
- ```
+```
+http://localchost:8080/docs
+```
### Sonar results
- ```
- https://sonarcloud.io/dashboard?id=onap_aaf-certservice
- ```
+```
+https://sonarcloud.io/dashboard?id=onap_aaf-certservice
+```
diff --git a/certService/src/main/resources/cmpServers.json b/certService/helm/aaf-cert-service/resources/cmpServers.json
index ee9e72b9..ee9e72b9 100644
--- a/certService/src/main/resources/cmpServers.json
+++ b/certService/helm/aaf-cert-service/resources/cmpServers.json
diff --git a/certService/helm/aaf-cert-service/templates/deployment.yaml b/certService/helm/aaf-cert-service/templates/deployment.yaml
index 0b64d730..2e16cbca 100644
--- a/certService/helm/aaf-cert-service/templates/deployment.yaml
+++ b/certService/helm/aaf-cert-service/templates/deployment.yaml
@@ -12,6 +12,10 @@ spec:
labels:
app: {{ .Values.appLabel }}
spec:
+ volumes:
+ - name: {{ .Values.volume.name }}
+ secret:
+ secretName: {{ .Values.secret.name }}
containers:
- name: aaf-cert-service
image: {{ .Values.repository }}/{{ .Values.image }}
@@ -30,5 +34,9 @@ spec:
path: {{ .Values.healthcheck.path }}
initialDelaySeconds: {{ .Values.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.readiness.periodSeconds }}
+ volumeMounts:
+ - name: {{ .Values.volume.name }}
+ mountPath: {{ .Values.volume.mountPath }}
+ readOnly: true
resources:
{{ toYaml .Values.resources }}
diff --git a/certService/helm/aaf-cert-service/templates/secret.yaml b/certService/helm/aaf-cert-service/templates/secret.yaml
new file mode 100644
index 00000000..77b25f4e
--- /dev/null
+++ b/certService/helm/aaf-cert-service/templates/secret.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ .Values.secret.name }}
+type: Opaque
+data:
+ {{ (.Files.Glob "resources/cmpServers.json").AsSecrets }} \ No newline at end of file
diff --git a/certService/helm/aaf-cert-service/values.yaml b/certService/helm/aaf-cert-service/values.yaml
index 9ec51c85..a971edd4 100644
--- a/certService/helm/aaf-cert-service/values.yaml
+++ b/certService/helm/aaf-cert-service/values.yaml
@@ -14,6 +14,9 @@ readiness:
periodSeconds: 10
healthcheck:
path: /actuator/health
+volume:
+ name: aaf-cert-service-volume
+ mountPath: /etc/onap/aaf/certservice
resources:
limits:
@@ -21,4 +24,7 @@ resources:
memory: 2Gi
requests:
cpu: 1
- memory: 1Gi \ No newline at end of file
+ memory: 1Gi
+
+secret:
+ name: aaf-cert-service-secret
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java
index 105b10e7..414f38bb 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfig.java
@@ -20,21 +20,30 @@
package org.onap.aaf.certservice.certification.configuration;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.PostConstruct;
import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
+import javax.annotation.PostConstruct;
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
@Configuration
public class CmpServersConfig {
-
private static final String CMP_SERVERS_CONFIG_FILENAME = "cmpServers.json";
+
+ @Autowired
+ private CmpServersConfigLoader cmpServersConfigLoader;
+ @Value("${app.config.path}")
+ private String configPath;
private List<Cmpv2Server> cmpServers;
@PostConstruct
- private void loadConfiguration() {
- cmpServers = Collections.unmodifiableList(new CmpServersConfigLoader().load(CMP_SERVERS_CONFIG_FILENAME));
+ void loadConfiguration() {
+ String configFilePath = configPath + File.separator + CMP_SERVERS_CONFIG_FILENAME;
+ this.cmpServers = Collections.unmodifiableList(cmpServersConfigLoader.load(configFilePath));
}
public List<Cmpv2Server> getCmpServers() {
diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java
index b31fbcad..c8415ac0 100644
--- a/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java
+++ b/certService/src/main/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoader.java
@@ -21,27 +21,26 @@
package org.onap.aaf.certservice.certification.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import org.onap.aaf.certservice.certification.CertificationModelFactory;
import org.onap.aaf.certservice.certification.configuration.model.CmpServers;
import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+@Component
class CmpServersConfigLoader {
- private static final Logger LOGGER = LoggerFactory.getLogger(CertificationModelFactory.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(CmpServersConfigLoader.class);
List<Cmpv2Server> load(String path) {
List<Cmpv2Server> result = new ArrayList<>();
try {
result = loadConfigFromFile(path).getCmpv2Servers();
- } catch (FileNotFoundException e) {
- LOGGER.error("CMP Servers configuration file not found: ", e);
+ LOGGER.info(String.format("CMP Servers configuration successfully loaded from file '%s'", path));
} catch (IOException e) {
LOGGER.error("Exception occurred during CMP Servers configuration loading: ", e);
}
@@ -50,11 +49,6 @@ class CmpServersConfigLoader {
private CmpServers loadConfigFromFile(String path) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
- URL resource = getClass().getClassLoader().getResource(path);
- if (resource == null) {
- throw new FileNotFoundException();
- }
- String configFilePath = resource.getFile();
- return objectMapper.readValue(new File(configFilePath), CmpServers.class);
+ return objectMapper.readValue(new File(path), CmpServers.class);
}
}
diff --git a/certService/src/main/resources/application.properties b/certService/src/main/resources/application.properties
index b9ce108a..eab43c08 100644
--- a/certService/src/main/resources/application.properties
+++ b/certService/src/main/resources/application.properties
@@ -1,5 +1,10 @@
-#Actuator properties
+# Actuator configuration
management.endpoints.enabled-by-default=false
management.endpoint.health.enabled=true
-springdoc.swagger-ui.path=/docs
springdoc.show-actuator=true
+
+# Swagger configuration
+springdoc.swagger-ui.path=/docs
+
+# AAF CertService app specific configuration
+app.config.path=/etc/onap/aaf/certservice \ No newline at end of file
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java
new file mode 100644
index 00000000..f4421ffe
--- /dev/null
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigLoaderTest.java
@@ -0,0 +1,85 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PROJECT
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. 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.aaf.certservice.certification.configuration;
+
+import org.junit.jupiter.api.Test;
+import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class CmpServersConfigLoaderTest {
+ private static final String EXISTING_CONFIG_FILENAME = "cmpServers.json";
+ private static final String NONEXISTING_CONFIG_FILENAME = "nonexisting_cmpServers.json";
+ private static final Map<String, String> EXPECTED_FIRST_CMP_SERVER = Map.of(
+ "CA_NAME", "TEST",
+ "URL", "http://127.0.0.1/ejbca/publicweb/cmp/cmp",
+ "ISSUER_DN", "CN=ManagementCA",
+ "CA_MODE", "CLIENT",
+ "IAK", "xxx",
+ "RV", "yyy"
+ );
+ private static final Map<String, String> EXPECTED_SECOND_CMP_SERVER = Map.of(
+ "CA_NAME", "TEST2",
+ "URL", "http://127.0.0.1/ejbca/publicweb/cmp/cmpRA",
+ "ISSUER_DN", "CN=ManagementCA2",
+ "CA_MODE", "RA",
+ "IAK", "xxx",
+ "RV", "yyy"
+ );
+
+ @Test
+ public void shouldLoadCmpServersConfigWhenFileAvailable() throws IOException {
+ // Given
+ String path = getClass().getClassLoader().getResource(EXISTING_CONFIG_FILENAME).getFile();
+
+ // When
+ List<Cmpv2Server> cmpServers = new CmpServersConfigLoader().load(path);
+
+ // Then
+ assertThat(cmpServers).isNotNull();
+ assertThat(cmpServers).hasSize(2);
+ verifyThatCmpServerEquals(cmpServers.get(0), EXPECTED_FIRST_CMP_SERVER);
+ verifyThatCmpServerEquals(cmpServers.get(1), EXPECTED_SECOND_CMP_SERVER);
+ }
+
+ @Test()
+ public void shouldReturnEmptyListWhenFileMissing() {
+ // When
+ List<Cmpv2Server> cmpServers = new CmpServersConfigLoader().load(NONEXISTING_CONFIG_FILENAME);
+
+ // Then
+ assertThat(cmpServers).isNotNull();
+ assertThat(cmpServers).isEmpty();
+ }
+
+ private void verifyThatCmpServerEquals(Cmpv2Server cmpv2Server, Map<String, String> expected) {
+ assertThat(cmpv2Server.getCaName()).isEqualTo(expected.get("CA_NAME"));
+ assertThat(cmpv2Server.getUrl()).isEqualTo(expected.get("URL"));
+ assertThat(cmpv2Server.getIssuerDN()).isEqualTo(expected.get("ISSUER_DN"));
+ assertThat(cmpv2Server.getCaMode().name()).isEqualTo(expected.get("CA_MODE"));
+ assertThat(cmpv2Server.getAuthentication().getIak()).isEqualTo(expected.get("IAK"));
+ assertThat(cmpv2Server.getAuthentication().getRv()).isEqualTo(expected.get("RV"));
+ }
+} \ No newline at end of file
diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java
index 4c9c5f66..43094f09 100644
--- a/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java
+++ b/certService/src/test/java/org/onap/aaf/certservice/certification/configuration/CmpServersConfigTest.java
@@ -20,28 +20,54 @@
package org.onap.aaf.certservice.certification.configuration;
-import static org.assertj.core.api.Assertions.assertThat;
-
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
import org.onap.aaf.certservice.CertServiceApplication;
+import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.startsWith;
+
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = CertServiceApplication.class)
+@TestPropertySource(properties = {"app.config.path=/fake/path/to/config"})
class CmpServersConfigTest {
+ private static final List<Cmpv2Server> SAMPLE_CMP_SERVERS = List.of(
+ new Cmpv2Server(),
+ new Cmpv2Server()
+ );
+
+ @MockBean
+ private CmpServersConfigLoader cmpServersConfigLoader;
+
@Autowired
private CmpServersConfig cmpServersConfig;
@Test
- public void shouldLoadCmpServersConfig() {
+ public void shouldCallLoaderWithPathFromPropertiesWhenCreated() {
+ Mockito.verify(cmpServersConfigLoader).load(startsWith("/fake/path/to/config"));
+ }
+
+ @Test
+ public void shouldReturnLoadedServersWhenGetCalled() {
+ // Given
+ Mockito.when(cmpServersConfigLoader.load(any())).thenReturn(SAMPLE_CMP_SERVERS);
+ this.cmpServersConfig.loadConfiguration(); // Manual PostConstruct call
+
+ // When
+ List<Cmpv2Server> receivedCmpServers = this.cmpServersConfig.getCmpServers();
+
// Then
- assertThat(cmpServersConfig.getCmpServers()).isNotNull();
- assertThat(cmpServersConfig.getCmpServers().size()).isEqualTo(2);
- assertThat(cmpServersConfig.getCmpServers().get(0).getCaName()).isEqualTo("TEST");
- assertThat(cmpServersConfig.getCmpServers().get(1).getCaName()).isEqualTo("TEST2");
+ assertThat(receivedCmpServers).hasSize(SAMPLE_CMP_SERVERS.size());
}
} \ No newline at end of file