rApp Prototype

Change-Id: I70e3e7235abb810784e41ebd70977d9133db2b16
Signed-off-by: Lathish <lathishbabu.ganesan@est.tech>
diff --git a/rapp-manager/.checkstyle b/rapp-manager/.checkstyle
new file mode 100644
index 0000000..0db75ec
--- /dev/null
+++ b/rapp-manager/.checkstyle
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="false" sync-formatter="false">
+  <local-check-config name="maven-checkstyle-plugin check-license" location="jar:file:/Users/lathish/.m2/repository/org/onap/oparent/checkstyle/1.1.1/checkstyle-1.1.1.jar!/onap-checkstyle/check-license.xml" type="remote" description="maven-checkstyle-plugin configuration check-license">
+    <property name="checkstyle.header.file" value="/Users/lathish/Documents/workspace/ccsdk-oran/.metadata/.plugins/org.eclipse.core.resources/.projects/rapp-manager/com.basistech.m2e.code.quality.checkstyleConfigurator/checkstyle-header-check-license.txt"/>
+    <property name="checkstyle.cache.file" value="${project_loc}/target/checkstyle-cachefile"/>
+  </local-check-config>
+  <local-check-config name="maven-checkstyle-plugin check-style" location="jar:file:/Users/lathish/.m2/repository/org/onap/oparent/checkstyle/1.1.1/checkstyle-1.1.1.jar!/onap-checkstyle/onap-java-style.xml" type="remote" description="maven-checkstyle-plugin configuration check-style">
+    <property name="checkstyle.header.file" value="/Users/lathish/Documents/workspace/ccsdk-oran/.metadata/.plugins/org.eclipse.core.resources/.projects/rapp-manager/com.basistech.m2e.code.quality.checkstyleConfigurator/checkstyle-header-check-style.txt"/>
+    <property name="checkstyle.cache.file" value="${project_loc}/target/checkstyle-cachefile"/>
+  </local-check-config>
+  <fileset name="java-sources-check-license" enabled="true" check-config-name="maven-checkstyle-plugin check-license" local="true">
+    <file-match-pattern match-pattern="^src/test/java/.*\/.*\.java" include-pattern="true"/>
+    <file-match-pattern match-pattern="^src/main/java/.*\/.*\.java" include-pattern="true"/>
+  </fileset>
+  <fileset name="java-sources-check-style" enabled="true" check-config-name="maven-checkstyle-plugin check-style" local="true">
+    <file-match-pattern match-pattern="^src/test/java/.*\/.*\.java" include-pattern="true"/>
+    <file-match-pattern match-pattern="^src/main/java/.*\/.*\.java" include-pattern="true"/>
+    <file-match-pattern match-pattern="^src/main/java/src/main/java.*\/.*\.java" include-pattern="true"/>
+    <file-match-pattern match-pattern="^src/main/resources.*\.properties" include-pattern="true"/>
+    <file-match-pattern match-pattern="^src/main/resources.*\.properties" include-pattern="true"/>
+    <file-match-pattern match-pattern="^src/test/resources.*\.properties" include-pattern="true"/>
+  </fileset>
+</fileset-config>
diff --git a/rapp-manager/.classpath b/rapp-manager/.classpath
new file mode 100644
index 0000000..1f94f5f
--- /dev/null
+++ b/rapp-manager/.classpath
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="test" value="true"/>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/classes" path="target/generated-sources/annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/rapp-manager/.gitignore b/rapp-manager/.gitignore
new file mode 100644
index 0000000..df309a1
--- /dev/null
+++ b/rapp-manager/.gitignore
@@ -0,0 +1,20 @@
+# Documentation
+.idea/
+.tox
+docs/_build/
+.DS_STORE
+.swagger*
+docs/offeredapis/swagger/README.md
+
+# Eclipse
+.checkstyle
+.classpath
+target/
+.sts4-cache
+.project
+.settings
+.pydevproject
+infer-out/
+
+.vscode
+.factorypath
diff --git a/rapp-manager/.project b/rapp-manager/.project
new file mode 100644
index 0000000..1f1a6f8
--- /dev/null
+++ b/rapp-manager/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>rapp-manager</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/rapp-manager/.settings/org.eclipse.core.resources.prefs b/rapp-manager/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..c6a8b3d
--- /dev/null
+++ b/rapp-manager/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
+encoding//target/generated-sources/annotations=UTF-8
+encoding/<project>=UTF-8
diff --git a/rapp-manager/.settings/org.eclipse.jdt.core.prefs b/rapp-manager/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..55e549b
--- /dev/null
+++ b/rapp-manager/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/rapp-manager/.settings/org.eclipse.m2e.core.prefs b/rapp-manager/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/rapp-manager/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/rapp-manager/Dockerfile b/rapp-manager/Dockerfile
new file mode 100644
index 0000000..786b12c
--- /dev/null
+++ b/rapp-manager/Dockerfile
@@ -0,0 +1,35 @@
+#
+# ============LICENSE_START=======================================================
+#  Copyright (C) 2021 Nordix Foundation.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+#
+FROM openjdk:11-jre-slim
+
+ARG JAR
+
+WORKDIR /opt/app/rapp-manager
+RUN mkdir -p /var/log/rapp-manager
+
+RUN apt-get update && apt install -y wget
+RUN wget https://get.helm.sh/helm-v3.5.2-linux-amd64.tar.gz && tar xvf helm-v3.5.2-linux-amd64.tar.gz && mv linux-amd64/helm /usr/local/bin
+RUN rm -rf linux-amd64 && rm helm-v3.5.2-linux-amd64.tar.gz
+
+EXPOSE 8080
+ADD /config/application.yaml /opt/app/rapp-manager/config/application.yaml
+ADD target/${JAR} /opt/app/rapp-manager/rapp-manager.jar
+
+CMD ["java", "-jar", "/opt/app/rapp-manager/rapp-manager.jar"]
\ No newline at end of file
diff --git a/rapp-manager/config/application.yaml b/rapp-manager/config/application.yaml
new file mode 100644
index 0000000..2100be1
--- /dev/null
+++ b/rapp-manager/config/application.yaml
@@ -0,0 +1,31 @@
+ # ========================LICENSE_START=================================
+ # Copyright (C) 2021 Nordix Foundation. 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===================================
+
+management:
+  endpoints:
+    web:
+      exposure:
+        include: "loggers,logfile,health,info,metrics,threaddump,heapdump"
+server:
+  port : 8080
+logging:
+  level:
+    ROOT: INFO
+app:
+  basepath: https://kubernetes.docker.internal:6443
+  certpath: /opt/app/rapp-manager/cert/ca.crt
+  tokenpath: /opt/app/rapp-manager/cert/token.txt
+  chartregistry: http://localhost:30081
diff --git a/rapp-manager/pom.xml b/rapp-manager/pom.xml
new file mode 100644
index 0000000..1758a17
--- /dev/null
+++ b/rapp-manager/pom.xml
@@ -0,0 +1,437 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+* ========================LICENSE_START=================================
+* O-RAN-SC
+* %%
+* Copyright (C) 2021 Nordix Foundation
+* %%
+* 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===================================
+-->
+<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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.3.8.RELEASE</version>
+        <relativePath/>
+    </parent>
+    <groupId>org.o-ran-sc.nonrtric</groupId>
+    <artifactId>rapp-manager</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <properties>
+        <java.version>11</java.version>
+        <springfox.version>3.0.0</springfox.version>
+        <immutable.version>2.8.8</immutable.version>
+        <json.version>20200518</json.version>
+        <formatter-maven-plugin.version>2.13.0</formatter-maven-plugin.version>
+        <spotless-maven-plugin.version>2.5.0</spotless-maven-plugin.version>
+        <commons-io.version>2.5</commons-io.version>
+        <docker-maven-plugin>0.30.0</docker-maven-plugin>
+        <surefire-maven-plugin.version>3.0.0-M5</surefire-maven-plugin.version>
+        <jacoco-maven-plugin.version>0.8.6</jacoco-maven-plugin.version>
+        <swagger-codegen-maven-plugin.version>3.0.11</swagger-codegen-maven-plugin.version>
+        <exec.skip>true</exec.skip>
+         <sdk.version>1.1.6</sdk.version>
+    </properties>
+    <dependencies>
+         <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-reactor-netty</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webflux</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-spring-web</artifactId>
+            <version>${springfox.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-spi</artifactId>
+            <version>${springfox.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-core</artifactId>
+            <version>${springfox.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+             <version>30.0-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>org.immutables</groupId>
+            <artifactId>value</artifactId>
+            <version>${immutable.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.immutables</groupId>
+            <artifactId>gson</artifactId>
+            <version>${immutable.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>${json.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Actuator dependencies -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <!--REQUIRED TO GENERATE DOCUMENTATION -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>${springfox.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>${springfox.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- For development help -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <optional>true</optional>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- TEST -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.projectreactor</groupId>
+            <artifactId>reactor-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>mockwebserver</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io.version}</version>
+           <!--  <scope>test</scope> -->
+        </dependency>
+        <dependency>
+            <groupId>io.kubernetes</groupId>
+            <artifactId>client-java</artifactId>
+            <version>10.0.0</version>
+        </dependency>
+        <dependency>
+           <groupId>commons-fileupload</groupId>
+           <artifactId>commons-fileupload</artifactId>
+           <version>1.4</version>
+        </dependency>
+        
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.build.directory}/generated-sources/annotations/</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>net.revelc.code.formatter</groupId>
+                <artifactId>formatter-maven-plugin</artifactId>
+                <version>${formatter-maven-plugin.version}</version>
+                <configuration>
+                    <lineEnding>LF</lineEnding>
+                    <configFile>${project.basedir}/eclipse-formatter.xml</configFile>
+                </configuration>
+                <!-- https://code.revelc.net/formatter-maven-plugin/ use mvn formatter:format
+                    spotless:apply process-sources -->
+            </plugin>
+            <plugin>
+                <groupId>com.diffplug.spotless</groupId>
+                <artifactId>spotless-maven-plugin</artifactId>
+                <version>${spotless-maven-plugin.version}</version>
+                <configuration>
+                    <lineEndings>UNIX</lineEndings>
+                    <java>
+                        <removeUnusedImports/>
+                        <importOrder>
+                            <order>com,java,javax,org</order>
+                        </importOrder>
+                    </java>
+                </configuration>
+                <!-- https://github.com/diffplug/spotless/tree/master/plugin-maven use
+                    mvn spotless:apply to rewrite source files use mvn spotless:check to validate
+                    source files -->
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire-maven-plugin.version}</version>
+                <configuration>
+                    <skipTests>false</skipTests>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>${project.build.directory}/generated-sources/annotations/</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>${jacoco-maven-plugin.version}</version>
+                <executions>
+                    <execution>
+                        <id>default-prepare-agent</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>default-report</id>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- <plugin>
+                <groupId>io.swagger.codegen.v3</groupId>
+                <artifactId>swagger-codegen-maven-plugin</artifactId>
+                <version>${swagger-codegen-maven-plugin.version}</version>
+                <executions>
+                    <execution>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <inputSpec>${project.basedir}/api/rapp-manager.json</inputSpec>
+                            <language>openapi-yaml</language>
+                            <output>${project.basedir}/api</output>
+                            <configOptions>
+                                <outputFile>rapp-manager-api.yaml</outputFile>
+                            </configOptions>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin> -->
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resource-one</id>
+                        <phase>install</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.basedir}/../docs/offeredapis/swagger</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>${project.basedir}/api</directory>
+                                    <includes>
+                                        <include>rapp-manager-api.*</include>
+                                    </includes>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>io.fabric8</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>${docker-maven-plugin}</version>
+                <inherited>false</inherited>
+                <executions>
+                    <execution>
+                        <id>generate-rapp-manager-image</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                        <configuration>
+                            <images>
+                                <image>
+                                    <name>o-ran-sc/nonrtric-rapp-manager:${project.version}</name>
+                                    <build>
+                                        <cleanup>try</cleanup>
+                                        <contextDir>${basedir}</contextDir>
+                                        <dockerFile>Dockerfile</dockerFile>
+                                        <args>
+                                            <JAR>${project.build.finalName}.jar</JAR>
+                                        </args>
+                                        <tags>
+                                            <tag>${project.version}</tag>
+                                        </tags>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>push-rapp-manager-image</id>
+                        <goals>
+                            <goal>build</goal>
+                            <goal>push</goal>
+                        </goals>
+                        <configuration>
+                            <images>
+                                <image>
+                                    <name>o-ran-sc/nonrtric-rapp-manager:${project.version}</name>
+                                    <build>
+                                        <contextDir>${basedir}</contextDir>
+                                        <dockerFile>Dockerfile</dockerFile>
+                                        <args>
+                                            <JAR>${project.build.finalName}.jar</JAR>
+                                        </args>
+                                        <tags>
+                                            <tag>${project.docker.latestminortag.version}</tag>
+                                            <tag>${project.docker.latestfulltag.version}</tag>
+                                            <tag>${project.docker.latesttagtimestamp.version}</tag>
+                                        </tags>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/Application.java b/rapp-manager/src/main/java/org/oransc/rappmanager/Application.java
new file mode 100644
index 0000000..e897b45
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/Application.java
@@ -0,0 +1,31 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/BeanFactory.java b/rapp-manager/src/main/java/org/oransc/rappmanager/BeanFactory.java
new file mode 100644
index 0000000..b35e5bb
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/BeanFactory.java
@@ -0,0 +1,47 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager;
+
+import org.oransc.rappmanager.client.AsyncRestClient;
+import org.oransc.rappmanager.configuration.ApplicationConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.multipart.MultipartResolver;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+
+@Configuration
+public class BeanFactory {
+
+    @Autowired
+    private ApplicationConfig appConfig;
+
+    @Bean
+    public AsyncRestClient getChartClient() {
+        return new AsyncRestClient(appConfig.getChartApi());
+    }
+    
+    @Bean(name = "multipartResolver")
+    public MultipartResolver multipartResolver() {
+        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
+        multipartResolver.setMaxUploadSize(100000);
+        return multipartResolver;
+    }
+
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/client/AsyncRestClient.java b/rapp-manager/src/main/java/org/oransc/rappmanager/client/AsyncRestClient.java
new file mode 100644
index 0000000..8f8bd82
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/client/AsyncRestClient.java
@@ -0,0 +1,298 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.client;
+
+import io.netty.channel.ChannelOption;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.SslContextBuilder;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.handler.timeout.WriteTimeoutHandler;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import org.immutables.value.Value;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.MultipartBodyBuilder;
+import org.springframework.http.client.reactive.ReactorClientHttpConnector;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.reactive.function.BodyInserters;
+import org.springframework.web.reactive.function.BodyInserters.MultipartInserter;
+import org.springframework.web.reactive.function.client.ExchangeStrategies;
+import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
+import reactor.core.publisher.Mono;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.resources.ConnectionProvider;
+import reactor.netty.tcp.TcpClient;
+
+/**
+ * Generic reactive REST client.
+ */
+public class AsyncRestClient {
+
+    @Value.Immutable
+    @Value.Style(redactedMask = "####")
+    public interface WebClientConfig {
+        public boolean isTrustStoreUsed();
+
+        @Value.Redacted
+        public String trustStorePassword();
+
+        public String trustStore();
+    }
+
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private WebClient webClient = null;
+    private final String baseUrl;
+    private static final AtomicInteger sequenceNumber = new AtomicInteger();
+    private final WebClientConfig clientConfig;
+    static KeyStore clientTrustStore = null;
+
+    public AsyncRestClient(String baseUrl) {
+        this(baseUrl, ImmutableWebClientConfig.builder().isTrustStoreUsed(false).trustStore("").trustStorePassword("")
+                .build());
+    }
+
+    public AsyncRestClient(String baseUrl, WebClientConfig config) {
+        this.baseUrl = baseUrl;
+        this.clientConfig = config;
+    }
+
+    public Mono<ResponseEntity<String>> putForEntity(String uri, String body) {
+        Object traceTag = createTraceTag();
+        logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri);
+        logger.trace("{} PUT body: {}", traceTag, body);
+        return getWebClient() //
+                .flatMap(client -> {
+                    RequestHeadersSpec<?> request = client.put() //
+                            .uri(uri) //
+                            .contentType(MediaType.APPLICATION_JSON) //
+                            .bodyValue(body);
+                    return retrieve(traceTag, request);
+                });
+    }
+
+    public Mono<ResponseEntity<String>> postForEntity(String uri, File file) {
+        Object traceTag = createTraceTag();
+        logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri);
+        logger.trace("{} PUT body: {}", traceTag, file.getName());
+        return getWebClient() //
+                .flatMap(client -> {
+                    RequestHeadersSpec<?> request = client.post() //
+                            .uri(uri) //
+                            .contentType(MediaType.MULTIPART_FORM_DATA) //
+                            .bodyValue(createPostFileBody(file));
+                    return retrieve(traceTag, request);
+                });
+    }
+
+    private MultipartInserter createPostFileBody(File file) {
+        MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder();
+        bodyBuilder.part("file", new FileSystemResource(file));
+        return BodyInserters.fromMultipartData(bodyBuilder.build());
+    }
+
+    public Mono<ResponseEntity<String>> putForEntity(String uri) {
+        Object traceTag = createTraceTag();
+        logger.debug("{} PUT uri = '{}{}''", traceTag, baseUrl, uri);
+        logger.trace("{} PUT body: <empty>", traceTag);
+        return getWebClient() //
+                .flatMap(client -> {
+                    RequestHeadersSpec<?> request = client.put() //
+                            .uri(uri);
+                    return retrieve(traceTag, request);
+                });
+    }
+
+    public Mono<String> put(String uri, String body) {
+        return putForEntity(uri, body) //
+                .flatMap(this::toBody);
+    }
+
+    public Mono<ResponseEntity<String>> getForEntity(String uri) {
+        Object traceTag = createTraceTag();
+        logger.debug("{} GET uri = '{}{}''", traceTag, baseUrl, uri);
+        return getWebClient() //
+                .flatMap(client -> {
+                    RequestHeadersSpec<?> request = client.get().uri(uri);
+                    return retrieve(traceTag, request);
+                });
+    }
+
+    public Mono<String> get(String uri) {
+        return getForEntity(uri) //
+                .flatMap(this::toBody);
+    }
+
+    public Mono<ResponseEntity<String>> deleteForEntity(String uri) {
+        Object traceTag = createTraceTag();
+        logger.debug("{} DELETE uri = '{}{}''", traceTag, baseUrl, uri);
+        return getWebClient() //
+                .flatMap(client -> {
+                    RequestHeadersSpec<?> request = client.delete().uri(uri);
+                    return retrieve(traceTag, request);
+                });
+    }
+
+    public Mono<String> delete(String uri) {
+        return deleteForEntity(uri) //
+                .flatMap(this::toBody);
+    }
+
+    private Mono<ResponseEntity<String>> retrieve(Object traceTag, RequestHeadersSpec<?> request) {
+        final Class<String> clazz = String.class;
+        return request.retrieve() //
+                .toEntity(clazz) //
+                .doOnNext(entity -> logger.trace("{} Received: {}", traceTag, entity.getBody())) //
+                .doOnError(throwable -> onHttpError(traceTag, throwable));
+    }
+
+    private static Object createTraceTag() {
+        return sequenceNumber.incrementAndGet();
+    }
+
+    private void onHttpError(Object traceTag, Throwable t) {
+        if (t instanceof WebClientResponseException) {
+            WebClientResponseException exception = (WebClientResponseException) t;
+            logger.debug("{} HTTP error status = '{}', body '{}'", traceTag, exception.getStatusCode(),
+                    exception.getResponseBodyAsString());
+        } else {
+            logger.debug("{} HTTP error: {}", traceTag, t.getMessage());
+        }
+    }
+
+    private Mono<String> toBody(ResponseEntity<String> entity) {
+        if (entity.getBody() == null) {
+            return Mono.just("");
+        } else {
+            return Mono.just(entity.getBody());
+        }
+    }
+
+    private boolean isCertificateEntry(KeyStore trustStore, String alias) {
+        try {
+            return trustStore.isCertificateEntry(alias);
+        } catch (KeyStoreException e) {
+            logger.error("Error reading truststore {}", e.getMessage());
+            return false;
+        }
+    }
+
+    private Certificate getCertificate(KeyStore trustStore, String alias) {
+        try {
+            return trustStore.getCertificate(alias);
+        } catch (KeyStoreException e) {
+            logger.error("Error reading truststore {}", e.getMessage());
+            return null;
+        }
+    }
+
+    private static synchronized KeyStore getTrustStore(String trustStorePath, String trustStorePass)
+            throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
+        if (clientTrustStore == null) {
+            KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
+            store.load(new FileInputStream(ResourceUtils.getFile(trustStorePath)), trustStorePass.toCharArray());
+            clientTrustStore = store;
+        }
+        return clientTrustStore;
+    }
+
+    private SslContext createSslContextRejectingUntrustedPeers(String trustStorePath, String trustStorePass)
+            throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
+
+        final KeyStore trustStore = getTrustStore(trustStorePath, trustStorePass);
+        List<Certificate> certificateList = Collections.list(trustStore.aliases()).stream() //
+                .filter(alias -> isCertificateEntry(trustStore, alias)) //
+                .map(alias -> getCertificate(trustStore, alias)) //
+                .collect(Collectors.toList());
+        final X509Certificate[] certificates = certificateList.toArray(new X509Certificate[certificateList.size()]);
+
+        return SslContextBuilder.forClient() //
+                .trustManager(certificates) //
+                .build();
+    }
+
+    private SslContext createSslContext()
+            throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
+        if (this.clientConfig.isTrustStoreUsed()) {
+            return createSslContextRejectingUntrustedPeers(this.clientConfig.trustStore(),
+                    this.clientConfig.trustStorePassword());
+        } else {
+            // Trust anyone
+            return SslContextBuilder.forClient() //
+                    .trustManager(InsecureTrustManagerFactory.INSTANCE) //
+                    .build();
+        }
+    }
+
+    private WebClient createWebClient(String baseUrl, SslContext sslContext) {
+        ConnectionProvider connectionProvider = ConnectionProvider.newConnection();
+        TcpClient tcpClient = TcpClient.create(connectionProvider) //
+                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
+                .secure(c -> c.sslContext(sslContext)) //
+
+                .doOnConnected(connection -> {
+                    connection.addHandlerLast(new ReadTimeoutHandler(30));
+                    connection.addHandlerLast(new WriteTimeoutHandler(30));
+                });
+        HttpClient httpClient = HttpClient.from(tcpClient);
+        ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
+
+        ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() //
+                .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) //
+                .build();
+
+        return WebClient.builder() //
+                .clientConnector(connector) //
+                .baseUrl(baseUrl) //
+                .exchangeStrategies(exchangeStrategies) //
+                .build();
+    }
+
+    private Mono<WebClient> getWebClient() {
+        if (this.webClient == null) {
+            try {
+                SslContext sslContext = createSslContext();
+                this.webClient = createWebClient(this.baseUrl, sslContext);
+            } catch (Exception e) {
+                logger.error("Could not create WebClient {}", e.getMessage());
+                return Mono.error(e);
+            }
+        }
+        return Mono.just(this.webClient);
+    }
+
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/configuration/ApplicationConfig.java b/rapp-manager/src/main/java/org/oransc/rappmanager/configuration/ApplicationConfig.java
new file mode 100644
index 0000000..7b8ced0
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/configuration/ApplicationConfig.java
@@ -0,0 +1,75 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.configuration;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import javax.validation.constraints.NotEmpty;
+import lombok.Getter;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties()
+@EnableConfigurationProperties
+public class ApplicationConfig {
+
+    @NotEmpty
+    @Getter
+    @Value("${app.certpath}")
+    private String certPath;
+
+    @NotEmpty
+    @Getter
+    @Value("${app.tokenpath}")
+    private String tokenPath;
+
+    @NotEmpty
+    @Getter
+    @Value("${app.basepath}")
+    private String basePath;
+
+    @NotEmpty
+    @Getter
+    @Value("${app.chartregistry}")
+    private String chartApi;
+
+    public String getToken() throws ServiceException {
+        try {
+            Path path = Path.of(tokenPath);
+            return Files.readString(path);
+        } catch (IOException e) {
+            throw new ServiceException("Error Reading token", e);
+        }
+    }
+
+    public InputStream getCert() throws ServiceException {
+        try {
+            return new FileInputStream(certPath);
+        } catch (IOException e) {
+            throw new ServiceException("Error Reading token", e);
+        }
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/configuration/KubernetesClusterConfig.java b/rapp-manager/src/main/java/org/oransc/rappmanager/configuration/KubernetesClusterConfig.java
new file mode 100644
index 0000000..ce2b348
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/configuration/KubernetesClusterConfig.java
@@ -0,0 +1,64 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.configuration;
+
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.Configuration;
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+import io.kubernetes.client.util.ClientBuilder;
+import java.io.IOException;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class KubernetesClusterConfig {
+
+    @Autowired
+    private ApplicationConfig appConfig;
+
+    private CoreV1Api api;
+
+    private static final Logger logger = LoggerFactory.getLogger(KubernetesClusterConfig.class);
+
+    private void connectToKubernetesCluster() throws ServiceException {
+        logger.debug("Reading Kubernetes Configuration");
+        ApiClient client;
+        try {
+            client = ClientBuilder.cluster().build();
+            client.setBasePath(appConfig.getBasePath());
+            client.setApiKey(appConfig.getToken());
+            client.setSslCaCert(appConfig.getCert());
+            Configuration.setDefaultApiClient(client);
+            api = new CoreV1Api();
+        } catch (IOException e) {
+            throw new ServiceException("Failed to Read the Kubernetes Configuration", e);
+        }
+    }
+
+    public CoreV1Api getKubernetesClient() throws ServiceException {
+        if (api == null) {
+            connectToKubernetesCluster();
+        }
+        return api;
+    }
+}
+
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
new file mode 100644
index 0000000..bf2e551
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/AppController.java
@@ -0,0 +1,88 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.oransc.rappmanager.service.App;
+import org.oransc.rappmanager.service.AppList;
+import org.oransc.rappmanager.service.AppService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("rAppController")
+@RequestMapping("rms")
+@Api(tags = {"rapp"})
+public class AppController {
+
+    @Autowired
+    private AppService appService;
+
+    @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 {
+        return new ResponseEntity<>(appService.getAllApps(), HttpStatus.OK);
+    }
+
+    @GetMapping(path = "/apps/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Return a App")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "rApp")})
+    public ResponseEntity<App> getApp(@PathVariable("name") String name) {
+        return new ResponseEntity<>(appService.getApp(name), HttpStatus.OK);
+    }
+
+    @GetMapping(path = "/apps/{name}/status", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Return the status of an App")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "rApp")})
+    public ResponseEntity<App> getAppStatus(@PathVariable("name") String name) throws ServiceException {
+        return new ResponseEntity<>(appService.getAppStatus(name), HttpStatus.OK);
+    }
+
+    @PostMapping(path = "/apps", consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Install the rApp")
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "rApp Installed")})
+    public ResponseEntity<?> installApp(@RequestBody App app) throws ServiceException {
+        appService.installApp(app);
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+
+    @DeleteMapping(path = "/apps/{name}", consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Uninstall the App")
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "rApp Uninstalled")})
+    public ResponseEntity<?> deleteApp(@PathVariable("name") String name,
+            @PathVariable("namespace") String releaseNamespace) throws ServiceException {
+        appService.uninstallApp(name, releaseNamespace);
+        return new ResponseEntity<>(HttpStatus.OK);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/controller/Chart.java b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/Chart.java
new file mode 100644
index 0000000..6974a25
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/Chart.java
@@ -0,0 +1,46 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.controller;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModel;
+import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.web.multipart.MultipartFile;
+
+@ApiModel(value = "Chart", description = "Chart Information")
+@Getter
+@Setter
+@JsonInclude(Include.NON_NULL)
+public class Chart {
+
+    private String name;
+    private String version;
+    private MultipartFile chart;
+    private String description;
+    private String apiVersion;
+    private String appVersion;
+    private List<String> urls;
+    private String digest;
+    @JsonProperty(required = false)
+    private boolean upgrade;
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/controller/ChartController.java b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/ChartController.java
new file mode 100644
index 0000000..275da2a
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/ChartController.java
@@ -0,0 +1,89 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import java.util.Map;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.oransc.rappmanager.service.ChartService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("chartController")
+@RequestMapping("rms")
+@Api(tags = {"chart"})
+public class ChartController {
+
+    @Autowired
+    private ChartService chartService;
+
+    @GetMapping(path = "/charts", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Return all Charts")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "Chart List")})
+    public ResponseEntity<Map<String, Chart[]>> getCharts() throws ServiceException {
+        return new ResponseEntity<>(chartService.getCharts(), HttpStatus.OK);
+    }
+
+    @GetMapping(path = "/charts/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Return a chart")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "Chart")})
+    public ResponseEntity<Chart[]> getChart(@PathVariable("name") String name) throws ServiceException {
+        return new ResponseEntity<>(chartService.getChart(name), HttpStatus.OK);
+    }
+
+    @PostMapping(path = "/charts", consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Onboard the Chart")
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")})
+    public ResponseEntity<?> onboardChart(@ModelAttribute Chart chart) throws ServiceException {
+        chartService.saveChart(chart);
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+
+    @DeleteMapping(path = "/charts/{id}", consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Delete the Chart")
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Deleted")})
+    public ResponseEntity<?> deleteChart(@PathVariable("name") String name, @PathVariable("version") String version)
+            throws ServiceException {
+        chartService.deleteChart(name, version);
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+
+    @PostMapping(path = "/charts", consumes = MediaType.APPLICATION_JSON_VALUE,
+            produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Update the Chart to new Version")
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Upgraded")})
+    public ResponseEntity<?> updateChart(@ModelAttribute Chart chart) throws ServiceException {
+        chartService.saveChart(chart);
+        return new ResponseEntity<>(HttpStatus.CREATED);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/controller/KubernetesConfigController.java b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/KubernetesConfigController.java
new file mode 100644
index 0000000..170a34f
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/controller/KubernetesConfigController.java
@@ -0,0 +1,56 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.oransc.rappmanager.configuration.KubernetesClusterConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController("KubernetesConfigController")
+@RequestMapping("rms")
+@Api(tags = {"kubeconfig"})
+public class KubernetesConfigController {
+
+    @Autowired
+    private KubernetesClusterConfig kubeConfig;
+
+    @GetMapping(path = "/config", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Return all Connected Kubernetes Cluster")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "Kubernetes Cluster List")})
+    public ResponseEntity<Object> getAllClusters() {
+        return new ResponseEntity<>(null, HttpStatus.OK);
+    }
+
+    @GetMapping(path = "/config/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ApiOperation(value = "Return a Kubernetes Cluster")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "Kubernetes Cluster")})
+    public ResponseEntity<Object> getCluster(@PathVariable("id") String clusterId) {
+        return new ResponseEntity<>(null, HttpStatus.OK);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/exception/EntityNotFoundException.java b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..2c01b08
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/EntityNotFoundException.java
@@ -0,0 +1,32 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.exception;
+
+public class EntityNotFoundException extends ServiceException {
+
+    private static final long serialVersionUID = 1L;
+
+    public EntityNotFoundException(String message) {
+        super(message);
+    }
+
+    public EntityNotFoundException(String message, Exception originalException) {
+        super(message, originalException);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/exception/ErrorInfo.java b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/ErrorInfo.java
new file mode 100644
index 0000000..69a878a
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/ErrorInfo.java
@@ -0,0 +1,17 @@
+package org.oransc.rappmanager.exception;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Builder
+public class ErrorInfo {
+
+    private String message;
+
+    private int code;
+
+}
+
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/exception/GlobalExceptionHandler.java b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..019f6ca
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/GlobalExceptionHandler.java
@@ -0,0 +1,44 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+@ControllerAdvice(annotations = RestController.class)
+public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
+
+    @ExceptionHandler(EntityNotFoundException.class)
+    public final ResponseEntity<ErrorInfo> handleNotFoundException(EntityNotFoundException ex) {
+        return getError(ex, HttpStatus.NOT_FOUND);
+    }
+
+    @ExceptionHandler(InvalidRequestException.class)
+    public final ResponseEntity<ErrorInfo> handleInvalidRequestException(InvalidRequestException ex) {
+        return getError(ex, HttpStatus.BAD_REQUEST);
+    }
+
+    private ResponseEntity<ErrorInfo> getError(Exception ex, HttpStatus status) {
+        ErrorInfo errorInfo = ErrorInfo.builder().message(ex.getMessage()).code(status.value()).build();
+        return new ResponseEntity<ErrorInfo>(errorInfo, status);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/exception/InvalidRequestException.java b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/InvalidRequestException.java
new file mode 100644
index 0000000..b0cd5e2
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/InvalidRequestException.java
@@ -0,0 +1,32 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.exception;
+
+public class InvalidRequestException extends ServiceException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InvalidRequestException(String message) {
+        super(message);
+    }
+
+    public InvalidRequestException(String message, Exception originalException) {
+        super(message, originalException);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/exception/ServiceException.java b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/ServiceException.java
new file mode 100644
index 0000000..28ae8d5
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/exception/ServiceException.java
@@ -0,0 +1,32 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.exception;
+
+public class ServiceException extends Exception {
+
+    private static final long serialVersionUID = 6810785674716590648L;
+
+    public ServiceException(String message) {
+        super(message);
+    }
+
+    public ServiceException(String message, Exception originalException) {
+        super(message, originalException);
+    }
+}
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
new file mode 100644
index 0000000..c98b40a
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmClient.java
@@ -0,0 +1,69 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.helm;
+
+import java.io.IOException;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.oransc.rappmanager.service.App;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+// Supports only helm3 + version
+@Component
+public class HelmClient {
+
+    @Autowired
+    private HelmUtil helmUtil;
+
+
+    public void addRepo(String repoName, String url) {
+
+    }
+
+    public void searchRepo(String chartName) {
+
+    }
+
+    public void repoUpdate() {
+
+    }
+
+    public boolean installApp(App app) throws ServiceException {
+        ProcessBuilder builder = helmUtil.prepareHelmCommand(app.getName(), app.getVersion(), app.getChartName(),
+                app.getReleaseNamespace(), "install");
+        return executeCommand(builder);
+    }
+
+    public boolean uninstallApp(String name, String releaseNamespace) throws ServiceException {
+        ProcessBuilder builder = helmUtil.prepareHelmCommand(name, null, null, releaseNamespace, "uninstall");
+        return executeCommand(builder);
+    }
+
+    private boolean executeCommand(ProcessBuilder builder) throws ServiceException {
+        try {
+            Process process = builder.start();
+            process.waitFor();
+            return process.exitValue() == 0;
+            // String output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8);
+            // return output.contains("uninstalled");
+        } catch (IOException | InterruptedException e) {
+            throw new ServiceException("Failed to execute the Command", e);
+        }
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmUtil.java b/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmUtil.java
new file mode 100644
index 0000000..3005e0d
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/helm/HelmUtil.java
@@ -0,0 +1,59 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.helm;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.oransc.rappmanager.configuration.ApplicationConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class HelmUtil {
+
+    private final String KUBE_API = "--kube-apiserver";
+    private final String KUBE_TOKEN = "--kube-token";
+    private final String KUBE_CERT = "--kube-ca-file";
+
+    // Responsible for adding default chart registry to helm repo
+    // Responsible for identifying the k8's config information required for helm
+    @Autowired
+    private ApplicationConfig appConfig;
+
+    public ProcessBuilder prepareHelmCommand(String name, String version, String chartName, String releaseNamespace,
+            String operation) {
+        List<String> helmArguments = null;
+        ProcessBuilder processBuilder = new ProcessBuilder();
+        if ("install".equalsIgnoreCase(operation)) {
+            helmArguments = Arrays.asList("helm", "install", name, chartName, "--version", version, "--namespace",
+                    releaseNamespace);
+        } else if ("uninstall".equalsIgnoreCase(operation)) {
+            helmArguments = Arrays.asList("helm", "uninstall", name, "--namespace", releaseNamespace);
+        }
+        addKubeApiInfo(helmArguments);
+        return processBuilder.command(helmArguments);
+    }
+
+    private void addKubeApiInfo(List<String> helmArguments) {
+        List<String> kubeApiInfo = Arrays.asList(KUBE_API, "", KUBE_TOKEN, "", KUBE_CERT, "");
+        helmArguments.addAll(kubeApiInfo);
+    }
+}
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
new file mode 100644
index 0000000..58f5271
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/App.java
@@ -0,0 +1,46 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.service;
+
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.web.multipart.MultipartFile;
+
+@Getter
+@Setter
+@Builder
+public class App {
+
+    private String name;
+    private String chartName;
+    private String version;
+    private MultipartFile overrideFile;
+    private String releaseNamespace; // helm
+    // verify that later
+    private String namespace; // kube
+
+    /**
+     * private Status status; // how to determine the status of the app. Which kubernetes object will tell me //that the
+     * app is running? It can have pod or deployment or jobs, statefulset. //Easy way is to get meta-data of the app
+     * 
+     * public enum Status { RUNNING, ERROR, }
+     **/
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppList.java b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppList.java
new file mode 100644
index 0000000..09689b4
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppList.java
@@ -0,0 +1,32 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.service;
+
+import java.util.List;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Builder
+public class AppList {
+
+    private List<App> apps;
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppService.java b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppService.java
new file mode 100644
index 0000000..eae8a60
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppService.java
@@ -0,0 +1,65 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.service;
+
+import org.oransc.rappmanager.exception.ServiceException;
+import org.oransc.rappmanager.helm.HelmClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AppService {
+
+    @Autowired
+    private AppStore appStore;
+
+    @Autowired
+    private HelmClient helmClient;
+
+    public AppList getAllApps() throws ServiceException {
+        // Call Kubernetes api to get the apps- pod, deplyment, statefulset, job?
+        // Get the apps list this ms managing.
+        return AppList.builder().apps(appStore.getAllApp()).build();
+    }
+
+    public App getApp(String name) {
+        return appStore.getApp(name);
+    }
+
+    public App getAppStatus(String name) throws ServiceException {
+        // Check the app status in the kubernetes cluster
+        return appStore.getApp(name);
+    }
+
+    public void installApp(App app) throws ServiceException {
+        // call the kubernetes api to create objects (helm call)
+        // Call the kubernetes api to create namespace
+        // Validate the override file
+        if (helmClient.installApp(app)) {
+            appStore.addApp(app);
+        }
+    }
+
+    public void uninstallApp(String name, String releaseNamespace) throws ServiceException {
+        // call the kubernetes api to delete objects (helm call)
+        if (helmClient.uninstallApp(name, releaseNamespace)) {
+            appStore.deleteApp(name);
+        }
+    }
+}
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
new file mode 100644
index 0000000..55f3456
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/AppStore.java
@@ -0,0 +1,56 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AppStore {
+
+    /**
+     * The appStore map contains app name as key & App as value
+     */
+    private Map<String, App> appStore = new HashMap<>();
+
+    public synchronized void addApp(App app) throws ServiceException {
+
+        if (!appStore.containsKey(app.getName())) {
+            appStore.put(app.getName(), app);
+        } else {
+            throw new ServiceException("App Already Exist");
+        }
+    }
+
+    public synchronized App getApp(String name) {
+        return appStore.get(name);
+    }
+
+    public synchronized List<App> getAllApp() {
+        return new ArrayList<App>(appStore.values());
+    }
+
+    public synchronized void deleteApp(String name) {
+        appStore.remove(name);
+    }
+}
diff --git a/rapp-manager/src/main/java/org/oransc/rappmanager/service/ChartService.java b/rapp-manager/src/main/java/org/oransc/rappmanager/service/ChartService.java
new file mode 100644
index 0000000..18691af
--- /dev/null
+++ b/rapp-manager/src/main/java/org/oransc/rappmanager/service/ChartService.java
@@ -0,0 +1,105 @@
+/*-
+ * ========================LICENSE_START=================================
+ * Copyright (C) 2021 Nordix Foundation. 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.oransc.rappmanager.service;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.Map;
+import org.oransc.rappmanager.client.AsyncRestClient;
+import org.oransc.rappmanager.controller.Chart;
+import org.oransc.rappmanager.exception.ServiceException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+// Need to support multiple Chart registry. So add an interface and use it based on the registry choice.
+@Service
+public class ChartService {
+
+    private static final Logger logger = LoggerFactory.getLogger(ChartService.class);
+
+    @Autowired
+    private AsyncRestClient chartClient;
+
+    private static Gson gson = new GsonBuilder().serializeNulls().create();
+
+    private static String basePath = "/api/charts";
+
+    public Map<String, Chart[]> getCharts() throws ServiceException {
+        ResponseEntity<String> rsp = chartClient.getForEntity(basePath).block();
+        if (rsp.getStatusCodeValue() != 200) {
+            throw new ServiceException("Error Getting Charts");
+        }
+        logger.debug("Sucessfully fetched the charts");
+        return parseChart(rsp.getBody());
+    }
+
+    public Chart[] getChart(String name) throws ServiceException {
+        ResponseEntity<String> rsp = chartClient.getForEntity(basePath + "/" + name).block();
+        if (rsp.getStatusCodeValue() != 200) {
+            throw new ServiceException("Error Getting Chart " + name);
+        }
+        logger.debug("Sucessfully fetched the chart");
+        return gson.fromJson(rsp.getBody(), Chart[].class);
+    }
+
+    // Not working. Need to check
+    public void saveChart(Chart chart) throws ServiceException {
+        ResponseEntity<String> rsp;
+        try {
+            File file = multipartToFile(chart.getChart(), chart.getName());
+            rsp = chartClient.postForEntity(basePath, file).block();
+        } catch (IOException e) {
+            throw new ServiceException("Error in saving Chart", e);
+        }
+        if (rsp.getStatusCodeValue() != 201) {
+            throw new ServiceException("Error in saving Chart " + chart.getName());
+        }
+        logger.debug("Sucessfully fetched the chart");
+    }
+
+    public void deleteChart(String name, String version) throws ServiceException {
+        ResponseEntity<String> rsp = chartClient.deleteForEntity(basePath + "/" + name + "/" + version).block();
+        if (rsp.getStatusCodeValue() != 200) {
+            throw new ServiceException("Error in deleting Chart " + name);
+        }
+        logger.debug("Sucessfully deleted the chart");
+    }
+
+    private Map<String, Chart[]> parseChart(String json) {
+        Type mapType = new TypeToken<Map<String, Chart[]>>() {}.getType();
+        return gson.fromJson(json, mapType);
+    }
+
+    private static File multipartToFile(MultipartFile multipart, String fileName)
+            throws IllegalStateException, IOException {
+        File convFile = new File("/opt/app/rapp-manager" + "/" + fileName);
+        multipart.transferTo(convFile);
+        return convFile;
+    }
+
+}
+
diff --git a/rapp-manager/src/test/java/org/oransc/rappmanager/controller/AppControllerTest.java b/rapp-manager/src/test/java/org/oransc/rappmanager/controller/AppControllerTest.java
new file mode 100644
index 0000000..062804d
--- /dev/null
+++ b/rapp-manager/src/test/java/org/oransc/rappmanager/controller/AppControllerTest.java
@@ -0,0 +1,59 @@
+package org.oransc.rappmanager.controller;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.oransc.rappmanager.Application;
+import org.oransc.rappmanager.service.App;
+import org.oransc.rappmanager.service.AppList;
+import org.oransc.rappmanager.service.AppService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+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.mock.mockito.MockBean;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
+@AutoConfigureMockMvc
+@EnableAutoConfiguration
+public class AppControllerTest {
+
+    @LocalServerPort
+    private int port;
+
+    @Autowired
+    private MockMvc mvc;
+
+    @MockBean
+    private AppService appService;
+
+    private AppList apps;
+
+    @Test
+    public void testGetAllApps() throws Exception {
+        apps = getAllApps();
+        given(appService.getAllApps()).willReturn(apps);
+        mvc.perform(get("/rms/apps").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
+                .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
+                .andExpect(jsonPath("$.apps.[0].name", is("helloworldApp")));
+    }
+
+    private AppList getAllApps() {
+        return AppList.builder()
+                .apps(Arrays.asList(App.builder().name("helloworldApp").releaseNamespace("helmrelease").build()))
+                .build();
+    }
+}
+
diff --git a/rapp-manager/src/test/java/org/oransc/rappmanager/controller/ChartControllerTest.java b/rapp-manager/src/test/java/org/oransc/rappmanager/controller/ChartControllerTest.java
new file mode 100644
index 0000000..8fc9171
--- /dev/null
+++ b/rapp-manager/src/test/java/org/oransc/rappmanager/controller/ChartControllerTest.java
@@ -0,0 +1,60 @@
+package org.oransc.rappmanager.controller;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.oransc.rappmanager.Application;
+import org.oransc.rappmanager.service.ChartService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+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.mock.mockito.MockBean;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
+@AutoConfigureMockMvc
+@EnableAutoConfiguration
+public class ChartControllerTest {
+
+    @LocalServerPort
+    private int port;
+
+    @Autowired
+    private MockMvc mvc;
+
+    @MockBean
+    private ChartService chartService;
+
+    private Map<String, Chart[]> charts = new HashMap<>();
+
+    @Test
+    public void testGetCharts() throws Exception {
+        chartList();
+        given(chartService.getCharts()).willReturn(charts);
+        mvc.perform(get("/rms/charts").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
+                .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
+                .andExpect(jsonPath("$.helloworldApp.[0].name", is("helloworldApp")));
+    }
+
+    private void chartList() {
+        Chart chart = new Chart();
+        chart.setName("helloworldApp");
+        Chart[] chartArray = new Chart[1];
+        chartArray[0] = chart;
+        charts.put("helloworldApp", chartArray);
+    }
+}
+