package discoverservice
import (
+ "fmt"
"net/http"
"oransc.org/nonrtric/capifcore/internal/common29122"
func (ds *DiscoverService) GetAllServiceAPIs(ctx echo.Context, params discoverapi.GetAllServiceAPIsParams) error {
allApis := ds.invokerRegister.GetInvokerApiList(params.ApiInvokerId)
if allApis == nil {
- return sendCoreError(ctx, http.StatusNotFound, "Invoker not registered")
+ return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Invoker %s not registered", params.ApiInvokerId))
}
filteredApis := []publishapi.ServiceAPIDescription{}
gatewayDomain := "r1-expo-func-aef"
func TestGetAllServiceAPIs(t *testing.T) {
var err error
+ apiName1 := "apiName1"
+ apiName2 := "apiName2"
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", "aefId", "apiCategory", "v1", nil, nil, ""),
- getAPI("apiName2", "aefId", "apiCategory", "v1", nil, nil, ""),
+ getAPI(apiName1, "aefId", "apiCategory", "v1", nil, nil, ""),
+ getAPI(apiName2, "aefId", "apiCategory", "v1", nil, nil, ""),
}
invokerId := "api_invoker_id"
invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
- assert.Equal(t, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[1].ApiName)
+ assert.Equal(t, apiName1, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName2, (*resultInvoker.ServiceAPIDescriptions)[1].ApiName)
assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
}
assert.NoError(t, err, "error unmarshaling response")
notFound := http.StatusNotFound
assert.Equal(t, ¬Found, problemDetails.Status)
- errMsg := "Invoker not registered"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, invokerId)
+ assert.Contains(t, *problemDetails.Cause, "not registered")
}
func TestFilterApiName(t *testing.T) {
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func TestFilterAefId(t *testing.T) {
var err error
+ apiName := "apiName1"
aefId := "aefId"
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", aefId, "", "", nil, nil, ""),
+ getAPI(apiName, aefId, "", "", nil, nil, ""),
getAPI("apiName2", "otherAefId", "", "", nil, nil, ""),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func TestFilterVersion(t *testing.T) {
var err error
+ apiName := "apiName1"
version := "v1"
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", "", "", version, nil, nil, ""),
+ getAPI(apiName, "", "", version, nil, nil, ""),
getAPI("apiName2", "", "", "v2", nil, nil, ""),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func TestFilterCommType(t *testing.T) {
var err error
+ apiName := "apiName1"
commType := publishapi.CommunicationTypeREQUESTRESPONSE
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", "", "", "", nil, nil, commType),
+ getAPI(apiName, "", "", "", nil, nil, commType),
getAPI("apiName2", "", "", "", nil, nil, publishapi.CommunicationTypeSUBSCRIBENOTIFY),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func TestFilterVersionAndCommType(t *testing.T) {
var err error
+ apiName := "apiName2"
version := "v1"
commType := publishapi.CommunicationTypeSUBSCRIBENOTIFY
apiList := []publishapi.ServiceAPIDescription{
getAPI("apiName1", "", "", version, nil, nil, publishapi.CommunicationTypeREQUESTRESPONSE),
- getAPI("apiName2", "", "", version, nil, nil, commType),
+ getAPI(apiName, "", "", version, nil, nil, commType),
getAPI("apiName3", "", "", "v2", nil, nil, commType),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func TestFilterAPICategory(t *testing.T) {
var err error
+ apiName := "apiName1"
apiCategory := "apiCategory"
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", "", apiCategory, "", nil, nil, ""),
+ getAPI(apiName, "", apiCategory, "", nil, nil, ""),
getAPI("apiName2", "", "", "", nil, nil, ""),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func TestFilterProtocol(t *testing.T) {
var err error
+ apiName := "apiName1"
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", "", "", "", &protocolHTTP11, nil, ""),
+ getAPI(apiName, "", "", "", &protocolHTTP11, nil, ""),
getAPI("apiName2", "", "", "", nil, nil, ""),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
var DataFormatOther publishapi.DataFormat = "OTHER"
func TestFilterDataFormat(t *testing.T) {
var err error
+ apiName := "apiName1"
apiList := []publishapi.ServiceAPIDescription{
- getAPI("apiName1", "", "", "", nil, &dataFormatJSON, ""),
+ getAPI(apiName, "", "", "", nil, &dataFormatJSON, ""),
getAPI("apiName2", "", "", "", nil, nil, ""),
}
invokerId := "api_invoker_id"
err = result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
- assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+ assert.Equal(t, apiName, (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
}
func getEcho(invokerManager invokermanagement.InvokerRegister) *echo.Echo {
"net/http"
"os"
"path"
+ "strings"
"testing"
"oransc.org/nonrtric/capifcore/internal/invokermanagementapi"
AefProfiles: &aefProfiles,
},
}
- newInvoker := getInvoker("invoker a", apiList)
+ invokerInfo := "invoker a"
+ newInvoker := getInvoker(invokerInfo, apiList)
// Onboard a valid invoker
result := testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(newInvoker).Go(t, requestHandler)
var resultInvoker invokermanagementapi.APIInvokerEnrolmentDetails
err := result.UnmarshalBodyToObject(&resultInvoker)
assert.NoError(t, err, "error unmarshaling response")
- assert.Equal(t, "api_invoker_id_invoker_a", *resultInvoker.ApiInvokerId)
+ wantedInvokerId := "api_invoker_id_" + strings.Replace(invokerInfo, " ", "_", 1)
+ assert.Equal(t, wantedInvokerId, *resultInvoker.ApiInvokerId)
assert.Equal(t, newInvoker.NotificationDestination, resultInvoker.NotificationDestination)
assert.Equal(t, newInvoker.OnboardingInformation.ApiInvokerPublicKey, resultInvoker.OnboardingInformation.ApiInvokerPublicKey)
- assert.Equal(t, "onboarding_secret_invoker_a", *resultInvoker.OnboardingInformation.OnboardingSecret)
+ wantedInvokerSecret := "onboarding_secret_" + strings.Replace(invokerInfo, " ", "_", 1)
+ assert.Equal(t, wantedInvokerSecret, *resultInvoker.OnboardingInformation.OnboardingSecret)
assert.Equal(t, "http://example.com/onboardedInvokers/"+*resultInvoker.ApiInvokerId, result.Recorder.Header().Get(echo.HeaderLocation))
- assert.True(t, invokerUnderTest.IsInvokerRegistered("api_invoker_id_invoker_a"))
- assert.True(t, invokerUnderTest.VerifyInvokerSecret("api_invoker_id_invoker_a", "onboarding_secret_invoker_a"))
+ assert.True(t, invokerUnderTest.IsInvokerRegistered(wantedInvokerId))
+ assert.True(t, invokerUnderTest.VerifyInvokerSecret(wantedInvokerId, wantedInvokerSecret))
publishRegisterMock.AssertCalled(t, "AreAPIsPublished", mock.Anything)
// Onboard an invoker missing required NotificationDestination, should get 400 with problem details
assert.NoError(t, err, "error unmarshaling response")
badRequest := http.StatusBadRequest
assert.Equal(t, &badRequest, problemDetails.Status)
- errMsg := "Invoker missing required NotificationDestination"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "missing")
+ assert.Contains(t, *problemDetails.Cause, "NotificationDestination")
// Onboard an invoker missing required OnboardingInformation.ApiInvokerPublicKey, should get 400 with problem details
invalidInvoker = invokermanagementapi.APIInvokerEnrolmentDetails{
err = result.UnmarshalBodyToObject(&problemDetails)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, &badRequest, problemDetails.Status)
- errMsg = "Invoker missing required OnboardingInformation.ApiInvokerPublicKey"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "missing")
+ assert.Contains(t, *problemDetails.Cause, "OnboardingInformation.ApiInvokerPublicKey")
}
func TestDeleteInvoker(t *testing.T) {
assert.NoError(t, err, "error unmarshaling response")
badRequest := http.StatusBadRequest
assert.Equal(t, &badRequest, problemDetails.Status)
- errMsg := "Invoker missing required NotificationDestination"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "missing")
+ assert.Contains(t, *problemDetails.Cause, "NotificationDestination")
// Update with an invoker missing required OnboardingInformation.ApiInvokerPublicKey, should get 400 with problem details
invalidInvoker.NotificationDestination = "url"
err = result.UnmarshalBodyToObject(&problemDetails)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, &badRequest, problemDetails.Status)
- errMsg = "Invoker missing required OnboardingInformation.ApiInvokerPublicKey"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "missing")
+ assert.Contains(t, *problemDetails.Cause, "OnboardingInformation.ApiInvokerPublicKey")
// Update with an invoker with other ApiInvokerId than the one provided in the URL, should get 400 with problem details
invalidId := "1"
err = result.UnmarshalBodyToObject(&problemDetails)
assert.NoError(t, err, "error unmarshaling response")
assert.Equal(t, &badRequest, problemDetails.Status)
- errMsg = "Invoker ApiInvokerId not matching"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "not matching")
+ assert.Contains(t, *problemDetails.Cause, "ApiInvokerId")
// Update an invoker that has not been onboarded, shold get 404 with problem details
missingId := "1"
assert.NoError(t, err, "error unmarshaling response")
notFound := http.StatusNotFound
assert.Equal(t, ¬Found, problemDetails.Status)
- errMsg = "The invoker to update has not been onboarded"
- assert.Equal(t, &errMsg, problemDetails.Cause)
+ assert.Contains(t, *problemDetails.Cause, "not been onboarded")
+ assert.Contains(t, *problemDetails.Cause, "invoker")
}
func TestGetInvokerApiList(t *testing.T) {
AefProfiles: &aefProfiles,
},
}
- newInvoker := getInvoker("invoker a", apiList)
+ invokerInfo := "invoker a"
+ newInvoker := getInvoker(invokerInfo, apiList)
testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(newInvoker).Go(t, requestHandler)
aefProfiles = []publishserviceapi.AefProfile{
getAefProfile("aefId2"),
newInvoker = getInvoker("invoker b", apiList)
testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(newInvoker).Go(t, requestHandler)
- wantedApiList := invokerUnderTest.GetInvokerApiList("api_invoker_id_invoker_a")
+ wantedApiList := invokerUnderTest.GetInvokerApiList("api_invoker_id_" + strings.Replace(invokerInfo, " ", "_", 1))
assert.NotNil(t, wantedApiList)
assert.Equal(t, apiId, *(*wantedApiList)[0].ApiId)
}
package publishservice
import (
+ "fmt"
"net/http"
"path"
"strings"
return err
}
} else {
- return sendCoreError(ctx, http.StatusNotFound, "Provider not registered")
+ return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Provider %s not registered", apfId))
}
return nil
var newServiceAPIDescription publishserviceapi.ServiceAPIDescription
err := ctx.Bind(&newServiceAPIDescription)
if err != nil {
- return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service")
+ return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service "+apfId)
}
ps.lock.Lock()
registeredFuncs := ps.serviceRegister.GetAefsForPublisher(apfId)
for _, profile := range *newServiceAPIDescription.AefProfiles {
if !slices.Contains(registeredFuncs, profile.AefId) {
- return sendCoreError(ctx, http.StatusNotFound, "Function not registered, "+profile.AefId)
+ return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Function %s not registered", profile.AefId))
}
}
newId := "api_id_" + newServiceAPIDescription.ApiName
newServiceAPIDescription.ApiId = &newId
- shouldReturn, returnValue := ps.installHelmChart(newServiceAPIDescription, err, ctx, newId)
+ shouldReturn, returnValue := ps.installHelmChart(newServiceAPIDescription, ctx)
if shouldReturn {
return returnValue
}
return nil
}
-func (ps *PublishService) installHelmChart(newServiceAPIDescription publishserviceapi.ServiceAPIDescription, err error, ctx echo.Context, newId string) (bool, error) {
+func (ps *PublishService) installHelmChart(newServiceAPIDescription publishserviceapi.ServiceAPIDescription, ctx echo.Context) (bool, error) {
info := strings.Split(*newServiceAPIDescription.Description, ",")
if len(info) == 5 {
- err = ps.helmManager.InstallHelmChart(info[1], info[2], info[3], info[4])
+ err := ps.helmManager.InstallHelmChart(info[1], info[2], info[3], info[4])
if err != nil {
- return true, sendCoreError(ctx, http.StatusBadRequest, "Unable to install Helm chart due to: "+err.Error())
+ return true, sendCoreError(ctx, http.StatusBadRequest, fmt.Sprintf("Unable to install Helm chart %s due to: %s", info[3], err.Error()))
}
- log.Info("Installed service: ", newId)
+ log.Debug("Installed service: ", newServiceAPIDescription.ApiId)
}
return false, nil
}
info := strings.Split(*description.Description, ",")
if len(info) == 5 {
ps.helmManager.UninstallHelmChart(info[1], info[3])
- log.Info("Deleted service: ", serviceApiId)
+ log.Debug("Deleted service: ", serviceApiId)
}
ps.lock.Lock()
defer ps.lock.Unlock()
assert.Equal(t, http.StatusNotFound, result.Code())
apiName := "app-management"
- description := "Description,namespace,repoName,chartName,releaseName"
+ namespace := "namespace"
+ repoName := "repoName"
+ chartName := "chartName"
+ releaseName := "releaseName"
+ description := fmt.Sprintf("Description,%s,%s,%s,%s", namespace, repoName, chartName, releaseName)
newServiceDescription := getServiceAPIDescription(aefId, apiName, description)
// Publish a service for provider
var resultService publishapi.ServiceAPIDescription
err := result.UnmarshalBodyToObject(&resultService)
assert.NoError(t, err, "error unmarshaling response")
- newApiId := "api_id_app-management"
+ newApiId := "api_id_" + apiName
assert.Equal(t, *resultService.ApiId, newApiId)
assert.Equal(t, "http://example.com/"+apfId+"/service-apis/"+*resultService.ApiId, result.Recorder.Header().Get(echo.HeaderLocation))
newServiceDescription.ApiId = &newApiId
wantedAPILIst := []publishapi.ServiceAPIDescription{newServiceDescription}
assert.True(t, serviceUnderTest.AreAPIsPublished(&wantedAPILIst))
- assert.True(t, serviceUnderTest.IsAPIPublished("aefId", "app-management"))
+ assert.True(t, serviceUnderTest.IsAPIPublished(aefId, apiName))
serviceRegisterMock.AssertCalled(t, "GetAefsForPublisher", apfId)
- helmManagerMock.AssertCalled(t, "InstallHelmChart", "namespace", "repoName", "chartName", "releaseName")
+ helmManagerMock.AssertCalled(t, "InstallHelmChart", namespace, repoName, chartName, releaseName)
assert.ElementsMatch(t, []string{aefId}, serviceUnderTest.getAllAefIds())
// Check that the service is published for the provider
result = testutil.NewRequest().Delete("/"+apfId+"/service-apis/"+newApiId).Go(t, requestHandler)
assert.Equal(t, http.StatusNoContent, result.Code())
- helmManagerMock.AssertCalled(t, "UninstallHelmChart", "namespace", "chartName")
+ helmManagerMock.AssertCalled(t, "UninstallHelmChart", namespace, chartName)
assert.Empty(t, serviceUnderTest.getAllAefIds())
// Check no services published
var resultError common29122.ProblemDetails
err := result.UnmarshalBodyToObject(&resultError)
assert.NoError(t, err, "error unmarshaling response")
- errMsg := "Function not registered, aefId"
- assert.Equal(t, &errMsg, resultError.Cause)
+ assert.Contains(t, *resultError.Cause, aefId)
+ assert.Contains(t, *resultError.Cause, "not registered")
notFound := http.StatusNotFound
assert.Equal(t, ¬Found, resultError.Status)
}
requestHandler := getEcho(&serviceRegisterMock, &publishRegisterMock, &invokerRegisterMock)
data := url.Values{}
- data.Set("client_id", "id")
- data.Add("client_secret", "secret")
+ clientId := "id"
+ clientSecret := "secret"
+ aefId := "aefId"
+ path := "path"
+ data.Set("client_id", clientId)
+ data.Add("client_secret", clientSecret)
data.Add("grant_type", "client_credentials")
- data.Add("scope", "scope#aefId:path")
+ data.Add("scope", "scope#"+aefId+":"+path)
encodedData := data.Encode()
result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
err := result.UnmarshalBodyToObject(&resultResponse)
assert.NoError(t, err, "error unmarshaling response")
assert.NotEmpty(t, resultResponse.AccessToken)
- assert.Equal(t, "scope#aefId:path", *resultResponse.Scope)
+ assert.Equal(t, "scope#"+aefId+":"+path, *resultResponse.Scope)
assert.Equal(t, securityapi.AccessTokenRspTokenTypeBearer, resultResponse.TokenType)
assert.Equal(t, common29122.DurationSec(0), resultResponse.ExpiresIn)
- invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", "id")
- invokerRegisterMock.AssertCalled(t, "VerifyInvokerSecret", "id", "secret")
- serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", "aefId")
- publishRegisterMock.AssertCalled(t, "IsAPIPublished", "aefId", "path")
+ invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", clientId)
+ invokerRegisterMock.AssertCalled(t, "VerifyInvokerSecret", clientId, clientSecret)
+ serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", aefId)
+ publishRegisterMock.AssertCalled(t, "IsAPIPublished", aefId, path)
}
func TestPostSecurityIdTokenInvokerNotRegistered(t *testing.T) {