CI: Add silent prescan SonarCloud job
[nonrtric/rapp/ransliceassurance.git] / smoversion / internal / structures / sliceassurance.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2021: 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 structures
22
23 import (
24         "fmt"
25         "regexp"
26         "strconv"
27
28         log "github.com/sirupsen/logrus"
29         "oransc.org/usecase/oduclosedloop/messages"
30 )
31
32 type MapKey struct {
33         Duid string
34         sd   int
35         sst  int
36 }
37
38 type SliceAssuranceMeas struct {
39         Metrics  map[MapKey]*SliceMetric
40         Policies map[string]*PolicyRatio
41 }
42
43 func NewSliceAssuranceMeas() *SliceAssuranceMeas {
44         s := SliceAssuranceMeas{}
45         s.Metrics = make(map[MapKey]*SliceMetric)
46         s.Policies = make(map[string]*PolicyRatio)
47         return &s
48 }
49
50 func (sa *SliceAssuranceMeas) AddNewPolicy(duid string, rrmPolicyRatio messages.RRMPolicyRatio) {
51         for _, policyMember := range rrmPolicyRatio.RRMPolicyMembers {
52                 metric := sa.GetSliceMetric(duid, policyMember.SliceDifferentiator, policyMember.SliceServiceType)
53                 if metric != nil {
54                         pr := NewPolicyRatio(rrmPolicyRatio.Id, rrmPolicyRatio.RRMPolicyMaxRatio, rrmPolicyRatio.RRMPolicyMinRatio, rrmPolicyRatio.RRMPolicyDedicatedRatio)
55                         _, check := sa.Policies[pr.PolicyRatioId]
56                         if !check {
57                                 log.Infof(" new policy has been added %+v", *pr)
58                         }
59                         sa.Policies[pr.PolicyRatioId] = pr
60                         metric.RRMPolicyRatioId = rrmPolicyRatio.Id
61
62                 }
63         }
64 }
65
66 func (sa *SliceAssuranceMeas) GetSliceMetric(duid string, sd int, sst int) *SliceMetric {
67         key := MapKey{duid, sd, sst}
68         value, check := sa.Metrics[key]
69
70         if check {
71                 return value
72         }
73
74         return nil
75 }
76
77 func (sa *SliceAssuranceMeas) AddOrUpdateMetric(meas messages.Measurement) (string, error) {
78
79         var duid string
80         var sd, sst int
81
82         regex := *regexp.MustCompile(`\/(.*)network-function\/distributed-unit-functions\[id=\'(.*)\'\]\/cell\[id=\'(.*)\'\]\/supported-measurements\[performance-measurement-type=\'(.*)\'\]\/supported-snssai-subcounter-instances\[slice-differentiator=\'(\d+)\'\]\[slice-service-type=\'(\d+)\'\]`)
83         res := regex.FindAllStringSubmatch(meas.MeasurementTypeInstanceReference, -1)
84
85         if res != nil && len(res[0]) == 7 {
86                 duid = res[0][2]
87                 sd = toInt(res[0][5])
88                 sst = toInt(res[0][6])
89
90                 key := MapKey{duid, sd, sst}
91                 value, check := sa.Metrics[key]
92
93                 if check {
94                         sa.updateMetric(key, value, res[0][4], meas.Value)
95                 } else {
96                         // Only add new one if value exceeds threshold
97                         sa.addMetric(res, meas.Value)
98                 }
99         } else {
100                 return duid, fmt.Errorf(" wrong format for MeasurementTypeInstanceReference")
101         }
102         return duid, nil
103 }
104
105 func (sa *SliceAssuranceMeas) addMetric(res [][]string, metricValue int) {
106         if metricValue > 700 {
107                 metric := NewSliceMetric(res[0][2], res[0][3], toInt(res[0][5]), toInt(res[0][6]))
108                 metric.PM[res[0][3]] = metricValue
109                 key := MapKey{res[0][2], toInt(res[0][5]), toInt(res[0][6])}
110                 sa.Metrics[key] = metric
111                 log.Infof(" new metric has been added %+v", *metric)
112         }
113 }
114
115 func (sa *SliceAssuranceMeas) updateMetric(key MapKey, value *SliceMetric, metricName string, metricValue int) {
116         if metricValue < 700 {
117                 delete(sa.Metrics, key)
118                 log.Infof(" metric with key %+v has been deleted", key)
119         } else {
120                 value.PM[metricName] = metricValue
121                 log.Infof(" metric value has been updated, new value: %v", metricValue)
122         }
123 }
124
125 func toInt(num string) int {
126         res, err := strconv.Atoi(num)
127         if err != nil {
128                 return -1
129         }
130         return res
131 }
132
133 func (sa *SliceAssuranceMeas) PrintStructures() {
134         fmt.Printf("SliceAssurance Metrics: \n")
135         for key, metric := range sa.Metrics {
136                 fmt.Printf("Key: %+v\n", key)
137                 fmt.Printf("Metric: %+v\n", metric)
138         }
139         fmt.Printf("SliceAssurance Policies: \n")
140         for key, metric := range sa.Policies {
141                 fmt.Printf("Key: %+v\n", key)
142                 fmt.Printf("Metric: %+v\n", metric)
143         }
144 }