Merge "Removing AAF references from Cert-Service in OOM repo. Certificates regenerate...
authorBogumil Zebek <bogumil.zebek@nokia.com>
Wed, 5 Aug 2020 12:33:59 +0000 (12:33 +0000)
committerGerrit Code Review <gerrit@onap.org>
Wed, 5 Aug 2020 12:33:59 +0000 (12:33 +0000)
20 files changed:
pom.xml
trustStoreMerger/Dockerfile [new file with mode: 0644]
trustStoreMerger/pom.xml [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/AppExitHandler.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/MainApp.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/EnvProvider.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/PathValidator.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProvider.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProviderException.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfiguration.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationException.java [new file with mode: 0644]
trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java [new file with mode: 0644]
trustStoreMerger/src/main/resources/log4j2.xml [new file with mode: 0644]
trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/TrustStoreMergerTest.java [new file with mode: 0644]
trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/PathValidatorTest.java [new file with mode: 0644]
trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProviderTest.java [new file with mode: 0644]
trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactoryTest.java [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index b0f25e6..919ac7b 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -75,6 +75,7 @@
     <modules>
         <module>certService</module>
         <module>certServiceClient</module>
+        <module>trustStoreMerger</module>
     </modules>
 
     <build>
diff --git a/trustStoreMerger/Dockerfile b/trustStoreMerger/Dockerfile
new file mode 100644 (file)
index 0000000..63d15c4
--- /dev/null
@@ -0,0 +1,13 @@
+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
+
+ENTRYPOINT ["java","-jar","./opt/onap/oom/truststoremerger/oom-truststore-merger.jar"]
diff --git a/trustStoreMerger/pom.xml b/trustStoreMerger/pom.xml
new file mode 100644 (file)
index 0000000..7f0db36
--- /dev/null
@@ -0,0 +1,169 @@
+<?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>aaf-certservice</artifactId>
+        <groupId>org.onap.aaf.certservice</groupId>
+        <version>1.2.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>oom-truststore-merger</artifactId>
+    <version>1.2.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.truststoremerger.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>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>
+    </dependencies>
+</project>
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/AppExitHandler.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/AppExitHandler.java
new file mode 100644 (file)
index 0000000..c257756
--- /dev/null
@@ -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.truststoremerger;
+
+import org.onap.oom.truststoremerger.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 following exit code: {} and message: {}",
+                exitStatus.getExitCodeValue(), exitStatus.getMessage());
+        System.exit(exitStatus.getExitCodeValue());
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/MainApp.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/MainApp.java
new file mode 100644 (file)
index 0000000..a26b9de
--- /dev/null
@@ -0,0 +1,28 @@
+/*============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.truststoremerger;
+
+public class MainApp {
+
+    public static void main(String[] args) {
+        TrustStoreMerger trustStoreMerger = new TrustStoreMerger(new AppExitHandler());
+        trustStoreMerger.run();
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/TrustStoreMerger.java
new file mode 100644 (file)
index 0000000..ee57b3a
--- /dev/null
@@ -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.truststoremerger;
+
+import org.onap.oom.truststoremerger.api.ExitStatus;
+import org.onap.oom.truststoremerger.api.ExitableException;
+import org.onap.oom.truststoremerger.certification.file.EnvProvider;
+import org.onap.oom.truststoremerger.certification.file.TruststoresPathsProvider;
+import org.onap.oom.truststoremerger.configuration.MergerConfiguration;
+import org.onap.oom.truststoremerger.configuration.MergerConfigurationException;
+import org.onap.oom.truststoremerger.configuration.MergerConfigurationFactory;
+import org.onap.oom.truststoremerger.certification.file.PathValidator;
+
+class TrustStoreMerger {
+
+    private final AppExitHandler appExitHandler;
+
+    TrustStoreMerger(AppExitHandler appExitHandler) {
+        this.appExitHandler = appExitHandler;
+    }
+
+    void run() {
+        try {
+            mergeTruststores();
+            appExitHandler.exit(ExitStatus.SUCCESS);
+        } catch (ExitableException e) {
+            appExitHandler.exit(e.applicationExitStatus());
+        }
+    }
+
+    private void mergeTruststores() throws ExitableException {
+        MergerConfiguration configuration = loadConfiguration();
+    }
+
+    private MergerConfiguration loadConfiguration() throws ExitableException {
+        TruststoresPathsProvider truststoresPathsProvider = new TruststoresPathsProvider(new EnvProvider(), new PathValidator());
+        MergerConfigurationFactory factory = new MergerConfigurationFactory(truststoresPathsProvider);
+        return factory.createConfiguration();
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitStatus.java
new file mode 100644 (file)
index 0000000..ae145f7
--- /dev/null
@@ -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.truststoremerger.api;
+
+public enum ExitStatus {
+
+    SUCCESS(0, "Success"),
+    TRUSTSTORES_PATHS_PROVIDER_EXCEPTION(1, "Invalid paths in environment variables"),
+    MERGER_CONFIGURATION_EXCEPTION(2, "Invalid merger configuration");
+
+    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/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/api/ExitableException.java
new file mode 100644 (file)
index 0000000..3cc4673
--- /dev/null
@@ -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.truststoremerger.api;
+
+public class ExitableException extends Exception {
+
+    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/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/EnvProvider.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/EnvProvider.java
new file mode 100644 (file)
index 0000000..f64edc8
--- /dev/null
@@ -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.truststoremerger.certification.file;
+
+import java.util.Optional;
+
+public class EnvProvider {
+
+    Optional<String> getEnv(String name) {
+        return Optional.ofNullable(System.getenv(name));
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/PathValidator.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/PathValidator.java
new file mode 100644 (file)
index 0000000..05b80f1
--- /dev/null
@@ -0,0 +1,38 @@
+/*============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.truststoremerger.certification.file;
+
+public class PathValidator {
+
+    private static final String TRUSTSTORE_PATH_REGEX = "^(/[a-zA-Z0-9_-]+)+\\.(pem|jks|p12)";
+    private static final String TRUSTSTORE_PASSWORD_PATH_REGEX = "^(/[a-zA-Z0-9_-]+)+\\.pass";
+
+    public boolean isTruststorePathValid(String truststorePath) {
+        return isPathValid(truststorePath, TRUSTSTORE_PATH_REGEX);
+    }
+
+    public boolean isTruststorePasswordPathValid(String truststorePasswordPath) {
+        return truststorePasswordPath.isEmpty() || isPathValid(truststorePasswordPath, TRUSTSTORE_PASSWORD_PATH_REGEX);
+    }
+
+    private boolean isPathValid(String path, String regex) {
+        return path.matches(regex);
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProvider.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProvider.java
new file mode 100644 (file)
index 0000000..b7b73e6
--- /dev/null
@@ -0,0 +1,69 @@
+/*============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.truststoremerger.certification.file;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+
+public class TruststoresPathsProvider {
+
+    static final String TRUSTSTORES_ENV = "TRUSTSTORES";
+    static final String TRUSTSTORES_PASSWORDS_ENV = "TRUSTSTORES_PASSWORDS";
+    private static final String DELIMITER = ":";
+    private static final int NEGATIVE_SPLIT_LIMIT = -1;
+
+    private EnvProvider envProvider;
+    private PathValidator pathValidator;
+
+    public TruststoresPathsProvider(EnvProvider envProvider, PathValidator pathValidator) {
+        this.envProvider = envProvider;
+        this.pathValidator = pathValidator;
+    }
+
+    public List<String> getTruststores() throws TruststoresPathsProviderException {
+        return envProvider.getEnv(TRUSTSTORES_ENV)
+                .filter(Predicate.not(String::isEmpty))
+                .map(this::splitToList)
+                .filter(this::validateTruststores)
+                .orElseThrow(() -> new TruststoresPathsProviderException("TRUSTSTORES environment variable does not contain valid truststores paths"));
+    }
+
+    public List<String> getTruststoresPasswords() throws TruststoresPathsProviderException {
+        return envProvider.getEnv(TRUSTSTORES_PASSWORDS_ENV)
+                .map(this::splitToList)
+                .filter(this::validateTruststoresPasswords)
+                .orElseThrow(() -> new TruststoresPathsProviderException("TRUSTSTORES_PASSWORDS environment variable does not contain valid passwords paths"));
+    }
+
+    private boolean validateTruststores(List<String> truststores) {
+        return truststores.stream()
+                .allMatch(pathValidator::isTruststorePathValid);
+    }
+
+    private boolean validateTruststoresPasswords(List<String> truststoresPasswords) {
+        return truststoresPasswords.stream()
+                .allMatch(pathValidator::isTruststorePasswordPathValid);
+    }
+
+    private List<String> splitToList(String stringToSplit) {
+        return Arrays.asList(stringToSplit.split(DELIMITER, NEGATIVE_SPLIT_LIMIT));
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProviderException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProviderException.java
new file mode 100644 (file)
index 0000000..5f491c3
--- /dev/null
@@ -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.truststoremerger.certification.file;
+
+import org.onap.oom.truststoremerger.api.ExitStatus;
+import org.onap.oom.truststoremerger.api.ExitableException;
+
+public class TruststoresPathsProviderException extends ExitableException {
+
+    TruststoresPathsProviderException(String message) {
+        super(message, ExitStatus.TRUSTSTORES_PATHS_PROVIDER_EXCEPTION);
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfiguration.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfiguration.java
new file mode 100644 (file)
index 0000000..f3b7d93
--- /dev/null
@@ -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.truststoremerger.configuration;
+
+import java.util.Collections;
+import java.util.List;
+
+public class MergerConfiguration {
+    private final List<String> truststoreFilePaths;
+    private final List<String> truststoreFilePasswordPaths;
+
+    public MergerConfiguration(List<String> truststoreFilePaths,
+                               List<String> truststoreFilePasswordPaths) {
+        this.truststoreFilePaths = List.copyOf(truststoreFilePaths);
+        this.truststoreFilePasswordPaths = List.copyOf(truststoreFilePasswordPaths);
+    }
+
+    public List<String> getTruststoreFilePaths() {
+        return Collections.unmodifiableList(truststoreFilePaths);
+    }
+
+
+    public List<String> getTruststoreFilePasswordPaths() {
+        return Collections.unmodifiableList(truststoreFilePasswordPaths);
+    }
+
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationException.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationException.java
new file mode 100644 (file)
index 0000000..54982f5
--- /dev/null
@@ -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.truststoremerger.configuration;
+
+import org.onap.oom.truststoremerger.api.ExitStatus;
+import org.onap.oom.truststoremerger.api.ExitableException;
+
+public class MergerConfigurationException extends ExitableException {
+
+    MergerConfigurationException(String message) {
+        super(message, ExitStatus.MERGER_CONFIGURATION_EXCEPTION);
+    }
+}
diff --git a/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java b/trustStoreMerger/src/main/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactory.java
new file mode 100644 (file)
index 0000000..eea0551
--- /dev/null
@@ -0,0 +1,45 @@
+/*============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.truststoremerger.configuration;
+
+import org.onap.oom.truststoremerger.certification.file.TruststoresPathsProvider;
+import org.onap.oom.truststoremerger.certification.file.TruststoresPathsProviderException;
+
+import java.util.List;
+
+public class MergerConfigurationFactory {
+
+    private final TruststoresPathsProvider pathsProvider;
+
+    public MergerConfigurationFactory(TruststoresPathsProvider pathsProvider) {
+        this.pathsProvider = pathsProvider;
+    }
+
+    public MergerConfiguration createConfiguration() throws MergerConfigurationException, TruststoresPathsProviderException {
+        List<String> truststores = pathsProvider.getTruststores();
+        List<String> truststoresPasswords = pathsProvider.getTruststoresPasswords();
+
+        if (truststores.size() != truststoresPasswords.size()) {
+            throw new MergerConfigurationException("Size of TRUSTSTORES does not match size of TRUSTSTORES_PASSWORDS environment variables");
+        }
+
+        return new MergerConfiguration(truststores, truststoresPasswords);
+    }
+}
diff --git a/trustStoreMerger/src/main/resources/log4j2.xml b/trustStoreMerger/src/main/resources/log4j2.xml
new file mode 100644 (file)
index 0000000..697017e
--- /dev/null
@@ -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/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/TrustStoreMergerTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/TrustStoreMergerTest.java
new file mode 100644 (file)
index 0000000..4787897
--- /dev/null
@@ -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.truststoremerger;
+
+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.truststoremerger.api.ExitStatus;
+
+import static org.mockito.Mockito.verify;
+
+@ExtendWith(MockitoExtension.class)
+class TrustStoreMergerTest {
+
+    @Mock
+    AppExitHandler appExitHandler;
+
+    @Test
+    void shouldExitWithMergeConfigurationExceptionDueToMissingEnvs() {
+        new TrustStoreMerger(appExitHandler).run();
+
+        verify(appExitHandler).exit(ExitStatus.MERGER_CONFIGURATION_EXCEPTION);
+    }
+}
diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/PathValidatorTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/PathValidatorTest.java
new file mode 100644 (file)
index 0000000..1c45576
--- /dev/null
@@ -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.truststoremerger.certification.file;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class PathValidatorTest {
+
+    private final PathValidator validator = new PathValidator();
+
+    @ParameterizedTest()
+    @ValueSource(strings = {"/opt/app/truststore.pem", "/opt/app/truststore.jks",
+            "/opt/app/truststore.p12", "/truststore.pem"})
+    void shouldAcceptValidTruststorePaths(String path) {
+        assertThat(validator.isTruststorePathValid(path)).isTrue();
+    }
+
+    @ParameterizedTest()
+    @ValueSource(strings = {"/opt/app/truststore.pass", "/opt/app/truststore.invalid", "/",
+            "truststore", "opt/app/truststore.p12", "/?.pem", "/.pem"})
+    void shouldRejectInValidTruststorePaths(String path) {
+        assertThat(validator.isTruststorePathValid(path)).isFalse();
+    }
+
+    @ParameterizedTest()
+    @ValueSource(strings = {"", "/opt/app/truststore.pass", "/truststore.pass"})
+    void shouldAcceptValidTruststorePasswordPaths(String path) {
+        assertThat(validator.isTruststorePasswordPathValid(path)).isTrue();
+    }
+
+    @ParameterizedTest()
+    @ValueSource(strings = {"/opt/app/truststore.pem", "/opt/app/truststore.jks",
+            "/opt/app/truststore.p12", "/", "truststore", "opt/app/truststore.p12", "/?.pass", "/.pass"})
+    void shouldRejectInValidTruststorePasswordPaths(String path) {
+        assertThat(validator.isTruststorePasswordPathValid(path)).isFalse();
+    }
+
+}
diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProviderTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/certification/file/TruststoresPathsProviderTest.java
new file mode 100644 (file)
index 0000000..d52d189
--- /dev/null
@@ -0,0 +1,88 @@
+package org.onap.oom.truststoremerger.certification.file;
+
+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 java.util.Optional;
+
+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.truststoremerger.certification.file.TruststoresPathsProvider.TRUSTSTORES_ENV;
+import static org.onap.oom.truststoremerger.certification.file.TruststoresPathsProvider.TRUSTSTORES_PASSWORDS_ENV;
+
+@ExtendWith(MockitoExtension.class)
+class TruststoresPathsProviderTest {
+
+    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 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";
+
+    @Mock
+    private EnvProvider envProvider;
+    private TruststoresPathsProvider truststoresPathsProvider;
+
+    @BeforeEach
+    void setUp() {
+        truststoresPathsProvider = new TruststoresPathsProvider(envProvider, new PathValidator());
+    }
+
+    @Test
+    void shouldReturnCorrectListWhenTruststoresValid() throws TruststoresPathsProviderException {
+        mockTruststoresEnv(VALID_TRUSTSTORES);
+
+        assertThat(truststoresPathsProvider.getTruststores())
+                .contains("/opt/app/certificates/truststore.jks",
+                        "/opt/app/certificates/truststore.pem");
+    }
+
+    @Test
+    void shouldReturnCorrectListWhenTruststoresPasswordsValid() throws TruststoresPathsProviderException {
+        mockTruststoresPasswordsEnv(VALID_TRUSTSTORES_PASSWORDS);
+
+        assertThat(truststoresPathsProvider.getTruststoresPasswords())
+                .contains("/opt/app/certificates/truststore.pass",
+                        "");
+    }
+
+    @Test
+    void shouldThrowExceptionWhenTruststoresEmpty() {
+        mockTruststoresEnv("");
+
+        assertThatExceptionOfType(TruststoresPathsProviderException.class)
+                .isThrownBy(truststoresPathsProvider::getTruststores);
+    }
+
+    @Test
+    void shouldThrowExceptionWhenOneOfTruststoresPathsInvalid() {
+        mockTruststoresEnv(INVALID_TRUSTSTORES);
+
+        assertThatExceptionOfType(TruststoresPathsProviderException.class)
+                .isThrownBy(truststoresPathsProvider::getTruststores);
+    }
+
+    @Test
+    void shouldThrowExceptionWhenOneOfTruststorePasswordPathsInvalid() {
+        mockTruststoresPasswordsEnv(INVALID_TRUSTSTORES_PASSWORDS);
+
+        assertThatExceptionOfType(TruststoresPathsProviderException.class)
+                .isThrownBy(truststoresPathsProvider::getTruststoresPasswords);
+    }
+
+    private void mockTruststoresEnv(String truststores) {
+        mockEnv(truststores, TRUSTSTORES_ENV);
+    }
+
+    private void mockTruststoresPasswordsEnv(String truststoresPasswords) {
+        mockEnv(truststoresPasswords, TRUSTSTORES_PASSWORDS_ENV);
+    }
+
+    private void mockEnv(String envValue, String envName) {
+        when(envProvider.getEnv(envName))
+                .thenReturn(Optional.of(envValue));
+    }
+}
diff --git a/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactoryTest.java b/trustStoreMerger/src/test/java/org/onap/oom/truststoremerger/configuration/MergerConfigurationFactoryTest.java
new file mode 100644 (file)
index 0000000..336ba5d
--- /dev/null
@@ -0,0 +1,98 @@
+/*============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.truststoremerger.configuration;
+
+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.truststoremerger.certification.file.TruststoresPathsProvider;
+import org.onap.oom.truststoremerger.certification.file.TruststoresPathsProviderException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class MergerConfigurationFactoryTest {
+
+    private static final String BASE_TRUSTSTORE_PATH = "/opt/app/truststore_";
+    private static final String TRUSTSTORE_EXTENSION = ".jks";
+    private static final String PASSWORD_EXTENSION = ".pass";
+
+    @Mock
+    private TruststoresPathsProvider pathsProvider;
+    private MergerConfigurationFactory factory;
+
+    @BeforeEach
+    void setUp() {
+        factory = new MergerConfigurationFactory(pathsProvider);
+    }
+
+    @Test
+    void shouldReturnConfigurationWithCorrectPaths() throws TruststoresPathsProviderException, MergerConfigurationException {
+        int numberOfPaths = 5;
+        List<String> truststoresPaths = createListOfPathsWithExtension(numberOfPaths, TRUSTSTORE_EXTENSION);
+        List<String> truststorePasswordPaths = createListOfPathsWithExtension(numberOfPaths, PASSWORD_EXTENSION);
+        mockPaths(truststoresPaths, truststorePasswordPaths);
+
+        MergerConfiguration configuration = factory.createConfiguration();
+
+        assertThat(configuration.getTruststoreFilePaths()).containsAll(truststoresPaths);
+        assertThat(configuration.getTruststoreFilePasswordPaths()).containsAll(truststorePasswordPaths);
+    }
+
+    @Test
+    void shouldThrowExceptionWhenTruststoresLenghtDifferentThanTruststoresPasswordsLength() throws TruststoresPathsProviderException {
+        int numberOfTruststores = 5;
+        int numberOfTruststoresPasswords = 4;
+        List<String> truststoresPaths = createListOfPathsWithExtension(numberOfTruststores, TRUSTSTORE_EXTENSION);
+        List<String> truststorePasswordPaths = createListOfPathsWithExtension(numberOfTruststoresPasswords, PASSWORD_EXTENSION);
+        mockPaths(truststoresPaths, truststorePasswordPaths);
+
+        assertThatExceptionOfType(MergerConfigurationException.class)
+                .isThrownBy(factory::createConfiguration);
+    }
+
+    private void mockPaths(List<String> truststores, List<String> truststoresPasswords) throws TruststoresPathsProviderException {
+        mockTruststores(truststores);
+        mockTruststoresPasswords(truststoresPasswords);
+    }
+
+    private void mockTruststores(List<String> truststores) throws TruststoresPathsProviderException {
+        when(pathsProvider.getTruststores()).thenReturn(truststores);
+    }
+
+    private void mockTruststoresPasswords(List<String> truststoresPasswords) throws TruststoresPathsProviderException {
+        when(pathsProvider.getTruststoresPasswords()).thenReturn(truststoresPasswords);
+    }
+
+    private List<String> createListOfPathsWithExtension(int numberOfPaths, String password_extension) {
+        List<String> paths = new ArrayList<>();
+        while (numberOfPaths-- > 0) {
+            paths.add(BASE_TRUSTSTORE_PATH + numberOfPaths + password_extension);
+        }
+        return paths;
+    }
+}