Merge "Demo of pm data/events to rapps"
diff --git a/capif/internal/publishservice/publishservice.go b/capif/internal/publishservice/publishservice.go
index ca2fb09..63a27db 100644
--- a/capif/internal/publishservice/publishservice.go
+++ b/capif/internal/publishservice/publishservice.go
@@ -23,9 +23,12 @@
 import (
 	"net/http"
 	"path"
+	"strings"
 	"sync"
 
 	"github.com/labstack/echo/v4"
+	log "github.com/sirupsen/logrus"
+	"oransc.org/nonrtric/plt/capif/internal/helmmanagement"
 	"oransc.org/nonrtric/plt/capif/internal/providermanagement"
 	"oransc.org/nonrtric/plt/capif/internal/readonly/common"
 	"oransc.org/nonrtric/plt/capif/internal/readonly/publishserviceapi"
@@ -41,11 +44,13 @@
 type PublishService struct {
 	publishedServices map[string]publishserviceapi.ServiceAPIDescription
 	serviceRegister   providermanagement.ServiceRegister
+	helmManager       helmmanagement.HelmManager
 	lock              sync.Mutex
 }
 
-func NewPublishService(serviceRegister providermanagement.ServiceRegister) *PublishService {
+func NewPublishService(serviceRegister providermanagement.ServiceRegister, hm helmmanagement.HelmManager) *PublishService {
 	return &PublishService{
+		helmManager:       hm,
 		publishedServices: make(map[string]publishserviceapi.ServiceAPIDescription),
 		serviceRegister:   serviceRegister,
 	}
@@ -145,6 +150,14 @@
 
 	newId := "api_id_" + newServiceAPIDescription.ApiName
 	newServiceAPIDescription.ApiId = &newId
+	info := strings.Split(*newServiceAPIDescription.Description, ",")
+	if len(info) == 5 {
+		err = ps.helmManager.InstallHelmChart(info[1], info[2], info[3], info[4])
+		if err != nil {
+			return sendCoreError(ctx, http.StatusBadRequest, "Unable to install Helm chart due to: "+err.Error())
+		}
+		log.Info("Installed service: ", newId)
+	}
 	ps.publishedServices[*newServiceAPIDescription.ApiId] = newServiceAPIDescription
 
 	uri := ctx.Request().Host + ctx.Request().URL.String()
@@ -159,11 +172,30 @@
 }
 
 func (ps *PublishService) DeleteApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
-	return ctx.NoContent(http.StatusNotImplemented)
+	serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
+	if ok {
+		info := strings.Split(*serviceDescription.Description, ",")
+		if len(info) == 5 {
+			ps.helmManager.UninstallHelmChart(info[1], info[3])
+			log.Info("Deleted service: ", serviceApiId)
+		}
+		delete(ps.publishedServices, string(serviceApiId))
+	}
+	return ctx.NoContent(http.StatusNoContent)
 }
 
 func (ps *PublishService) GetApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
-	return ctx.NoContent(http.StatusNotImplemented)
+	serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
+	if ok {
+		err := ctx.JSON(http.StatusOK, serviceDescription)
+		if err != nil {
+			// Something really bad happened, tell Echo that our handler failed
+			return err
+		}
+
+		return nil
+	}
+	return ctx.NoContent(http.StatusNotFound)
 }
 
 func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
diff --git a/capif/internal/publishservice/publishservice_test.go b/capif/internal/publishservice/publishservice_test.go
index d8e0813..364362c 100644
--- a/capif/internal/publishservice/publishservice_test.go
+++ b/capif/internal/publishservice/publishservice_test.go
@@ -31,19 +31,31 @@
 	"github.com/labstack/echo/v4"
 	echomiddleware "github.com/labstack/echo/v4/middleware"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+	"oransc.org/nonrtric/plt/capif/internal/helmmanagement"
+	helmMocks "oransc.org/nonrtric/plt/capif/internal/helmmanagement/mocks"
 	"oransc.org/nonrtric/plt/capif/internal/providermanagement"
-	"oransc.org/nonrtric/plt/capif/internal/providermanagement/mocks"
+	serviceMocks "oransc.org/nonrtric/plt/capif/internal/providermanagement/mocks"
 	"oransc.org/nonrtric/plt/capif/internal/readonly/publishserviceapi"
 )
 
-func TestPublishService(t *testing.T) {
+func TestPublishUnpublishService(t *testing.T) {
 	aefId := "aefId"
-	serviceRegisterMock := mocks.ServiceRegister{}
+	newApiId := "api_id_app-management"
+	serviceRegisterMock := serviceMocks.ServiceRegister{}
 	serviceRegisterMock.On("IsFunctionRegistered", aefId).Return(true)
-	serviceUnderTest, requestHandler := getEcho(&serviceRegisterMock)
+	helmManagerMock := helmMocks.HelmManager{}
+	helmManagerMock.On("InstallHelmChart", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
+	serviceUnderTest, requestHandler := getEcho(&serviceRegisterMock, &helmManagerMock)
+
+	// Check no services published
+	result := testutil.NewRequest().Get("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+	assert.Equal(t, http.StatusNotFound, result.Code())
 
 	domainName := "domain"
 	var protocol publishserviceapi.Protocol = "HTTP_1_1"
+	description := "Description,namespace,repoName,chartName,releaseName"
 	newServiceDescription := publishserviceapi.ServiceAPIDescription{
 		AefProfiles: &[]publishserviceapi.AefProfile{
 			{
@@ -68,17 +80,16 @@
 			},
 		},
 		ApiName:     "app-management",
-		Description: new(string),
+		Description: &description,
 	}
 
 	// Publish a service
-	result := testutil.NewRequest().Post("/aefId/service-apis").WithJsonBody(newServiceDescription).Go(t, requestHandler)
+	result = testutil.NewRequest().Post("/aefId/service-apis").WithJsonBody(newServiceDescription).Go(t, requestHandler)
 
 	assert.Equal(t, http.StatusCreated, result.Code())
 	var resultService publishserviceapi.ServiceAPIDescription
 	err := result.UnmarshalBodyToObject(&resultService)
 	assert.NoError(t, err, "error unmarshaling response")
-	newApiId := "api_id_app-management"
 	assert.Equal(t, *resultService.ApiId, newApiId)
 	assert.Equal(t, "http://example.com/"+aefId+"/service-apis/"+*resultService.ApiId, result.Recorder.Header().Get(echo.HeaderLocation))
 	newServiceDescription.ApiId = &newApiId
@@ -86,10 +97,32 @@
 	assert.True(t, serviceUnderTest.AreAPIsRegistered(&wantedAPILIst))
 	assert.True(t, serviceUnderTest.IsAPIRegistered("aefId", "app-management"))
 	serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", aefId)
+	helmManagerMock.AssertCalled(t, "InstallHelmChart", "namespace", "repoName", "chartName", "releaseName")
 	assert.ElementsMatch(t, wantedAPILIst, *serviceUnderTest.GetAPIs())
+
+	// Check that service is published
+	result = testutil.NewRequest().Get("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+	assert.Equal(t, http.StatusOK, result.Code())
+	err = result.UnmarshalBodyToObject(&resultService)
+	assert.NoError(t, err, "error unmarshaling response")
+	assert.Equal(t, *resultService.ApiId, newApiId)
+
+	// Delete a service
+	helmManagerMock.On("UninstallHelmChart", mock.Anything, mock.Anything).Return(nil)
+	result = testutil.NewRequest().Delete("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+	assert.Equal(t, http.StatusNoContent, result.Code())
+	helmManagerMock.AssertCalled(t, "UninstallHelmChart", "namespace", "chartName")
+	assert.Empty(t, *serviceUnderTest.GetAPIs())
+
+	// Check no services published
+	result = testutil.NewRequest().Get("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+	assert.Equal(t, http.StatusNotFound, result.Code())
 }
 
-func getEcho(serviceRegister providermanagement.ServiceRegister) (*PublishService, *echo.Echo) {
+func getEcho(serviceRegister providermanagement.ServiceRegister, helmManager helmmanagement.HelmManager) (*PublishService, *echo.Echo) {
 	swagger, err := publishserviceapi.GetSwagger()
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
@@ -98,7 +131,7 @@
 
 	swagger.Servers = nil
 
-	ps := NewPublishService(serviceRegister)
+	ps := NewPublishService(serviceRegister, helmManager)
 
 	e := echo.New()
 	e.Use(echomiddleware.Logger())
diff --git a/capif/main.go b/capif/main.go
index f50f539..0e481ba 100644
--- a/capif/main.go
+++ b/capif/main.go
@@ -38,6 +38,7 @@
 	"helm.sh/helm/v3/pkg/getter"
 	"helm.sh/helm/v3/pkg/repo"
 	"oransc.org/nonrtric/plt/capif/internal/discoverservice"
+	"oransc.org/nonrtric/plt/capif/internal/helmmanagement"
 	"oransc.org/nonrtric/plt/capif/internal/invokermanagement"
 	"oransc.org/nonrtric/plt/capif/internal/providermanagement"
 	"oransc.org/nonrtric/plt/capif/internal/publishservice"
@@ -96,7 +97,7 @@
 		log.Fatalf("Error loading PublishService swagger spec\n: %s", err)
 	}
 	publishServiceSwagger.Servers = nil
-	publishService := publishservice.NewPublishService(providerManager)
+	publishService := publishservice.NewPublishService(providerManager, helmmanagement.NewHelmManager(settings))
 	group = e.Group("/published-apis/v1")
 	group.Use(middleware.OapiRequestValidator(publishServiceSwagger))
 	publishserviceapi.RegisterHandlersWithBaseURL(e, publishService, "/published-apis/v1")