NONRTRIC-946:Remove hard-coded kong domain
[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 //   Copyright (C) 2023: OpenInfra Foundation Europe.
7 //   %%
8 //   Licensed under the Apache License, Version 2.0 (the "License");
9 //   you may not use this file except in compliance with the License.
10 //   You may obtain a copy of the License at
11 //
12 //        http://www.apache.org/licenses/LICENSE-2.0
13 //
14 //   Unless required by applicable law or agreed to in writing, software
15 //   distributed under the License is distributed on an "AS IS" BASIS,
16 //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 //   See the License for the specific language governing permissions and
18 //   limitations under the License.
19 //   ========================LICENSE_END===================================
20 //
21
22 package discoverservice
23
24 import (
25         "fmt"
26         "net/http"
27
28         "oransc.org/nonrtric/capifcore/internal/common29122"
29         discoverapi "oransc.org/nonrtric/capifcore/internal/discoverserviceapi"
30         "oransc.org/nonrtric/capifcore/internal/invokermanagement"
31
32         "github.com/labstack/echo/v4"
33
34         publishapi "oransc.org/nonrtric/capifcore/internal/publishserviceapi"
35 )
36
37 type DiscoverService struct {
38         invokerRegister invokermanagement.InvokerRegister
39 }
40
41 func NewDiscoverService(invokerRegister invokermanagement.InvokerRegister) *DiscoverService {
42         return &DiscoverService{
43                 invokerRegister: invokerRegister,
44         }
45 }
46
47 func (ds *DiscoverService) GetAllServiceAPIs(ctx echo.Context, params discoverapi.GetAllServiceAPIsParams) error {
48         allApis := ds.invokerRegister.GetInvokerApiList(params.ApiInvokerId)
49         if allApis == nil {
50                 return sendCoreError(ctx, http.StatusNotFound, fmt.Sprintf("Invoker %s not registered", params.ApiInvokerId))
51         }
52
53         filteredApis := []publishapi.ServiceAPIDescription{}
54         for _, api := range *allApis {
55                 if matchesFilter(api, params) {
56                         filteredApis = append(filteredApis, api)
57                 }
58         }
59         discoveredApis := discoverapi.DiscoveredAPIs{
60                 ServiceAPIDescriptions: &filteredApis,
61         }
62         err := ctx.JSON(http.StatusOK, discoveredApis)
63         if err != nil {
64                 // Something really bad happened, tell Echo that our handler failed
65                 return err
66         }
67
68         return nil
69 }
70
71 func matchesFilter(api publishapi.ServiceAPIDescription, filter discoverapi.GetAllServiceAPIsParams) bool {
72         if filter.ApiName != nil && *filter.ApiName != api.ApiName {
73                 return false
74         }
75         if filter.ApiCat != nil && (api.ServiceAPICategory == nil || *filter.ApiCat != *api.ServiceAPICategory) {
76                 return false
77         }
78         profiles := *api.AefProfiles
79         for _, profile := range profiles {
80                 if checkAefId(filter, profile) && checkVersionAndCommType(profile, filter) && checkProtocol(filter, profile) && checkDataFormat(filter, profile) {
81                         return true
82                 }
83         }
84         return false
85 }
86
87 func checkAefId(filter discoverapi.GetAllServiceAPIsParams, profile publishapi.AefProfile) bool {
88         if filter.AefId != nil {
89                 return *filter.AefId == profile.AefId
90         }
91         return true
92 }
93
94 func checkVersionAndCommType(profile publishapi.AefProfile, filter discoverapi.GetAllServiceAPIsParams) bool {
95         match := false
96         if filter.ApiVersion != nil {
97                 for _, version := range profile.Versions {
98                         match = checkVersion(version, filter.ApiVersion, filter.CommType)
99                         if match {
100                                 break
101                         }
102                 }
103         } else if filter.CommType != nil {
104                 for _, version := range profile.Versions {
105                         match = checkCommType(version.Resources, filter.CommType)
106                 }
107         } else {
108                 match = true
109         }
110         return match
111 }
112
113 func checkProtocol(filter discoverapi.GetAllServiceAPIsParams, profile publishapi.AefProfile) bool {
114         if filter.Protocol != nil {
115                 return profile.Protocol != nil && *filter.Protocol == *profile.Protocol
116         }
117         return true
118 }
119
120 func checkDataFormat(filter discoverapi.GetAllServiceAPIsParams, profile publishapi.AefProfile) bool {
121         if filter.DataFormat != nil {
122                 return profile.DataFormat != nil && *filter.DataFormat == *profile.DataFormat
123         }
124         return true
125 }
126
127 func checkVersion(version publishapi.Version, wantedVersion *string, commType *publishapi.CommunicationType) bool {
128         match := false
129         if *wantedVersion == version.ApiVersion {
130                 if commType != nil {
131                         match = checkCommType(version.Resources, commType)
132                 } else {
133                         match = true
134                 }
135         }
136         return match
137 }
138
139 func checkCommType(resources *[]publishapi.Resource, commType *publishapi.CommunicationType) bool {
140         for _, resource := range *resources {
141                 if resource.CommType == *commType {
142                         return true
143                 }
144         }
145         return false
146 }
147
148 // This function wraps sending of an error in the Error format, and
149 // handling the failure to marshal that.
150 func sendCoreError(ctx echo.Context, code int, message string) error {
151         pd := common29122.ProblemDetails{
152                 Cause:  &message,
153                 Status: &code,
154         }
155         err := ctx.JSON(code, pd)
156         return err
157 }