aboutsummaryrefslogtreecommitdiffstats
path: root/certServicePostProcessor
diff options
context:
space:
mode:
Diffstat (limited to 'certServicePostProcessor')
-rw-r--r--certServicePostProcessor/Dockerfile16
-rw-r--r--certServicePostProcessor/README.md87
-rw-r--r--certServicePostProcessor/pom.xml177
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExecutor.java54
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExitHandler.java34
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/CertificatePostProcessor.java47
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/MainApp.java27
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/CertificateConstants.java31
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitStatus.java56
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitableException.java40
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolver.java42
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/FileTools.java52
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/PasswordReader.java41
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationLoader.java33
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProvider.java82
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/CertificatesPathsValidationException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/ConfigurationException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/AppConfiguration.java56
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/EnvVariable.java51
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitter.java49
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReader.java39
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctions.java57
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopier.java74
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreFileCopyException.java31
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreNotExistException.java31
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProvider.java46
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreMerger.java54
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/AliasConflictException.java31
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/CreateBackupException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/KeystoreInstanceException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/LoadTruststoreException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/MissingTruststoreException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/PasswordReaderException.java29
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreDataOperationException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreFileFactoryException.java30
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/WriteTruststoreFileException.java31
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststore.java166
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreFactory.java48
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststore.java156
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/Truststore.java47
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactory.java64
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAlias.java41
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAliasFactory.java33
-rw-r--r--certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGenerator.java42
-rw-r--r--certServicePostProcessor/src/main/resources/log4j2.xml30
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/AppExecutorTest.java76
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolverTest.java44
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/FileToolsTest.java71
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/PasswordReaderTest.java43
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProviderTest.java141
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitterTest.java107
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReaderTest.java62
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctionsTest.java135
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopierTest.java147
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProviderTest.java63
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreTest.java56
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststoreTest.java128
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TestCertificateProvider.java152
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactoryTest.java109
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreTest.java206
-rw-r--r--certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGeneratorTest.java58
-rw-r--r--certServicePostProcessor/src/test/resources/empty-truststore.pem1
-rw-r--r--certServicePostProcessor/src/test/resources/keystore.p12bin0 -> 2873 bytes
-rw-r--r--certServicePostProcessor/src/test/resources/keystore.pass1
-rw-r--r--certServicePostProcessor/src/test/resources/truststore-jks-uniq.jksbin0 -> 1530 bytes
-rw-r--r--certServicePostProcessor/src/test/resources/truststore-jks.jksbin0 -> 1285 bytes
-rw-r--r--certServicePostProcessor/src/test/resources/truststore-jks.pass1
-rw-r--r--certServicePostProcessor/src/test/resources/truststore-p12.p12bin0 -> 1530 bytes
-rw-r--r--certServicePostProcessor/src/test/resources/truststore-p12.pass1
-rw-r--r--certServicePostProcessor/src/test/resources/truststore-with-private-key.pem56
-rw-r--r--certServicePostProcessor/src/test/resources/truststore.pem28
71 files changed, 3951 insertions, 0 deletions
diff --git a/certServicePostProcessor/Dockerfile b/certServicePostProcessor/Dockerfile
new file mode 100644
index 00000000..8f0f2481
--- /dev/null
+++ b/certServicePostProcessor/Dockerfile
@@ -0,0 +1,16 @@
+FROM docker.io/openjdk:11-jre-slim
+
+ARG VERSION=${version}
+
+RUN groupadd onap && useradd -g onap truststoreMerger
+
+RUN chown -R truststoreMerger:onap /var/log
+
+USER truststoreMerger:onap
+
+COPY target/oom-truststore-merger-${VERSION}.jar ./opt/onap/oom/truststoremerger/oom-truststore-merger.jar
+
+#Run as root allow to manage certificates provided by other containers. It should be change in future
+USER root
+
+ENTRYPOINT ["java","-jar","./opt/onap/oom/truststoremerger/oom-truststore-merger.jar"]
diff --git a/certServicePostProcessor/README.md b/certServicePostProcessor/README.md
new file mode 100644
index 00000000..5a2c2b47
--- /dev/null
+++ b/certServicePostProcessor/README.md
@@ -0,0 +1,87 @@
+# Truststore merger
+
+### Project building
+```
+mvn clean package
+```
+
+### Install the package into the local repository
+```
+mvn clean install
+```
+
+### Building Docker image and install the package into the local repository
+```
+mvn clean install -P docker
+```
+
+### Nexus container image
+```
+nexus3.onap.org:10001/onap/org.onap.oom.platform.cert-service.oom-truststore-merger:latest
+```
+
+### Running application as standalone docker container
+
+Exemplary config.env file with necessary envs
+```
+TRUSTSTORES_PATHS=/var/certs/truststore.jks:/var/certs/truststore.pem
+TRUSTSTORES_PASSWORDS_PATHS=/var/certs/truststoreJks.pass:
+KEYSTORE_SOURCE_PATHS=/var/certs/external/keystore.jks:/var/certs/external/keystore.pass
+KEYSTORE_DESTINATION_PATHS=/var/certs/cert.jks:/var/certs/jks.pass
+```
+TRUSTSTORES_PATHS env indicates paths (separated by ":") where truststores files are located.
+
+TRUSTSTORES_PASSWORDS_PATHS env indicates paths (separated by ":") where files with passwords to truststores are located.
+PEM is not protected by password so its value should be empty
+
+KEYSTORE_SOURCE_PATHS env (optional) indicates paths (separated by ":") where files to copy are located.
+
+KEYSTORE_DESTINATION_PATHS env (optional) indicates paths (separated by ":") to files which should be replaced. Before keystore files override, destination files will be copied with addition of .bak extension.
+
+Execute below command in order to run app as docker container
+```
+docker run \
+ --name oom-truststore-merger \
+ --env-file ./config.env \
+ --mount type=bind,src=<src_path>,dst=/var/certs \
+onap/org.onap.oom.platform.cert-service.oom-truststore-merger:latest
+```
+Before run replace <src_path> with absolute path where you located truststores to merge (eg. /certs/resources/)
+
+Output from merger (when pointed more than one truststore to merge in TRUSTSTORES_PATHS env and provided optional envs) success execution should be:
+1. Created backup file (with .bak ext) of first truststore pointed in TRUSTSTORES_PATHS env
+2. Keystores files listed in KEYSTORE_SOURCE_PATHS env overrides corresponding to them files defined in KEYSTORE_DESTINATION_PATHS env.
+3. Keystores listed in KEYSTORE_SOURCE_PATHS env are in locations taken from KEYSTORE_DESTINATION_PATHS env. Files listed in KEYSTORE_DESTINATION_PATHS env before application run, still exist with appended .bak extension.
+
+Remove docker container:
+```
+docker rm oom-truststore-merger
+```
+
+### Logs locally
+
+path:
+```
+var/log/onap/oom/truststore-merger/truststore-merger.log
+```
+### Logs in Docker container
+```
+docker logs oom-merger
+```
+###Exit codes
+```
+0 Success
+1 Invalid paths in environment variables
+2 Invalid merger configuration
+3 Invalid truststore file-password pair
+4 Cannot read password from file
+5 Cannot create backup file
+6 Cannot initialize keystore instance
+7 Cannot load truststore file
+8 Cannot operate on truststore data
+9 Missing truststore certificates in provided file
+10 Alias conflict detected
+11 Cannot save truststore file
+12 Cannot copy keystore file
+13 Keystore file does not exist
+99 Application exited abnormally
diff --git a/certServicePostProcessor/pom.xml b/certServicePostProcessor/pom.xml
new file mode 100644
index 00000000..d150a9b3
--- /dev/null
+++ b/certServicePostProcessor/pom.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>oom-certservice</artifactId>
+ <groupId>org.onap.oom.platform.cert-service</groupId>
+ <version>2.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>oom-truststore-merger</artifactId>
+ <version>2.0.0-SNAPSHOT</version>
+ <name>oom-truststore-merger</name>
+ <description>Truststore merging application</description>
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>docker-staging</id>
+ <properties>
+ <docker.tag>${project.version}-STAGING-${maven.build.timestamp}</docker.tag>
+ <docker.latest.tag>${project.version}-STAGING-latest</docker.latest.tag>
+ </properties>
+ </profile>
+
+ <profile>
+ <id>docker</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <properties>
+ <os.detected.name>linux</os.detected.name>
+ <os.detected.arch>x86_64</os.detected.arch>
+ <os.detected.classifier>${os.detected.name}-${os.detected.arch}</os.detected.classifier>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>${maven-shade-plugin.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <createDependencyReducedPom>false</createDependencyReducedPom>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>META-INF/*.SF</exclude>
+ <exclude>META-INF/*.DSA</exclude>
+ <exclude>META-INF/*.RSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ <transformers>
+ <transformer
+ implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+ <mainClass>org.onap.oom.certservice.postprocessor.MainApp</mainClass>
+ </transformer>
+ </transformers>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>io.fabric8</groupId>
+ <artifactId>docker-maven-plugin</artifactId>
+ <version>${docker-maven-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>docker-build-image</id>
+ <phase>package</phase>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>docker-push-image</id>
+ <phase>deploy</phase>
+ <goals>
+ <goal>push</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <skipPush>${skipDockerPush}</skipPush>
+ <verbose>true</verbose>
+ <imagePullPolicy>IfNotPresent</imagePullPolicy>
+ <images>
+ <image>
+ <alias>${project.artifactId}</alias>
+ <name>${docker-image.namespace}/${docker-image.name}:${docker-image.tag.latest}
+ </name>
+ <registry>${docker-image.registry}</registry>
+ <build>
+ <dockerFileDir>${project.basedir}</dockerFileDir>
+ <tags>
+ <tag>${project.version}-${maven.build.timestamp}Z</tag>
+ </tags>
+ </build>
+ </image>
+ </images>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <distributionManagement>
+ <repository>
+ <id>ecomp-releases</id>
+ <name>ONAP Release Repository</name>
+ <url>${nexusproxy}${releaseNexusPath}</url>
+ </repository>
+ <snapshotRepository>
+ <id>ecomp-snapshots</id>
+ <name>ONAP Snapshot Repository</name>
+ <url>${nexusproxy}${snapshotNexusPath}</url>
+ </snapshotRepository>
+ <site>
+ <id>ecomp-site</id>
+ <url>dav:${nexusproxy}${sitePath}</url>
+ </site>
+ </distributionManagement>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-log4j2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExecutor.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExecutor.java
new file mode 100644
index 00000000..2ef30b68
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExecutor.java
@@ -0,0 +1,54 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AppExecutor {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AppExecutor.class);
+
+ private AppExitHandler exitHandler;
+
+ AppExecutor() {
+ this(new AppExitHandler());
+ }
+
+ AppExecutor(AppExitHandler exitHandler) {
+ this.exitHandler = exitHandler;
+ }
+
+
+ public void execute(Runnable logic) {
+ try {
+ logic.run();
+ exitHandler.exit(ExitStatus.SUCCESS);
+ } catch (ExitableException e) {
+ LOGGER.error("Application failed: ", e);
+ exitHandler.exit(e.applicationExitStatus());
+ } catch (Exception e) {
+ LOGGER.error("Application failed (unexpected error): ", e);
+ exitHandler.exit(ExitStatus.UNEXPECTED_EXCEPTION);
+ }
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExitHandler.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExitHandler.java
new file mode 100644
index 00000000..15677dc4
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/AppExitHandler.java
@@ -0,0 +1,34 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AppExitHandler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AppExitHandler.class);
+
+ public void exit(ExitStatus exitStatus) {
+ LOGGER.info("Application exits with code [{}] and message: {}",
+ exitStatus.getExitCodeValue(), exitStatus.getMessage());
+ System.exit(exitStatus.getExitCodeValue());
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/CertificatePostProcessor.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/CertificatePostProcessor.java
new file mode 100644
index 00000000..b9038227
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/CertificatePostProcessor.java
@@ -0,0 +1,47 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor;
+
+import org.onap.oom.certservice.postprocessor.common.FileTools;
+import org.onap.oom.certservice.postprocessor.configuration.AppConfigurationLoader;
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.copier.KeystoreCopier;
+import org.onap.oom.certservice.postprocessor.merger.TruststoreMerger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class CertificatePostProcessor implements Runnable {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CertificatePostProcessor.class);
+
+ private AppConfigurationLoader config = new AppConfigurationLoader();
+ private TruststoreMerger merger = new TruststoreMerger();
+ private KeystoreCopier copier = new KeystoreCopier(new FileTools());
+
+ public void run() {
+ LOGGER.debug("Loading configuration...");
+ AppConfiguration configuration = config.loadConfiguration();
+ LOGGER.debug("Starting TruststoreMerger...");
+ merger.mergeTruststores(configuration);
+ LOGGER.debug("Starting KeystoreCopier...");
+ copier.copyKeystores(configuration);
+ LOGGER.debug("Certificate post processing finished successfully.");
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/MainApp.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/MainApp.java
new file mode 100644
index 00000000..f815f489
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/MainApp.java
@@ -0,0 +1,27 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor;
+
+public class MainApp {
+
+ public static void main(String[] args) {
+ new AppExecutor().execute(new CertificatePostProcessor());
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/CertificateConstants.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/CertificateConstants.java
new file mode 100644
index 00000000..3442621b
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/CertificateConstants.java
@@ -0,0 +1,31 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.api;
+
+public class CertificateConstants {
+
+ private CertificateConstants() { }
+
+ public static final String JKS_TYPE = "JKS";
+ public static final String PKCS12_TYPE = "PKCS12";
+ public static final String X_509_CERTIFICATE = "X.509";
+ public static final String BOUNCY_CASTLE_PROVIDER = "BC";
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitStatus.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitStatus.java
new file mode 100644
index 00000000..b6cebeb1
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitStatus.java
@@ -0,0 +1,56 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.api;
+
+public enum ExitStatus {
+
+ SUCCESS(0, "Success"),
+ CERTIFICATES_PATHS_VALIDATION_EXCEPTION(1, "Invalid paths in environment variables"),
+ CONFIGURATION_EXCEPTION(2, "Invalid merger configuration"),
+ TRUSTSTORE_FILE_FACTORY_EXCEPTION(3, "Invalid truststore file-password pair"),
+ PASSWORD_READER_EXCEPTION(4, "Cannot read password from file"),
+ CREATE_BACKUP_EXCEPTION(5, "Cannot create backup file"),
+ KEYSTORE_INSTANCE_EXCEPTION(6, "Cannot initialize keystore instance"),
+ TRUSTSTORE_LOAD_FILE_EXCEPTION(7, "Cannot load truststore file"),
+ TRUSTSTORE_DATA_OPERATION_EXCEPTION(8, "Cannot operate on truststore data"),
+ MISSING_TRUSTSTORE_EXCEPTION(9, "Missing truststore certificates in provided file"),
+ ALIAS_CONFLICT_EXCEPTION(10, "Alias conflict detected"),
+ WRITE_TRUSTSTORE_FILE_EXCEPTION(11, "Cannot save truststore file"),
+ KEYSTORE_FILE_COPY_EXCEPTION(12, "Cannot copy keystore file"),
+ KEYSTORE_NOT_EXIST_EXCEPTION(13, "Keystore file does not exist"),
+ UNEXPECTED_EXCEPTION(99, "Application exited abnormally");
+
+
+ private final int value;
+ private final String message;
+
+ ExitStatus(int value, String message) {
+ this.value = value;
+ this.message = message;
+ }
+
+ public int getExitCodeValue() {
+ return value;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitableException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitableException.java
new file mode 100644
index 00000000..54a7c6a1
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/api/ExitableException.java
@@ -0,0 +1,40 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.api;
+
+public class ExitableException extends RuntimeException {
+
+ private final ExitStatus exitStatus;
+
+ public ExitableException(Throwable cause, ExitStatus exitStatus) {
+ super(cause);
+ this.exitStatus = exitStatus;
+ }
+
+ public ExitableException(String message, ExitStatus exitStatus) {
+ super(message);
+ this.exitStatus = exitStatus;
+ }
+
+ public ExitStatus applicationExitStatus() {
+ return exitStatus;
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolver.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolver.java
new file mode 100644
index 00000000..7a785ae1
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolver.java
@@ -0,0 +1,42 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.common;
+
+import java.io.File;
+
+public final class ExtensionResolver {
+
+ private static final int INDEX_NOT_FOUND = -1;
+
+ private ExtensionResolver() {}
+
+ public static String get(File file) {
+ int extStartIndex = file.getName().lastIndexOf(".");
+ if (extStartIndex == INDEX_NOT_FOUND) {
+ return "";
+ }
+ return file.getName().substring(extStartIndex).toLowerCase();
+ }
+
+ public static boolean checkIfFileExists(File file) {
+ return file.exists();
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/FileTools.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/FileTools.java
new file mode 100644
index 00000000..620d8088
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/FileTools.java
@@ -0,0 +1,52 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.common;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.onap.oom.certservice.postprocessor.merger.exception.CreateBackupException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class FileTools {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FileTools.class);
+ private static final String BACKUP_EXTENSION = ".bak";
+
+ public void createBackup(File file) throws CreateBackupException {
+ LOGGER.debug("Try to create a backup of the file: {}", file.getPath());
+ File backupFile = new File(file.getAbsolutePath() + BACKUP_EXTENSION);
+ try {
+ copy(file, backupFile);
+ } catch (IOException e) {
+ LOGGER.error("Could not create backup of the file: '{}'", file.getPath());
+ throw new CreateBackupException(e);
+ }
+ LOGGER.debug("Backup file created: '{}'", backupFile.getAbsolutePath());
+ }
+
+ public void copy(File source, File destination) throws IOException {
+ LOGGER.debug("Try to copy from '{}' to '{}'.", source.getAbsolutePath(), destination.getAbsolutePath());
+ FileUtils.copyFile(source, destination);
+ LOGGER.debug("File copied from '{}' to '{}'.", source.getAbsolutePath(),
+ destination.getAbsolutePath());
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/PasswordReader.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/PasswordReader.java
new file mode 100644
index 00000000..6e4a5f3a
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/common/PasswordReader.java
@@ -0,0 +1,41 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import org.onap.oom.certservice.postprocessor.merger.exception.PasswordReaderException;
+
+public final class PasswordReader {
+
+ private static final String COULD_NOT_READ_PASSWORD_FROM_FILE_MSG_TEMPLATE = "Could not read password from file: %s";
+
+ private PasswordReader() {
+ }
+
+ public static String readPassword(File file) {
+ try {
+ return Files.readString(file.toPath());
+ } catch (IOException e) {
+ throw new PasswordReaderException(String.format(COULD_NOT_READ_PASSWORD_FROM_FILE_MSG_TEMPLATE, file));
+ }
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationLoader.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationLoader.java
new file mode 100644
index 00000000..a3f49d86
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationLoader.java
@@ -0,0 +1,33 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration;
+
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.configuration.path.DelimitedPathsSplitter;
+import org.onap.oom.certservice.postprocessor.configuration.path.env.EnvReader;
+
+public class AppConfigurationLoader {
+
+ public AppConfiguration loadConfiguration() {
+ DelimitedPathsSplitter pathsSplitter = new DelimitedPathsSplitter();
+ AppConfigurationProvider factory = new AppConfigurationProvider(pathsSplitter, new EnvReader());
+ return factory.createConfiguration();
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProvider.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProvider.java
new file mode 100644
index 00000000..1e9ef8a9
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProvider.java
@@ -0,0 +1,82 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration;
+
+
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.KEYSTORE_DESTINATION_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.KEYSTORE_SOURCE_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PASSWORDS_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PATHS;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import org.onap.oom.certservice.postprocessor.configuration.path.env.EnvReader;
+import org.onap.oom.certservice.postprocessor.configuration.exception.ConfigurationException;
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable;
+import org.onap.oom.certservice.postprocessor.configuration.path.DelimitedPathsSplitter;
+
+public class AppConfigurationProvider {
+
+ private final EnvReader envReader;
+ private final DelimitedPathsSplitter pathsSplitter;
+
+ public AppConfigurationProvider(DelimitedPathsSplitter pathsSplitter, EnvReader envReader) {
+ this.envReader = envReader;
+ this.pathsSplitter = pathsSplitter;
+ }
+
+ public AppConfiguration createConfiguration() {
+ List<String> truststoresPaths = getPaths(TRUSTSTORES_PATHS);
+ List<String> truststoresPasswordsPaths = getPaths(TRUSTSTORES_PASSWORDS_PATHS);
+ List<String> sourceKeystorePaths = getPaths(KEYSTORE_SOURCE_PATHS);
+ List<String> destinationKeystorePaths = getPaths(KEYSTORE_DESTINATION_PATHS);
+
+ ensureSameSize(truststoresPaths, truststoresPasswordsPaths, TRUSTSTORES_PATHS.name(),
+ TRUSTSTORES_PASSWORDS_PATHS.name());
+ ensureSameSize(sourceKeystorePaths, destinationKeystorePaths, KEYSTORE_SOURCE_PATHS.name(),
+ KEYSTORE_DESTINATION_PATHS.name());
+
+ return new AppConfiguration(truststoresPaths, truststoresPasswordsPaths, sourceKeystorePaths,
+ destinationKeystorePaths);
+ }
+
+ private List<String> getPaths(EnvVariable envVariable) {
+ Optional<String> envValue = envReader.getEnv(envVariable.name());
+ isMandatoryEnvPresent(envVariable, envValue);
+ return envValue.isPresent() ? pathsSplitter.getValidatedPaths(envVariable, envValue) : Collections.emptyList();
+ }
+
+ private void isMandatoryEnvPresent(EnvVariable envVariable, Optional<String> envValue) {
+ if (envVariable.isMandatory() && envValue.isEmpty()) {
+ throw new ConfigurationException(envVariable + " mandatory environment variable is not defined");
+ }
+ }
+
+ private void ensureSameSize(List<String> firstList, List<String> secondList, String firstListEnvName,
+ String secondListEnvName) {
+ if (firstList.size() != secondList.size()) {
+ throw new ConfigurationException(
+ "Size of " + firstListEnvName
+ + " does not match size of " + secondListEnvName + " environment variables");
+ }
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/CertificatesPathsValidationException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/CertificatesPathsValidationException.java
new file mode 100644
index 00000000..fb621017
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/CertificatesPathsValidationException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class CertificatesPathsValidationException extends ExitableException {
+
+ public CertificatesPathsValidationException(String errorMessage) {
+ super(errorMessage, ExitStatus.CERTIFICATES_PATHS_VALIDATION_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/ConfigurationException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/ConfigurationException.java
new file mode 100644
index 00000000..c9f9a416
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/exception/ConfigurationException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class ConfigurationException extends ExitableException {
+
+ public ConfigurationException(String errorMessage) {
+ super(errorMessage, ExitStatus.CONFIGURATION_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/AppConfiguration.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/AppConfiguration.java
new file mode 100644
index 00000000..d28dcac5
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/AppConfiguration.java
@@ -0,0 +1,56 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.model;
+
+import java.util.Collections;
+import java.util.List;
+
+public final class AppConfiguration {
+ private final List<String> truststoreFilePaths;
+ private final List<String> truststoreFilePasswordPaths;
+ private final List<String> sourceKeystorePaths;
+ private final List<String> destinationKeystorePaths;
+
+ public AppConfiguration(List<String> truststoreFilePaths,
+ List<String> truststoreFilePasswordPaths, List<String> sourceKeystorePaths,
+ List<String> destinationKeystorePaths) {
+ this.truststoreFilePaths = List.copyOf(truststoreFilePaths);
+ this.truststoreFilePasswordPaths = List.copyOf(truststoreFilePasswordPaths);
+ this.sourceKeystorePaths = List.copyOf(sourceKeystorePaths);
+ this.destinationKeystorePaths = List.copyOf(destinationKeystorePaths);
+ }
+
+ public List<String> getTruststoreFilePaths() {
+ return Collections.unmodifiableList(truststoreFilePaths);
+ }
+
+ public List<String> getTruststoreFilePasswordPaths() {
+ return Collections.unmodifiableList(truststoreFilePasswordPaths);
+ }
+
+
+ public List<String> getDestinationKeystorePaths() {
+ return Collections.unmodifiableList(destinationKeystorePaths);
+ }
+
+ public List<String> getSourceKeystorePaths() {
+ return Collections.unmodifiableList(sourceKeystorePaths);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/EnvVariable.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/EnvVariable.java
new file mode 100644
index 00000000..be49d39c
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/model/EnvVariable.java
@@ -0,0 +1,51 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.model;
+
+import static org.onap.oom.certservice.postprocessor.configuration.path.validation.ValidationFunctions.doesItContainValidCertificatesPaths;
+import static org.onap.oom.certservice.postprocessor.configuration.path.validation.ValidationFunctions.doesItContainValidPasswordPaths;
+import static org.onap.oom.certservice.postprocessor.configuration.path.validation.ValidationFunctions.doesItContainValidPathsToCopy;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+public enum EnvVariable {
+ TRUSTSTORES_PATHS(true, doesItContainValidCertificatesPaths()),
+ TRUSTSTORES_PASSWORDS_PATHS(true, doesItContainValidPasswordPaths()),
+ KEYSTORE_SOURCE_PATHS(false, doesItContainValidPathsToCopy()),
+ KEYSTORE_DESTINATION_PATHS(false, doesItContainValidPathsToCopy());
+
+ boolean isMandatory;
+
+ Predicate<List<String>> validationFunction;
+
+ EnvVariable(boolean isMandatory, Predicate<List<String>> validationFunction) {
+ this.isMandatory = isMandatory;
+ this.validationFunction = validationFunction;
+ }
+
+ public boolean isMandatory() {
+ return isMandatory;
+ }
+
+ public Predicate<List<String>> getValidationFunction() {
+ return validationFunction;
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitter.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitter.java
new file mode 100644
index 00000000..b2e71cb3
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitter.java
@@ -0,0 +1,49 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.path;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import org.onap.oom.certservice.postprocessor.configuration.exception.CertificatesPathsValidationException;
+import org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable;
+
+public class DelimitedPathsSplitter {
+
+ private static final String DELIMITER = ":";
+ private static final int NEGATIVE_SPLIT_LIMIT = -1;
+
+ public List<String> getValidatedPaths(EnvVariable envVariable, Optional<String> envValue)
+ throws CertificatesPathsValidationException {
+ return envValue.filter(this::hasValue)
+ .map(this::splitToList)
+ .filter(envVariable.getValidationFunction())
+ .orElseThrow(() -> new CertificatesPathsValidationException(
+ envVariable + " environment variable does not contain valid paths"));
+ }
+
+ private boolean hasValue(String envValue) {
+ return !envValue.isEmpty();
+ }
+
+ private List<String> splitToList(String stringToSplit) {
+ return Arrays.asList(stringToSplit.split(DELIMITER, NEGATIVE_SPLIT_LIMIT));
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReader.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReader.java
new file mode 100644
index 00000000..f30e43be
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReader.java
@@ -0,0 +1,39 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.path.env;
+
+import java.util.Optional;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnvReader {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(EnvReader.class);
+
+ public Optional<String> getEnv(String name) {
+ return getSystemEnv(name);
+ }
+
+ Optional<String> getSystemEnv(String name) {
+ String value = System.getenv(name);
+ LOGGER.info("Read variable: {} , value: {}", name, value);
+ return Optional.ofNullable(value);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctions.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctions.java
new file mode 100644
index 00000000..f65a21a0
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctions.java
@@ -0,0 +1,57 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.path.validation;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+public final class ValidationFunctions {
+
+ private static final String CERTIFICATE_PATH_REGEX = "^(/[a-zA-Z0-9_-]+)+\\.(pem|jks|p12)";
+ private static final String CERTIFICATE_PASSWORD_PATH_REGEX = "^(/[a-zA-Z0-9_-]+)+\\.pass";
+
+ private ValidationFunctions() {
+ }
+
+ public static Predicate<List<String>> doesItContainValidPasswordPaths() {
+ return paths -> paths.stream().allMatch(ValidationFunctions::isCertificatePasswordPathValid);
+ }
+
+ public static Predicate<List<String>> doesItContainValidCertificatesPaths() {
+ return paths -> paths.stream().allMatch(ValidationFunctions::isCertificatePathValid);
+ }
+
+ public static Predicate<List<String>> doesItContainValidPathsToCopy() {
+ return paths -> paths.stream().allMatch(path ->
+ doesMatch(path, CERTIFICATE_PASSWORD_PATH_REGEX) || isCertificatePathValid(path));
+ }
+
+ private static boolean isCertificatePathValid(String path) {
+ return doesMatch(path, CERTIFICATE_PATH_REGEX);
+ }
+
+ private static boolean isCertificatePasswordPathValid(String path) {
+ return path.isEmpty() || doesMatch(path, CERTIFICATE_PASSWORD_PATH_REGEX);
+ }
+
+ private static boolean doesMatch(String path, String regex) {
+ return path.matches(regex);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopier.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopier.java
new file mode 100644
index 00000000..f5cea212
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopier.java
@@ -0,0 +1,74 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.copier;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import org.onap.oom.certservice.postprocessor.common.FileTools;
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.copier.exception.KeystoreFileCopyException;
+import org.onap.oom.certservice.postprocessor.copier.exception.KeystoreNotExistException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class KeystoreCopier {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(KeystoreCopier.class);
+ private final FileTools fileTools;
+
+ public KeystoreCopier(FileTools fileTools) {
+ this.fileTools = fileTools;
+ }
+
+ public void copyKeystores(AppConfiguration configuration) {
+ final List<String> sources = configuration.getSourceKeystorePaths();
+ final List<String> destinations = configuration.getDestinationKeystorePaths();
+ containsPaths(sources);
+ try {
+ for (int i = 0; i < sources.size(); i++) {
+ copy(sources.get(i), destinations.get(i));
+ }
+ } catch (IOException e) {
+ throw new KeystoreFileCopyException(e);
+ }
+ }
+
+ private void containsPaths(List<String> sources) {
+ if (sources.isEmpty()) {
+ LOGGER.info("No Keystore files to copy");
+ }
+ }
+
+ private void copy(String sourcePath, String destinationPath) throws IOException {
+ final File source = new File(sourcePath);
+ final File destination = new File(destinationPath);
+
+ if (!source.exists()) {
+ throw new KeystoreNotExistException("Keystore file does not exist '" + source.getAbsolutePath() + "'!");
+ }
+
+ if (destination.exists()) {
+ fileTools.createBackup(destination);
+ }
+ fileTools.copy(source, destination);
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreFileCopyException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreFileCopyException.java
new file mode 100644
index 00000000..66190965
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreFileCopyException.java
@@ -0,0 +1,31 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.copier.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class KeystoreFileCopyException extends ExitableException {
+
+ public KeystoreFileCopyException(Exception e) {
+ super(e, ExitStatus.KEYSTORE_FILE_COPY_EXCEPTION);
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreNotExistException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreNotExistException.java
new file mode 100644
index 00000000..37f2f537
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/copier/exception/KeystoreNotExistException.java
@@ -0,0 +1,31 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.copier.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class KeystoreNotExistException extends ExitableException {
+
+ public KeystoreNotExistException(String message) {
+ super(message, ExitStatus.KEYSTORE_NOT_EXIST_EXCEPTION);
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProvider.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProvider.java
new file mode 100644
index 00000000..9e30bd44
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProvider.java
@@ -0,0 +1,46 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.oom.certservice.postprocessor.merger.model.Truststore;
+import org.onap.oom.certservice.postprocessor.merger.model.TruststoreFactory;
+
+public class TruststoreFilesProvider {
+
+
+ private TruststoreFilesProvider() {
+ }
+
+ public static List<Truststore> getTruststoreFiles(List<String> truststoreFilePaths,
+ List<String> truststoreFilePasswordPaths) {
+ List<Truststore> truststoreFiles = new ArrayList<>();
+ for (int i = 0; i < truststoreFilePaths.size(); i++) {
+ String truststorePath = truststoreFilePaths.get(i);
+ String passwordPath = truststoreFilePasswordPaths.get(i);
+
+ Truststore truststore = TruststoreFactory.create(truststorePath, passwordPath);
+ truststoreFiles.add(truststore);
+ }
+
+ return truststoreFiles;
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreMerger.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreMerger.java
new file mode 100644
index 00000000..3cf60da1
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/TruststoreMerger.java
@@ -0,0 +1,54 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger;
+
+import java.util.List;
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.merger.model.Truststore;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+
+public class TruststoreMerger {
+
+ private static final int FIRST_TRUSTSTORE_INDEX = 0;
+ private static final int SECOND_TRUSTSTORE_INDEX = 1;
+
+ public void mergeTruststores(AppConfiguration configuration) {
+ List<Truststore> truststoreFilesList = getTruststoreFiles(configuration);
+
+ Truststore baseFile = truststoreFilesList.get(FIRST_TRUSTSTORE_INDEX);
+ baseFile.createBackup();
+
+ for (int i = SECOND_TRUSTSTORE_INDEX; i < truststoreFilesList.size(); i++) {
+ Truststore truststore = truststoreFilesList.get(i);
+ List<CertificateWithAlias> certificateWrappers = truststore.getCertificates();
+ baseFile.addCertificates(certificateWrappers);
+ }
+
+ baseFile.saveFile();
+ }
+
+ private List<Truststore> getTruststoreFiles(AppConfiguration configuration) {
+ return TruststoreFilesProvider
+ .getTruststoreFiles(
+ configuration.getTruststoreFilePaths(),
+ configuration.getTruststoreFilePasswordPaths()
+ );
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/AliasConflictException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/AliasConflictException.java
new file mode 100644
index 00000000..2e7939b7
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/AliasConflictException.java
@@ -0,0 +1,31 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class AliasConflictException extends ExitableException {
+
+ public AliasConflictException(String errorMessage) {
+ super(errorMessage, ExitStatus.ALIAS_CONFLICT_EXCEPTION);
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/CreateBackupException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/CreateBackupException.java
new file mode 100644
index 00000000..8e99f993
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/CreateBackupException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class CreateBackupException extends ExitableException {
+
+ public CreateBackupException(Exception cause) {
+ super(cause, ExitStatus.CREATE_BACKUP_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/KeystoreInstanceException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/KeystoreInstanceException.java
new file mode 100644
index 00000000..1279dff7
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/KeystoreInstanceException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class KeystoreInstanceException extends ExitableException {
+
+ public KeystoreInstanceException(Exception cause) {
+ super(cause, ExitStatus.KEYSTORE_INSTANCE_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/LoadTruststoreException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/LoadTruststoreException.java
new file mode 100644
index 00000000..b3493fd6
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/LoadTruststoreException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class LoadTruststoreException extends ExitableException {
+
+ public LoadTruststoreException(Exception cause) {
+ super(cause, ExitStatus.TRUSTSTORE_LOAD_FILE_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/MissingTruststoreException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/MissingTruststoreException.java
new file mode 100644
index 00000000..51660f60
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/MissingTruststoreException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class MissingTruststoreException extends ExitableException {
+
+ public MissingTruststoreException(String errorMessage) {
+ super(errorMessage, ExitStatus.MISSING_TRUSTSTORE_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/PasswordReaderException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/PasswordReaderException.java
new file mode 100644
index 00000000..b1bdf1ea
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/PasswordReaderException.java
@@ -0,0 +1,29 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class PasswordReaderException extends ExitableException {
+ public PasswordReaderException(String errorMessage) {
+ super(errorMessage, ExitStatus.PASSWORD_READER_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreDataOperationException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreDataOperationException.java
new file mode 100644
index 00000000..77ae366e
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreDataOperationException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class TruststoreDataOperationException extends ExitableException {
+
+ public TruststoreDataOperationException(Exception cause) {
+ super(cause, ExitStatus.TRUSTSTORE_DATA_OPERATION_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreFileFactoryException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreFileFactoryException.java
new file mode 100644
index 00000000..a87a62a3
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/TruststoreFileFactoryException.java
@@ -0,0 +1,30 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class TruststoreFileFactoryException extends ExitableException {
+ public TruststoreFileFactoryException(String errorMessage) {
+ super(errorMessage, ExitStatus.TRUSTSTORE_FILE_FACTORY_EXCEPTION);
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/WriteTruststoreFileException.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/WriteTruststoreFileException.java
new file mode 100644
index 00000000..f9b772ca
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/exception/WriteTruststoreFileException.java
@@ -0,0 +1,31 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.exception;
+
+import org.onap.oom.certservice.postprocessor.api.ExitStatus;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+
+public class WriteTruststoreFileException extends ExitableException {
+
+ public WriteTruststoreFileException(Exception cause) {
+ super(cause, ExitStatus.WRITE_TRUSTSTORE_FILE_EXCEPTION);
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststore.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststore.java
new file mode 100644
index 00000000..d264d2f4
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststore.java
@@ -0,0 +1,166 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.onap.oom.certservice.postprocessor.merger.exception.AliasConflictException;
+import org.onap.oom.certservice.postprocessor.merger.exception.LoadTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.MissingTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreDataOperationException;
+import org.onap.oom.certservice.postprocessor.merger.exception.WriteTruststoreFileException;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+import org.onap.oom.certservice.postprocessor.common.FileTools;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAliasFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class JavaTruststore extends Truststore {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JavaTruststore.class);
+
+ private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory();
+ private final KeyStore keyStore;
+ private final String password;
+
+
+ private JavaTruststore(KeyStore keyStore, File storeFile, String password) {
+ super(storeFile, new FileTools());
+ this.keyStore = keyStore;
+ this.password = password;
+ }
+
+ public static JavaTruststore createWithLoadingFile(KeyStore keyStore, File storeFile, String password)
+ throws LoadTruststoreException {
+ JavaTruststore javaTruststore = new JavaTruststore(keyStore, storeFile, password);
+ javaTruststore.loadFile();
+ return javaTruststore;
+ }
+
+ public List<CertificateWithAlias> getCertificates() throws ExitableException {
+ LOGGER.debug("Attempt to read certificates from file: {}", storeFile.getPath());
+ List<String> aliases = getTruststoreAliases();
+ if (aliases.isEmpty()) {
+ throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath());
+ }
+ return getWrappedCertificates(aliases);
+ }
+
+ public void addCertificates(List<CertificateWithAlias> certificatesWithAliases)
+ throws ExitableException {
+ LOGGER.debug("Attempt to add certificates for saving to file");
+ if (getTruststoreAliases().isEmpty()) {
+ throw new MissingTruststoreException("Missing certificate aliases in file: " + storeFile.getPath());
+ }
+ for (CertificateWithAlias certificate : certificatesWithAliases) {
+ addCertificate(certificate);
+ }
+ }
+
+ public void saveFile() throws WriteTruststoreFileException {
+ LOGGER.debug("Attempt to save file: {}", storeFile.getPath());
+ try (FileOutputStream outputStream = new FileOutputStream(storeFile)) {
+ keyStore.store(outputStream, this.password.toCharArray());
+ } catch (Exception e) {
+ LOGGER.error("Cannot write truststore file");
+ throw new WriteTruststoreFileException(e);
+ }
+ }
+
+ private void loadFile() throws LoadTruststoreException {
+ try {
+ keyStore.load(new FileInputStream(storeFile), this.password.toCharArray());
+ } catch (Exception e) {
+ LOGGER.error("Cannot load file: {}", storeFile.getPath());
+ throw new LoadTruststoreException(e);
+ }
+ }
+
+ private void addCertificate(CertificateWithAlias certificate)
+ throws TruststoreDataOperationException, AliasConflictException {
+ if (hasAliasConflict(certificate)) {
+ LOGGER.error("Alias conflict detected");
+ throw new AliasConflictException("Alias conflict detected. Alias conflicted: " + certificate.getAlias());
+ }
+ try {
+ keyStore.setCertificateEntry(certificate.getAlias(), certificate.getCertificate());
+ } catch (KeyStoreException e) {
+ LOGGER.error("Cannot merge certificate with alias: {}", certificate.getAlias());
+ throw new TruststoreDataOperationException(e);
+ }
+ }
+
+ private boolean hasAliasConflict(CertificateWithAlias certificate) throws TruststoreDataOperationException {
+ try {
+ return keyStore.containsAlias(certificate.getAlias());
+ } catch (KeyStoreException e) {
+ LOGGER.error("Cannot check alias conflict");
+ throw new TruststoreDataOperationException(e);
+ }
+ }
+
+ private List<CertificateWithAlias> getWrappedCertificates(List<String> aliases)
+ throws TruststoreDataOperationException {
+
+ List<CertificateWithAlias> certificateWrapped = new ArrayList<>();
+
+ for (String alias : aliases) {
+ certificateWrapped.add(createWrappedCertificate(alias));
+ }
+ return certificateWrapped;
+ }
+
+ private CertificateWithAlias createWrappedCertificate(String alias) throws TruststoreDataOperationException {
+ try {
+ return factory.createCertificateWithAlias(keyStore.getCertificate(alias), alias);
+ } catch (KeyStoreException e) {
+ LOGGER.warn("Cannot get certificate with alias: {} ", alias);
+ throw new TruststoreDataOperationException(e);
+ }
+ }
+
+ private List<String> getTruststoreAliases() throws TruststoreDataOperationException {
+ try {
+ List<String> aliases = Collections.list(keyStore.aliases());
+ return getFilteredAlias(aliases);
+ } catch (KeyStoreException e) {
+ LOGGER.warn("Cannot read truststore aliases");
+ throw new TruststoreDataOperationException(e);
+ }
+ }
+
+ private List<String> getFilteredAlias(List<String> aliases) throws KeyStoreException {
+ List<String> filteredAlias = new ArrayList<>();
+ for (String alias : aliases) {
+ if (keyStore.isCertificateEntry(alias)) {
+ filteredAlias.add(alias);
+ }
+ }
+ return filteredAlias;
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreFactory.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreFactory.java
new file mode 100644
index 00000000..4740d0f6
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreFactory.java
@@ -0,0 +1,48 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import java.io.File;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.KeystoreInstanceException;
+import org.onap.oom.certservice.postprocessor.common.PasswordReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JavaTruststoreFactory {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JavaTruststoreFactory.class);
+
+ private JavaTruststoreFactory() {
+ }
+
+ public static Truststore create(File certFile, String truststorePasswordPath, String keystoreType) {
+ String password = PasswordReader.readPassword(new File(truststorePasswordPath));
+ try {
+ return JavaTruststore
+ .createWithLoadingFile(KeyStore.getInstance(keystoreType), certFile, password);
+ } catch (KeyStoreException e) {
+ LOGGER.error("Cannot initialize Java Keystore instance");
+ throw new KeystoreInstanceException(e);
+ }
+ }
+}
+
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststore.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststore.java
new file mode 100644
index 00000000..d7f4bfd2
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststore.java
@@ -0,0 +1,156 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.BOUNCY_CASTLE_PROVIDER;
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.X_509_CERTIFICATE;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
+import org.bouncycastle.util.io.pem.PemObjectGenerator;
+import org.bouncycastle.util.io.pem.PemWriter;
+import org.onap.oom.certservice.postprocessor.merger.exception.MissingTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreDataOperationException;
+import org.onap.oom.certservice.postprocessor.merger.exception.WriteTruststoreFileException;
+import org.onap.oom.certservice.postprocessor.common.FileTools;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAliasFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PemTruststore extends Truststore {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PemTruststore.class);
+
+ private static final boolean APPEND_TO_FILE = true;
+
+ private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory();
+ private final List<CertificateWithAlias> certificatesToBeSaved = new ArrayList<>();
+
+ public PemTruststore(File storeFile) {
+ super(storeFile, new FileTools());
+ }
+
+ public List<CertificateWithAlias> getCertificates()
+ throws TruststoreDataOperationException, MissingTruststoreException {
+ LOGGER.debug("Attempt to read certificates from file: {}", storeFile.getPath());
+ if (isFileWithoutPemCertificate()) {
+ throw new MissingTruststoreException("File does not contain any certificate");
+ }
+ List<Certificate> extractedCertificate = extractCertificatesFromFile();
+ return wrapCertificates(extractedCertificate);
+ }
+
+ public void addCertificates(List<CertificateWithAlias> certificates)
+ throws TruststoreDataOperationException, MissingTruststoreException {
+ LOGGER.debug("Attempt to add certificates for saving to file");
+ if (isFileWithoutPemCertificate()) {
+ LOGGER.error("File does not contain any certificate. File path: {} ", storeFile.getPath());
+ throw new MissingTruststoreException("File does not contain any certificate");
+ }
+ certificatesToBeSaved.addAll(certificates);
+ }
+
+ public void saveFile() throws WriteTruststoreFileException, TruststoreDataOperationException {
+ LOGGER.debug("Attempt to save file: {}", storeFile.getPath());
+ List<Certificate> certificates = certificatesToBeSaved.stream()
+ .map(CertificateWithAlias::getCertificate)
+ .collect(Collectors.toList());
+ String certificatesAsString = transformToStringInPemFormat(certificates);
+ appendToFile(certificatesAsString);
+ }
+
+ boolean isFileWithoutPemCertificate() throws TruststoreDataOperationException {
+ List<Certificate> certificateList = extractCertificatesFromFile();
+ return certificateList.isEmpty();
+ }
+
+ String transformToStringInPemFormat(List<Certificate> certificates) throws TruststoreDataOperationException {
+ StringWriter sw = new StringWriter();
+ List<PemObjectGenerator> generators = transformToPemGenerators(certificates);
+ try (PemWriter pemWriter = new PemWriter(sw)) {
+ for (PemObjectGenerator generator : generators) {
+ pemWriter.writeObject(generator);
+ }
+ } catch (IOException e) {
+ LOGGER.error("Cannot convert certificates to PEM format");
+ throw new TruststoreDataOperationException(e);
+ }
+ return sw.toString();
+ }
+
+ private List<Certificate> extractCertificatesFromFile() throws TruststoreDataOperationException {
+ try (FileInputStream inputStream = new FileInputStream(storeFile)) {
+ Security.addProvider(new BouncyCastleProvider());
+ CertificateFactory factory = CertificateFactory.getInstance(X_509_CERTIFICATE, BOUNCY_CASTLE_PROVIDER);
+ return new ArrayList<>(factory.generateCertificates(inputStream));
+ } catch (Exception e) {
+ LOGGER.error("Cannot read certificates from file: {}", storeFile.getPath());
+ throw new TruststoreDataOperationException(e);
+ }
+ }
+
+ private List<PemObjectGenerator> transformToPemGenerators(List<Certificate> certificates)
+ throws TruststoreDataOperationException {
+ List<PemObjectGenerator> generators = new ArrayList<>();
+ for (Certificate certificate : certificates) {
+ PemObjectGenerator generator = createPemGenerator(certificate);
+ generators.add(generator);
+ }
+ return generators;
+ }
+
+ private JcaMiscPEMGenerator createPemGenerator(Certificate certificate)
+ throws TruststoreDataOperationException {
+ try {
+ return new JcaMiscPEMGenerator(certificate);
+ } catch (IOException e) {
+ LOGGER.error("Cannot convert Certificate Object to PemGenerator Object");
+ throw new TruststoreDataOperationException(e);
+ }
+ }
+
+ private List<CertificateWithAlias> wrapCertificates(List<Certificate> rawCertificates) {
+ return rawCertificates.stream()
+ .map(factory::createPemCertificate)
+ .collect(Collectors.toList());
+ }
+
+ private void appendToFile(String certificatesAsString) throws WriteTruststoreFileException {
+ try {
+ FileOutputStream fileOutputStream = new FileOutputStream(storeFile, APPEND_TO_FILE);
+ fileOutputStream.write(certificatesAsString.getBytes());
+ } catch (Exception e) {
+ LOGGER.error("Cannot write certificates to file");
+ throw new WriteTruststoreFileException(e);
+ }
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/Truststore.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/Truststore.java
new file mode 100644
index 00000000..058613a9
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/Truststore.java
@@ -0,0 +1,47 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import java.io.File;
+import java.util.List;
+import org.onap.oom.certservice.postprocessor.common.FileTools;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+
+public abstract class Truststore {
+
+ final File storeFile;
+
+ private final FileTools fileTools;
+
+ public Truststore(File storeFile, FileTools fileTools) {
+ this.storeFile = storeFile;
+ this.fileTools = fileTools;
+ }
+
+ public void createBackup() {
+ fileTools.createBackup(storeFile);
+ }
+
+ public abstract List<CertificateWithAlias> getCertificates();
+
+ public abstract void addCertificates(List<CertificateWithAlias> certificates);
+
+ public abstract void saveFile();
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactory.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactory.java
new file mode 100644
index 00000000..5167c301
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactory.java
@@ -0,0 +1,64 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.JKS_TYPE;
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.PKCS12_TYPE;
+
+import java.io.File;
+import org.onap.oom.certservice.postprocessor.common.ExtensionResolver;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreFileFactoryException;
+
+public class TruststoreFactory {
+
+ private static final String JKS_EXTENSION = ".jks";
+ private static final String P12_EXTENSION = ".p12";
+ private static final String PEM_EXTENSION = ".pem";
+ private static final String FILE_DOES_NOT_EXIST_MSG_TEMPLATE = "File: %s does not exist";
+ private static final String UNKNOWN_TRUSTSTORE_TYPE_MSG_TEMPLATE = "Unknown truststore extension type: %s";
+
+
+ private TruststoreFactory() {
+ }
+
+ public static Truststore create(String truststoreFilePath, String truststorePasswordPath) {
+ File truststoreFile = new File(truststoreFilePath);
+ if (!ExtensionResolver.checkIfFileExists(truststoreFile)) {
+ throw new TruststoreFileFactoryException(String.format(FILE_DOES_NOT_EXIST_MSG_TEMPLATE, truststoreFile));
+ }
+ return createTypedTruststore(truststoreFile, truststorePasswordPath);
+ }
+
+ private static Truststore createTypedTruststore(File truststoreFile, String truststorePasswordPath) {
+ String extension = ExtensionResolver.get(truststoreFile);
+ switch (extension) {
+ case JKS_EXTENSION:
+ return JavaTruststoreFactory.create(truststoreFile, truststorePasswordPath, JKS_TYPE);
+ case P12_EXTENSION:
+ return JavaTruststoreFactory.create(truststoreFile, truststorePasswordPath, PKCS12_TYPE);
+ case PEM_EXTENSION:
+ return new PemTruststore(truststoreFile);
+ default:
+ throw new TruststoreFileFactoryException(
+ String.format(UNKNOWN_TRUSTSTORE_TYPE_MSG_TEMPLATE, extension));
+ }
+ }
+
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAlias.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAlias.java
new file mode 100644
index 00000000..098ffcd0
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAlias.java
@@ -0,0 +1,41 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model.certificate;
+
+import java.security.cert.Certificate;
+
+public class CertificateWithAlias {
+
+ private final Certificate certificate;
+ private final String alias;
+
+ public CertificateWithAlias(Certificate certificate, String alias) {
+ this.certificate = certificate;
+ this.alias = alias;
+ }
+
+ public String getAlias() {
+ return this.alias;
+ }
+
+ public Certificate getCertificate() {
+ return this.certificate;
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAliasFactory.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAliasFactory.java
new file mode 100644
index 00000000..4ad2b417
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/CertificateWithAliasFactory.java
@@ -0,0 +1,33 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model.certificate;
+
+import java.security.cert.Certificate;
+
+public class CertificateWithAliasFactory {
+
+ public CertificateWithAlias createCertificateWithAlias(Certificate certificate, String alias) {
+ return new CertificateWithAlias(certificate, alias);
+ }
+
+ public CertificateWithAlias createPemCertificate(Certificate certificate) {
+ return new CertificateWithAlias(certificate, PemAliasGenerator.getInstance().getAlias());
+ }
+}
diff --git a/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGenerator.java b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGenerator.java
new file mode 100644
index 00000000..a89b1031
--- /dev/null
+++ b/certServicePostProcessor/src/main/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGenerator.java
@@ -0,0 +1,42 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model.certificate;
+
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class PemAliasGenerator {
+
+ private static final String PREFIX_ALIAS_NAME = "pem-trusted-certificate-";
+ private static final PemAliasGenerator INSTANCE = new PemAliasGenerator();
+ private static AtomicInteger counter = new AtomicInteger(0);
+
+ private PemAliasGenerator() {
+ }
+
+ public static PemAliasGenerator getInstance() {
+ return INSTANCE;
+ }
+
+ public String getAlias() {
+
+ return PREFIX_ALIAS_NAME + counter.getAndIncrement();
+ }
+}
diff --git a/certServicePostProcessor/src/main/resources/log4j2.xml b/certServicePostProcessor/src/main/resources/log4j2.xml
new file mode 100644
index 00000000..697017e3
--- /dev/null
+++ b/certServicePostProcessor/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<Configuration status="INFO">
+
+ <Appenders>
+ <Console name="CONSOLE" target="SYSTEM_OUT">
+ <PatternLayout
+ pattern="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} %highlight{${LOG_LEVEL_PATTERN:-%5p}}{FATAL=red blink, ERROR=red, WARN=yellow bold, INFO=green, DEBUG=green bold, TRACE=blue} %style{%pid}{magenta} [%15.15t] %style{%-40.40C{1.}}{cyan} : %m%n%throwable"/>
+ </Console>
+
+ <RollingFile fileName="var/log/onap/oom/truststore-merger/truststore-merger.log"
+ filePattern="logs/truststore-merger-%d{yyyy-MM-dd}-%i.log" name="ROLLING_FILE">
+ <PatternLayout pattern="[%d{ISO8601}][%-5p][%-5c] %m%n"/>
+ <Policies>
+ <SizeBasedTriggeringPolicy size="64 MB"/>
+ </Policies>
+ <DefaultRolloverStrategy max="10"/>
+ </RollingFile>
+
+ </Appenders>
+
+ <Loggers>
+
+ <Root level="DEBUG">
+ <AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="ROLLING_FILE"/>
+ </Root>
+
+ </Loggers>
+</Configuration>
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/AppExecutorTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/AppExecutorTest.java
new file mode 100644
index 00000000..19833cb8
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/AppExecutorTest.java
@@ -0,0 +1,76 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+import static org.onap.oom.certservice.postprocessor.api.ExitStatus.ALIAS_CONFLICT_EXCEPTION;
+import static org.onap.oom.certservice.postprocessor.api.ExitStatus.SUCCESS;
+import static org.onap.oom.certservice.postprocessor.api.ExitStatus.UNEXPECTED_EXCEPTION;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.oom.certservice.postprocessor.merger.exception.AliasConflictException;
+
+@ExtendWith(MockitoExtension.class)
+class AppExecutorTest {
+
+ @Mock
+ Runnable logic;
+ @Mock
+ AppExitHandler exitHandler;
+ @InjectMocks
+ AppExecutor executor = new AppExecutor();
+
+ @Test
+ void shouldExitWithUnexpectedException() {
+ doThrow(new NullPointerException()).when(logic).run();
+ doNothing().when(exitHandler).exit(UNEXPECTED_EXCEPTION);
+
+ executor.execute(logic);
+
+ verify(exitHandler).exit(UNEXPECTED_EXCEPTION);
+ }
+
+ @Test
+ void shouldExitWithKnownException() {
+ doThrow(new AliasConflictException("")).when(logic).run();
+ doNothing().when(exitHandler).exit(ALIAS_CONFLICT_EXCEPTION);
+
+ executor.execute(logic);
+
+ verify(exitHandler).exit(ALIAS_CONFLICT_EXCEPTION);
+ }
+
+ @Test
+ void shouldExitWithSuccess() {
+ doNothing().when(logic).run();
+ doNothing().when(exitHandler).exit(SUCCESS);
+
+ executor.execute(logic);
+
+ verify(exitHandler).exit(SUCCESS);
+ }
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolverTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolverTest.java
new file mode 100644
index 00000000..8450ab6d
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/ExtensionResolverTest.java
@@ -0,0 +1,44 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.common;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+import java.io.File;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class ExtensionResolverTest {
+
+ @ParameterizedTest
+ @CsvSource(value = {
+ "opt/app/truststore.jks:.jks",
+ "opt/app/truststore.p12:.p12",
+ "opt/app/truststore.pem:.pem",
+ "opt/app/truststore.PEM:.pem",
+ "opt/app/truststore:''",
+ }, delimiter = ':')
+ void shouldReturnCorrectExtension(String filePath, String expectedExtension) {
+ String extension = ExtensionResolver.get(new File(filePath));
+ assertThat(extension).isEqualTo(expectedExtension);
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/FileToolsTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/FileToolsTest.java
new file mode 100644
index 00000000..7b3b28ae
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/FileToolsTest.java
@@ -0,0 +1,71 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.common;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+class FileToolsTest {
+
+ public static final String BAK_EXTENSION = ".bak";
+
+ @TempDir
+ File dir;
+
+ @Test
+ void shouldCreateBackupProvidedFile() throws Exception {
+ //given
+ File fileToBackup = createFile("truststore.pem", "arbitrary content");
+ String backupFilePath = fileToBackup.getPath() + BAK_EXTENSION;
+ //when
+ new FileTools().createBackup(fileToBackup);
+ //then
+ assertThat(fileToBackup).hasSameBinaryContentAs(new File(backupFilePath));
+ }
+
+ @Test
+ void shouldCopyFile() throws IOException {
+ //given
+ File sourceFile = createFile("source.p12", "any content");
+ File destinationFile = new File(dir.getAbsolutePath() + "destination.p12");
+ //when
+ new FileTools().copy(sourceFile, destinationFile);
+ //then
+ assertThat(sourceFile).hasSameBinaryContentAs(destinationFile);
+ }
+
+
+ private File createFile(String name, String content) throws IOException {
+ File file = new File(dir.getAbsolutePath() + File.pathSeparator + name);
+ if (file.createNewFile()) {
+ FileUtils.write(file, content, Charset.defaultCharset());
+ } else {
+ throw new IllegalStateException("File could not be created: " + file.getAbsolutePath());
+ }
+ return file;
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/PasswordReaderTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/PasswordReaderTest.java
new file mode 100644
index 00000000..697eaa83
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/common/PasswordReaderTest.java
@@ -0,0 +1,43 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.common;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+import org.onap.oom.certservice.postprocessor.merger.exception.PasswordReaderException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+class PasswordReaderTest {
+
+ @Test
+ void shouldReturnCorrectPasswordFromFile() throws PasswordReaderException {
+ String fileData = PasswordReader.readPassword(new File("src/test/resources/truststore-jks.pass"));
+ assertThat(fileData).isEqualTo("EOyuFbuYDyq_EhpboM72RHua");
+ }
+
+ @Test
+ void shouldThrowExceptionForNonExistingFile() {
+ assertThatExceptionOfType(PasswordReaderException.class)
+ .isThrownBy(() -> PasswordReader.readPassword(new File("src/test/resources/non-esisting-file.pass")));
+ }
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProviderTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProviderTest.java
new file mode 100644
index 00000000..24e2dab8
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/AppConfigurationProviderTest.java
@@ -0,0 +1,141 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.mockito.Mockito.when;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.KEYSTORE_DESTINATION_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.KEYSTORE_SOURCE_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PASSWORDS_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PATHS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.oom.certservice.postprocessor.configuration.exception.CertificatesPathsValidationException;
+import org.onap.oom.certservice.postprocessor.configuration.exception.ConfigurationException;
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.configuration.path.DelimitedPathsSplitter;
+import org.onap.oom.certservice.postprocessor.configuration.path.env.EnvReader;
+
+@ExtendWith(MockitoExtension.class)
+class AppConfigurationProviderTest {
+
+ private static final String BASE_TRUSTSTORE_PATH = "/opt/app/truststore_";
+ private static final String JKS_EXTENSION = ".jks";
+ private static final String PASS_EXTENSION = ".pass";
+ private static final String SAMPLE_TRUSTSTORES_PATHS = "/opt/app/certificates/truststore.jks:/opt/app/certificates/truststore.pem";
+ private static final String SAMPLE_TRUSTSTORES_PASSWORDS_PATHS = "/opt/app/certificates/truststore.pass:/trust.pass";
+
+ @Mock
+ private DelimitedPathsSplitter pathsSplitter;
+ @Mock
+ private EnvReader envReader;
+ private AppConfigurationProvider provider;
+
+ @BeforeEach
+ void setUp() {
+ provider = new AppConfigurationProvider(pathsSplitter, envReader);
+ }
+
+ @Test
+ void shouldThrowExceptionWhenMandatoryEnvNotPresent() {
+ // given
+ when(envReader.getEnv(TRUSTSTORES_PATHS.name())).thenReturn(Optional.empty());
+ // when, then
+ assertThatExceptionOfType(ConfigurationException.class).isThrownBy(() -> provider.createConfiguration())
+ .withMessageContaining(TRUSTSTORES_PATHS + " mandatory environment variable is not defined");
+ }
+
+ @Test
+ void shouldThrowExceptionWhenTrustorePathsSizesDoNotMatch() {
+ // given
+ List<String> truststores = createListOfPathsWithExtension(2, JKS_EXTENSION);
+ List<String> truststoresPasswords = createListOfPathsWithExtension(1, PASS_EXTENSION);
+
+ mockTruststorePaths(truststores, truststoresPasswords);
+ // when, then
+ assertThatExceptionOfType(ConfigurationException.class)
+ .isThrownBy(() -> provider.createConfiguration())
+ .withMessageContaining("Size of " + TRUSTSTORES_PATHS
+ + " does not match size of " + TRUSTSTORES_PASSWORDS_PATHS + " environment variables");
+ }
+
+ @Test
+ void shouldReturnEmptyListWhenOptionalEnvNotPresent() {
+ // given
+ List<String> truststores = createListOfPathsWithExtension(2, JKS_EXTENSION);
+ List<String> truststoresPasswords = createListOfPathsWithExtension(2, PASS_EXTENSION);
+ mockTruststorePaths(truststores, truststoresPasswords);
+ mockKeystorePaths(Optional.empty(), Optional.empty());
+ // when
+ AppConfiguration paths = provider.createConfiguration();
+ // then
+ assertThat(paths.getDestinationKeystorePaths()).isEmpty();
+ assertThat(paths.getSourceKeystorePaths()).isEmpty();
+ }
+
+ private void mockTruststorePaths(List<String> truststores, List<String> truststoresPasswords) {
+ mockTruststores(truststores);
+ mockTruststoresPasswords(truststoresPasswords);
+ }
+
+ private void mockKeystorePaths(Optional<String> sourceKeystoresPairPaths, Optional<String> destKeystoresPairPaths) {
+ mockKeystoreCopierSourcePaths(sourceKeystoresPairPaths);
+ mockKeystoreCopierDestinationPaths(destKeystoresPairPaths);
+ }
+
+ private void mockTruststores(List<String> truststores) throws CertificatesPathsValidationException {
+ when(envReader.getEnv(TRUSTSTORES_PATHS.name())).thenReturn(Optional.of(SAMPLE_TRUSTSTORES_PATHS));
+ when(pathsSplitter.getValidatedPaths(TRUSTSTORES_PATHS, Optional.of(SAMPLE_TRUSTSTORES_PATHS)))
+ .thenReturn(truststores);
+ }
+
+ private void mockTruststoresPasswords(List<String> truststoresPasswords)
+ throws CertificatesPathsValidationException {
+ Optional<String> passwordsPaths = Optional.of(SAMPLE_TRUSTSTORES_PASSWORDS_PATHS);
+ when(envReader.getEnv(TRUSTSTORES_PASSWORDS_PATHS.name())).thenReturn(passwordsPaths);
+ when(pathsSplitter.getValidatedPaths(TRUSTSTORES_PASSWORDS_PATHS, passwordsPaths))
+ .thenReturn(truststoresPasswords);
+ }
+
+ private void mockKeystoreCopierSourcePaths(Optional<String> paths) {
+ when(envReader.getEnv(KEYSTORE_SOURCE_PATHS.name())).thenReturn(paths);
+ }
+
+ private void mockKeystoreCopierDestinationPaths(Optional<String> paths) {
+ when(envReader.getEnv(KEYSTORE_DESTINATION_PATHS.name())).thenReturn(paths);
+ }
+
+ private List<String> createListOfPathsWithExtension(int numberOfPaths, String passwordExtension) {
+ List<String> paths = new ArrayList<>();
+ while (numberOfPaths-- > 0) {
+ paths.add(BASE_TRUSTSTORE_PATH + numberOfPaths + passwordExtension);
+ }
+ return paths;
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitterTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitterTest.java
new file mode 100644
index 00000000..be1bc394
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/DelimitedPathsSplitterTest.java
@@ -0,0 +1,107 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.path;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PASSWORDS_PATHS;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PATHS;
+
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.oom.certservice.postprocessor.configuration.exception.CertificatesPathsValidationException;
+
+@ExtendWith(MockitoExtension.class)
+class DelimitedPathsSplitterTest {
+
+ private static final String VALID_TRUSTSTORES = "/opt/app/certificates/truststore.jks:/opt/app/certificates/truststore.pem";
+ private static final String VALID_TRUSTSTORES_PASSWORDS = "/opt/app/certificates/truststore.pass:";
+ private static final String VALID_TRUSTSTORES_PASSWORDS_WITH_EMPTY_IN_THE_MIDDLE = "/opt/app/certificates/truststore.pass::/etc/truststore.pass";
+ private static final String INVALID_TRUSTSTORES = "/opt/app/certificates/truststore.jks:/opt/app/certificates/truststore.invalid";
+ private static final String INVALID_TRUSTSTORES_PASSWORDS = "/opt/app/certificates/truststore.pass:/.pass";
+
+ private DelimitedPathsSplitter delimitedPathsSplitter;
+
+ @BeforeEach
+ void setUp() {
+ delimitedPathsSplitter = new DelimitedPathsSplitter();
+ }
+
+ @Test
+ void shouldReturnCorrectListWhenTruststoresValid() {
+ // when, then
+ assertThat(delimitedPathsSplitter.getValidatedPaths(TRUSTSTORES_PATHS, Optional.of(VALID_TRUSTSTORES)))
+ .containsSequence("/opt/app/certificates/truststore.jks",
+ "/opt/app/certificates/truststore.pem");
+ }
+
+ @Test
+ void shouldThrowExceptionWhenTruststoresPathsEnvIsEmpty() {
+ // when, then
+ assertThatExceptionOfType(CertificatesPathsValidationException.class)
+ .isThrownBy(() -> delimitedPathsSplitter.getValidatedPaths(TRUSTSTORES_PATHS, Optional.of("")));
+ }
+
+ @Test
+ void shouldThrowExceptionWhenOneOfTruststoresPathsInvalid() {
+ // when, then
+ assertThatExceptionOfType(CertificatesPathsValidationException.class)
+ .isThrownBy(() -> delimitedPathsSplitter
+ .getValidatedPaths(TRUSTSTORES_PATHS, Optional.of(INVALID_TRUSTSTORES)));
+ }
+
+ @Test
+ void shouldReturnCorrectListWhenTruststoresPasswordsValid() {
+ // when, then
+ assertThat(delimitedPathsSplitter
+ .getValidatedPaths(TRUSTSTORES_PASSWORDS_PATHS, Optional.of(VALID_TRUSTSTORES_PASSWORDS)))
+ .containsSequence("/opt/app/certificates/truststore.pass", "");
+ }
+
+ @Test
+ void shouldReturnCorrectListWhenTruststoresPasswordsContainsEmptyPathsInTheMiddle() {
+ // when, then
+ assertThat(delimitedPathsSplitter.getValidatedPaths(TRUSTSTORES_PASSWORDS_PATHS,
+ Optional.of(VALID_TRUSTSTORES_PASSWORDS_WITH_EMPTY_IN_THE_MIDDLE))).containsSequence(
+ "/opt/app/certificates/truststore.pass",
+ "",
+ "/etc/truststore.pass"
+ );
+ }
+
+ @Test
+ void shouldThrowExceptionWhenTruststoresPasswordsPathEnvIsEmpty() {
+ // when, then
+ assertThatExceptionOfType(CertificatesPathsValidationException.class)
+ .isThrownBy(
+ () -> delimitedPathsSplitter.getValidatedPaths(TRUSTSTORES_PASSWORDS_PATHS, Optional.of("")));
+ }
+
+ @Test
+ void shouldThrowExceptionWhenOneOfTruststorePasswordPathsInvalid() {
+ // when, then
+ assertThatExceptionOfType(CertificatesPathsValidationException.class)
+ .isThrownBy(() -> delimitedPathsSplitter
+ .getValidatedPaths(TRUSTSTORES_PASSWORDS_PATHS, Optional.of(INVALID_TRUSTSTORES_PASSWORDS)));
+ }
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReaderTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReaderTest.java
new file mode 100644
index 00000000..343e5655
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/env/EnvReaderTest.java
@@ -0,0 +1,62 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.path.env;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+import static org.onap.oom.certservice.postprocessor.configuration.model.EnvVariable.TRUSTSTORES_PASSWORDS_PATHS;
+
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+class EnvReaderTest {
+
+ private static final String SAMPLE_PASS_PATH = "/sample/path/trust.pass";
+ EnvReader provider;
+
+ @BeforeEach
+ void setUp() {
+ provider = Mockito.spy(EnvReader.class);
+ }
+
+ @Test
+ void shouldReturnOptionalWithEnv() {
+ // given
+ String envName = TRUSTSTORES_PASSWORDS_PATHS.name();
+ when(provider.getSystemEnv(envName)).thenReturn(Optional.of(SAMPLE_PASS_PATH));
+ // when
+ Optional<String> result = provider.getEnv(envName);
+ // then
+ assertThat(result).isEqualTo(Optional.of(SAMPLE_PASS_PATH));
+ }
+
+ @Test
+ void shouldReturnEmptyOptional() {
+ // given
+ String envName = TRUSTSTORES_PASSWORDS_PATHS.name();
+ // when
+ Optional<String> result = provider.getEnv(envName);
+ // then
+ assertThat(result).isEmpty();
+ }
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctionsTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctionsTest.java
new file mode 100644
index 00000000..f65147a9
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/configuration/path/validation/ValidationFunctionsTest.java
@@ -0,0 +1,135 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.configuration.path.validation;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.onap.oom.certservice.postprocessor.configuration.path.validation.ValidationFunctions.doesItContainValidCertificatesPaths;
+import static org.onap.oom.certservice.postprocessor.configuration.path.validation.ValidationFunctions.doesItContainValidPasswordPaths;
+import static org.onap.oom.certservice.postprocessor.configuration.path.validation.ValidationFunctions.doesItContainValidPathsToCopy;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+class ValidationFunctionsTest {
+
+ @Test
+ void shouldValidateWithSuccessCorrectCertificatesPaths() {
+ // given
+ List<String> certPaths = Arrays.asList("/opt/app/certificates/truststore.p12");
+ // when
+ boolean result = doesItContainValidCertificatesPaths().test(certPaths);
+ // then
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldValidateWithFailureCertificatesPathsWithOneEmptyPath() {
+ // given
+ List<String> certPaths = Arrays.asList("/opt/app/certificates/truststore.p12", "");
+ // when
+ boolean result = doesItContainValidCertificatesPaths().test(certPaths);
+ // then
+ assertThat(result).isFalse();
+ }
+
+ @Test
+ void shouldValidateWithFailureCertificatesPathsWithOnePathWhichHasIncorrectExtension() {
+ // given
+ List<String> certPaths = Arrays.asList("/opt/app/certificates/truststore.txt", "/opt/cert.p12");
+ // when
+ boolean result = doesItContainValidCertificatesPaths().test(certPaths);
+ // then
+ assertThat(result).isFalse();
+ }
+
+ @Test
+ void shouldValidateWithSuccessCertificatesPasswordPaths() {
+ // given
+ List<String> passwordPaths = Arrays.asList("/opt/app/certificates/truststore.pass", "");
+ // when
+ boolean result = doesItContainValidPasswordPaths().test(passwordPaths);
+ // then
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldValidateWithSuccessCertificatePasswordsPathsWhichContainsEmptyPathsInTheMiddle() {
+ // given
+ List<String> passwordPaths = Arrays.asList("/opt/app/certificates/truststore.pass", "", "/etc/truststore.pass");
+ // when
+ boolean result = doesItContainValidPasswordPaths().test(passwordPaths);
+ // then
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldValidateWithFailureCertificatesPasswordsPathsWithIncorrectExtension() {
+ // given
+ List<String> passwordPaths = Arrays.asList("/pass.txt");
+ // when
+ boolean result = doesItContainValidPasswordPaths().test(passwordPaths);
+ // then
+ assertThat(result).isFalse();
+ }
+
+ @Test
+ void shouldValidateWithFailureCertificatesPasswordPathsWithMissingPrecedingSlash() {
+ // given
+ List<String> passwordPaths = Arrays.asList("jks.pass");
+ // when
+ boolean result = doesItContainValidPasswordPaths().test(passwordPaths);
+ // then
+ assertThat(result).isFalse();
+ }
+
+ @Test
+ void shouldValidateWithSuccessSourcePathsToCopyFiles() {
+ // given
+ List<String> sourcePaths = Arrays.asList("/opt/dcae/cacert/external/keystore.p12",
+ "/opt/dcae/cacert/external/keystore.pass");
+ // when
+ boolean result = doesItContainValidPathsToCopy().test(sourcePaths);
+ // then
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldValidateWithSuccessDestinationPathsToCopyFiles() {
+ // given
+ List<String> sourcePaths = Arrays.asList("/opt/dcae/cacert/cert.p12","/opt/dcae/cacert/p12.pass");
+ // when
+ boolean result = doesItContainValidPathsToCopy().test(sourcePaths);
+ // then
+ assertThat(result).isTrue();
+ }
+
+ @Test
+ void shouldValidateWithFailureDestinationPathsWithIncorrectExtension() {
+ // given
+ List<String> sourcePaths = Arrays.asList("/opt/dcae/cacert/cert.txt","/opt/dcae/cacert/p12.other");
+ // when
+ boolean result = doesItContainValidPathsToCopy().test(sourcePaths);
+ // then
+ assertThat(result).isFalse();
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopierTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopierTest.java
new file mode 100644
index 00000000..99193a8d
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/copier/KeystoreCopierTest.java
@@ -0,0 +1,147 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.copier;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.onap.oom.certservice.postprocessor.common.FileTools;
+import org.onap.oom.certservice.postprocessor.configuration.model.AppConfiguration;
+import org.onap.oom.certservice.postprocessor.copier.exception.KeystoreFileCopyException;
+import org.onap.oom.certservice.postprocessor.copier.exception.KeystoreNotExistException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+public class KeystoreCopierTest {
+
+ private static final String SOURCE_CONTENT = "source content";
+ private static final String DESTINATION_CONTENT = "destination content";
+
+ @TempDir
+ File dir;
+
+ private KeystoreCopier copier = new KeystoreCopier(new FileTools());
+
+ @Test
+ void shouldDoNothingForEmptySourceFileList() {
+ AppConfiguration configuration = createEmptyConfiguration();
+
+ copier.copyKeystores(configuration);
+
+ assertThat(dir.listFiles()).isEmpty();
+ }
+
+
+ @Test
+ void shouldCopyFileAndCreateBackup() throws IOException {
+ File source = createFile("source.p12", SOURCE_CONTENT);
+ File destination = createFile("destination.p12", DESTINATION_CONTENT);
+ File backup = declareFile("destination.p12.bak");
+ AppConfiguration configuration = createConfiguration(source, destination);
+
+ copier.copyKeystores(configuration);
+
+ assertThat(readFile(destination)).isEqualTo(readFile(source));
+ assertThat(backup.exists()).isTrue();
+ assertThat(readFile(backup)).isEqualTo(DESTINATION_CONTENT);
+ }
+
+ @Test
+ void shouldCopyFileWithoutCreatingBackup() throws IOException {
+ File source = createFile("source.p12", SOURCE_CONTENT);
+ File destination = declareFile("destination.p12");
+ File backup = declareFile("destination.p12.bak");
+ AppConfiguration configuration = createConfiguration(source, destination);
+
+ copier.copyKeystores(configuration);
+
+ assertThat(destination.exists()).isTrue();
+ assertThat(readFile(destination)).isEqualTo(readFile(source));
+ assertThat(backup.exists()).isFalse();
+ }
+
+ @Test
+ void shouldThrowKeystoreNotExistException() throws IOException {
+ File source = declareFile("source.p12");
+ File destination = declareFile("destination.p12");
+ File backup = declareFile("destination.p12.bak");
+ AppConfiguration configuration = createConfiguration(source, destination);
+
+ assertThatExceptionOfType(KeystoreNotExistException.class).isThrownBy( () ->
+ copier.copyKeystores(configuration)
+ );
+
+ assertThat(source.exists()).isFalse();
+ assertThat(destination.exists()).isFalse();
+ assertThat(backup.exists()).isFalse();
+ }
+
+ @Test
+ void shouldThrowKeystoreFileCopyException() throws IOException {
+ File source = createFile("source.p12", SOURCE_CONTENT);
+ source.setReadable(false);
+ File destination = declareFile("destination.p12");
+ File backup = declareFile("destination.p12.bak");
+ AppConfiguration configuration = createConfiguration(source, destination);
+
+ assertThatExceptionOfType(KeystoreFileCopyException.class).isThrownBy( () ->
+ copier.copyKeystores(configuration)
+ );
+
+ assertThat(source.exists()).isTrue();
+ assertThat(destination.exists()).isFalse();
+ assertThat(backup.exists()).isFalse();
+ }
+
+ private AppConfiguration createConfiguration(File source, File destination) {
+ return new AppConfiguration(Collections.emptyList(), Collections.emptyList(),
+ Collections.singletonList(source.getAbsolutePath()),
+ Collections.singletonList(destination.getAbsolutePath()));
+ }
+
+ private AppConfiguration createEmptyConfiguration() {
+ return new AppConfiguration(Collections.emptyList(), Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList());
+ }
+
+ private String readFile(File file) throws IOException {
+ return FileUtils.readFileToString(file, Charset.defaultCharset());
+ }
+
+ private File declareFile(String name) {
+ return new File(dir.getAbsolutePath() + File.pathSeparator + name);
+ }
+
+ private File createFile(String name, String content) throws IOException {
+ File file = new File(dir.getAbsolutePath() + File.pathSeparator + name);
+ if (file.createNewFile()) {
+ FileUtils.write(file, content, Charset.defaultCharset());
+ } else {
+ throw new IllegalStateException("File could not be created: " + file.getAbsolutePath());
+ }
+ return file;
+ }
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProviderTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProviderTest.java
new file mode 100644
index 00000000..9040b53d
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/TruststoreFilesProviderTest.java
@@ -0,0 +1,63 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.onap.oom.certservice.postprocessor.merger.exception.KeystoreInstanceException;
+import org.onap.oom.certservice.postprocessor.merger.exception.LoadTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.PasswordReaderException;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreFileFactoryException;
+import org.onap.oom.certservice.postprocessor.merger.model.Truststore;
+import org.onap.oom.certservice.postprocessor.merger.model.TruststoreFactory;
+
+class TruststoreFilesProviderTest {
+
+ private static final String TRUSTSTORE_JKS_PATH = "src/test/resources/truststore-jks.jks";
+ private static final String TRUSTSTORE_JKS_PASS_PATH = "src/test/resources/truststore-jks.pass";
+ private static final String TRUSTSTORE_P12_PATH = "src/test/resources/truststore-p12.p12";
+ private static final String TRUSTSTORE_P12_PASS_PATH = "src/test/resources/truststore-p12.pass";
+ private static final String TRUSTSTORE_PEM_PATH = "src/test/resources/truststore.pem";
+ private static final String EMPTY_PASS_PATH = "";
+
+ @Test
+ void shouldReturnTruststoreFilesList()
+ throws TruststoreFileFactoryException, PasswordReaderException, LoadTruststoreException, KeystoreInstanceException {
+ //given
+ List<String> truststorePaths = Arrays.asList(TRUSTSTORE_JKS_PATH, TRUSTSTORE_P12_PATH, TRUSTSTORE_PEM_PATH);
+ List<String> truststorePasswordPaths = Arrays
+ .asList(TRUSTSTORE_JKS_PASS_PATH, TRUSTSTORE_P12_PASS_PATH, EMPTY_PASS_PATH);
+
+ //when
+ List<Truststore> truststoreFilesList = TruststoreFilesProvider
+ .getTruststoreFiles(truststorePaths, truststorePasswordPaths);
+
+ //then
+ assertThat(truststoreFilesList.size()).isEqualTo(3);
+ TruststoreFactory.create(TRUSTSTORE_JKS_PATH, TRUSTSTORE_JKS_PASS_PATH);
+ TruststoreFactory.create(TRUSTSTORE_P12_PATH, TRUSTSTORE_P12_PASS_PATH);
+ TruststoreFactory.create(TRUSTSTORE_PEM_PATH, EMPTY_PASS_PATH);
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreTest.java
new file mode 100644
index 00000000..93a5359b
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/JavaTruststoreTest.java
@@ -0,0 +1,56 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+import org.onap.oom.certservice.postprocessor.merger.exception.AliasConflictException;
+import org.onap.oom.certservice.postprocessor.merger.exception.MissingTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+
+class JavaTruststoreTest {
+
+ @Test
+ void throwExceptionWhenAliasConflictDetected() throws Exception {
+ //given
+ Truststore p12Truststore = TestCertificateProvider.getSampleP12Truststore();
+
+ List<CertificateWithAlias> certificateFromJks = TestCertificateProvider
+ .getSampleJksTruststoreFile().getCertificates();
+
+ //when //then
+ assertThatExceptionOfType(AliasConflictException.class)
+ .isThrownBy(() -> p12Truststore.addCertificates(certificateFromJks));
+ }
+
+ @Test
+ void throwExceptionWhenFileNotContainsTruststoreEntry() throws ExitableException {
+ //given
+ Truststore p12Truststore = TestCertificateProvider.getSampleP12Keystore();
+
+ //when//then
+ assertThatExceptionOfType(MissingTruststoreException.class)
+ .isThrownBy(() -> p12Truststore.getCertificates());
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststoreTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststoreTest.java
new file mode 100644
index 00000000..af254896
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/PemTruststoreTest.java
@@ -0,0 +1,128 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreSpi;
+import java.security.cert.Certificate;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.jupiter.api.Test;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+import org.onap.oom.certservice.postprocessor.merger.exception.MissingTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreDataOperationException;
+import org.onap.oom.certservice.postprocessor.merger.exception.WriteTruststoreFileException;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+
+class PemTruststoreTest {
+
+ private static final int EXPECTED_ONE = 1;
+
+ @Test
+ void getCertificatesShouldThrowExceptionWhenFileNotContainsCertificate() {
+ //given
+ File emptyPemFile = TestCertificateProvider.getEmptyPemFile();
+ PemTruststore pemCertificate = new PemTruststore(emptyPemFile);
+ //when//then
+ assertThatExceptionOfType(MissingTruststoreException.class)
+ .isThrownBy(pemCertificate::getCertificates);
+ }
+
+ @Test
+ void shouldThrowExceptionWhenCannotSaveFile() {
+ //given
+ KeyStoreSpi keyStoreSpi = mock(KeyStoreSpi.class);
+ KeyStore keyStore = new KeyStore(keyStoreSpi, null, "") {
+ };
+ File pemFile = TestCertificateProvider.getEmptyPemFile();
+ pemFile.setWritable(false);
+ PemTruststore pem = new PemTruststore(pemFile);
+
+ //when. then
+ assertThatExceptionOfType(WriteTruststoreFileException.class)
+ .isThrownBy(pem::saveFile);
+ }
+
+ @Test
+ void transformToStringInPemFormatShouldCorrectlyTransform() throws ExitableException, IOException {
+ //given
+ Truststore pemTruststore = TestCertificateProvider.getSamplePemTruststoreFile();
+
+ List<CertificateWithAlias> wrappedCertificates = pemTruststore.getCertificates();
+ List<Certificate> certificateList = unWrapCertificate(wrappedCertificates);
+ File notEmptyPemFile = TestCertificateProvider.getNotEmptyPemFile();
+ PemTruststore pemCertificate = new PemTruststore(notEmptyPemFile);
+
+ //when
+ String certificateTransformed = pemCertificate.transformToStringInPemFormat(certificateList);
+
+ //then
+ String expected = TestCertificateProvider.getExpectedPemCertificateAsString();
+ assertThat(certificateTransformed).isEqualTo(expected);
+ }
+
+ @Test
+ void fileNotContainsPemCertificateShouldReturnTrueIfFileNotContainsCertificate()
+ throws TruststoreDataOperationException {
+ //given
+ File emptyPemFile = TestCertificateProvider.getEmptyPemFile();
+ PemTruststore pemCertificate = new PemTruststore(emptyPemFile);
+ //when//then
+ assertThat(pemCertificate.isFileWithoutPemCertificate()).isTrue();
+ }
+
+ @Test
+ void fileNotContainsPemCertificateShouldReturnFalseIfFileContainsCertificate()
+ throws TruststoreDataOperationException {
+ //given
+ File notEmptyPemFile = TestCertificateProvider.getNotEmptyPemFile();
+ PemTruststore pemCertificate = new PemTruststore(notEmptyPemFile);
+
+ //when//then
+ assertThat(pemCertificate.isFileWithoutPemCertificate()).isFalse();
+ }
+
+ @Test
+ void privateKeyIsSkippedWhileReadingCertificates() throws ExitableException {
+ //given
+ File pemTruststoreFile = TestCertificateProvider.getPemWithPrivateKeyFile();
+ PemTruststore pemCertificate = new PemTruststore(pemTruststoreFile);
+
+ //when
+ List<CertificateWithAlias> certificate = pemCertificate.getCertificates();
+
+ //then
+ assertThat(certificate).hasSize(EXPECTED_ONE);
+ }
+
+ private List<Certificate> unWrapCertificate(List<CertificateWithAlias> certificateWithAliases) {
+ return certificateWithAliases
+ .stream()
+ .map(CertificateWithAlias::getCertificate)
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TestCertificateProvider.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TestCertificateProvider.java
new file mode 100644
index 00000000..f32e09ce
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TestCertificateProvider.java
@@ -0,0 +1,152 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.JKS_TYPE;
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.PKCS12_TYPE;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import org.onap.oom.certservice.postprocessor.merger.exception.KeystoreInstanceException;
+import org.onap.oom.certservice.postprocessor.merger.exception.LoadTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.PasswordReaderException;
+
+public final class TestCertificateProvider {
+
+ public static final String SAMPLE_P12_TRUSTSTORE_FILE_PATH = "src/test/resources/truststore-p12.p12";
+ public static final String SAMPLE_P12_TRUSTSTORE_PASSWORD_PATH = "src/test/resources/truststore-p12.pass";
+ public static final String TMP_P12_TRUSTSTORE_FILE_PATH = "src/test/resources/tmp-truststore-p12.p12";
+
+ public static final String SAMPLE_P12_KEYSTORE_FILE_PATH = "src/test/resources/keystore.p12";
+ public static final String SAMPLE_P12_KEYSTORE_PASSWORD_PATH = "src/test/resources/keystore.pass";
+
+ public static final String SAMPLE_JKS_TRUSTSTORE_FILE_PATH = "src/test/resources/truststore-jks.jks";
+ public static final String SAMPLE_JKS_TRUSTSTORE_UNIQUE_ALIAS_FILE_PATH = "src/test/resources/truststore-jks-uniq.jks";
+ public static final String SAMPLE_JKS_TRUSTSTORE_PASSWORD_PATH = "src/test/resources/truststore-jks.pass";
+ public static final String TMP_JKS_TRUSTSTORE_FILE_PATH = "src/test/resources/tmp-truststore-jks.jks";
+
+ public static final String SAMPLE_PEM_TRUSTSTORE_FILE_PATH = "src/test/resources/truststore.pem";
+ public static final String EMPTY_PEM_TRUSTSTORE_FILE_PATH = "src/test/resources/empty-truststore.pem";
+ public static final String TMP_PEM_TRUSTSTORE_FILE_PATH = "src/test/resources/tmp-truststore.pem";
+ public static final String SAMPLE_PEM_TRUSTSTORE_WITH_PRIVATE_KEY_FILE_PATH = "src/test/resources/truststore-with-private-key.pem";
+
+ public static final String PEM_FILE_PATH = "src/test/resources/truststore.pem";
+ public static final String PEM_BACKUP_FILE_PATH = "src/test/resources/truststore.pem.bak";
+
+ private TestCertificateProvider() {
+ }
+
+ public static Truststore getSampleP12Truststore()
+ throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ return createJavaTruststore(SAMPLE_P12_TRUSTSTORE_FILE_PATH, SAMPLE_P12_TRUSTSTORE_PASSWORD_PATH, PKCS12_TYPE);
+ }
+
+ public static Truststore getSampleP12Keystore()
+ throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ return createJavaTruststore(SAMPLE_P12_KEYSTORE_FILE_PATH, SAMPLE_P12_KEYSTORE_PASSWORD_PATH, PKCS12_TYPE);
+ }
+
+ public static Truststore createTmpP12TruststoreFile()
+ throws IOException, LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ copyFile(SAMPLE_P12_TRUSTSTORE_FILE_PATH, TMP_P12_TRUSTSTORE_FILE_PATH);
+ return createJavaTruststore(TMP_P12_TRUSTSTORE_FILE_PATH, SAMPLE_P12_TRUSTSTORE_PASSWORD_PATH, PKCS12_TYPE);
+ }
+
+ public static Truststore getSamplePemTruststoreFile() {
+ return getPemTruststoreInstance(SAMPLE_PEM_TRUSTSTORE_FILE_PATH);
+ }
+
+ public static Truststore createEmptyTmpPemTruststoreFile()
+ throws IOException {
+ copyFile(EMPTY_PEM_TRUSTSTORE_FILE_PATH, TMP_PEM_TRUSTSTORE_FILE_PATH);
+ return getPemTruststoreInstance(TMP_PEM_TRUSTSTORE_FILE_PATH);
+ }
+
+ public static Truststore createTmpPemTruststoreFile()
+ throws IOException {
+ copyFile(SAMPLE_PEM_TRUSTSTORE_FILE_PATH, TMP_PEM_TRUSTSTORE_FILE_PATH);
+ return getPemTruststoreInstance(TMP_PEM_TRUSTSTORE_FILE_PATH);
+ }
+
+ public static String getExpectedPemCertificateAsString() throws IOException {
+ Path samplePemFilePath = Paths.get(SAMPLE_PEM_TRUSTSTORE_FILE_PATH);
+ return Files.readString(samplePemFilePath);
+ }
+
+ public static Truststore getSampleJksTruststoreFile()
+ throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ return createJavaTruststore(SAMPLE_JKS_TRUSTSTORE_FILE_PATH, SAMPLE_JKS_TRUSTSTORE_PASSWORD_PATH, JKS_TYPE);
+ }
+
+ public static Truststore getSampleJksTruststoreFileWithUniqueAlias()
+ throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ return createJavaTruststore(SAMPLE_JKS_TRUSTSTORE_UNIQUE_ALIAS_FILE_PATH, SAMPLE_JKS_TRUSTSTORE_PASSWORD_PATH,
+ JKS_TYPE);
+ }
+
+ public static Truststore createTmpJksTruststoreFileWithUniqAlias()
+ throws IOException, LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ copyFile(SAMPLE_JKS_TRUSTSTORE_UNIQUE_ALIAS_FILE_PATH, TMP_JKS_TRUSTSTORE_FILE_PATH);
+ return createJavaTruststore(TMP_JKS_TRUSTSTORE_FILE_PATH, SAMPLE_JKS_TRUSTSTORE_PASSWORD_PATH, JKS_TYPE);
+ }
+
+ public static File getEmptyPemFile() {
+ return getFile(EMPTY_PEM_TRUSTSTORE_FILE_PATH);
+ }
+
+ public static File getNotEmptyPemFile() {
+ return getFile(SAMPLE_PEM_TRUSTSTORE_FILE_PATH);
+ }
+
+ public static File getPemWithPrivateKeyFile() {
+ return getFile(SAMPLE_PEM_TRUSTSTORE_WITH_PRIVATE_KEY_FILE_PATH);
+ }
+
+ public static void removeTemporaryFiles() throws IOException {
+ Files.deleteIfExists(Paths.get(TMP_PEM_TRUSTSTORE_FILE_PATH));
+ Files.deleteIfExists(Paths.get(TMP_JKS_TRUSTSTORE_FILE_PATH));
+ Files.deleteIfExists(Paths.get(TMP_P12_TRUSTSTORE_FILE_PATH));
+ Files.deleteIfExists(Paths.get(PEM_BACKUP_FILE_PATH));
+ }
+
+ private static Truststore createJavaTruststore(String filePath, String password, String instanceType)
+ throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ File certFile = getFile(filePath);
+ return JavaTruststoreFactory.create(certFile, password, instanceType);
+ }
+
+ private static Truststore getPemTruststoreInstance(
+ String tmpPemTruststoreFilePath) {
+ File file = getFile(tmpPemTruststoreFilePath);
+ return new PemTruststore(file);
+ }
+
+ private static void copyFile(String sourcePath, String destPath) throws IOException {
+ Files.copy(Paths.get(sourcePath), Paths.get(destPath), StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ private static File getFile(String path) {
+ return new File(path);
+ }
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactoryTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactoryTest.java
new file mode 100644
index 00000000..42bf533a
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreFactoryTest.java
@@ -0,0 +1,109 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.oom.certservice.postprocessor.merger.exception.KeystoreInstanceException;
+import org.onap.oom.certservice.postprocessor.merger.exception.LoadTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.PasswordReaderException;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreFileFactoryException;
+
+@ExtendWith(MockitoExtension.class)
+class TruststoreFactoryTest {
+
+ private static final String TRUSTSTORE_JKS_PATH = "src/test/resources/truststore-jks.jks";
+ private static final String TRUSTSTORE_JKS_PASS_PATH = "src/test/resources/truststore-jks.pass";
+ private static final String TRUSTSTORE_P12_PATH = "src/test/resources/truststore-p12.p12";
+ private static final String TRUSTSTORE_P12_PASS_PATH = "src/test/resources/truststore-p12.pass";
+ private static final String TRUSTSTORE_PEM_PATH = "src/test/resources/truststore.pem";
+ private static final String EMPTY_PASS_PATH = "";
+ private static final String TRUSTSTORE_UNKNOWN_EXTENSION_PATH = "src/test/resources/truststore-jks.unknown";
+ private static final String NON_EXISTING_TRUSTSTORE_PATH = "src/test/resources/non-existing-truststore.jks";
+
+ @Test
+ void shouldReturnCorrectJksTruststoreForJksFile()
+ throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException {
+ //given, when
+ Truststore truststore = TruststoreFactory
+ .create(TRUSTSTORE_JKS_PATH, TRUSTSTORE_JKS_PASS_PATH);
+
+ //then
+ assertThat(truststore).isInstanceOf(Truststore.class);
+ }
+
+ @Test
+ void shouldReturnCorrectP12TruststoreForP12File()
+ throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException {
+ //given, when
+ Truststore truststore = TruststoreFactory
+ .create(TRUSTSTORE_P12_PATH, TRUSTSTORE_P12_PASS_PATH);
+
+ //then
+ assertThat(truststore).isInstanceOf(Truststore.class);
+ }
+
+ @Test
+ void shouldReturnCorrectPemTruststoreForPemFile()
+ throws LoadTruststoreException, PasswordReaderException, TruststoreFileFactoryException, KeystoreInstanceException {
+ //given, when
+ Truststore truststore = TruststoreFactory
+ .create(TRUSTSTORE_PEM_PATH,
+ EMPTY_PASS_PATH);
+
+ //then
+ assertThat(truststore).isInstanceOf(Truststore.class);
+ }
+
+ @Test
+ void shouldThrowExceptionForInvalidP12PassPath() {
+ assertThatExceptionOfType(PasswordReaderException.class).isThrownBy(
+ () -> TruststoreFactory.create(TRUSTSTORE_P12_PATH, EMPTY_PASS_PATH)
+ );
+ }
+
+ @Test
+ void shouldThrowExceptionForInvalidJksPassPath() {
+ assertThatExceptionOfType(PasswordReaderException.class).isThrownBy(
+ () -> TruststoreFactory.create(TRUSTSTORE_JKS_PATH, EMPTY_PASS_PATH)
+ );
+ }
+
+ @Test
+ void shouldThrowExceptionForUnknownTruststoreExtension() {
+ assertThatExceptionOfType(TruststoreFileFactoryException.class).isThrownBy(
+ () -> TruststoreFactory
+ .create(TRUSTSTORE_UNKNOWN_EXTENSION_PATH, TRUSTSTORE_JKS_PASS_PATH)
+ );
+ }
+
+ @Test
+ void shouldThrowExceptionForNonExistingTruststoreFile() {
+ assertThatExceptionOfType(TruststoreFileFactoryException.class).isThrownBy(
+ () -> TruststoreFactory.create(NON_EXISTING_TRUSTSTORE_PATH, TRUSTSTORE_JKS_PASS_PATH)
+ );
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreTest.java
new file mode 100644
index 00000000..8ef148a8
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/TruststoreTest.java
@@ -0,0 +1,206 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.onap.oom.certservice.postprocessor.api.CertificateConstants.X_509_CERTIFICATE;
+import static org.onap.oom.certservice.postprocessor.merger.model.TestCertificateProvider.PEM_BACKUP_FILE_PATH;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.onap.oom.certservice.postprocessor.api.CertificateConstants;
+import org.onap.oom.certservice.postprocessor.api.ExitableException;
+import org.onap.oom.certservice.postprocessor.merger.exception.CreateBackupException;
+import org.onap.oom.certservice.postprocessor.merger.exception.KeystoreInstanceException;
+import org.onap.oom.certservice.postprocessor.merger.exception.LoadTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.MissingTruststoreException;
+import org.onap.oom.certservice.postprocessor.merger.exception.PasswordReaderException;
+import org.onap.oom.certservice.postprocessor.merger.exception.TruststoreDataOperationException;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAlias;
+import org.onap.oom.certservice.postprocessor.merger.model.certificate.CertificateWithAliasFactory;
+
+class TruststoreTest {
+
+ private static final String BACKUP_EXTENSION = ".bak";
+
+ private static final int EXPECTED_ONE = 1;
+ public static final int EXPECTED_THREE = 3;
+ public static final int FIRST_ELEMENT = 0;
+
+ private final CertificateWithAliasFactory factory = new CertificateWithAliasFactory();
+
+ @Test
+ void createBackupShouldCreateFileWithExtension() throws CreateBackupException {
+ //given
+ File pemFile = new File(TestCertificateProvider.PEM_FILE_PATH);
+ Truststore truststore = new PemTruststore(pemFile);
+ //when
+ truststore.createBackup();
+
+ //then
+ File backupFile = new File(PEM_BACKUP_FILE_PATH);
+ assertThat(backupFile.getName().endsWith(BACKUP_EXTENSION)).isTrue();
+ assertThat(backupFile.isFile()).isTrue();
+ }
+
+ @ParameterizedTest
+ @MethodSource("truststoreProvider")
+ void truststoreShouldReadCertificatesFromFile(Truststore truststore) throws ExitableException {
+ //when
+
+ List<CertificateWithAlias> certificates = truststore.getCertificates();
+ Certificate certificate = certificates.get(FIRST_ELEMENT).getCertificate();
+
+ //then
+ assertThat(certificates).hasSize(EXPECTED_ONE);
+ assertThat(certificate.getType()).isEqualTo(X_509_CERTIFICATE);
+ }
+
+ @Test
+ void jksTruststoreShouldAddDifferentCertificates() throws Exception {
+ //given
+ Truststore jksTruststore = TestCertificateProvider.createTmpJksTruststoreFileWithUniqAlias();
+
+ List<CertificateWithAlias> certificateFromP12 = TestCertificateProvider.getSampleP12Truststore()
+ .getCertificates();
+
+ List<CertificateWithAlias> certificateFromPem = TestCertificateProvider
+ .getSamplePemTruststoreFile().getCertificates();
+
+ //when
+
+ jksTruststore.addCertificates(certificateFromP12);
+
+ jksTruststore.addCertificates(certificateFromPem);
+
+ jksTruststore.saveFile();
+
+ //then
+
+ assertThat(jksTruststore.getCertificates()).hasSize(EXPECTED_THREE);
+ }
+
+ @Test
+ void p12TruststoreShouldAddDifferentCertificates() throws Exception {
+ //given
+ Truststore p12Truststore = TestCertificateProvider.createTmpP12TruststoreFile();
+
+ List<CertificateWithAlias> certificateFromJks = TestCertificateProvider
+ .getSampleJksTruststoreFileWithUniqueAlias().getCertificates();
+
+ List<CertificateWithAlias> certificateFromPem = TestCertificateProvider
+ .getSamplePemTruststoreFile().getCertificates();
+
+ //when
+
+ p12Truststore.addCertificates(certificateFromJks);
+ p12Truststore.addCertificates(certificateFromPem);
+ p12Truststore.saveFile();
+
+ //then
+
+ assertThat(p12Truststore.getCertificates()).hasSize(EXPECTED_THREE);
+ }
+
+ @Test
+ void pemTruststoreShouldAddDifferentCertificates() throws IOException, ExitableException {
+ //given
+ Truststore pemTruststore = TestCertificateProvider
+ .createTmpPemTruststoreFile();
+
+ List<CertificateWithAlias> certificateFromJks = TestCertificateProvider
+ .getSampleJksTruststoreFileWithUniqueAlias().getCertificates();
+
+ List<CertificateWithAlias> certificateFromP12 = TestCertificateProvider.getSampleP12Truststore()
+ .getCertificates();
+
+ //when
+
+ pemTruststore.addCertificates(certificateFromJks);
+
+ pemTruststore.addCertificates(certificateFromP12);
+
+ pemTruststore.saveFile();
+
+ //then
+
+ List<CertificateWithAlias> addedCertificates = pemTruststore.getCertificates();
+ Certificate certificate = addedCertificates.get(FIRST_ELEMENT).getCertificate();
+
+ assertThat(pemTruststore.getCertificates()).hasSize(EXPECTED_THREE);
+ assertThat(certificate.getType()).isEqualTo(X_509_CERTIFICATE);
+ }
+
+ @Test
+ void shouldThrowExceptionWhenFileNotContainsCertificate() throws IOException {
+ //given
+ Truststore tmpPemTruststoreFile = TestCertificateProvider
+ .createEmptyTmpPemTruststoreFile();
+ //when//then
+ assertThatExceptionOfType(MissingTruststoreException.class)
+ .isThrownBy(() -> tmpPemTruststoreFile.getCertificates());
+ }
+
+ @Test
+ void shouldThrowExceptionWhenCannotConvertCertificateToPem() throws Exception {
+ //given
+ Truststore pemTruststore = TestCertificateProvider.createTmpPemTruststoreFile();
+ Certificate certificate = mock(Certificate.class);
+
+ when(certificate.getEncoded()).thenThrow(new CertificateEncodingException());
+
+ List<CertificateWithAlias> certificateFromPem = new ArrayList<>();
+ certificateFromPem.add(factory.createPemCertificate(certificate));
+
+ pemTruststore.addCertificates(certificateFromPem);
+
+ //when //then
+ assertThatExceptionOfType(TruststoreDataOperationException.class)
+ .isThrownBy(() -> pemTruststore.saveFile());
+ }
+
+ @AfterEach
+ void removeTemporaryFiles() throws IOException {
+ TestCertificateProvider.removeTemporaryFiles();
+ }
+
+ private static Stream<Arguments> truststoreProvider()
+ throws LoadTruststoreException, KeystoreInstanceException, PasswordReaderException {
+ return Stream.of(
+ Arguments.of(TestCertificateProvider.getSampleJksTruststoreFile()),
+ Arguments.of(TestCertificateProvider.getSampleP12Truststore()),
+ Arguments.of(TestCertificateProvider.getSamplePemTruststoreFile())
+ );
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGeneratorTest.java b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGeneratorTest.java
new file mode 100644
index 00000000..03989f6f
--- /dev/null
+++ b/certServicePostProcessor/src/test/java/org/onap/oom/certservice/postprocessor/merger/model/certificate/PemAliasGeneratorTest.java
@@ -0,0 +1,58 @@
+/*============LICENSE_START=======================================================
+ * oom-truststore-merger
+ * ================================================================================
+ * 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.oom.certservice.postprocessor.merger.model.certificate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+
+class PemAliasGeneratorTest {
+
+ private static final String PREFIX_ALIAS_NAME = "pem-trusted-certificate-";
+ static final int GENERATED_ALIASES_NUMBER = 100;
+
+ @Test
+ void aliasHasPemPrefix() {
+ //given
+ PemAliasGenerator pemAliasGenerator = PemAliasGenerator.getInstance();
+ //when
+ String alias = pemAliasGenerator.getAlias();
+ //then
+ assertThat(alias).contains(PREFIX_ALIAS_NAME);
+ }
+
+ @Test
+ void generatedAliasesHaveUniqNames() {
+ //given
+ PemAliasGenerator pemAliasGenerator = PemAliasGenerator.getInstance();
+ Set<String> aliases = new HashSet<>();
+
+ //when
+ for (int i = 0; i < GENERATED_ALIASES_NUMBER; i++) {
+ aliases.add(pemAliasGenerator.getAlias());
+ }
+
+ //then
+ assertThat(aliases).hasSize(GENERATED_ALIASES_NUMBER);
+ }
+
+}
diff --git a/certServicePostProcessor/src/test/resources/empty-truststore.pem b/certServicePostProcessor/src/test/resources/empty-truststore.pem
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/empty-truststore.pem
@@ -0,0 +1 @@
+
diff --git a/certServicePostProcessor/src/test/resources/keystore.p12 b/certServicePostProcessor/src/test/resources/keystore.p12
new file mode 100644
index 00000000..bc047a98
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/keystore.p12
Binary files differ
diff --git a/certServicePostProcessor/src/test/resources/keystore.pass b/certServicePostProcessor/src/test/resources/keystore.pass
new file mode 100644
index 00000000..665ff8e6
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/keystore.pass
@@ -0,0 +1 @@
+Foh49MJNYI7S_pEzE9gvUDSu \ No newline at end of file
diff --git a/certServicePostProcessor/src/test/resources/truststore-jks-uniq.jks b/certServicePostProcessor/src/test/resources/truststore-jks-uniq.jks
new file mode 100644
index 00000000..76ce8bc4
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore-jks-uniq.jks
Binary files differ
diff --git a/certServicePostProcessor/src/test/resources/truststore-jks.jks b/certServicePostProcessor/src/test/resources/truststore-jks.jks
new file mode 100644
index 00000000..38229811
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore-jks.jks
Binary files differ
diff --git a/certServicePostProcessor/src/test/resources/truststore-jks.pass b/certServicePostProcessor/src/test/resources/truststore-jks.pass
new file mode 100644
index 00000000..7426fd4d
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore-jks.pass
@@ -0,0 +1 @@
+EOyuFbuYDyq_EhpboM72RHua \ No newline at end of file
diff --git a/certServicePostProcessor/src/test/resources/truststore-p12.p12 b/certServicePostProcessor/src/test/resources/truststore-p12.p12
new file mode 100644
index 00000000..0fa8aecc
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore-p12.p12
Binary files differ
diff --git a/certServicePostProcessor/src/test/resources/truststore-p12.pass b/certServicePostProcessor/src/test/resources/truststore-p12.pass
new file mode 100644
index 00000000..86cc5aac
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore-p12.pass
@@ -0,0 +1 @@
+88y9v5D8H3SG6bZWRVHDfOAo \ No newline at end of file
diff --git a/certServicePostProcessor/src/test/resources/truststore-with-private-key.pem b/certServicePostProcessor/src/test/resources/truststore-with-private-key.pem
new file mode 100644
index 00000000..95179062
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore-with-private-key.pem
@@ -0,0 +1,56 @@
+-----BEGIN CERTIFICATE-----
+MIIEszCCAxugAwIBAgIUE+27eIlr12tQ+AMxkJTf2Y+ycOEwDQYJKoZIhvcNAQEL
+BQAwYTEjMCEGCgmSJomT8ixkAQEME2MtMDRjYmE2YjhhMDQ5ODEyNGQxFTATBgNV
+BAMMDE1hbmFnZW1lbnRDQTEjMCEGA1UECgwaRUpCQ0EgQ29udGFpbmVyIFF1aWNr
+c3RhcnQwHhcNMjAwNzA4MTIzODU4WhcNMzAwNzA4MTIzODU4WjBhMSMwIQYKCZIm
+iZPyLGQBAQwTYy0wNGNiYTZiOGEwNDk4MTI0ZDEVMBMGA1UEAwwMTWFuYWdlbWVu
+dENBMSMwIQYDVQQKDBpFSkJDQSBDb250YWluZXIgUXVpY2tzdGFydDCCAaIwDQYJ
+KoZIhvcNAQEBBQADggGPADCCAYoCggGBALTlx22Ld87VO5QgkD7OJvx81a8xLRWt
+b4cqmLSBRKw+jTjX4fHCtLh98hXNtYXJ9nxPa2t8MKR/I00Wf1razX1IYN9H/diV
+uICjyMxDyK6nwEMpqaWiQgOQx1N4TjNhr19ULTbyFLQMVfXy1OrTsfoWQ2omvRxN
+LIoVKwPHd92KG6iqJDZU14ErfA6UtypDV+4rOKQBh0JrfFI/KxKFKRH3e0oDxD8c
+PIOUpYVccVv/4Gbc0ZRs8KK0uPZN73LlQccYzPrSk/VAUeuZ52Wqk6dNrq5FHSCe
+EwPbx6aqgLwhTLlYAJqmYuDsGU9ZL09buCVKim1pjZiPaoaYAvv3KHdjEKAu9NxF
+dezd4JZ24hqYCA7EGnKgyjHxA0SiD/B8f+aBdRGDZbMlH1gKFKivjuHSfPwRv6Op
+p8ykEzk3yp0RcqSflVPg0mj+LPViYo/loLLOLybFFR7BetyFieN5QV7BKRyfc7Qi
+Se6Idh1nLIrYR9ek8BDkEE9u/JiTT0gP3QIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
+AQH/MB8GA1UdIwQYMBaAFDYtHGSe9lYaC9+WnNT91wuiMlkjMB0GA1UdDgQWBBQ2
+LRxknvZWGgvflpzU/dcLojJZIzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL
+BQADggGBAIcLj76GVhYSuVaWMMCVlVl8rHhYYufT9z2X7G/0D1G655/dAeAJLltL
+S4T7SZI44XKfVH4ztc4TO6OEMLZzslcfDzv/tUzL4EOsXtBTpsK9JgHP2lzCE+aj
+a7uxn5SGWlu0YmT/++2d+QYaVVAjqalal8NsppOYCh8GB84TXbQjOMWcR9YBozZf
+DSy3/vDNMuggZfdEOMMP57M10NoOKor+8eMGB42k4NR+G2npYHZ4uh1Ifk+eoTAh
+o5O0iz3+/8eMTkLavqpnfzBhWHfRTI8wUu6zgm+QI+tsqhPePRuwauD8r79JBnPW
+0gayZI5jIWTwvufpweKMgLyQbiGVUDtsr2c43kJ6XHoEf0ACUzbJKtGDD3Y7H/G1
+5Q7hBWbQwhUpiVeRnofS9jHQPWu0Ueq4/784hy+yPWotBIeIWEy4KzKTS+GaRDm0
+OSYtta/BdU0iZO/PzzTC5yIzwrsaq+5Idp16mub7mCAW0B36x0Phmr0DQWpZwxmX
+9envV9HcJw==
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCeCRM315FGH1Fa
+nlHRo/JfNwPi+xAor+cC4b/5qEIsGI9Zwgg9rzs/k9XOyUYoWMCNzn8c3nTYhd8h
+8KzPu7o5thiHsr1z6luVPf9zF6K4UJupR0Vba812n7Z8Ye/uyOBu0TeE6RGL7Vxv
+2cKDBLKHIRpexhic2+NkfhZGyfU5kB6IMQBs08LC4wmiPffCWhoWcLk9QbNlJL0d
+3g389oWZQ2NVD2zCvkKe4+LfaNE1Rzk+1Wb+fHhLbL/2tFi9bbM8GjzVewREZekw
+vS4fD8i/Sdx85m35QqzX33b1KbUPmZummmyC37l2oihfWrNKxcpC0alYvfwypHZp
+E26Xy2D/AgMBAAECggEABUJeDlyxK/k81twv8t8W4M5O5c3fIst/z5u9rMxJr3f9
+xUnsxki/mwULd39BQ3R4q/90QXyxvMbvvwxoY91mfCcwN8vd/C6Pb68JgkYGF0Yv
+d/m0OC+lPc5g31DPEE5FEcsKovSyrcpvahWAIKYWXuLeIstK5GV48s4zZZWxAIJa
+7IhLst4I3Y7B6vmPHCutOxL6VXPllhe1gAI/tRWH0Hpbk/KiN0jGirTWo9FrNgAZ
+aRLcrS+a4sZuVZBMe7/NR4qXs+NbafFcuWcgRdgZLoktnKyWk5/WuhRXVuTY6H5B
+pBgrffaab+qMDuziQ2SyHlm1eCnQGbl/++9UPAHZ6QKBgQDQIpVwqzfDsGxsBFo5
+y6wL5uWP8oiDoAkTjX41tgFy5G+ccHaIle/N8U+yrMkgW4tKKYFdREfA9eNxLbsB
+Dy6MkYlbE6cWbcf42QN7/Nn0jWBVrSNBssAPdQYtCJw+07/Qn1rWVIkTNHpqvEV7
+T9+JgLtSD9d3yMEeW/wWpF0PBQKBgQDCYQEQ2iwqyMtsd5GRZFXboBWAVdjfuEd9
+7sZ3SM6z3U1fkKXImdncnihlLN2Ll7tMftGLMF8yxT4OWHPC9Tn7qnatlc3oSVIm
+82Kj0S0j0dr0V4tjpxAhcfuDh1n02A+JQX1gK/rQN/H8JMqpc5FySTV3lBswTvAs
+Gdk7J2tHMwKBgDeX1TS39vglCoC7lOH1Heo77TtKu930hBgd5gUwrShkDc/KVk7b
+RadLek8uSbaD3Suc9HnWABhxVSPo5Bc/V96iDP8vu6SJBC3awUx/2DOzA3U+/rjQ
+pu46AsFKmHlLk+OEfP3crJRdowkZarGqPvn6UY50vse27qZOSYI+usCFAoGBAJhF
+fZxCDY+GtTVHhdWsEEZ45d8fYUIBDqBsyTTw6Fym5NIUcorvW2gkzehUeUm9l5CZ
+WHX9ctZHBhIe4LC9gqrQIyBg1mk95wl0aLWETCRfZXM8kYmDenN441tqUOIp0CHq
+F9mbGmS7LuojuE9+pVYuW6BNee8iJ6ukpDRe8P9ZAoGAHbXYDvWfNgHE4w15uCpE
+riR19yvlWk9tsswdefhyIb36/2qX7+4cQLZsD9b/nVF+GVwbXFgn/qjRQyds+YUD
+dpD/KciWewZRhlQvWChEH/hZrzauBnkE0qcMURW6Xf7NHn/7d+jembEc3bkyjnEI
+6yNDF7D4l5W6gvqgiN5VSM8=
+-----END RSA PRIVATE KEY-----
diff --git a/certServicePostProcessor/src/test/resources/truststore.pem b/certServicePostProcessor/src/test/resources/truststore.pem
new file mode 100644
index 00000000..3268e3a6
--- /dev/null
+++ b/certServicePostProcessor/src/test/resources/truststore.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEszCCAxugAwIBAgIUE+27eIlr12tQ+AMxkJTf2Y+ycOEwDQYJKoZIhvcNAQEL
+BQAwYTEjMCEGCgmSJomT8ixkAQEME2MtMDRjYmE2YjhhMDQ5ODEyNGQxFTATBgNV
+BAMMDE1hbmFnZW1lbnRDQTEjMCEGA1UECgwaRUpCQ0EgQ29udGFpbmVyIFF1aWNr
+c3RhcnQwHhcNMjAwNzA4MTIzODU4WhcNMzAwNzA4MTIzODU4WjBhMSMwIQYKCZIm
+iZPyLGQBAQwTYy0wNGNiYTZiOGEwNDk4MTI0ZDEVMBMGA1UEAwwMTWFuYWdlbWVu
+dENBMSMwIQYDVQQKDBpFSkJDQSBDb250YWluZXIgUXVpY2tzdGFydDCCAaIwDQYJ
+KoZIhvcNAQEBBQADggGPADCCAYoCggGBALTlx22Ld87VO5QgkD7OJvx81a8xLRWt
+b4cqmLSBRKw+jTjX4fHCtLh98hXNtYXJ9nxPa2t8MKR/I00Wf1razX1IYN9H/diV
+uICjyMxDyK6nwEMpqaWiQgOQx1N4TjNhr19ULTbyFLQMVfXy1OrTsfoWQ2omvRxN
+LIoVKwPHd92KG6iqJDZU14ErfA6UtypDV+4rOKQBh0JrfFI/KxKFKRH3e0oDxD8c
+PIOUpYVccVv/4Gbc0ZRs8KK0uPZN73LlQccYzPrSk/VAUeuZ52Wqk6dNrq5FHSCe
+EwPbx6aqgLwhTLlYAJqmYuDsGU9ZL09buCVKim1pjZiPaoaYAvv3KHdjEKAu9NxF
+dezd4JZ24hqYCA7EGnKgyjHxA0SiD/B8f+aBdRGDZbMlH1gKFKivjuHSfPwRv6Op
+p8ykEzk3yp0RcqSflVPg0mj+LPViYo/loLLOLybFFR7BetyFieN5QV7BKRyfc7Qi
+Se6Idh1nLIrYR9ek8BDkEE9u/JiTT0gP3QIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
+AQH/MB8GA1UdIwQYMBaAFDYtHGSe9lYaC9+WnNT91wuiMlkjMB0GA1UdDgQWBBQ2
+LRxknvZWGgvflpzU/dcLojJZIzAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL
+BQADggGBAIcLj76GVhYSuVaWMMCVlVl8rHhYYufT9z2X7G/0D1G655/dAeAJLltL
+S4T7SZI44XKfVH4ztc4TO6OEMLZzslcfDzv/tUzL4EOsXtBTpsK9JgHP2lzCE+aj
+a7uxn5SGWlu0YmT/++2d+QYaVVAjqalal8NsppOYCh8GB84TXbQjOMWcR9YBozZf
+DSy3/vDNMuggZfdEOMMP57M10NoOKor+8eMGB42k4NR+G2npYHZ4uh1Ifk+eoTAh
+o5O0iz3+/8eMTkLavqpnfzBhWHfRTI8wUu6zgm+QI+tsqhPePRuwauD8r79JBnPW
+0gayZI5jIWTwvufpweKMgLyQbiGVUDtsr2c43kJ6XHoEf0ACUzbJKtGDD3Y7H/G1
+5Q7hBWbQwhUpiVeRnofS9jHQPWu0Ueq4/784hy+yPWotBIeIWEy4KzKTS+GaRDm0
+OSYtta/BdU0iZO/PzzTC5yIzwrsaq+5Idp16mub7mCAW0B36x0Phmr0DQWpZwxmX
+9envV9HcJw==
+-----END CERTIFICATE-----