<modules>
<module>certService</module>
<module>certServiceClient</module>
+ <module>trustStoreMerger</module>
</modules>
<build>
--- /dev/null
+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"]
--- /dev/null
+<?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>
--- /dev/null
+/*============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());
+ }
+}
--- /dev/null
+/*============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();
+ }
+}
--- /dev/null
+/*============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();
+ }
+}
--- /dev/null
+/*============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;
+ }
+}
--- /dev/null
+/*============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;
+ };
+}
--- /dev/null
+/*============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));
+ }
+}
--- /dev/null
+/*============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);
+ }
+}
--- /dev/null
+/*============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));
+ }
+}
--- /dev/null
+/*============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);
+ }
+}
--- /dev/null
+/*============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);
+ }
+
+}
--- /dev/null
+/*============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);
+ }
+}
--- /dev/null
+/*============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);
+ }
+}
--- /dev/null
+<?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>
--- /dev/null
+/*============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);
+ }
+}
--- /dev/null
+/*============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();
+ }
+
+}
--- /dev/null
+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));
+ }
+}
--- /dev/null
+/*============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;
+ }
+}