From a98d361fe90ebac93c13a599529c4b743e11ace2 Mon Sep 17 00:00:00 2001 From: DenisGNoonan Date: Mon, 15 Jan 2024 10:22:43 +0000 Subject: [PATCH] NONRTRIC-946: Make GET for GetApfIdServiceApis stateless Change-Id: I647e6e7198456eeb8102fb9c168bd667cdd14ff1 Issue-ID: NONRTRIC-946 Change-Id: I83b8d87fce4082e5312346016aa3688fe652c885 Signed-off-by: DenisGNoonan --- .../internal/helmmanagement/mocks/HelmManager.go | 11 ++- .../invokermanagement/mocks/InvokerRegister.go | 11 ++- .../internal/keycloak/mocks/AccessManagement.go | 11 ++- .../providermanagement/mocks/ServiceRegister.go | 11 ++- .../publishservice/mocks/PublishRegister.go | 11 ++- .../internal/publishservice/publishservice.go | 23 +++--- .../internal/publishservice/publishservice_test.go | 88 +++++++++++++++++----- capifcore/internal/restclient/mocks/HTTPClient.go | 11 ++- 8 files changed, 112 insertions(+), 65 deletions(-) diff --git a/capifcore/internal/helmmanagement/mocks/HelmManager.go b/capifcore/internal/helmmanagement/mocks/HelmManager.go index 762f977..8f7339a 100644 --- a/capifcore/internal/helmmanagement/mocks/HelmManager.go +++ b/capifcore/internal/helmmanagement/mocks/HelmManager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package mocks @@ -42,13 +42,12 @@ func (_m *HelmManager) UninstallHelmChart(namespace string, chartName string) { _m.Called(namespace, chartName) } -type mockConstructorTestingTNewHelmManager interface { +// NewHelmManager creates a new instance of HelmManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHelmManager(t interface { mock.TestingT Cleanup(func()) -} - -// NewHelmManager creates a new instance of HelmManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewHelmManager(t mockConstructorTestingTNewHelmManager) *HelmManager { +}) *HelmManager { mock := &HelmManager{} mock.Mock.Test(t) diff --git a/capifcore/internal/invokermanagement/mocks/InvokerRegister.go b/capifcore/internal/invokermanagement/mocks/InvokerRegister.go index 123dd9a..d1e6c83 100644 --- a/capifcore/internal/invokermanagement/mocks/InvokerRegister.go +++ b/capifcore/internal/invokermanagement/mocks/InvokerRegister.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package mocks @@ -56,13 +56,12 @@ func (_m *InvokerRegister) VerifyInvokerSecret(invokerId string, secret string) return r0 } -type mockConstructorTestingTNewInvokerRegister interface { +// NewInvokerRegister creates a new instance of InvokerRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewInvokerRegister(t interface { mock.TestingT Cleanup(func()) -} - -// NewInvokerRegister creates a new instance of InvokerRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewInvokerRegister(t mockConstructorTestingTNewInvokerRegister) *InvokerRegister { +}) *InvokerRegister { mock := &InvokerRegister{} mock.Mock.Test(t) diff --git a/capifcore/internal/keycloak/mocks/AccessManagement.go b/capifcore/internal/keycloak/mocks/AccessManagement.go index 35086d4..dde3212 100644 --- a/capifcore/internal/keycloak/mocks/AccessManagement.go +++ b/capifcore/internal/keycloak/mocks/AccessManagement.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.20.0. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package mocks @@ -76,13 +76,12 @@ func (_m *AccessManagement) GetToken(realm string, data map[string][]string) (ke return r0, r1 } -type mockConstructorTestingTNewAccessManagement interface { +// NewAccessManagement creates a new instance of AccessManagement. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAccessManagement(t interface { mock.TestingT Cleanup(func()) -} - -// NewAccessManagement creates a new instance of AccessManagement. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAccessManagement(t mockConstructorTestingTNewAccessManagement) *AccessManagement { +}) *AccessManagement { mock := &AccessManagement{} mock.Mock.Test(t) diff --git a/capifcore/internal/providermanagement/mocks/ServiceRegister.go b/capifcore/internal/providermanagement/mocks/ServiceRegister.go index a1f9c41..a35f17d 100644 --- a/capifcore/internal/providermanagement/mocks/ServiceRegister.go +++ b/capifcore/internal/providermanagement/mocks/ServiceRegister.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.20.0. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package mocks @@ -53,13 +53,12 @@ func (_m *ServiceRegister) IsPublishingFunctionRegistered(apiProvFuncId string) return r0 } -type mockConstructorTestingTNewServiceRegister interface { +// NewServiceRegister creates a new instance of ServiceRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewServiceRegister(t interface { mock.TestingT Cleanup(func()) -} - -// NewServiceRegister creates a new instance of ServiceRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewServiceRegister(t mockConstructorTestingTNewServiceRegister) *ServiceRegister { +}) *ServiceRegister { mock := &ServiceRegister{} mock.Mock.Test(t) diff --git a/capifcore/internal/publishservice/mocks/PublishRegister.go b/capifcore/internal/publishservice/mocks/PublishRegister.go index df25620..2efd373 100644 --- a/capifcore/internal/publishservice/mocks/PublishRegister.go +++ b/capifcore/internal/publishservice/mocks/PublishRegister.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package mocks @@ -43,13 +43,12 @@ func (_m *PublishRegister) IsAPIPublished(aefId string, path string) bool { return r0 } -type mockConstructorTestingTNewPublishRegister interface { +// NewPublishRegister creates a new instance of PublishRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPublishRegister(t interface { mock.TestingT Cleanup(func()) -} - -// NewPublishRegister creates a new instance of PublishRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewPublishRegister(t mockConstructorTestingTNewPublishRegister) *PublishRegister { +}) *PublishRegister { mock := &PublishRegister{} mock.Mock.Test(t) diff --git a/capifcore/internal/publishservice/publishservice.go b/capifcore/internal/publishservice/publishservice.go index 2fe5b2e..bb065d2 100644 --- a/capifcore/internal/publishservice/publishservice.go +++ b/capifcore/internal/publishservice/publishservice.go @@ -2,7 +2,8 @@ // ========================LICENSE_START================================= // O-RAN-SC // %% -// Copyright (C) 2022: Nordix Foundation +// Copyright (C) 2022-2023: Nordix Foundation +// Copyright (C) 2024: OpenInfra Foundation Europe // %% // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -27,7 +28,7 @@ import ( "strings" "sync" - "github.com/labstack/echo/v4" + echo "github.com/labstack/echo/v4" "k8s.io/utils/strings/slices" "oransc.org/nonrtric/capifcore/internal/common29122" @@ -95,17 +96,17 @@ func (ps *PublishService) GetAllPublishedServices() []publishapi.ServiceAPIDescr // Retrieve all published APIs. func (ps *PublishService) GetApfIdServiceApis(ctx echo.Context, apfId string) error { - serviceDescriptions, ok := ps.publishedServices[apfId] - if ok { - err := ctx.JSON(http.StatusOK, serviceDescriptions) - if err != nil { - // Something really bad happened, tell Echo that our handler failed - return err - } - } else { - return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Provider %s not registered", apfId)) + if !ps.serviceRegister.IsPublishingFunctionRegistered(apfId) { + errorMsg := fmt.Sprintf("Unable to get the service due to %s api is only available for publishers", apfId) + return sendCoreError(ctx, http.StatusNotFound, errorMsg) } + serviceDescriptions := ps.publishedServices[apfId] + err := ctx.JSON(http.StatusOK, serviceDescriptions) + if err != nil { + // Something really bad happened, tell Echo that our handler failed + return err + } return nil } diff --git a/capifcore/internal/publishservice/publishservice_test.go b/capifcore/internal/publishservice/publishservice_test.go index 8de1e9f..6882bc9 100644 --- a/capifcore/internal/publishservice/publishservice_test.go +++ b/capifcore/internal/publishservice/publishservice_test.go @@ -2,7 +2,8 @@ // ========================LICENSE_START================================= // O-RAN-SC // %% -// Copyright (C) 2022: Nordix Foundation +// Copyright (C) 2022-2023: Nordix Foundation +// Copyright (C) 2024: OpenInfra Foundation Europe // %% // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -46,6 +47,28 @@ import ( "github.com/stretchr/testify/mock" ) +func TestUnregisteredService(t *testing.T) { + apfId := "apfId" + serviceRegisterMock := serviceMocks.ServiceRegister{} + serviceRegisterMock.On("IsPublishingFunctionRegistered", apfId).Return(false) + + helmManagerMock := helmMocks.HelmManager{} + helmManagerMock.On("InstallHelmChart", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + _, _, requestHandler := getEcho(&serviceRegisterMock, &helmManagerMock) + + // Check no services published + result := testutil.NewRequest().Get("/"+apfId+"/service-apis").Go(t, requestHandler) + assert.Equal(t, http.StatusNotFound, result.Code()) + + var resultError common29122.ProblemDetails + err := result.UnmarshalJsonToObject(&resultError) + assert.NoError(t, err, "error unmarshaling response") + + assert.Contains(t, *resultError.Cause, "api is only available for publishers") + assert.Equal(t, http.StatusNotFound, *resultError.Status) +} + + func TestPublishUnpublishService(t *testing.T) { apfId := "apfId" @@ -57,10 +80,17 @@ func TestPublishUnpublishService(t *testing.T) { helmManagerMock.On("InstallHelmChart", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) serviceUnderTest, eventChannel, requestHandler := getEcho(&serviceRegisterMock, &helmManagerMock) - // Check no services published for provider + // Check no services published + var resultServices []publishapi.ServiceAPIDescription result := testutil.NewRequest().Get("/"+apfId+"/service-apis").Go(t, requestHandler) + assert.Equal(t, http.StatusOK, result.Code()) - assert.Equal(t, http.StatusNotFound, result.Code()) + // Parse JSON from the response body + err := result.UnmarshalJsonToObject(&resultServices) + assert.NoError(t, err, "error unmarshaling response") + + // Check if the parsed array is empty + assert.Zero(t, len(resultServices)) apiName := "app-management" namespace := "namespace" @@ -73,8 +103,10 @@ func TestPublishUnpublishService(t *testing.T) { // Publish a service for provider result = testutil.NewRequest().Post("/"+apfId+"/service-apis").WithJsonBody(newServiceDescription).Go(t, requestHandler) assert.Equal(t, http.StatusCreated, result.Code()) + var resultService publishapi.ServiceAPIDescription - err := result.UnmarshalBodyToObject(&resultService) + + err = result.UnmarshalJsonToObject(&resultService) assert.NoError(t, err, "error unmarshaling response") newApiId := "api_id_" + apiName assert.Equal(t, newApiId, *resultService.ApiId) @@ -95,7 +127,7 @@ func TestPublishUnpublishService(t *testing.T) { result = testutil.NewRequest().Get("/"+apfId+"/service-apis/"+newApiId).Go(t, requestHandler) assert.Equal(t, http.StatusOK, result.Code()) - err = result.UnmarshalBodyToObject(&resultService) + err = result.UnmarshalJsonToObject(&resultService) assert.NoError(t, err, "error unmarshaling response") assert.Equal(t, *resultService.ApiId, newApiId) @@ -104,7 +136,7 @@ func TestPublishUnpublishService(t *testing.T) { assert.Equal(t, http.StatusForbidden, result.Code()) var resultError common29122.ProblemDetails - err = result.UnmarshalBodyToObject(&resultError) + err = result.UnmarshalJsonToObject(&resultError) assert.NoError(t, err, "error unmarshaling response") assert.Contains(t, *resultError.Cause, "already published") assert.Equal(t, http.StatusForbidden, *resultError.Status) @@ -118,7 +150,7 @@ func TestPublishUnpublishService(t *testing.T) { helmManagerMock.AssertCalled(t, "UninstallHelmChart", namespace, chartName) assert.Empty(t, serviceUnderTest.getAllAefIds()) - // Check no services published + // Check no services published for a provider result = testutil.NewRequest().Get("/"+apfId+"/service-apis/"+newApiId).Go(t, requestHandler) if publishEvent, ok := waitForEvent(eventChannel, 1*time.Second); ok { @@ -129,6 +161,18 @@ func TestPublishUnpublishService(t *testing.T) { } assert.Equal(t, http.StatusNotFound, result.Code()) + + // Check no services published + result = testutil.NewRequest().Get("/"+apfId+"/service-apis").Go(t, requestHandler) + assert.Equal(t, http.StatusOK, result.Code()) + + // Parse JSON from the response body + var responseArray []publishapi.ServiceAPIDescription + err = result.UnmarshalJsonToObject(&responseArray) + assert.NoError(t, err, "error unmarshaling response") + + // Check if the parsed array is empty + assert.Zero(t, len(responseArray)) } func TestPostUnpublishedServiceWithUnregisteredFunction(t *testing.T) { @@ -146,7 +190,7 @@ func TestPostUnpublishedServiceWithUnregisteredFunction(t *testing.T) { assert.Equal(t, http.StatusNotFound, result.Code()) var resultError common29122.ProblemDetails - err := result.UnmarshalBodyToObject(&resultError) + err := result.UnmarshalJsonToObject(&resultError) assert.NoError(t, err, "error unmarshaling response") assert.Contains(t, *resultError.Cause, aefId) assert.Contains(t, *resultError.Cause, "not registered") @@ -161,10 +205,18 @@ func TestGetServices(t *testing.T) { serviceRegisterMock.On("IsPublishingFunctionRegistered", apfId).Return(true) _, _, requestHandler := getEcho(&serviceRegisterMock, nil) - // Check no services published for provider + // Check no services published + var resultServices []publishapi.ServiceAPIDescription + result := testutil.NewRequest().Get("/"+apfId+"/service-apis").Go(t, requestHandler) + assert.Equal(t, http.StatusOK, result.Code()) - assert.Equal(t, http.StatusNotFound, result.Code()) + // Parse JSON from the response body + err := result.UnmarshalJsonToObject(&resultServices) + assert.NoError(t, err, "error unmarshaling response") + + // Check if the parsed array is empty + assert.Zero(t, len(resultServices)) serviceDescription1 := getServiceAPIDescription(aefId, "api1", "Description") serviceDescription2 := getServiceAPIDescription(aefId, "api2", "Description") @@ -176,14 +228,16 @@ func TestGetServices(t *testing.T) { // Get all services for provider result = testutil.NewRequest().Get("/"+apfId+"/service-apis").Go(t, requestHandler) assert.Equal(t, http.StatusOK, result.Code()) - var resultServices []publishapi.ServiceAPIDescription - err := result.UnmarshalBodyToObject(&resultServices) + + err = result.UnmarshalJsonToObject(&resultServices) assert.NoError(t, err, "error unmarshaling response") + assert.Len(t, resultServices, 2) apiId1 := "api_id_api1" serviceDescription1.ApiId = &apiId1 apiId2 := "api_id_api2" serviceDescription2.ApiId = &apiId2 + assert.Contains(t, resultServices, serviceDescription1) assert.Contains(t, resultServices, serviceDescription2) } @@ -234,10 +288,8 @@ func TestUpdateDescription(t *testing.T) { newProfileDomain := "new profile Domain name" var protocol publishapi.Protocol = "HTTP_1_1" - test := make([]publishapi.AefProfile, 1) - test = *updatedServiceDescription.AefProfiles - test = append(test, publishapi.AefProfile{ + test := append(*updatedServiceDescription.AefProfiles, publishapi.AefProfile{ AefId: "aefIdNew", DomainName: &newProfileDomain, Protocol: &protocol, @@ -265,7 +317,7 @@ func TestUpdateDescription(t *testing.T) { var resultService publishapi.ServiceAPIDescription assert.Equal(t, http.StatusOK, result.Code()) - err := result.UnmarshalBodyToObject(&resultService) + err := result.UnmarshalJsonToObject(&resultService) assert.NoError(t, err, "error unmarshaling response") assert.Equal(t, newDescription, *resultService.Description) assert.Equal(t, newDomainName, *(*resultService.AefProfiles)[0].DomainName) @@ -363,7 +415,7 @@ func TestUpdateValidServiceWithDeletedFunction(t *testing.T) { result := testutil.NewRequest().Put("/"+apfId+"/service-apis/"+serviceApiId).WithJsonBody(updatedServiceDescription).Go(t, requestHandler) var resultService publishapi.ServiceAPIDescription assert.Equal(t, http.StatusOK, result.Code()) - err := result.UnmarshalBodyToObject(&resultService) + err := result.UnmarshalJsonToObject(&resultService) assert.NoError(t, err, "error unmarshaling response") assert.Len(t, (*resultService.AefProfiles), 1) assert.False(t, serviceUnderTest.IsAPIPublished("aefId", "path")) @@ -383,7 +435,7 @@ func TestPublishInvalidService(t *testing.T) { assert.Equal(t, http.StatusBadRequest, result.Code()) var resultError common29122.ProblemDetails - err := result.UnmarshalBodyToObject(&resultError) + err := result.UnmarshalJsonToObject(&resultError) assert.NoError(t, err, "error unmarshaling response") assert.Contains(t, *resultError.Cause, "missing") assert.Contains(t, *resultError.Cause, "apiName") diff --git a/capifcore/internal/restclient/mocks/HTTPClient.go b/capifcore/internal/restclient/mocks/HTTPClient.go index 7d0064a..6d65026 100644 --- a/capifcore/internal/restclient/mocks/HTTPClient.go +++ b/capifcore/internal/restclient/mocks/HTTPClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.20.0. DO NOT EDIT. +// Code generated by mockery v2.35.4. DO NOT EDIT. package mocks @@ -65,13 +65,12 @@ func (_m *HTTPClient) Get(url string) (*http.Response, error) { return r0, r1 } -type mockConstructorTestingTNewHTTPClient interface { +// NewHTTPClient creates a new instance of HTTPClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewHTTPClient(t interface { mock.TestingT Cleanup(func()) -} - -// NewHTTPClient creates a new instance of HTTPClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewHTTPClient(t mockConstructorTestingTNewHTTPClient) *HTTPClient { +}) *HTTPClient { mock := &HTTPClient{} mock.Mock.Test(t) -- 2.16.6