Add filter options to Discovery Service
[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/discoverserviceapi"
30
31         "oransc.org/nonrtric/capifcore/internal/publishservice"
32
33         "github.com/labstack/echo/v4"
34
35         publishapi "oransc.org/nonrtric/capifcore/internal/publishserviceapi"
36
37         "oransc.org/nonrtric/capifcore/internal/publishservice/mocks"
38
39         "github.com/deepmap/oapi-codegen/pkg/middleware"
40         "github.com/deepmap/oapi-codegen/pkg/testutil"
41         echomiddleware "github.com/labstack/echo/v4/middleware"
42         "github.com/stretchr/testify/assert"
43 )
44
45 var protocolHTTP11 = publishapi.ProtocolHTTP11
46 var dataFormatJSON = publishapi.DataFormatJSON
47
48 func TestGetAllServiceAPIs(t *testing.T) {
49         var err error
50
51         apiList := []publishapi.ServiceAPIDescription{
52                 getAPI("apiName1", "aefId", "apiCategory", "v1", nil, nil, ""),
53                 getAPI("apiName2", "aefId", "apiCategory", "v1", nil, nil, ""),
54         }
55         apiRegisterMock := mocks.APIRegister{}
56         apiRegisterMock.On("GetAPIs").Return(&apiList)
57         requestHandler := getEcho(&apiRegisterMock)
58
59         // Get all APIs, without any filter
60         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id").Go(t, requestHandler)
61
62         assert.Equal(t, http.StatusOK, result.Code())
63         var resultInvoker discoverserviceapi.DiscoveredAPIs
64         err = result.UnmarshalBodyToObject(&resultInvoker)
65         assert.NoError(t, err, "error unmarshaling response")
66         assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
67         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
68         assert.Equal(t, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[1].ApiName)
69         apiRegisterMock.AssertCalled(t, "GetAPIs")
70         assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
71 }
72
73 func TestFilterApiName(t *testing.T) {
74         var err error
75
76         apiList := []publishapi.ServiceAPIDescription{
77                 getAPI("apiName1", "", "", "", nil, nil, ""),
78                 getAPI("apiName2", "", "", "", nil, nil, ""),
79         }
80         apiRegisterMock := mocks.APIRegister{}
81         apiRegisterMock.On("GetAPIs").Return(&apiList)
82         requestHandler := getEcho(&apiRegisterMock)
83
84         // Get APIs with filter
85         result := testutil.NewRequest().Get("/allServiceAPIs?api-name=apiName1&api-invoker-id=api_invoker_id").Go(t, requestHandler)
86
87         assert.Equal(t, http.StatusOK, result.Code())
88         var resultInvoker discoverserviceapi.DiscoveredAPIs
89         err = result.UnmarshalBodyToObject(&resultInvoker)
90         assert.NoError(t, err, "error unmarshaling response")
91         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
92         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
93 }
94
95 func TestFilterAefId(t *testing.T) {
96         var err error
97
98         apiList := []publishapi.ServiceAPIDescription{
99                 getAPI("apiName1", "aefId", "", "", nil, nil, ""),
100                 getAPI("apiName2", "otherAefId", "", "", nil, nil, ""),
101         }
102         apiRegisterMock := mocks.APIRegister{}
103         apiRegisterMock.On("GetAPIs").Return(&apiList)
104         requestHandler := getEcho(&apiRegisterMock)
105
106         // Get APIs with filter
107         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id&aef-id=aefId").Go(t, requestHandler)
108
109         assert.Equal(t, http.StatusOK, result.Code())
110         var resultInvoker discoverserviceapi.DiscoveredAPIs
111         err = result.UnmarshalBodyToObject(&resultInvoker)
112         assert.NoError(t, err, "error unmarshaling response")
113         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
114         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
115 }
116
117 func TestFilterVersion(t *testing.T) {
118         var err error
119
120         apiList := []publishapi.ServiceAPIDescription{
121                 getAPI("apiName1", "", "", "v1", nil, nil, ""),
122                 getAPI("apiName2", "", "", "v2", nil, nil, ""),
123         }
124         apiRegisterMock := mocks.APIRegister{}
125         apiRegisterMock.On("GetAPIs").Return(&apiList)
126         requestHandler := getEcho(&apiRegisterMock)
127
128         // Get APIs with filter
129         result := testutil.NewRequest().Get("/allServiceAPIs?api-version=v1&api-invoker-id=api_invoker_id").Go(t, requestHandler)
130
131         assert.Equal(t, http.StatusOK, result.Code())
132         var resultInvoker discoverserviceapi.DiscoveredAPIs
133         err = result.UnmarshalBodyToObject(&resultInvoker)
134         assert.NoError(t, err, "error unmarshaling response")
135         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
136         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
137 }
138
139 func TestFilterCommType(t *testing.T) {
140         var err error
141
142         apiList := []publishapi.ServiceAPIDescription{
143                 getAPI("apiName1", "", "", "", nil, nil, publishapi.CommunicationTypeREQUESTRESPONSE),
144                 getAPI("apiName2", "", "", "", nil, nil, publishapi.CommunicationTypeSUBSCRIBENOTIFY),
145         }
146         apiRegisterMock := mocks.APIRegister{}
147         apiRegisterMock.On("GetAPIs").Return(&apiList)
148         requestHandler := getEcho(&apiRegisterMock)
149
150         // Get APIs with filter
151         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id&comm-type=REQUEST_RESPONSE").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 TestFilterVersionAndCommType(t *testing.T) {
162         var err error
163
164         apiList := []publishapi.ServiceAPIDescription{
165                 getAPI("apiName1", "", "", "v1", nil, nil, publishapi.CommunicationTypeREQUESTRESPONSE),
166                 getAPI("apiName2", "", "", "v1", nil, nil, publishapi.CommunicationTypeSUBSCRIBENOTIFY),
167                 getAPI("apiName3", "", "", "v2", nil, nil, publishapi.CommunicationTypeSUBSCRIBENOTIFY),
168         }
169         apiRegisterMock := mocks.APIRegister{}
170         apiRegisterMock.On("GetAPIs").Return(&apiList)
171         requestHandler := getEcho(&apiRegisterMock)
172
173         // Get APIs with filter
174         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id&api-version=v1&comm-type=SUBSCRIBE_NOTIFY").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, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
182 }
183
184 func TestFilterAPICategory(t *testing.T) {
185         var err error
186
187         apiList := []publishapi.ServiceAPIDescription{
188                 getAPI("apiName1", "", "apiCategory", "", nil, nil, ""),
189                 getAPI("apiName2", "", "", "", nil, nil, ""),
190         }
191         apiRegisterMock := mocks.APIRegister{}
192         apiRegisterMock.On("GetAPIs").Return(&apiList)
193         requestHandler := getEcho(&apiRegisterMock)
194
195         // Get APIs with filter
196         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id&api-cat=apiCategory").Go(t, requestHandler)
197
198         assert.Equal(t, http.StatusOK, result.Code())
199         var resultInvoker discoverserviceapi.DiscoveredAPIs
200         err = result.UnmarshalBodyToObject(&resultInvoker)
201         assert.NoError(t, err, "error unmarshaling response")
202         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
203         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
204 }
205
206 func TestFilterProtocol(t *testing.T) {
207         var err error
208
209         apiList := []publishapi.ServiceAPIDescription{
210                 getAPI("apiName1", "", "", "", &protocolHTTP11, nil, ""),
211                 getAPI("apiName2", "", "", "", nil, nil, ""),
212         }
213         apiRegisterMock := mocks.APIRegister{}
214         apiRegisterMock.On("GetAPIs").Return(&apiList)
215         requestHandler := getEcho(&apiRegisterMock)
216
217         // Get APIs with filter
218         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id&protocol=HTTP_1_1").Go(t, requestHandler)
219
220         assert.Equal(t, http.StatusOK, result.Code())
221         var resultInvoker discoverserviceapi.DiscoveredAPIs
222         err = result.UnmarshalBodyToObject(&resultInvoker)
223         assert.NoError(t, err, "error unmarshaling response")
224         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
225         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
226 }
227
228 var DataFormatOther publishapi.DataFormat = "OTHER"
229
230 func TestFilterDataFormat(t *testing.T) {
231         var err error
232
233         apiList := []publishapi.ServiceAPIDescription{
234                 getAPI("apiName1", "", "", "", nil, &dataFormatJSON, ""),
235                 getAPI("apiName2", "", "", "", nil, nil, ""),
236         }
237         apiRegisterMock := mocks.APIRegister{}
238         apiRegisterMock.On("GetAPIs").Return(&apiList)
239         requestHandler := getEcho(&apiRegisterMock)
240
241         // Get APIs with filter
242         result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id&data-format=JSON").Go(t, requestHandler)
243
244         assert.Equal(t, http.StatusOK, result.Code())
245         var resultInvoker discoverserviceapi.DiscoveredAPIs
246         err = result.UnmarshalBodyToObject(&resultInvoker)
247         assert.NoError(t, err, "error unmarshaling response")
248         assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
249         assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
250 }
251
252 func getEcho(apiRegister publishservice.APIRegister) *echo.Echo {
253         swagger, err := discoverserviceapi.GetSwagger()
254         if err != nil {
255                 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
256                 os.Exit(1)
257         }
258
259         swagger.Servers = nil
260
261         ds := NewDiscoverService(apiRegister)
262
263         e := echo.New()
264         e.Use(echomiddleware.Logger())
265         e.Use(middleware.OapiRequestValidator(swagger))
266
267         discoverserviceapi.RegisterHandlers(e, ds)
268         return e
269 }
270
271 func getAPI(apiName, aefId, apiCategory, apiVersion string, protocol *publishapi.Protocol, dataFormat *publishapi.DataFormat, commType publishapi.CommunicationType) publishapi.ServiceAPIDescription {
272         apiId := "apiId_" + apiName
273         description := "description"
274         domainName := "domain"
275         otherDomainName := "otherDomain"
276         var otherProtocol publishapi.Protocol = "HTTP_2"
277         categoryPointer := &apiCategory
278         if apiCategory == "" {
279                 categoryPointer = nil
280         }
281         return publishapi.ServiceAPIDescription{
282                 ApiId:              &apiId,
283                 ApiName:            apiName,
284                 Description:        &description,
285                 ServiceAPICategory: categoryPointer,
286                 AefProfiles: &[]publishapi.AefProfile{
287                         {
288                                 AefId:      aefId,
289                                 DomainName: &domainName,
290                                 Protocol:   protocol,
291                                 DataFormat: dataFormat,
292                                 Versions: []publishapi.Version{
293                                         {
294                                                 ApiVersion: apiVersion,
295                                                 Resources: &[]publishapi.Resource{
296                                                         {
297                                                                 ResourceName: "app",
298                                                                 CommType:     commType,
299                                                                 Uri:          "uri",
300                                                                 Operations: &[]publishapi.Operation{
301                                                                         "POST",
302                                                                 },
303                                                         },
304                                                 },
305                                         },
306                                         {
307                                                 ApiVersion: "v2",
308                                                 Resources: &[]publishapi.Resource{
309                                                         {
310                                                                 ResourceName: "app",
311                                                                 CommType:     publishapi.CommunicationTypeSUBSCRIBENOTIFY,
312                                                                 Uri:          "uri",
313                                                                 Operations: &[]publishapi.Operation{
314                                                                         "POST",
315                                                                 },
316                                                         },
317                                                 },
318                                         },
319                                 },
320                         },
321                         {
322                                 AefId:      "otherAefId",
323                                 DomainName: &otherDomainName,
324                                 Protocol:   &otherProtocol,
325                                 DataFormat: &DataFormatOther,
326                                 Versions: []publishapi.Version{
327                                         {
328                                                 ApiVersion: "v3",
329                                                 Resources: &[]publishapi.Resource{
330                                                         {
331                                                                 ResourceName: "app",
332                                                                 CommType:     commType,
333                                                                 Uri:          "uri",
334                                                                 Operations: &[]publishapi.Operation{
335                                                                         "POST",
336                                                                 },
337                                                         },
338                                                 },
339                                         },
340                                 },
341                         },
342                 },
343         }
344 }