c243d1853b68f96c282b7cb8da4b6bb87ac03c6c
[nonrtric.git] / test / usecases / odusliceassurance / goversion / 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         "oransc.org/usecase/oduclosedloop/messages"
29 )
30
31 type MapKey struct {
32         Duid string
33         sd   int
34         sst  int
35 }
36
37 type SliceAssuranceMeas struct {
38         Metrics  map[MapKey]*SliceMetric
39         Policies map[string]*PolicyRatio
40 }
41
42 func NewSliceAssuranceMeas() *SliceAssuranceMeas {
43         s := SliceAssuranceMeas{}
44         s.Metrics = make(map[MapKey]*SliceMetric)
45         s.Policies = make(map[string]*PolicyRatio)
46         return &s
47 }
48
49 func (sa *SliceAssuranceMeas) AddNewPolicy(duid string, rrmPolicyRatio messages.RRMPolicyRatio) {
50         for _, policyMember := range rrmPolicyRatio.RRMPolicyMembers {
51                 metric := sa.GetSliceMetric(duid, policyMember.SliceDifferentiator, policyMember.SliceServiceType)
52                 if metric != nil {
53                         pr := NewPolicyRatio(rrmPolicyRatio.Id, rrmPolicyRatio.RRMPolicyMaxRatio, rrmPolicyRatio.RRMPolicyMinRatio, rrmPolicyRatio.RRMPolicyDedicatedRatio)
54                         sa.Policies[pr.PolicyRatioId] = pr
55                         metric.RRMPolicyRatioId = rrmPolicyRatio.Id
56                 }
57         }
58 }
59
60 func (sa *SliceAssuranceMeas) GetSliceMetric(duid string, sd int, sst int) *SliceMetric {
61         key := MapKey{duid, sd, sst}
62         value, check := sa.Metrics[key]
63
64         if check {
65                 return value
66         }
67
68         return nil
69 }
70
71 func (sa *SliceAssuranceMeas) AddOrUpdateMetric(meas messages.Measurement) (string, error) {
72
73         var duid string
74         var sd, sst int
75
76         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+)\]`)
77         res := regex.FindAllStringSubmatch(meas.MeasurementTypeInstanceReference, -1)
78
79         if res != nil && len(res[0]) == 6 {
80                 duid = res[0][1]
81                 sd = toInt(res[0][4])
82                 sst = toInt(res[0][5])
83
84                 key := MapKey{duid, sd, sst}
85                 value, check := sa.Metrics[key]
86
87                 if check {
88                         sa.updateMetric(key, value, res[0][3], meas.Value)
89                 } else {
90                         // Only add new one if value exceeds threshold
91                         sa.addMetric(res, meas.Value)
92                 }
93         } else {
94                 return duid, fmt.Errorf(" wrong format for MeasurementTypeInstanceReference")
95         }
96         return duid, nil
97 }
98
99 func (sa *SliceAssuranceMeas) addMetric(res [][]string, metricValue int) {
100         if metricValue > 700 {
101                 metric := NewSliceMetric(res[0][1], res[0][2], toInt(res[0][4]), toInt(res[0][5]))
102                 metric.PM[res[0][3]] = metricValue
103                 key := MapKey{res[0][1], toInt(res[0][4]), toInt(res[0][5])}
104                 sa.Metrics[key] = metric
105         }
106 }
107
108 func (sa *SliceAssuranceMeas) updateMetric(key MapKey, value *SliceMetric, metricName string, metricValue int) {
109         if metricValue < 700 {
110                 delete(sa.Metrics, key)
111         } else {
112                 value.PM[metricName] = metricValue
113         }
114 }
115
116 func toInt(num string) int {
117         res, err := strconv.Atoi(num)
118         if err != nil {
119                 return -1
120         }
121         return res
122 }
123
124 func (sa *SliceAssuranceMeas) PrintStructures() {
125         fmt.Printf("SliceAssurance Metrics: \n")
126         for key, metric := range sa.Metrics {
127                 fmt.Printf("Key: %+v\n", key)
128                 fmt.Printf("Metric: %+v\n", metric)
129         }
130         fmt.Printf("SliceAssurance Policies: \n")
131         for key, metric := range sa.Policies {
132                 fmt.Printf("Key: %+v\n", key)
133                 fmt.Printf("Metric: %+v\n", metric)
134         }
135 }