RIC:1060: Change in PTL
[ric-plt/a1.git] / pkg / policy / policyManager.go
1 /*
2 ==================================================================================
3   Copyright (c) 2022 Samsung
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17    This source code is part of the near-RT RIC (RAN Intelligent Controller)
18    platform project (RICP).
19 ==================================================================================
20 */
21
22 package policy
23
24 import (
25         "encoding/json"
26         "errors"
27         "fmt"
28         "strconv"
29         "strings"
30
31         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/a1"
32         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/models"
33         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/notification"
34         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/restapi/operations/a1_mediator"
35         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
36 )
37
38 var policyTypeNotFoundError = errors.New("Policy Type Not Found")
39 var policyInstanceNotFoundError = errors.New("Policy Instance Not Found")
40
41 const (
42         a1HandlerPrefix                 = "a1.policy_handler."
43         a1PolicyPrefix                  = "a1.policy_type."
44         a1MediatorNs                    = "A1m_ns"
45         a1InstancePrefix                = "a1.policy_instance."
46         a1NotificationDestinationPrefix = "a1.policy_notification_destination."
47 )
48
49 func NewPolicyManager(sdl *sdlgo.SyncStorage) *PolicyManager {
50         return createPolicyManager(sdl)
51 }
52
53 func createPolicyManager(sdlInst iSdl) *PolicyManager {
54         pm := &PolicyManager{
55                 db: sdlInst,
56         }
57         return pm
58 }
59 func (pm *PolicyManager) SetPolicyInstanceStatus(policyTypeId int, policyInstanceID string, status string) error {
60         a1.Logger.Debug("In SetPolicyInstanceStatus message recieved for %d and %s", policyTypeId, policyInstanceID)
61         instancehandlerKey := a1HandlerPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + policyInstanceID
62         err := pm.db.Set(a1MediatorNs, instancehandlerKey, status)
63         if err != nil {
64                 a1.Logger.Error("error1 :%+v", err)
65                 return err
66         }
67         return nil
68 }
69
70 func (pm *PolicyManager) GetPolicyInstanceStatus(policyTypeId int, policyInstanceID string) (bool, error) {
71         a1.Logger.Debug("In GetPolicyInstanceStatus message recieved for %d and %s", policyTypeId, policyInstanceID)
72         instancehandlerKey := a1HandlerPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + policyInstanceID
73         keys := []string{instancehandlerKey}
74         resp, err := pm.db.Get(a1MediatorNs, keys)
75         if err != nil {
76                 a1.Logger.Error("error1 :%+v", err)
77                 return false, err
78         }
79         for _, key := range resp {
80                 if key == "OK" {
81                         return true, nil
82                 }
83         }
84         return false, nil
85 }
86
87 func (pm *PolicyManager) SendPolicyStatusNotification(policyTypeId int, policyInstanceID string, handler string, status string) error {
88         a1.Logger.Debug("In SendPolicyStatusNotification status message recieved for %d and %s", policyTypeId, policyInstanceID)
89         notificationDestinationkey := a1NotificationDestinationPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + fmt.Sprint(policyInstanceID)
90         keys := [1]string{notificationDestinationkey}
91         data, err := pm.db.Get(a1MediatorNs, keys[:])
92         if err != nil {
93                 a1.Logger.Error("error1 :%+v", err)
94                 return err
95         }
96
97         if data[notificationDestinationkey] == nil {
98                 // notificationDestination URL is not available. Not an error, non-RT RIC
99                 // possibly not expecting any callback.
100                 return nil
101         }
102
103         notificationDestination, ok := data[notificationDestinationkey].(string)
104         if !ok {
105                 return errors.New("failed to process notificationDestination URL")
106         }
107
108         policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{EnforceStatus: "ENFORCED"}
109         enforced, err := pm.GetPolicyInstanceStatus(policyTypeId, policyInstanceID)
110         if err != nil {
111                 return err
112         }
113
114         if !enforced {
115                 policyInstanceStatus.EnforceStatus = "NOT ENFORCED"
116                 policyInstanceStatus.EnforceReason = "OTHER_REASON"
117         }
118
119         jsonbody, err := json.Marshal(policyInstanceStatus)
120         if err != nil {
121                 return err
122         }
123         err = notification.SendNotification(notificationDestination, string(jsonbody))
124         if err != nil {
125                 return err
126         }
127         return nil
128 }
129
130 func (im *PolicyManager) GetAllPolicyInstance(policyTypeId int) ([]models.PolicyInstanceID, error) {
131         a1.Logger.Debug("GetAllPolicyInstance")
132         var policyTypeInstances = []models.PolicyInstanceID{}
133         keys, err := im.db.GetAll("A1m_ns")
134
135         if err != nil {
136                 a1.Logger.Error("error in retrieving policy. err: %v", err)
137                 return policyTypeInstances, err
138         }
139         a1.Logger.Debug("keys : %+v", keys)
140         typekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "."
141
142         for _, key := range keys {
143                 if strings.HasPrefix(strings.TrimLeft(key, " "), typekey) {
144                         pti := strings.Split(strings.Trim(key, " "), typekey)[1]
145                         a1.Logger.Debug("pti %+v", pti)
146                         policyTypeInstances = append(policyTypeInstances, models.PolicyInstanceID(pti))
147                 }
148         }
149
150         if len(policyTypeInstances) == 0 {
151                 a1.Logger.Debug("policy instance Not Present  ")
152                 return policyTypeInstances, policyInstanceNotFoundError
153         }
154
155         a1.Logger.Debug("return : %+v", policyTypeInstances)
156         return policyTypeInstances, nil
157 }
158
159 func (im *PolicyManager) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (interface{}, error) {
160         a1.Logger.Debug("GetPolicyInstance1")
161
162         var keys [1]string
163
164         typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
165         keys[0] = typekey
166
167         a1.Logger.Debug("key1 : %+v", typekey)
168
169         valmap, err := im.db.Get(a1MediatorNs, keys[:])
170         if len(valmap) == 0 {
171                 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
172                 return nil, policyTypeNotFoundError
173         }
174
175         if err != nil {
176                 a1.Logger.Error("error in retrieving policy type. err: %v", err)
177                 return nil, err
178         }
179
180         if valmap[typekey] == nil {
181                 a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId)
182                 return nil, policyTypeNotFoundError
183         }
184
185         a1.Logger.Debug("keysmap : %+v", valmap[typekey])
186
187         instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
188         a1.Logger.Debug("key2 : %+v", instancekey)
189         keys[0] = instancekey
190         instanceMap, err := im.db.Get(a1MediatorNs, keys[:])
191         if err != nil {
192                 a1.Logger.Error("policy instance error : %v", err)
193                 return nil, err
194         }
195         a1.Logger.Debug("policyinstancetype map : %+v", instanceMap)
196
197         if instanceMap[instancekey] == nil {
198                 a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID)
199                 return nil, policyInstanceNotFoundError
200         }
201
202         valStr := fmt.Sprint(instanceMap[instancekey])
203         return valStr, nil
204 }