Add filter options to Discovery Service
[nonrtric/plt/sme.git] / capifcore / internal / discoverservice / discoverservice.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         "net/http"
25
26         discoverapi "oransc.org/nonrtric/capifcore/internal/discoverserviceapi"
27
28         "oransc.org/nonrtric/capifcore/internal/publishservice"
29
30         "github.com/labstack/echo/v4"
31
32         publishapi "oransc.org/nonrtric/capifcore/internal/publishserviceapi"
33 )
34
35 type DiscoverService struct {
36         apiRegister publishservice.APIRegister
37 }
38
39 func NewDiscoverService(apiRegister publishservice.APIRegister) *DiscoverService {
40         return &DiscoverService{
41                 apiRegister: apiRegister,
42         }
43 }
44
45 func (ds *DiscoverService) GetAllServiceAPIs(ctx echo.Context, params discoverapi.GetAllServiceAPIsParams) error {
46         allApis := *ds.apiRegister.GetAPIs()
47         filteredApis := []publishapi.ServiceAPIDescription{}
48         gatewayDomain := "r1-expo-func-aef"
49         for _, api := range allApis {
50                 if !matchesFilter(api, params) {
51                         continue
52                 }
53                 profiles := *api.AefProfiles
54                 for i, profile := range profiles {
55                         profile.DomainName = &gatewayDomain // Hardcoded for now. Should be provided through some other mechanism.
56                         profiles[i] = profile
57                 }
58                 filteredApis = append(filteredApis, api)
59         }
60         discoveredApis := discoverapi.DiscoveredAPIs{
61                 ServiceAPIDescriptions: &filteredApis,
62         }
63         err := ctx.JSON(http.StatusOK, discoveredApis)
64         if err != nil {
65                 // Something really bad happened, tell Echo that our handler failed
66                 return err
67         }
68
69         return nil
70 }
71
72 func matchesFilter(api publishapi.ServiceAPIDescription, filter discoverapi.GetAllServiceAPIsParams) bool {
73         if filter.ApiName != nil && *filter.ApiName != api.ApiName {
74                 return false
75         }
76         if filter.ApiCat != nil && (api.ServiceAPICategory == nil || *filter.ApiCat != *api.ServiceAPICategory) {
77                 return false
78         }
79         profiles := *api.AefProfiles
80         aefIdMatch := true
81         protocolMatch := true
82         dataFormatMatch := true
83         versionMatch := true
84         for _, profile := range profiles {
85                 if filter.AefId != nil {
86                         aefIdMatch = *filter.AefId == profile.AefId
87                 }
88                 if filter.ApiVersion != nil || filter.CommType != nil {
89                         versionMatch = checkVersionAndCommType(profile, filter.ApiVersion, filter.CommType)
90                 }
91                 if filter.Protocol != nil {
92                         protocolMatch = profile.Protocol != nil && *filter.Protocol == *profile.Protocol
93                 }
94                 if filter.DataFormat != nil {
95                         dataFormatMatch = profile.DataFormat != nil && *filter.DataFormat == *profile.DataFormat
96                 }
97                 if aefIdMatch && versionMatch && protocolMatch && dataFormatMatch {
98                         return true
99                 }
100         }
101         return false
102 }
103
104 func checkVersionAndCommType(profile publishapi.AefProfile, wantedVersion *string, commType *publishapi.CommunicationType) bool {
105         match := false
106         if wantedVersion != nil {
107                 for _, version := range profile.Versions {
108                         match = checkVersion(version, wantedVersion, commType)
109                         if match {
110                                 break
111                         }
112                 }
113         } else if commType != nil {
114                 for _, version := range profile.Versions {
115                         match = checkCommType(version.Resources, commType)
116                 }
117         } else {
118                 match = true
119         }
120         return match
121 }
122
123 func checkVersion(version publishapi.Version, wantedVersion *string, commType *publishapi.CommunicationType) bool {
124         match := false
125         if *wantedVersion == version.ApiVersion {
126                 if commType != nil {
127                         match = checkCommType(version.Resources, commType)
128                 } else {
129                         match = true
130                 }
131         }
132         return match
133 }
134
135 func checkCommType(resources *[]publishapi.Resource, commType *publishapi.CommunicationType) bool {
136         match := false
137         if commType != nil {
138                 for _, resource := range *resources {
139                         if resource.CommType == *commType {
140                                 match = true
141                                 break
142                         }
143                 }
144         } else {
145                 match = true
146         }
147         return match
148 }