Merge "Upgrade to helm3"
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/controller/AppController.java b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/AppController.java
index ca1994b..04f0f05 100644
--- a/rapp-manager/src/main/java/org/oransc/rappmanager/controller/AppController.java
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/AppController.java
@@ -56,13 +56,12 @@
     @Autowired
     private AppService appService;
 
-    @Autowired
     private static Gson gson = new GsonBuilder().create();
 
     @GetMapping(path = "/apps", produces = MediaType.APPLICATION_JSON_VALUE)
     @ApiOperation(value = "Return all Apps")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "rApp List")})
-    public ResponseEntity<AppList> getAllApps() throws ServiceException {
+    public ResponseEntity<AppList> getAllApps() {
         Collection<AppInfo> apps = new ArrayList<>();
         appService.getAllApps().forEach(app -> apps.add(toAppInfo(app)));
         AppList list = AppList.builder().apps(apps).build();
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmClient.java b/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmClient.java
index d7c9af3..bfdb439 100644
--- a/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmClient.java
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmClient.java
@@ -70,14 +70,15 @@
             Process process = builder.start();
             process.waitFor();
             int exitValue = process.exitValue();
+            String commandStr = toString(builder);
 
             if (exitValue != 0) {
                 String error = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8);
-                logger.error("Executing helm command {} failed, exitValue: {} {}", toString(builder), exitValue, error);
-                throw new ServiceException("Command execution failed: " + builder + " " + error);
+                logger.error("Executing helm command <{}> failed, exitValue: {} {}", commandStr, exitValue, error);
+                throw new ServiceException("Command execution failed: " + commandStr + " " + error);
             }
             String output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8);
-            logger.debug("Command execution, output:{}", output);
+            logger.debug("Command <{}> execution, output:{}", commandStr, output);
             return output;
         } catch (Exception e) {
             throw new ServiceException("Failed to execute the Command", e);
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/service/App.java b/rapp-manager/src/main/java/org/oransc/rappmanager/service/App.java
index 11b4529..939ac43 100644
--- a/rapp-manager/src/main/java/org/oransc/rappmanager/service/App.java
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/App.java
@@ -20,10 +20,8 @@
 
 import lombok.Builder;
 import lombok.Getter;
-import lombok.Setter;
 
 @Getter
-@Setter
 @Builder
 public class App {
 
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppStore.java b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppStore.java
index 39b503f..4c49dce 100644
--- a/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppStore.java
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppStore.java
@@ -18,11 +18,17 @@
 
 package org.oransc.rappmanager.service;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.lang.invoke.MethodHandles;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -42,13 +48,19 @@
 public class AppStore {
 
     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static Gson gson = new GsonBuilder().create();
+
     /**
      * The appStore map contains app name as key & App as value
      */
     private Map<String, App> appMap = new HashMap<>();
 
-    @Autowired
-    ApplicationConfig appConfig;
+    private final ApplicationConfig appConfig;
+
+    public AppStore(@Autowired ApplicationConfig appConfig) {
+        this.appConfig = appConfig;
+        this.restoreFromDatabase();
+    }
 
     public File getOverrideFile(App app) {
         Path appPath = getAppPath(app.getName(), app.getVersion());
@@ -78,6 +90,7 @@
         overrideFile.transferTo(getOverrideFile(app));
 
         appMap.put(key(app), app);
+        storeAppInFile(app);
         return app;
     }
 
@@ -104,9 +117,45 @@
         appMap.remove(key(app));
     }
 
+    private void storeAppInFile(App app) {
+        try (PrintStream out = new PrintStream(new FileOutputStream(getFile(app)))) {
+            out.print(gson.toJson(app));
+        } catch (Exception e) {
+            logger.warn("Could not store app: {} {}", app.getName(), e.getMessage());
+        }
+    }
+
+    private File getFile(App app) {
+        String appPath = getAppPath(app.getName(), app.getVersion()).toString();
+        return Path.of(appPath, APP_FILE_NAME).toFile();
+    }
+
+    private static final String APP_FILE_NAME = "App.json";
+
+    public synchronized void restoreFromDatabase() {
+        try {
+            Files.createDirectories(Paths.get(getDatabaseDirectory()));
+            restoreFromDatabase(new File(getDatabaseDirectory()));
+        } catch (IOException e) {
+            logger.warn("Could not restore apps from database: {}", e.getMessage());
+        }
+    }
+
+    public synchronized void restoreFromDatabase(File file) throws IOException {
+        if (file.isDirectory()) {
+            for (File dirElement : file.listFiles()) {
+                restoreFromDatabase(dirElement);
+            }
+        } else if (file.getName().equals(APP_FILE_NAME)) {
+            String json = Files.readString(file.toPath());
+            App app = gson.fromJson(json, App.class);
+            appMap.put(key(app), app);
+        }
+    }
+
     public synchronized void reset() {
         try {
-            FileSystemUtils.deleteRecursively(Path.of(this.appConfig.getVardataDirectory()));
+            FileSystemUtils.deleteRecursively(Path.of(getDatabaseDirectory()));
         } catch (IOException e) {
             logger.warn("Could not delete database : {}", e.getMessage());
         }
diff --git a/rapp-manager/src/test/java/org/oransc/rappmanager/controller/KubernetesTest.java b/rapp-manager/src/test/java/org/oransc/rappmanager/controller/KubernetesTest.java
index 39351e3..d47461a 100644
--- a/rapp-manager/src/test/java/org/oransc/rappmanager/controller/KubernetesTest.java
+++ b/rapp-manager/src/test/java/org/oransc/rappmanager/controller/KubernetesTest.java
@@ -11,9 +11,8 @@
 import java.util.Arrays;
 import java.util.List;
 
-import org.junit.Test;
 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.junit.runner.RunWith;
 import org.oransc.rappmanager.BeanFactory;
@@ -29,7 +28,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 import org.springframework.boot.test.context.TestConfiguration;
@@ -48,7 +46,6 @@
 import org.springframework.web.reactive.function.BodyInserters;
 import org.springframework.web.reactive.function.BodyInserters.MultipartInserter;
 
-@AutoConfigureMockMvc
 @RunWith(SpringRunner.class)
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@@ -164,7 +161,6 @@
         }
     }
 
-    @BeforeEach
     @AfterEach
     void reset() {
         appStore.reset();
@@ -184,6 +180,15 @@
         deleteApp();
     }
 
+    @Test
+    public void testStoreApp() throws ServiceException {
+        appStore.reset();
+        onboardApp();
+        AppStore tmpAppStore = new AppStore(this.applicationConfig);
+        App app = tmpAppStore.getApp(APP_NAME, VERSION);
+        assertThat(app.getNamespace()).isEqualTo(NAMESPACE);
+    }
+
     private void onboardApp() {
         String url = "/rms/apps";
         AppInfo appInfo = AppInfo.builder().name(APP_NAME).version(VERSION).namespace(NAMESPACE).build();