Rename APIRegister to PublishRegister
[nonrtric/plt/sme.git] / capifcore / internal / discoverservice / discoverservice_test.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2022: Nordix Foundation
6 //   %%
7 //   Licensed under the Apache License, Version 2.0 (the "License");
8 //   you may not use this file except in compliance with the License.
9 //   You may obtain a copy of the License at
10 //
11 //        http://www.apache.org/licenses/LICENSE-2.0
12 //
13 //   Unless required by applicable law or agreed to in writing, software
14 //   distributed under the License is distributed on an "AS IS" BASIS,
15 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 //   See the License for the specific language governing permissions and
17 //   limitations under the License.
18 //   ========================LICENSE_END===================================
19 //
20
21 package discoverservice
22
23 import (
24         "fmt"
25         "net/http"
26         "os"
27         "testing"
28
29         "oransc.org/nonrtric/capifcore/internal/common29122"
30         "oransc.org/nonrtric/capifcore/internal/discoverserviceapi"
31         "oransc.org/nonrtric/capifcore/internal/invokermanagement"
32         "oransc.org/nonrtric/capifcore/internal/invokermanagementapi"
33
34         "github.com/labstack/echo/v4"
35
36         publishapi "oransc.org/nonrtric/capifcore/internal/publishserviceapi"
37
38         "oransc.org/nonrtric/capifcore/internal/invokermanagement/mocks"
39
40         "github.com/deepmap/oapi-codegen/pkg/middleware"
41         "github.com/deepmap/oapi-codegen/pkg/testutil"
42         echomiddleware "github.com/labstack/echo/v4/middleware"
43         "github.com/stretchr/testify/assert"
44 )
45
46 var protocolHTTP11 = publishapi.ProtocolHTTP11
47 var dataFormatJSON = publishapi.DataFormatJSON
48
49 func TestGetAllServiceAPIs(t *testing.T) {
50         var err error
51
52         apiList := []publishapi.ServiceAPIDescription{
53                 getAPI("apiName1", "aefId", "apiCategory", "v1", nil, nil, ""),
54                 getAPI("apiName2", "aefId", "apiCategory", "v1", nil, nil, ""),
55         }
56         invokerId := "api_invoker_id"
57         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
58         requestHandler := getEcho(invokerRegisterrMock)
59
60         // Get all APIs, without any filter
61         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId).Go(t, requestHandler)
62
63         assert.Equal(t, http.StatusOK, result.Code())
64         var resultInvoker discoverserviceapi.DiscoveredAPIs
65         err = result.UnmarshalBodyToObject(&resultInvoker)
66         assert.NoError(t, err, "error unmarshaling response")
67         assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
68         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
69         assert.Equal(t, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[1].ApiName)
70         assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
71 }
72
73 func TestGetAllServiceAPIsWhenMissingProvider(t *testing.T) {
74         invokerId := "unregistered"
75         invokerRegisterrMock := getInvokerRegisterMock(invokerId, nil)
76
77         requestHandler := getEcho(invokerRegisterrMock)
78
79         // Get all APIs, without any filter
80         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId).Go(t, requestHandler)
81
82         assert.Equal(t, http.StatusNotFound, result.Code())
83         var problemDetails common29122.ProblemDetails
84         err := result.UnmarshalBodyToObject(&problemDetails)
85         assert.NoError(t, err, "error unmarshaling response")
86         notFound := http.StatusNotFound
87         assert.Equal(t, &notFound, problemDetails.Status)
88         errMsg := "Invoker not registered"
89         assert.Equal(t, &errMsg, problemDetails.Cause)
90 }
91
92 func TestFilterApiName(t *testing.T) {
93         var err error
94
95         apiName := "apiName1"
96         apiList := []publishapi.ServiceAPIDescription{
97                 getAPI(apiName, "", "", "", nil, nil, ""),
98                 getAPI("apiName2", "", "", "", nil, nil, ""),
99         }
100         invokerId := "api_invoker_id"
101         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
102         requestHandler := getEcho(invokerRegisterrMock)
103
104         // Get APIs with filter
105         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&api-name="+apiName).Go(t, requestHandler)
106
107         assert.Equal(t, http.StatusOK, result.Code())
108         var resultInvoker discoverserviceapi.DiscoveredAPIs
109         err = result.UnmarshalBodyToObject(&resultInvoker)
110         assert.NoError(t, err, "error unmarshaling response")
111         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
112         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
113 }
114
115 func TestFilterAefId(t *testing.T) {
116         var err error
117
118         aefId := "aefId"
119         apiList := []publishapi.ServiceAPIDescription{
120                 getAPI("apiName1", aefId, "", "", nil, nil, ""),
121                 getAPI("apiName2", "otherAefId", "", "", nil, nil, ""),
122         }
123         invokerId := "api_invoker_id"
124         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
125         requestHandler := getEcho(invokerRegisterrMock)
126
127         // Get APIs with filter
128         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&aef-id="+aefId).Go(t, requestHandler)
129
130         assert.Equal(t, http.StatusOK, result.Code())
131         var resultInvoker discoverserviceapi.DiscoveredAPIs
132         err = result.UnmarshalBodyToObject(&resultInvoker)
133         assert.NoError(t, err, "error unmarshaling response")
134         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
135         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
136 }
137
138 func TestFilterVersion(t *testing.T) {
139         var err error
140
141         version := "v1"
142         apiList := []publishapi.ServiceAPIDescription{
143                 getAPI("apiName1", "", "", version, nil, nil, ""),
144                 getAPI("apiName2", "", "", "v2", nil, nil, ""),
145         }
146         invokerId := "api_invoker_id"
147         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
148         requestHandler := getEcho(invokerRegisterrMock)
149
150         // Get APIs with filter
151         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&api-version="+version).Go(t, requestHandler)
152
153         assert.Equal(t, http.StatusOK, result.Code())
154         var resultInvoker discoverserviceapi.DiscoveredAPIs
155         err = result.UnmarshalBodyToObject(&resultInvoker)
156         assert.NoError(t, err, "error unmarshaling response")
157         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
158         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
159 }
160
161 func TestFilterCommType(t *testing.T) {
162         var err error
163
164         commType := publishapi.CommunicationTypeREQUESTRESPONSE
165         apiList := []publishapi.ServiceAPIDescription{
166                 getAPI("apiName1", "", "", "", nil, nil, commType),
167                 getAPI("apiName2", "", "", "", nil, nil, publishapi.CommunicationTypeSUBSCRIBENOTIFY),
168         }
169         invokerId := "api_invoker_id"
170         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
171         requestHandler := getEcho(invokerRegisterrMock)
172
173         // Get APIs with filter
174         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&comm-type="+string(commType)).Go(t, requestHandler)
175
176         assert.Equal(t, http.StatusOK, result.Code())
177         var resultInvoker discoverserviceapi.DiscoveredAPIs
178         err = result.UnmarshalBodyToObject(&resultInvoker)
179         assert.NoError(t, err, "error unmarshaling response")
180         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
181         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
182 }
183
184 func TestFilterVersionAndCommType(t *testing.T) {
185         var err error
186
187         version := "v1"
188         commType := publishapi.CommunicationTypeSUBSCRIBENOTIFY
189         apiList := []publishapi.ServiceAPIDescription{
190                 getAPI("apiName1", "", "", version, nil, nil, publishapi.CommunicationTypeREQUESTRESPONSE),
191                 getAPI("apiName2", "", "", version, nil, nil, commType),
192                 getAPI("apiName3", "", "", "v2", nil, nil, commType),
193         }
194         invokerId := "api_invoker_id"
195         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
196         requestHandler := getEcho(invokerRegisterrMock)
197
198         // Get APIs with filter
199         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&api-version="+version+"&comm-type="+string(commType)).Go(t, requestHandler)
200
201         assert.Equal(t, http.StatusOK, result.Code())
202         var resultInvoker discoverserviceapi.DiscoveredAPIs
203         err = result.UnmarshalBodyToObject(&resultInvoker)
204         assert.NoError(t, err, "error unmarshaling response")
205         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
206         assert.Equal(t, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
207 }
208
209 func TestFilterAPICategory(t *testing.T) {
210         var err error
211
212         apiCategory := "apiCategory"
213         apiList := []publishapi.ServiceAPIDescription{
214                 getAPI("apiName1", "", apiCategory, "", nil, nil, ""),
215                 getAPI("apiName2", "", "", "", nil, nil, ""),
216         }
217         invokerId := "api_invoker_id"
218         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
219         requestHandler := getEcho(invokerRegisterrMock)
220
221         // Get APIs with filter
222         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&api-cat="+apiCategory).Go(t, requestHandler)
223
224         assert.Equal(t, http.StatusOK, result.Code())
225         var resultInvoker discoverserviceapi.DiscoveredAPIs
226         err = result.UnmarshalBodyToObject(&resultInvoker)
227         assert.NoError(t, err, "error unmarshaling response")
228         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
229         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
230 }
231
232 func TestFilterProtocol(t *testing.T) {
233         var err error
234
235         apiList := []publishapi.ServiceAPIDescription{
236                 getAPI("apiName1", "", "", "", &protocolHTTP11, nil, ""),
237                 getAPI("apiName2", "", "", "", nil, nil, ""),
238         }
239         invokerId := "api_invoker_id"
240         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
241         requestHandler := getEcho(invokerRegisterrMock)
242
243         // Get APIs with filter
244         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&protocol="+string(protocolHTTP11)).Go(t, requestHandler)
245
246         assert.Equal(t, http.StatusOK, result.Code())
247         var resultInvoker discoverserviceapi.DiscoveredAPIs
248         err = result.UnmarshalBodyToObject(&resultInvoker)
249         assert.NoError(t, err, "error unmarshaling response")
250         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
251         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
252 }
253
254 var DataFormatOther publishapi.DataFormat = "OTHER"
255
256 func TestFilterDataFormat(t *testing.T) {
257         var err error
258
259         apiList := []publishapi.ServiceAPIDescription{
260                 getAPI("apiName1", "", "", "", nil, &dataFormatJSON, ""),
261                 getAPI("apiName2", "", "", "", nil, nil, ""),
262         }
263         invokerId := "api_invoker_id"
264         invokerRegisterrMock := getInvokerRegisterMock(invokerId, apiList)
265         requestHandler := getEcho(invokerRegisterrMock)
266
267         // Get APIs with filter
268         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id="+invokerId+"&data-format="+string(dataFormatJSON)).Go(t, requestHandler)
269
270         assert.Equal(t, http.StatusOK, result.Code())
271         var resultInvoker discoverserviceapi.DiscoveredAPIs
272         err = result.UnmarshalBodyToObject(&resultInvoker)
273         assert.NoError(t, err, "error unmarshaling response")
274         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
275         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
276 }
277
278 func getEcho(invokerManager invokermanagement.InvokerRegister) *echo.Echo {
279         swagger, err := discoverserviceapi.GetSwagger()
280         if err != nil {
281                 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
282                 os.Exit(1)
283         }
284
285         swagger.Servers = nil
286
287         ds := NewDiscoverService(invokerManager)
288
289         e := echo.New()
290         e.Use(echomiddleware.Logger())
291         e.Use(middleware.OapiRequestValidator(swagger))
292
293         discoverserviceapi.RegisterHandlers(e, ds)
294         return e
295 }
296
297 func getInvokerRegisterMock(invokerId string, apisToReturn []publishapi.ServiceAPIDescription) *mocks.InvokerRegister {
298         apiList := invokermanagementapi.APIList(apisToReturn)
299         invokerRegisterrMock := mocks.InvokerRegister{}
300         if apisToReturn != nil {
301                 invokerRegisterrMock.On("GetInvokerApiList", invokerId).Return(&apiList)
302         } else {
303                 invokerRegisterrMock.On("GetInvokerApiList", invokerId).Return(nil)
304         }
305         return &invokerRegisterrMock
306 }
307
308 func getAPI(apiName, aefId, apiCategory, apiVersion string, protocol *publishapi.Protocol, dataFormat *publishapi.DataFormat, commType publishapi.CommunicationType) publishapi.ServiceAPIDescription {
309         apiId := "apiId_" + apiName
310         description := "description"
311         domainName := "domain"
312         otherDomainName := "otherDomain"
313         var otherProtocol publishapi.Protocol = "HTTP_2"
314         categoryPointer := &apiCategory
315         if apiCategory == "" {
316                 categoryPointer = nil
317         }
318         return publishapi.ServiceAPIDescription{
319                 ApiId:              &apiId,
320                 ApiName:            apiName,
321                 Description:        &description,
322                 ServiceAPICategory: categoryPointer,
323                 AefProfiles: &[]publishapi.AefProfile{
324                         {
325                                 AefId:      aefId,
326                                 DomainName: &domainName,
327                                 Protocol:   protocol,
328                                 DataFormat: dataFormat,
329                                 Versions: []publishapi.Version{
330                                         {
331                                                 ApiVersion: apiVersion,
332                                                 Resources: &[]publishapi.Resource{
333                                                         {
334                                                                 ResourceName: "app",
335                                                                 CommType:     commType,
336                                                                 Uri:          "uri",
337                                                                 Operations: &[]publishapi.Operation{
338                                                                         "POST",
339                                                                 },
340                                                         },
341                                                 },
342                                         },
343                                         {
344                                                 ApiVersion: "v2",
345                                                 Resources: &[]publishapi.Resource{
346                                                         {
347                                                                 ResourceName: "app",
348                                                                 CommType:     publishapi.CommunicationTypeSUBSCRIBENOTIFY,
349                                                                 Uri:          "uri",
350                                                                 Operations: &[]publishapi.Operation{
351                                                                         "POST",
352                                                                 },
353                                                         },
354                                                 },
355                                         },
356                                 },
357                         },
358                         {
359                                 AefId:      "otherAefId",
360                                 DomainName: &otherDomainName,
361                                 Protocol:   &otherProtocol,
362                                 DataFormat: &DataFormatOther,
363                                 Versions: []publishapi.Version{
364                                         {
365                                                 ApiVersion: "v3",
366                                                 Resources: &[]publishapi.Resource{
367                                                         {
368                                                                 ResourceName: "app",
369                                                                 CommType:     commType,
370                                                                 Uri:          "uri",
371                                                                 Operations: &[]publishapi.Operation{
372                                                                         "POST",
373                                                                 },
374                                                         },
375                                                 },
376                                         },
377                                 },
378                         },
379                 },
380         }
381 }