Improved helm-generator code to make it more testable and improved code coverage 66/124566/2
authorDhrumin Desai <dd303q@att.com>
Wed, 29 Sep 2021 12:34:18 +0000 (08:34 -0400)
committerDhrumin Desai <dd303q@att.com>
Tue, 5 Oct 2021 01:30:28 +0000 (21:30 -0400)
Issue-ID: DCAEGEN2-2911
Issue-ID: DCAEGEN2-2917
Change-Id: Ifc1f336b627b37a9356a3a72b33fcac18bdaa686
Signed-off-by: Dhrumin Desai <dd303q@att.com>
23 files changed:
mod2/helm-generator/Changelog.md
mod2/helm-generator/helmchartgenerator-cli/pom.xml
mod2/helm-generator/helmchartgenerator-cli/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/HelmChartGeneratorApplicationTests.java
mod2/helm-generator/helmchartgenerator-core/pom.xml
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/Utils.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/chartbuilder/ChartBuilder.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/chartbuilder/ChartGenerator.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/chartbuilder/ComponentSpecParser.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/chartbuilder/HelmClientImpl.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/distribution/ChartMuseumDistributor.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/validation/ChartTemplateStructureValidator.java
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/validation/ChartTemplateStructureValidatorImpl.java [new file with mode: 0644]
mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/validation/ComponentSpecValidatorImpl.java
mod2/helm-generator/helmchartgenerator-core/src/main/resources/application.properties
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartBuilderTest.java [new file with mode: 0644]
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartGeneratorTest.java [new file with mode: 0644]
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartMuseumDistributorTest.java [new file with mode: 0644]
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartTemplateStructureValidatorTest.java
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ComponentSpecParserTest.java
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ComponentSpecValidatorTest.java
mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/KeyValueMergerTest.java [new file with mode: 0644]
mod2/helm-generator/lombok.config
mod2/helm-generator/pom.xml

index d38f0b4..fa5463d 100644 (file)
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
+## [1.0.1]- 2021-10-04
+
+*  [DCAEGEN2-2911] Refactor the code to make it more testable
+    - Converted some static methods to instance methods
+*  [DCAEGEN2-2911] Distributor throws an error if distribution fails
+*  [DCAEGEN2-2917] Add helm repo registry step when initializing the helm client
+    - Add "helm repo add ..."
+    - Add "helm deployment update" before linting
 
 ## [1.0.0]
 
index 3c6de24..d7edca3 100644 (file)
@@ -5,10 +5,10 @@
   <parent>
     <groupId>org.onap.dcaegen2.platform</groupId>
     <artifactId>helmchartgenerator</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.1-SNAPSHOT</version>
   </parent>
     <artifactId>helmchartgenerator-cli</artifactId>
-  <version>1.0.0-SNAPSHOT</version>
+  <version>1.0.1-SNAPSHOT</version>
   <name>helmchartgenerator-cli</name>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -17,7 +17,7 @@
     <dependency>
       <groupId>org.onap.dcaegen2.platform</groupId>
       <artifactId>helmchartgenerator-core</artifactId>
-      <version>1.0.0-SNAPSHOT</version>
+      <version>1.0.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
   <build>
index 20b2c17..122a535 100644 (file)
@@ -26,7 +26,7 @@ import org.springframework.test.context.junit.jupiter.DisabledIf;
  * Disabling the test as it is using 'helm' command from the local environment.
  */
 @DisabledIf("true")
-@SpringBootTest(args = {"src/test/input/specs/ves.json", "src/test/input/blueprint", "src/test/output/charts"})
+@SpringBootTest(args = {"src/test/input-new/specs/ves.json", "src/test/input-new/blueprint", "src/test/output/charts", "--distribute"})
 class HelmChartGeneratorApplicationTests {
 
        @Test
index be8e39b..4dbbd3b 100644 (file)
@@ -5,10 +5,10 @@
     <parent>
         <groupId>org.onap.dcaegen2.platform</groupId>
         <artifactId>helmchartgenerator</artifactId>
-        <version>1.0.0-SNAPSHOT</version>
+        <version>1.0.1-SNAPSHOT</version>
     </parent>
     <artifactId>helmchartgenerator-core</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.0.1-SNAPSHOT</version>
     <name>helmchartgenerator-core</name>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
index 83c67b1..a252886 100644 (file)
@@ -21,6 +21,7 @@ package org.onap.dcaegen2.platform.helmchartgenerator;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.io.FileUtils;
+import org.springframework.stereotype.Component;
 
 import java.io.File;
 import java.io.IOException;
@@ -33,13 +34,12 @@ import java.util.Map;
  * @author Dhrumin Desai
  */
 @Slf4j
+@Component
 public class Utils {
 
-    private static final ObjectMapper MAPPER = new ObjectMapper();
+    private final ObjectMapper MAPPER = new ObjectMapper();
 
-    private Utils() {}
-
-    public static <T> T deserializeJsonFileToModel(String filePath, Class<T> modelClass) {
+    public <T> T deserializeJsonFileToModel(String filePath, Class<T> modelClass) {
         return deserializeJsonFileToModel(new File(filePath), modelClass);
     }
 
@@ -49,7 +49,7 @@ public class Utils {
      * @param modelClass target model class for mapping
      * @return mapped model instance
      */
-    public static <T> T deserializeJsonFileToModel(File file, Class<T> modelClass) {
+    public <T> T deserializeJsonFileToModel(File file, Class<T> modelClass) {
         try {
             return MAPPER.readValue(file, modelClass);
         } catch (IOException e) {
@@ -63,7 +63,7 @@ public class Utils {
      * @param srcLocation
      * @return
      */
-    public static File cloneFileToTempLocation(String srcLocation) {
+    public File cloneFileToTempLocation(String srcLocation) {
         File cloneLocation = null;
         try {
             Path tempRootDir = Files.createTempDirectory("chart");
@@ -81,7 +81,7 @@ public class Utils {
      * deletes dir / file from temp location of OS
      * @param dir  dir to be deleted
      */
-    public static void deleteTempFileLocation(File dir) {
+    public void deleteTempFileLocation(File dir) {
         try {
             FileUtils.deleteDirectory(dir);
         } catch (IOException e) {
@@ -95,7 +95,7 @@ public class Utils {
      * @param key a key
      * @param value a value
      */
-    public static void putIfNotNull(Map<String, Object> map, String key, Object value){
+    public void putIfNotNull(Map<String, Object> map, String key, Object value){
         if(value != null){
             map.put(key, value);
         }
index ac73544..21f5dae 100644 (file)
@@ -41,14 +41,20 @@ public class ChartBuilder {
    @Autowired
    private ChartGenerator chartGenerator;
 
+   @Autowired
+   private ChartTemplateStructureValidator validator;
+
     /**
      * constructor of ChartBuilder
      * @param specParser implementation of ComponentSpecParser
      * @param chartGenerator implementation of ChartGenerator
+     * @param validator implementation of Chart Template Validator
      */
-    public ChartBuilder(ComponentSpecParser specParser, ChartGenerator chartGenerator) {
+    public ChartBuilder(ComponentSpecParser specParser, ChartGenerator chartGenerator,
+                        ChartTemplateStructureValidator validator) {
         this.specParser = specParser;
         this.chartGenerator = chartGenerator;
+        this.validator = validator;
     }
 
     /**
@@ -61,7 +67,7 @@ public class ChartBuilder {
      * @throws Exception
      */
     public File build(String specFileLocation, String chartTemplateLocation, String outputLocation, String specSchemaLocation ) throws Exception {
-        ChartTemplateStructureValidator.validateChartTemplateStructure(chartTemplateLocation);
+        validator.validateChartTemplateStructure(chartTemplateLocation);
         ChartInfo chartInfo = specParser.extractChartInfo(specFileLocation, chartTemplateLocation, specSchemaLocation);
         return chartGenerator.generate(chartTemplateLocation, chartInfo, outputLocation);
     }
index b9980d7..be02d68 100644 (file)
 
 package org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder;
 
-import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
+import org.onap.dcaegen2.platform.helmchartgenerator.Utils;
 import org.onap.dcaegen2.platform.helmchartgenerator.models.chartinfo.ChartInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.io.File;
 
-import static org.onap.dcaegen2.platform.helmchartgenerator.Utils.cloneFileToTempLocation;
-import static org.onap.dcaegen2.platform.helmchartgenerator.Utils.deleteTempFileLocation;
-
 /**
  * ChartGenerator interacts with HelmClient and generates a packaged helm chart
  * @author Dhrumin Desai
@@ -37,22 +34,25 @@ import static org.onap.dcaegen2.platform.helmchartgenerator.Utils.deleteTempFile
 @Slf4j
 public class ChartGenerator {
 
-    @Setter
     @Autowired
     private HelmClient helmClient;
 
-    @Setter
     @Autowired
     private KeyValueMerger merger;
 
+    @Autowired
+    private Utils utils;
+
     /**
      * Constructor for ChartGenerator
      * @param helmClient HelmClient implementation
      * @param merger KeyValueMerger implementation
+     * @param utils
      */
-    public ChartGenerator(HelmClient helmClient, KeyValueMerger merger) {
+    public ChartGenerator(HelmClient helmClient, KeyValueMerger merger, Utils utils) {
         this.helmClient = helmClient;
         this.merger = merger;
+        this.utils = utils;
     }
 
     /**
@@ -63,11 +63,11 @@ public class ChartGenerator {
      * @return generated helm chart tgz file
      */
     public File generate(String chartBlueprintLocation, ChartInfo chartInfo, String outputLocation) {
-        File newChartDir = cloneFileToTempLocation(chartBlueprintLocation + "/base");
+        File newChartDir = utils.cloneFileToTempLocation(chartBlueprintLocation + "/base");
         merger.mergeValuesToChart(chartInfo, newChartDir);
         helmClient.lint(newChartDir);
         final File chartLocation = helmClient.packageChart(newChartDir, outputLocation);
-        deleteTempFileLocation(newChartDir);
+        utils.deleteTempFileLocation(newChartDir);
         return chartLocation;
     }
 }
index 942e5ae..b0830d1 100644 (file)
@@ -18,7 +18,6 @@
 
 package org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder;
 
-import org.jetbrains.annotations.NotNull;
 import org.onap.dcaegen2.platform.helmchartgenerator.Utils;
 import org.onap.dcaegen2.platform.helmchartgenerator.models.chartinfo.ChartInfo;
 import org.onap.dcaegen2.platform.helmchartgenerator.models.chartinfo.Metadata;
@@ -55,12 +54,17 @@ public class ComponentSpecParser {
     @Autowired
     private ComponentSpecValidator specValidator;
 
+    @Autowired
+    private Utils utils;
+
     /**
      * Constructor for ComponentSpecParser
      * @param specValidator ComponentSpecValidator implementation
+     * @param utils
      */
-    public ComponentSpecParser(ComponentSpecValidator specValidator) {
+    public ComponentSpecParser(ComponentSpecValidator specValidator, Utils utils) {
         this.specValidator = specValidator;
+        this.utils = utils;
     }
 
     /**
@@ -73,7 +77,7 @@ public class ComponentSpecParser {
      */
     public ChartInfo extractChartInfo(String specFileLocation, String chartTemplateLocation, String specSchemaLocation) throws Exception {
         specValidator.validateSpecFile(specFileLocation, specSchemaLocation);
-        ComponentSpec cs = Utils.deserializeJsonFileToModel(specFileLocation, ComponentSpec.class);
+        ComponentSpec cs = utils.deserializeJsonFileToModel(specFileLocation, ComponentSpec.class);
         ChartInfo chartInfo = new ChartInfo();
         chartInfo.setMetadata(extractMetadata(cs.getSelf()));
         chartInfo.setValues(extractValues(cs, chartTemplateLocation));
@@ -83,14 +87,14 @@ public class ComponentSpecParser {
     private Map<String, Object> extractValues(ComponentSpec cs, String chartTemplateLocation) {
         Map<String, Object> outerValues = new LinkedHashMap<>();
         if(cs.getAuxilary() != null && cs.getAuxilary().getTlsInfo() != null){
-            Utils.putIfNotNull(outerValues,"certDirectory", cs.getAuxilary().getTlsInfo().getCertDirectory());
-            Utils.putIfNotNull(outerValues, "tlsServer", cs.getAuxilary().getTlsInfo().getUseTls());
+            utils.putIfNotNull(outerValues,"certDirectory", cs.getAuxilary().getTlsInfo().getCertDirectory());
+            utils.putIfNotNull(outerValues, "tlsServer", cs.getAuxilary().getTlsInfo().getUseTls());
         }
         if(cs.getAuxilary() != null && cs.getAuxilary().getLogInfo() != null) {
-            Utils.putIfNotNull(outerValues,"logDirectory", cs.getAuxilary().getLogInfo().get("log_directory"));
+            utils.putIfNotNull(outerValues,"logDirectory", cs.getAuxilary().getLogInfo().get("log_directory"));
         }
         if(imageUriExistsForFirstArtifact(cs)){
-            Utils.putIfNotNull(outerValues,"image", cs.getArtifacts()[0].getUri());
+            utils.putIfNotNull(outerValues,"image", cs.getArtifacts()[0].getUri());
         }
         populateApplicationConfigSection(outerValues, cs);
         populateReadinessSection(outerValues, cs);
@@ -115,7 +119,7 @@ public class ComponentSpecParser {
          for(Parameters param : parameters){
             applicationConfig.put(param.getName(), param.getValue());
          }
-         Utils.putIfNotNull(outerValues,"applicationConfig", applicationConfig);
+        utils.putIfNotNull(outerValues,"applicationConfig", applicationConfig);
     }
 
     private void populateReadinessSection(Map<String, Object> outerValues, ComponentSpec cs) {
@@ -124,7 +128,7 @@ public class ComponentSpecParser {
 
         Map<String, Object> readiness = new LinkedHashMap<>();
         final HealthCheck healthcheck = cs.getAuxilary().getHealthcheck();
-        Utils.putIfNotNull(readiness, "initialDelaySeconds", healthcheck.getInitialDelaySeconds());
+        utils.putIfNotNull(readiness, "initialDelaySeconds", healthcheck.getInitialDelaySeconds());
 
         if(healthcheck.getInterval() != null) {
             readiness.put("periodSeconds", getSeconds(healthcheck.getInterval(), "interval"));
@@ -159,7 +163,7 @@ public class ComponentSpecParser {
     private void populateApplicationEnvSection(Map<String, Object> outerValues, ComponentSpec cs){
         if(applicationEnvExists(cs)) {
             Object applicationEnv = cs.getAuxilary().getHelm().getApplicationEnv();
-            Utils.putIfNotNull(outerValues,"applicationEnv", applicationEnv);
+            utils.putIfNotNull(outerValues,"applicationEnv", applicationEnv);
         }
     }
 
@@ -178,10 +182,10 @@ public class ComponentSpecParser {
         if(serviceFromSpec.getPorts() != null){
             List<Object> ports = mapServicePorts(serviceFromSpec.getPorts());
             service.put("ports", ports);
-            Utils.putIfNotNull(service, "type", serviceFromSpec.getType());
+            utils.putIfNotNull(service, "type", serviceFromSpec.getType());
         }
-        Utils.putIfNotNull(service,"name", serviceFromSpec.getName());
-        Utils.putIfNotNull(service,"has_internal_only_ports", serviceFromSpec.getHasInternalOnlyPorts());
+        utils.putIfNotNull(service,"name", serviceFromSpec.getName());
+        utils.putIfNotNull(service,"has_internal_only_ports", serviceFromSpec.getHasInternalOnlyPorts());
         outerValues.put("service", service);
     }
 
@@ -230,8 +234,8 @@ public class ComponentSpecParser {
             keystore.put("outputType", List.of("jks"));
             keystore.put("passwordSecretRef", passwordsSecretRef);
             certificate.put("mountPath", mountPath);
-            Utils.putIfNotNull(certificate,"commonName", cs.getSelf().getName());
-            Utils.putIfNotNull(certificate,"dnsNames", List.of(cs.getSelf().getName()));
+            utils.putIfNotNull(certificate,"commonName", cs.getSelf().getName());
+            utils.putIfNotNull(certificate,"dnsNames", List.of(cs.getSelf().getName()));
             certificate.put("keystore", keystore);
             outerValues.put("certificates", List.of(certificate));
         }
index 098ddda..83bc477 100644 (file)
@@ -19,6 +19,7 @@
 package org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder;
 
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import java.io.BufferedReader;
@@ -26,6 +27,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.stream.Collectors;
 
 /**
  * HelmClient implementation which uses helm command installed in the runtime environment.
@@ -35,12 +37,40 @@ import java.io.InputStreamReader;
 @Slf4j
 public class HelmClientImpl implements HelmClient {
 
+    private final String repoUrl;
+
+    private final String username;
+
+    private final String password;
+
+    public HelmClientImpl(@Value("${chartmuseum.baseurl}")String repoUrl,
+                          @Value("${chartmuseum.auth.basic.username}")String username,
+                          @Value("${chartmuseum.auth.basic.password}")String password) {
+        this.repoUrl = repoUrl;
+        this.username = username;
+        this.password = password;
+        try{
+            repoAdd(repoUrl, username,password);
+        }catch (Exception e){
+            log.warn("Could not add helm repo.");
+        }
+    }
+
+    private void repoAdd(String repoUrl, String username, String password) {
+        ProcessBuilder builder = new ProcessBuilder();
+        builder.inheritIO();
+        builder.command("helm", "repo", "add", "local",  repoUrl,
+                        "--username", username, "--password", password);
+        runProcess(builder, "repoAdd");
+    }
+
     /**
      * performs <code>helm lint</code> operation
      * @param chartLocation helm chart location
      */
     @Override
     public void lint(File chartLocation) {
+        helmDepUp(chartLocation.getAbsolutePath());
         ProcessBuilder builder = new ProcessBuilder();
         builder.command("helm", "lint", chartLocation.getAbsolutePath());
         runProcess(builder, "lint");
@@ -60,16 +90,24 @@ public class HelmClientImpl implements HelmClient {
         return runProcess(builder, "package");
     }
 
+    private void helmDepUp(String chartLocation) {
+        ProcessBuilder builder = new ProcessBuilder();
+        builder.inheritIO();
+        builder.command("helm", "dep", "up",chartLocation);
+        runProcess(builder, "helmDepUp");
+    }
+
     private File runProcess(ProcessBuilder builder, String command) {
+        log.info("running: " + String.join(" ",builder.command()));
         Process process = null;
         String chartPath = "";
         try {
             process = builder.start();
-            if(command.equals("lint")) {
-                printLintingProcessOutput(process);
+            if(command.equals("package")) {
+                chartPath = printPackagingProcessOutput(process);
             }
             else {
-                chartPath = printPackagingProcessOutput(process);
+                printProcessOutput(process);
             }
             assertExitCode(process);
         }  catch (IOException e) {
@@ -83,7 +121,7 @@ public class HelmClientImpl implements HelmClient {
         return new File(chartPath);
     }
 
-    private void printLintingProcessOutput(Process process) throws IOException {
+    private void printProcessOutput(Process process) throws IOException {
         final InputStream inputStream = process.getInputStream();
         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
         reader.lines().forEach(log::info);
index ed861b0..ab0b964 100644 (file)
@@ -40,14 +40,19 @@ import java.util.Objects;
 @Slf4j
 public class ChartMuseumDistributor implements ChartDistributor {
 
-    @Value("${chartmuseum.baseurl}")
-    private String chartMuseumUrl;
+    private final String chartMuseumUrl;
 
-    @Value("${chartmuseum.auth.basic.username}")
-    private String username;
+    private final String username;
 
-    @Value("${chartmuseum.auth.basic.password}")
-    private String password;
+    private final String password;
+
+    public ChartMuseumDistributor( @Value("${chartmuseum.baseurl}") String chartMuseumUrl,
+                                   @Value("${chartmuseum.auth.basic.username}") String username,
+                                   @Value("${chartmuseum.auth.basic.password}")String password) {
+        this.chartMuseumUrl = chartMuseumUrl;
+        this.username = username;
+        this.password = password;
+    }
 
     /**
      * distributes chart to Chart Museum
@@ -60,6 +65,9 @@ public class ChartMuseumDistributor implements ChartDistributor {
         try {
             Response response = client.newCall(request).execute();
             log.info(Objects.requireNonNull(response.body()).string());
+            if(!response.isSuccessful()){
+                throw new RuntimeException("Distribution Failed.");
+            }
         } catch (IOException e) {
             throw new RuntimeException(e.getMessage());
         }
@@ -70,7 +78,7 @@ public class ChartMuseumDistributor implements ChartDistributor {
         MediaType mediaType = MediaType.parse("application/octet-stream");
         RequestBody body = RequestBody.create(chartFile, mediaType);
         return new Request.Builder()
-                .url(chartMuseumUrl)
+                .url(chartMuseumUrl + "/api/charts")
                 .method("POST", body)
                 .addHeader("Content-Type", "application/octet-stream")
                 .addHeader("Authorization", credential)
index 796ee91..07b97c9 100644 (file)
 
 package org.onap.dcaegen2.platform.helmchartgenerator.validation;
 
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
 /**
- * A class to validate structure of the base helm directory
+ * An interface to validate structure of the base helm directory
  */
-public class ChartTemplateStructureValidator {
-
-    /**
-     * validates base helm chart directory and throws error if the structure is not proper.
-     * @param chartTemplateLocation base helm chart dir location
-     */
-    public static void validateChartTemplateStructure(String chartTemplateLocation) {
-        checkBaseDirectory(chartTemplateLocation);
-    }
-
-    private static void checkBaseDirectory(String chartTemplateLocation) {
-        Path base = Paths.get(chartTemplateLocation, "base");
-        Path charts = Paths.get(chartTemplateLocation, "base/charts");
-        Path templates = Paths.get(chartTemplateLocation, "base/templates");
-        Path chart = Paths.get(chartTemplateLocation, "base/Chart.yaml");
-        Path values = Paths.get(chartTemplateLocation, "base/values.yaml");
-        if(!Files.exists(base)){
-            throw new RuntimeException("base directory not found in chart template location");
-        }
-        if(!Files.exists(charts)){
-            throw new RuntimeException("charts directory not found in base directory");
-        }
-        if(!Files.exists(templates)){
-            throw new RuntimeException("templates directory not found in base directory");
-        }
-        if(!Files.exists(chart)){
-            throw new RuntimeException("chart.yaml not found in base directory");
-        }
-        if(!Files.exists(values)){
-            throw new RuntimeException("values.yaml not found in base directory");
-        }
-    }
+public interface ChartTemplateStructureValidator {
+    void validateChartTemplateStructure(String chartTemplateLocation);
 }
diff --git a/mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/validation/ChartTemplateStructureValidatorImpl.java b/mod2/helm-generator/helmchartgenerator-core/src/main/java/org/onap/dcaegen2/platform/helmchartgenerator/validation/ChartTemplateStructureValidatorImpl.java
new file mode 100644 (file)
index 0000000..6c22108
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # Licensed under the Apache License, Version 2.0 (the "License");
+ * # you may not use this file except in compliance with the License.
+ * # You may obtain a copy of the License at
+ * #
+ * #      http://www.apache.org/licenses/LICENSE-2.0
+ * #
+ * # Unless required by applicable law or agreed to in writing, software
+ * # distributed under the License is distributed on an "AS IS" BASIS,
+ * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * # See the License for the specific language governing permissions and
+ * # limitations under the License.
+ * # ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.platform.helmchartgenerator.validation;
+
+import org.springframework.stereotype.Component;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * A class to validate structure of the base helm directory
+ */
+@Component
+public class ChartTemplateStructureValidatorImpl implements ChartTemplateStructureValidator {
+
+    /**
+     * validates base helm chart directory and throws error if the structure is not proper.
+     * @param chartTemplateLocation base helm chart dir location
+     */
+    @Override
+    public void validateChartTemplateStructure(String chartTemplateLocation) {
+        checkBaseDirectory(chartTemplateLocation);
+    }
+
+    private void checkBaseDirectory(String chartTemplateLocation) {
+        Path base = Paths.get(chartTemplateLocation, "base");
+        Path templates = Paths.get(chartTemplateLocation, "base/templates");
+        Path chart = Paths.get(chartTemplateLocation, "base/Chart.yaml");
+        Path values = Paths.get(chartTemplateLocation, "base/values.yaml");
+        if(!Files.exists(base)){
+            throw new RuntimeException("base directory not found in chart template location");
+        }
+        if(!Files.exists(templates)){
+            throw new RuntimeException("templates directory not found in base directory");
+        }
+        if(!Files.exists(chart)){
+            throw new RuntimeException("chart.yaml not found in base directory");
+        }
+        if(!Files.exists(values)){
+            throw new RuntimeException("values.yaml not found in base directory");
+        }
+    }
+}
index a74cab1..fd1f19f 100644 (file)
@@ -26,6 +26,7 @@ import org.json.JSONObject;
 import org.json.JSONTokener;
 import org.onap.dcaegen2.platform.helmchartgenerator.Utils;
 import org.onap.dcaegen2.platform.helmchartgenerator.models.componentspec.base.ComponentSpec;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.stereotype.Service;
 
@@ -43,6 +44,13 @@ import java.io.InputStream;
 @Slf4j
 public class ComponentSpecValidatorImpl implements ComponentSpecValidator {
 
+    @Autowired
+    private Utils utils;
+
+    public ComponentSpecValidatorImpl(Utils utils) {
+        this.utils = utils;
+    }
+
     /**
      * Validates the spec json file  against schema and prints errors if found
      * @param specFileLocation specification json file location
@@ -52,7 +60,7 @@ public class ComponentSpecValidatorImpl implements ComponentSpecValidator {
     @Override
     public void validateSpecFile(String specFileLocation, String specSchemaLocation) throws IOException {
         File schemaFile = getSchemaFile(specSchemaLocation);
-        ComponentSpec cs = Utils.deserializeJsonFileToModel(specFileLocation, ComponentSpec.class);
+        ComponentSpec cs = utils.deserializeJsonFileToModel(specFileLocation, ComponentSpec.class);
         validateSpecSchema(new File(specFileLocation), schemaFile);
         validateHelmRequirements(cs);
     }
index df2005a..f033b65 100644 (file)
@@ -1,5 +1,5 @@
 spring.main.web-application-type=NONE
 
-chartmuseum.baseurl=http://localhost:8081/api/charts
+chartmuseum.baseurl=http://localhost:8081
 chartmuseum.auth.basic.username=TBD
 chartmuseum.auth.basic.password=TBD
\ No newline at end of file
diff --git a/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartBuilderTest.java b/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartBuilderTest.java
new file mode 100644 (file)
index 0000000..dd19382
--- /dev/null
@@ -0,0 +1,54 @@
+ /** # ============LICENSE_START=======================================================
+ * # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # Licensed under the Apache License, Version 2.0 (the "License");
+ * # you may not use this file except in compliance with the License.
+ * # You may obtain a copy of the License at
+ * #
+ * #      http://www.apache.org/licenses/LICENSE-2.0
+ * #
+ * # Unless required by applicable law or agreed to in writing, software
+ * # distributed under the License is distributed on an "AS IS" BASIS,
+ * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * # See the License for the specific language governing permissions and
+ * # limitations under the License.
+ * # ============LICENSE_END=========================================================
+*/
+
+
+package org.onap.dcaegen2.platform.helmchartgenerator;
+
+ import org.junit.jupiter.api.Test;
+ import org.junit.jupiter.api.extension.ExtendWith;
+ import org.mockito.Mock;
+ import org.mockito.Mockito;
+ import org.mockito.junit.jupiter.MockitoExtension;
+ import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.ChartBuilder;
+ import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.ChartGenerator;
+ import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.ComponentSpecParser;
+ import org.onap.dcaegen2.platform.helmchartgenerator.validation.ChartTemplateStructureValidator;
+
+ import static org.mockito.ArgumentMatchers.any;
+
+ @ExtendWith(MockitoExtension.class)
+class ChartBuilderTest {
+
+    @Mock
+    private ChartGenerator chartGenerator;
+
+    @Mock
+    private ComponentSpecParser specParser;
+
+    @Mock
+    private ChartTemplateStructureValidator validator;
+
+    @Test
+    void testChartBuilderSteps() throws Exception{
+        ChartBuilder builder = new ChartBuilder(specParser, chartGenerator, validator);
+        builder.build("someSpec", "someChartLocation", "someOutputLocation", "someSpecSchemaLocation");
+
+        Mockito.verify(specParser, Mockito.times(1)).extractChartInfo(any(), any(), any());
+        Mockito.verify(chartGenerator, Mockito.times(1)).generate(any(), any(), any());
+        Mockito.verify(validator, Mockito.times(1)).validateChartTemplateStructure(any());
+    }
+}
diff --git a/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartGeneratorTest.java b/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartGeneratorTest.java
new file mode 100644 (file)
index 0000000..1c2c9bc
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # Licensed under the Apache License, Version 2.0 (the "License");
+ * # you may not use this file except in compliance with the License.
+ * # You may obtain a copy of the License at
+ * #
+ * #      http://www.apache.org/licenses/LICENSE-2.0
+ * #
+ * # Unless required by applicable law or agreed to in writing, software
+ * # distributed under the License is distributed on an "AS IS" BASIS,
+ * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * # See the License for the specific language governing permissions and
+ * # limitations under the License.
+ * # ============LICENSE_END=========================================================
+ */
+
+
+package org.onap.dcaegen2.platform.helmchartgenerator;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.ChartGenerator;
+import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.HelmClient;
+import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.KeyValueMerger;
+import org.onap.dcaegen2.platform.helmchartgenerator.models.chartinfo.ChartInfo;
+
+import static org.mockito.ArgumentMatchers.any;
+
+@ExtendWith(MockitoExtension.class)
+class ChartGeneratorTest {
+
+    @Mock
+    private KeyValueMerger kvMerger;
+
+    @Mock
+    private HelmClient helmClient;
+
+    @Mock
+    private Utils utils;
+
+    @Test
+    void testChartGenerationSteps() throws Exception{
+        ChartGenerator chartGenerator = new ChartGenerator(helmClient, kvMerger, utils);
+        Mockito.when(utils.cloneFileToTempLocation(any())).thenReturn(any());
+
+        chartGenerator.generate("src/test/input/blueprint", new ChartInfo(), "src/test/output");
+
+        Mockito.verify(kvMerger, Mockito.times(1)).mergeValuesToChart(any(), any());
+        Mockito.verify(helmClient, Mockito.times(1)).lint(any());
+        Mockito.verify(helmClient, Mockito.times(1)).packageChart(any(), any());
+    }
+
+}
diff --git a/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartMuseumDistributorTest.java b/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/ChartMuseumDistributorTest.java
new file mode 100644 (file)
index 0000000..c0d0663
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # Licensed under the Apache License, Version 2.0 (the "License");
+ * # you may not use this file except in compliance with the License.
+ * # You may obtain a copy of the License at
+ * #
+ * #      http://www.apache.org/licenses/LICENSE-2.0
+ * #
+ * # Unless required by applicable law or agreed to in writing, software
+ * # distributed under the License is distributed on an "AS IS" BASIS,
+ * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * # See the License for the specific language governing permissions and
+ * # limitations under the License.
+ * # ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.platform.helmchartgenerator;
+
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.dcaegen2.platform.helmchartgenerator.distribution.ChartMuseumDistributor;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ChartMuseumDistributorTest {
+
+    ChartMuseumDistributor distributor;
+
+    public static MockWebServer mockChartMuseumServer;
+
+    private static File mockChartFile;
+
+    @BeforeAll
+    static void init() throws IOException {
+        mockChartMuseumServer = new MockWebServer();
+        mockChartMuseumServer.start();
+        mockChartFile = File.createTempFile("dcae-ves-collector-1.8.0","tgz");
+    }
+
+    @BeforeEach
+    void setUp(){
+        String baseUrl = String.format("http://localhost:%s",
+                mockChartMuseumServer.getPort());
+        distributor = new ChartMuseumDistributor(baseUrl, "mockUsername", "mockPassword");
+    }
+
+    @Test
+    void distribute() throws Exception{
+        mockChartMuseumServer.enqueue(getMock201Response());
+        distributor.distribute(mockChartFile);
+    }
+
+    private MockResponse getMock201Response() {
+        return new MockResponse()
+                .setResponseCode(201)
+                .setBody("{\"saved\": true}");
+    }
+
+
+    @AfterAll
+    static void tearDown() throws IOException {
+        mockChartMuseumServer.shutdown();
+        FileUtils.deleteQuietly(mockChartFile);
+    }
+}
+
index 9bef191..3e94b64 100644 (file)
 
 package org.onap.dcaegen2.platform.helmchartgenerator;
 
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.onap.dcaegen2.platform.helmchartgenerator.validation.ChartTemplateStructureValidator;
+import org.onap.dcaegen2.platform.helmchartgenerator.validation.ChartTemplateStructureValidatorImpl;
 
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 public class ChartTemplateStructureValidatorTest {
 
+    private ChartTemplateStructureValidatorImpl validator;
+
+    @BeforeEach
+    void setUp() {
+        validator = new ChartTemplateStructureValidatorImpl();
+    }
+
     @Test
     void validateTemplateStructure(){
         String validStructureLocation = "src/test/input/blueprint";
-        assertDoesNotThrow(() -> ChartTemplateStructureValidator.validateChartTemplateStructure(validStructureLocation));
+        assertDoesNotThrow(() -> validator.validateChartTemplateStructure(validStructureLocation));
     }
 
     @Test
     void invalidateTemplateStructureShouldThrowRuntimeError() {
         String invalidStructureLocation = "test";
-        assertThrows(RuntimeException.class, () -> ChartTemplateStructureValidator.validateChartTemplateStructure(invalidStructureLocation));
+        assertThrows(RuntimeException.class, () -> validator.validateChartTemplateStructure(invalidStructureLocation));
     }
 }
index c14edda..0f157d3 100644 (file)
@@ -44,7 +44,7 @@ class ComponentSpecParserTest {
 
     @BeforeEach
     void setUp() {
-        parser = new ComponentSpecParser(validator);
+        parser = new ComponentSpecParser(validator, new Utils());
     }
 
     @Test
@@ -183,4 +183,5 @@ class ComponentSpecParserTest {
         assertThat(secret1.get("password")).isEqualTo("{{ .Values.postgres.config.pgUserPassword }}");
         assertThat(secret1.get("passwordPolicy")).isEqualTo("generate");
     }
-}
\ No newline at end of file
+}
+
diff --git a/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/KeyValueMergerTest.java b/mod2/helm-generator/helmchartgenerator-core/src/test/java/org/onap/dcaegen2/platform/helmchartgenerator/KeyValueMergerTest.java
new file mode 100644 (file)
index 0000000..4082170
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * # ============LICENSE_START=======================================================
+ * # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+ * # ================================================================================
+ * # Licensed under the Apache License, Version 2.0 (the "License");
+ * # you may not use this file except in compliance with the License.
+ * # You may obtain a copy of the License at
+ * #
+ * #      http://www.apache.org/licenses/LICENSE-2.0
+ * #
+ * # Unless required by applicable law or agreed to in writing, software
+ * # distributed under the License is distributed on an "AS IS" BASIS,
+ * # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * # See the License for the specific language governing permissions and
+ * # limitations under the License.
+ * # ============LICENSE_END=========================================================
+ */
+
+package org.onap.dcaegen2.platform.helmchartgenerator;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.AfterEach;
+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.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.dcaegen2.platform.helmchartgenerator.chartbuilder.KeyValueMerger;
+import org.onap.dcaegen2.platform.helmchartgenerator.models.chartinfo.ChartInfo;
+import org.onap.dcaegen2.platform.helmchartgenerator.models.chartinfo.Metadata;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+
+@ExtendWith(MockitoExtension.class)
+class KeyValueMergerTest {
+
+    private KeyValueMerger merger;
+
+    @Mock
+    private Yaml yamlHelper;
+
+    private File chartDir;
+
+    @BeforeEach
+    void setUp() {
+        merger = new KeyValueMerger(yamlHelper);
+    }
+
+    @Test
+    void mergeValuesToChart() throws IOException {
+        ChartInfo chartInfo = prepareChartInfo();
+        chartDir = prepareChartDir();
+
+        Mockito.when(yamlHelper.load(any(InputStream.class))).thenReturn(new HashMap<String, Object>());
+
+        merger.mergeValuesToChart(chartInfo, chartDir);
+        Mockito.verify(yamlHelper, Mockito.times(2)).dump(any(HashMap.class), any(PrintWriter.class));
+    }
+
+    @AfterEach
+    void tearDown(){
+        FileUtils.deleteQuietly(chartDir);
+    }
+
+    private File prepareChartDir() throws IOException {
+        final Path chartDir = Files.createTempDirectory("chartDir");
+        Files.createFile(chartDir.resolve("Chart.yaml"));
+        Files.createFile(chartDir.resolve("values.yaml"));
+        return chartDir.toFile();
+    }
+
+    private ChartInfo prepareChartInfo() {
+        ChartInfo chartInfo = new ChartInfo();
+
+        Metadata metadata = new Metadata();
+        metadata.setName("someComponent");
+        metadata.setVersion("someVersion");
+        metadata.setDescription("someDescription");
+
+        Map<String, Object> values = new HashMap<>();
+        values.put("someKey", "someValue");
+
+        chartInfo.setMetadata(metadata);
+        chartInfo.setValues(values);
+
+        return chartInfo;
+    }
+}
+
index 8f7e8aa..d4149f2 100644 (file)
@@ -1 +1,3 @@
-lombok.addLombokGeneratedAnnotation = true
\ No newline at end of file
+config.stopBubbling = true
+lombok.addLombokGeneratedAnnotation = true
+
index dc87a54..7f9801c 100644 (file)
@@ -33,7 +33,7 @@
 
        <groupId>org.onap.dcaegen2.platform</groupId>
        <artifactId>helmchartgenerator</artifactId>
-       <version>1.0.0-SNAPSHOT</version>
+       <version>1.0.1-SNAPSHOT</version>
        <name>helm-chart-generator</name>
        <description>Helm chart generator</description>
        <properties>
                        <artifactId>okhttp</artifactId>
                        <version>4.0.1</version>
                </dependency>
+               <dependency>
+                       <groupId>com.squareup.okhttp3</groupId>
+                       <artifactId>mockwebserver</artifactId>
+                       <version>4.0.1</version>
+                       <scope>test</scope>
+               </dependency>
        </dependencies>
        <dependencyManagement>
                <dependencies>