subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 1 | /* |
| 2 | ================================================================================== |
| 3 | Copyright (c) 2021 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 | package resthooks |
| 22 | |
| 23 | import ( |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 24 | "encoding/json" |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 25 | "errors" |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 26 | "fmt" |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 27 | "strconv" |
| 28 | "strings" |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 29 | "time" |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 30 | |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 31 | "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/a1" |
| 32 | "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/models" |
naman.gupta | 6d6fe01 | 2022-11-30 15:21:16 +0530 | [diff] [blame] | 33 | "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/policy" |
| 34 | "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/restapi/operations/a1_mediator" |
naman.gupta | b513650 | 2022-10-18 00:25:14 +0530 | [diff] [blame] | 35 | "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/rmr" |
subhash kumar singh | 6017d6a | 2021-10-26 12:14:26 +0000 | [diff] [blame] | 36 | "gerrit.o-ran-sc.org/r/ric-plt/sdlgo" |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 37 | "github.com/santhosh-tekuri/jsonschema/v5" |
| 38 | "gopkg.in/yaml.v2" |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 39 | ) |
| 40 | |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 41 | const ( |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 42 | a1PolicyPrefix = "a1.policy_type." |
| 43 | a1MediatorNs = "A1m_ns" |
| 44 | a1InstancePrefix = "a1.policy_instance." |
naman.gupta | f1e014d | 2022-08-03 16:37:44 +0530 | [diff] [blame] | 45 | a1InstanceMetadataPrefix = "a1.policy_inst_metadata." |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 46 | a1HandlerPrefix = "a1.policy_handler." |
naman.gupta | 159ddb7 | 2022-11-08 19:52:05 +0530 | [diff] [blame] | 47 | a1PolicyRequest = 20010 |
| 48 | a1EIDataDelivery = 20017 |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 49 | ) |
| 50 | |
| 51 | var typeAlreadyError = errors.New("Policy Type already exists") |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 52 | var InstanceAlreadyError = errors.New("Policy Instance already exists") |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 53 | var typeMismatchError = errors.New("Policytype Mismatch") |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 54 | var invalidJsonSchema = errors.New("Invalid Json ") |
| 55 | var policyInstanceNotFoundError = errors.New("Policy Instance Not Found") |
| 56 | var policyTypeNotFoundError = errors.New("Policy Type Not Found") |
naman.gupta | b513650 | 2022-10-18 00:25:14 +0530 | [diff] [blame] | 57 | var policyTypeCanNotBeDeletedError = errors.New("tried to delete a type that isn't empty") |
naman.gupta | 52ef1de | 2022-11-02 21:45:05 +0530 | [diff] [blame] | 58 | var policyInstanceCanNotBeDeletedError = errors.New("tried to delete a Instance that isn't empty") |
| 59 | |
| 60 | func (rh *Resthook) CanPolicyInstanceBeDeleted(err error) bool { |
| 61 | return err == policyInstanceCanNotBeDeletedError |
| 62 | } |
naman.gupta | b513650 | 2022-10-18 00:25:14 +0530 | [diff] [blame] | 63 | |
| 64 | func (rh *Resthook) CanPolicyTypeBeDeleted(err error) bool { |
| 65 | return err == policyTypeCanNotBeDeletedError |
| 66 | } |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 67 | |
| 68 | func (rh *Resthook) IsPolicyTypePresent(err error) bool { |
| 69 | return err == policyTypeNotFoundError |
| 70 | } |
| 71 | |
| 72 | func (rh *Resthook) IsPolicyInstanceNotFound(err error) bool { |
| 73 | return err == policyInstanceNotFoundError |
| 74 | } |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 75 | |
| 76 | func (rh *Resthook) IsTypeAlready(err error) bool { |
| 77 | return err == typeAlreadyError |
| 78 | } |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 79 | func (rh *Resthook) IsInstanceAlready(err error) bool { |
| 80 | return err == InstanceAlreadyError |
| 81 | } |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 82 | func (rh *Resthook) IsTypeMismatch(err error) bool { |
| 83 | return err == typeMismatchError |
| 84 | } |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 85 | |
| 86 | func (rh *Resthook) IsValidJson(err error) bool { |
| 87 | return err == invalidJsonSchema |
| 88 | } |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 89 | func NewResthook() *Resthook { |
naman.gupta | 6d6fe01 | 2022-11-30 15:21:16 +0530 | [diff] [blame] | 90 | sdl := sdlgo.NewSyncStorage() |
| 91 | policyManager := policy.NewPolicyManager(sdl) |
| 92 | return createResthook(sdl, rmr.NewRMRSender(policyManager)) |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 93 | } |
| 94 | |
naman.gupta | 1a41ce7 | 2022-10-18 00:14:49 +0530 | [diff] [blame] | 95 | func createResthook(sdlInst iSdl, rmrSenderInst rmr.IRmrSender) *Resthook { |
naman.gupta | 6d6fe01 | 2022-11-30 15:21:16 +0530 | [diff] [blame] | 96 | rh := &Resthook{ |
naman.gupta | 1a41ce7 | 2022-10-18 00:14:49 +0530 | [diff] [blame] | 97 | db: sdlInst, |
| 98 | iRmrSenderInst: rmrSenderInst, |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 99 | } |
naman.gupta | 6d6fe01 | 2022-11-30 15:21:16 +0530 | [diff] [blame] | 100 | |
| 101 | return rh |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 102 | } |
| 103 | |
naman.gupta | a5d9928 | 2022-11-17 18:20:03 +0530 | [diff] [blame] | 104 | func (rh *Resthook) GetA1Health() bool { |
| 105 | data, _ := rh.db.GetAll(a1MediatorNs) |
| 106 | if data != nil { |
| 107 | a1.Logger.Debug("Database connected and A1 is healthy") |
| 108 | return true |
| 109 | } |
| 110 | return false |
| 111 | } |
| 112 | |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 113 | func (rh *Resthook) GetAllPolicyType() []models.PolicyTypeID { |
| 114 | |
| 115 | var policyTypeIDs []models.PolicyTypeID |
| 116 | |
| 117 | keys, err := rh.db.GetAll("A1m_ns") |
| 118 | |
| 119 | if err != nil { |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 120 | a1.Logger.Error("error in retrieving policy. err: %v", err) |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 121 | return policyTypeIDs |
| 122 | } |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 123 | a1.Logger.Debug("keys : %+v", keys) |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 124 | |
| 125 | for _, key := range keys { |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 126 | if strings.HasPrefix(strings.TrimLeft(key, " "), a1PolicyPrefix) { |
| 127 | pti := strings.Split(strings.Trim(key, " "), a1PolicyPrefix)[1] |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 128 | ptii, _ := strconv.ParseInt(pti, 10, 64) |
| 129 | policyTypeIDs = append(policyTypeIDs, models.PolicyTypeID(ptii)) |
| 130 | } |
| 131 | } |
| 132 | |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 133 | a1.Logger.Debug("return : %+v", policyTypeIDs) |
subhash kumar singh | 327d9db | 2021-09-30 19:07:18 +0000 | [diff] [blame] | 134 | return policyTypeIDs |
| 135 | } |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 136 | |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 137 | func (rh *Resthook) GetPolicyType(policyTypeId models.PolicyTypeID) *models.PolicyTypeSchema { |
| 138 | a1.Logger.Debug("GetPolicyType1") |
| 139 | |
| 140 | var policytypeschema *models.PolicyTypeSchema |
| 141 | var keys [1]string |
| 142 | |
| 143 | key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10) |
| 144 | keys[0] = key |
| 145 | |
| 146 | a1.Logger.Debug("key : %+v", key) |
| 147 | |
| 148 | valmap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 149 | |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 150 | a1.Logger.Debug("policytype map : %+v", valmap) |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 151 | |
| 152 | if len(valmap) == 0 { |
| 153 | a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId) |
| 154 | return policytypeschema |
| 155 | } |
| 156 | |
| 157 | if err != nil { |
| 158 | a1.Logger.Error("error in retrieving policy type. err: %v", err) |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 159 | return nil |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 160 | } |
| 161 | |
| 162 | if valmap[key] == nil { |
| 163 | a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId) |
| 164 | return policytypeschema |
| 165 | } |
| 166 | |
| 167 | a1.Logger.Debug("keysmap : %+v", valmap[key]) |
| 168 | |
| 169 | var item models.PolicyTypeSchema |
| 170 | valStr := fmt.Sprint(valmap[key]) |
| 171 | |
| 172 | a1.Logger.Debug("Policy type for %+v : %+v", key, valStr) |
| 173 | valkey := "`" + valStr + "`" |
| 174 | valToUnmarshall, err := strconv.Unquote(valkey) |
| 175 | if err != nil { |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 176 | a1.Logger.Error("unquote error : %+v", err) |
| 177 | return nil |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 178 | } |
| 179 | |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 180 | a1.Logger.Debug("Policy type for %+v : %+v", key, string(valToUnmarshall)) |
| 181 | |
naman.gupta | 6864473 | 2022-02-24 14:41:55 +0530 | [diff] [blame] | 182 | errunm := json.Unmarshal([]byte(valToUnmarshall), &item) |
| 183 | |
| 184 | a1.Logger.Debug(" Unmarshalled json : %+v", (errunm)) |
| 185 | a1.Logger.Debug("Policy type Name : %v", (item.Name)) |
| 186 | |
| 187 | return &item |
| 188 | } |
| 189 | |
naman.gupta | ab3e9ee | 2022-02-18 18:03:36 +0530 | [diff] [blame] | 190 | func (rh *Resthook) CreatePolicyType(policyTypeId models.PolicyTypeID, httprequest models.PolicyTypeSchema) error { |
| 191 | a1.Logger.Debug("CreatePolicyType function") |
| 192 | if policyTypeId != models.PolicyTypeID(*httprequest.PolicyTypeID) { |
| 193 | //error message |
| 194 | a1.Logger.Debug("Policytype Mismatch") |
| 195 | return typeMismatchError |
| 196 | } |
| 197 | key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10) |
| 198 | a1.Logger.Debug("key %+v ", key) |
| 199 | if data, err := httprequest.MarshalBinary(); err == nil { |
| 200 | a1.Logger.Debug("Marshaled String : %+v", string(data)) |
| 201 | success, err1 := rh.db.SetIfNotExists(a1MediatorNs, key, string(data)) |
| 202 | a1.Logger.Info("success:%+v", success) |
| 203 | if err1 != nil { |
| 204 | a1.Logger.Error("error :%+v", err1) |
| 205 | return err1 |
| 206 | } |
| 207 | if !success { |
| 208 | a1.Logger.Debug("Policy type %+v already exist", policyTypeId) |
| 209 | return typeAlreadyError |
| 210 | } |
| 211 | } |
| 212 | return nil |
| 213 | } |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 214 | |
| 215 | func toStringKeys(val interface{}) (interface{}, error) { |
| 216 | var err error |
| 217 | switch val := val.(type) { |
| 218 | case map[interface{}]interface{}: |
| 219 | m := make(map[string]interface{}) |
| 220 | for k, v := range val { |
| 221 | k, ok := k.(string) |
| 222 | if !ok { |
| 223 | return nil, errors.New("found non-string key") |
| 224 | } |
| 225 | m[k], err = toStringKeys(v) |
| 226 | if err != nil { |
| 227 | return nil, err |
| 228 | } |
| 229 | } |
| 230 | return m, nil |
| 231 | case []interface{}: |
| 232 | var l = make([]interface{}, len(val)) |
| 233 | for i, v := range val { |
| 234 | l[i], err = toStringKeys(v) |
| 235 | if err != nil { |
| 236 | return nil, err |
| 237 | } |
| 238 | } |
| 239 | return l, nil |
| 240 | default: |
| 241 | return val, nil |
| 242 | } |
| 243 | } |
| 244 | |
naman.gupta | 6242a3f | 2022-10-03 16:05:10 +0530 | [diff] [blame] | 245 | func validate(httpBodyString string, schemaString string) bool { |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 246 | var m interface{} |
| 247 | err := yaml.Unmarshal([]byte(httpBodyString), &m) |
| 248 | if err != nil { |
| 249 | a1.Logger.Error("Unmarshal error : %+v", err) |
| 250 | } |
| 251 | m, err = toStringKeys(m) |
| 252 | if err != nil { |
| 253 | a1.Logger.Error("Conversion to string error : %+v", err) |
| 254 | return false |
| 255 | } |
| 256 | compiler := jsonschema.NewCompiler() |
| 257 | if err := compiler.AddResource("schema.json", strings.NewReader(schemaString)); err != nil { |
| 258 | a1.Logger.Error("string reader error : %+v", err) |
| 259 | return false |
| 260 | } |
| 261 | schema, err := compiler.Compile("schema.json") |
| 262 | if err != nil { |
| 263 | a1.Logger.Error("schema json compile error : %+v", err) |
| 264 | return false |
| 265 | } |
| 266 | if err := schema.Validate(m); err != nil { |
| 267 | a1.Logger.Error("schema validation error : %+v", err) |
| 268 | return false |
| 269 | } |
| 270 | a1.Logger.Debug("validation successfull") |
| 271 | return true |
| 272 | } |
| 273 | |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 274 | func (rh *Resthook) storePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) (string, error) { |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 275 | var keys [1]string |
| 276 | operation := "CREATE" |
| 277 | typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10) |
| 278 | keys[0] = typekey |
| 279 | |
| 280 | a1.Logger.Debug("key1 : %+v", typekey) |
| 281 | |
| 282 | valmap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 283 | if err != nil { |
| 284 | a1.Logger.Error("policy type error : %+v", err) |
| 285 | } |
| 286 | a1.Logger.Debug("policytype map : %+v", valmap) |
| 287 | if valmap[typekey] == nil { |
| 288 | a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId) |
| 289 | return operation, policyTypeNotFoundError |
| 290 | } |
| 291 | // TODO : rmr creation_timestamp := time.Now() // will be needed for rmr to notify the creation of instance |
| 292 | |
| 293 | instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 294 | keys[0] = typekey |
| 295 | instanceMap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 296 | if err != nil { |
| 297 | a1.Logger.Error("policy type error : %v", err) |
| 298 | } |
| 299 | a1.Logger.Debug("policyinstancetype map : %+v", instanceMap) |
| 300 | |
| 301 | if instanceMap[instancekey] != nil { |
| 302 | operation = "UPDATE" |
| 303 | a1.Logger.Debug("UPDATE") |
| 304 | data, _ := json.Marshal(httpBody) |
| 305 | a1.Logger.Debug("Marshaled String : %+v", string(data)) |
| 306 | a1.Logger.Debug("key : %+v", instancekey) |
| 307 | success, err1 := rh.db.SetIf(a1MediatorNs, instancekey, instanceMap[instancekey], string(data)) |
| 308 | if err1 != nil { |
| 309 | a1.Logger.Error("error2 :%+v", err1) |
| 310 | return operation, err1 |
| 311 | } |
| 312 | if !success { |
| 313 | a1.Logger.Debug("Policy instance %+v already exist", policyInstanceID) |
| 314 | return operation, InstanceAlreadyError |
| 315 | } |
| 316 | } else { |
| 317 | data, _ := json.Marshal(httpBody) |
| 318 | a1.Logger.Debug("Marshaled String : %+v", string(data)) |
| 319 | a1.Logger.Debug("key : %+v", instancekey) |
| 320 | |
| 321 | var instance_map []interface{} |
| 322 | instance_map = append(instance_map, instancekey, string(data)) |
| 323 | a1.Logger.Debug("policyinstancetype map : %+v", instance_map[1]) |
| 324 | a1.Logger.Debug("policyinstancetype to create : %+v", instance_map) |
| 325 | |
| 326 | err1 := rh.db.Set(a1MediatorNs, instancekey, string(data)) |
| 327 | if err1 != nil { |
| 328 | a1.Logger.Error("error1 :%+v", err1) |
| 329 | return operation, err1 |
| 330 | } |
| 331 | } |
| 332 | a1.Logger.Debug("Policy Instance created ") |
| 333 | return operation, nil |
| 334 | } |
| 335 | |
naman.gupta | f1e014d | 2022-08-03 16:37:44 +0530 | [diff] [blame] | 336 | func (rh *Resthook) storePolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (bool, error) { |
| 337 | |
| 338 | creation_timestamp := time.Now() |
| 339 | instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 340 | |
| 341 | a1.Logger.Debug("key : %+v", instanceMetadataKey) |
| 342 | |
| 343 | var metadatajson []interface{} |
| 344 | metadatajson = append(metadatajson, map[string]string{"created_at": creation_timestamp.Format("2006-01-02 15:04:05"), "has_been_deleted": "False"}) |
| 345 | metadata, _ := json.Marshal(metadatajson) |
| 346 | |
| 347 | a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(metadata)) |
| 348 | |
| 349 | err := rh.db.Set(a1MediatorNs, instanceMetadataKey, string(metadata)) |
| 350 | |
| 351 | if err != nil { |
| 352 | a1.Logger.Error("error :%+v", err) |
| 353 | return false, err |
| 354 | } |
| 355 | |
| 356 | a1.Logger.Debug("Policy Instance Meta Data created at :%+v", creation_timestamp) |
| 357 | |
| 358 | return true, nil |
| 359 | } |
naman.gupta | 44f5c8a | 2022-05-25 23:31:47 +0530 | [diff] [blame] | 360 | |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 361 | func (rh *Resthook) CreatePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, httpBody interface{}) error { |
| 362 | a1.Logger.Debug("CreatePolicyInstance function") |
| 363 | // validate the PUT against the schema |
| 364 | var policyTypeSchema *models.PolicyTypeSchema |
| 365 | policyTypeSchema = rh.GetPolicyType(policyTypeId) |
| 366 | schemaStr, err := json.Marshal(policyTypeSchema.CreateSchema) |
| 367 | if err != nil { |
| 368 | a1.Logger.Error("Json Marshal error : %+v", err) |
| 369 | return err |
| 370 | } |
| 371 | a1.Logger.Debug("schema to validate %+v", string(schemaStr)) |
| 372 | a1.Logger.Debug("httpbody to validate %+v", httpBody) |
| 373 | schemaString := fmt.Sprint(string(schemaStr)) |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 374 | httpBodyMarshal, err := json.Marshal(httpBody) |
| 375 | httpBodyString := string((httpBodyMarshal)) |
| 376 | a1.Logger.Debug("schema to validate sprint %+v", (schemaString)) |
| 377 | a1.Logger.Debug("httpbody to validate sprint %+v", httpBodyString) |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 378 | isvalid := validate(httpBodyString, schemaString) |
| 379 | if isvalid { |
naman.gupta | 44f5c8a | 2022-05-25 23:31:47 +0530 | [diff] [blame] | 380 | var operation string |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 381 | operation, err = rh.storePolicyInstance(policyTypeId, policyInstanceID, httpBody) |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 382 | if err != nil { |
| 383 | a1.Logger.Error("error :%+v", err) |
| 384 | return err |
| 385 | } |
| 386 | a1.Logger.Debug("policy instance :%+v", operation) |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 387 | iscreated, errmetadata := rh.storePolicyInstanceMetadata(policyTypeId, policyInstanceID) |
naman.gupta | f1e014d | 2022-08-03 16:37:44 +0530 | [diff] [blame] | 388 | if errmetadata != nil { |
| 389 | a1.Logger.Error("error :%+v", errmetadata) |
| 390 | return errmetadata |
| 391 | } |
| 392 | if iscreated { |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 393 | a1.Logger.Debug("policy instance metadata created") |
naman.gupta | f1e014d | 2022-08-03 16:37:44 +0530 | [diff] [blame] | 394 | } |
naman.gupta | 327e01c | 2022-10-30 21:50:52 +0530 | [diff] [blame] | 395 | |
| 396 | message := rmr.Message{} |
naman.gupta | 521fb55 | 2022-12-01 18:49:35 +0530 | [diff] [blame] | 397 | rmrMessage, err := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), httpBodyString, operation) |
naman.gupta | 327e01c | 2022-10-30 21:50:52 +0530 | [diff] [blame] | 398 | if err != nil { |
| 399 | a1.Logger.Error("error : %v", err) |
| 400 | return err |
| 401 | } |
naman.gupta | 159ddb7 | 2022-11-08 19:52:05 +0530 | [diff] [blame] | 402 | isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest) |
naman.gupta | 1a41ce7 | 2022-10-18 00:14:49 +0530 | [diff] [blame] | 403 | if isSent { |
| 404 | a1.Logger.Debug("rmrSendToXapp : message sent") |
| 405 | } else { |
| 406 | a1.Logger.Debug("rmrSendToXapp : message not sent") |
| 407 | } |
| 408 | |
naman.gupta | 3ad6de4 | 2022-04-26 21:59:05 +0530 | [diff] [blame] | 409 | } else { |
| 410 | a1.Logger.Error("%+v", invalidJsonSchema) |
| 411 | return invalidJsonSchema |
| 412 | } |
| 413 | |
| 414 | return nil |
| 415 | } |
naman.gupta | 6579f78 | 2022-05-02 15:34:31 +0530 | [diff] [blame] | 416 | |
| 417 | func (rh *Resthook) GetPolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (interface{}, error) { |
| 418 | a1.Logger.Debug("GetPolicyInstance1") |
| 419 | |
| 420 | var keys [1]string |
| 421 | |
| 422 | typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10) |
| 423 | keys[0] = typekey |
| 424 | |
| 425 | a1.Logger.Debug("key1 : %+v", typekey) |
| 426 | |
| 427 | valmap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 428 | if len(valmap) == 0 { |
| 429 | a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId) |
| 430 | return "{}", policyTypeNotFoundError |
| 431 | } |
| 432 | |
| 433 | if err != nil { |
| 434 | a1.Logger.Error("error in retrieving policy type. err: %v", err) |
| 435 | return "{}", err |
| 436 | } |
| 437 | |
| 438 | if valmap[typekey] == nil { |
| 439 | a1.Logger.Debug("policy type Not Present for policyid : %v", policyTypeId) |
| 440 | return "{}", policyTypeNotFoundError |
| 441 | } |
| 442 | |
| 443 | a1.Logger.Debug("keysmap : %+v", valmap[typekey]) |
| 444 | |
| 445 | instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 446 | a1.Logger.Debug("key2 : %+v", instancekey) |
| 447 | keys[0] = instancekey |
| 448 | instanceMap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 449 | if err != nil { |
| 450 | a1.Logger.Error("policy instance error : %v", err) |
| 451 | } |
| 452 | a1.Logger.Debug("policyinstancetype map : %+v", instanceMap) |
| 453 | |
| 454 | if instanceMap[instancekey] == nil { |
| 455 | a1.Logger.Debug("policy instance Not Present for policyinstaneid : %v", policyInstanceID) |
| 456 | return "{}", policyInstanceNotFoundError |
| 457 | } |
| 458 | |
| 459 | valStr := fmt.Sprint(instanceMap[instancekey]) |
| 460 | return valStr, nil |
| 461 | } |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 462 | |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 463 | func (rh *Resthook) GetAllPolicyInstance(policyTypeId models.PolicyTypeID) ([]models.PolicyInstanceID, error) { |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 464 | a1.Logger.Debug("GetAllPolicyInstance") |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 465 | var policyTypeInstances = []models.PolicyInstanceID{} |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 466 | |
| 467 | keys, err := rh.db.GetAll("A1m_ns") |
| 468 | |
| 469 | if err != nil { |
| 470 | a1.Logger.Error("error in retrieving policy. err: %v", err) |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 471 | return policyTypeInstances, err |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 472 | } |
| 473 | a1.Logger.Debug("keys : %+v", keys) |
| 474 | typekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." |
naman.gupta | 44f5c8a | 2022-05-25 23:31:47 +0530 | [diff] [blame] | 475 | |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 476 | for _, key := range keys { |
| 477 | if strings.HasPrefix(strings.TrimLeft(key, " "), typekey) { |
| 478 | pti := strings.Split(strings.Trim(key, " "), typekey)[1] |
| 479 | a1.Logger.Debug("pti %+v", pti) |
| 480 | policyTypeInstances = append(policyTypeInstances, models.PolicyInstanceID(pti)) |
| 481 | } |
| 482 | } |
| 483 | |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 484 | if len(policyTypeInstances) == 0 { |
naman.gupta | 44f5c8a | 2022-05-25 23:31:47 +0530 | [diff] [blame] | 485 | a1.Logger.Debug("policy instance Not Present ") |
| 486 | } |
| 487 | |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 488 | a1.Logger.Debug("return : %+v", policyTypeInstances) |
Naman Gupta/Single vRAN Call Control /SRI-Bangalore/Engineer/Samsung Electronics | 584d755 | 2022-09-27 10:32:15 +0530 | [diff] [blame] | 489 | return policyTypeInstances, nil |
naman.gupta | 05a0f58 | 2022-05-05 15:59:51 +0530 | [diff] [blame] | 490 | } |
naman.gupta | b513650 | 2022-10-18 00:25:14 +0530 | [diff] [blame] | 491 | |
| 492 | func (rh *Resthook) DeletePolicyType(policyTypeId models.PolicyTypeID) error { |
| 493 | a1.Logger.Debug("DeletePolicyType") |
| 494 | |
| 495 | policyinstances, err := rh.GetAllPolicyInstance(policyTypeId) |
| 496 | if err != nil { |
| 497 | a1.Logger.Error("error in retrieving policy. err: %v", err) |
| 498 | return err |
| 499 | } |
| 500 | |
| 501 | var keys [1]string |
| 502 | key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10) |
| 503 | keys[0] = key |
| 504 | if len(policyinstances) == 0 { |
| 505 | err := rh.db.Remove(a1MediatorNs, keys[:]) |
| 506 | if err != nil { |
| 507 | a1.Logger.Error("error in deleting policy type err: %v", err) |
| 508 | return err |
| 509 | } |
| 510 | } else { |
| 511 | a1.Logger.Error("tried to delete a type that isn't empty") |
| 512 | return policyTypeCanNotBeDeletedError |
| 513 | } |
| 514 | return nil |
| 515 | } |
naman.gupta | dd7944b | 2022-10-26 14:38:04 +0530 | [diff] [blame] | 516 | |
| 517 | func (rh *Resthook) typeValidity(policyTypeId models.PolicyTypeID) error { |
| 518 | var keys [1]string |
| 519 | |
| 520 | typekey := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10) |
| 521 | keys[0] = typekey |
| 522 | |
| 523 | a1.Logger.Debug("key1 : %+v", typekey) |
| 524 | valmap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 525 | if err != nil { |
| 526 | a1.Logger.Error("error in retrieving policytype err: %v", err) |
| 527 | return err |
| 528 | } |
| 529 | if len(valmap) == 0 { |
| 530 | a1.Logger.Error("policy type Not Present for policyid : %v", policyTypeId) |
| 531 | return policyTypeNotFoundError |
| 532 | } |
naman.gupta | 9f4fe4d | 2022-12-07 16:18:18 +0530 | [diff] [blame^] | 533 | return nil |
naman.gupta | dd7944b | 2022-10-26 14:38:04 +0530 | [diff] [blame] | 534 | } |
| 535 | |
| 536 | func (rh *Resthook) instanceValidity(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error { |
| 537 | err := rh.typeValidity(policyTypeId) |
| 538 | if err != nil { |
| 539 | return err |
| 540 | } |
| 541 | policyTypeInstances, err := rh.GetPolicyInstance(policyTypeId, policyInstanceID) |
| 542 | if err != nil { |
| 543 | a1.Logger.Error("policy instance error : %v", err) |
| 544 | return err |
| 545 | } |
| 546 | if len(policyTypeInstances.(string)) == 0 { |
| 547 | a1.Logger.Debug("policy instance Not Present ") |
| 548 | return policyInstanceNotFoundError |
| 549 | } |
naman.gupta | 9f4fe4d | 2022-12-07 16:18:18 +0530 | [diff] [blame^] | 550 | return nil |
naman.gupta | dd7944b | 2022-10-26 14:38:04 +0530 | [diff] [blame] | 551 | } |
| 552 | |
| 553 | func (rh *Resthook) getMetaData(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (map[string]interface{}, error) { |
| 554 | instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 555 | a1.Logger.Debug("instanceMetadata key : %+v", instanceMetadataKey) |
| 556 | var keys [1]string |
| 557 | keys[0] = instanceMetadataKey |
| 558 | instanceMetadataMap, err := rh.db.Get(a1MediatorNs, keys[:]) |
| 559 | if err != nil { |
| 560 | a1.Logger.Error("policy instance error : %v", err) |
| 561 | } |
| 562 | a1.Logger.Debug("instanceMetadata map : %+v", instanceMetadataMap) |
| 563 | if instanceMetadataMap[instanceMetadataKey] == nil { |
| 564 | a1.Logger.Error("policy instance Not Present for policyinstaneid : %v", policyInstanceID) |
| 565 | return map[string]interface{}{}, policyInstanceNotFoundError |
| 566 | } |
| 567 | return instanceMetadataMap, nil |
| 568 | } |
| 569 | |
| 570 | func (rh *Resthook) GetPolicyInstanceStatus(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) (*a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody, error) { |
| 571 | err := rh.instanceValidity(policyTypeId, policyInstanceID) |
naman.gupta | 9f4fe4d | 2022-12-07 16:18:18 +0530 | [diff] [blame^] | 572 | policyInstanceStatus := a1_mediator.A1ControllerGetPolicyInstanceStatusOKBody{} |
naman.gupta | dd7944b | 2022-10-26 14:38:04 +0530 | [diff] [blame] | 573 | if err != nil && err == policyInstanceNotFoundError || err == policyTypeNotFoundError { |
| 574 | policyInstanceStatus.InstanceStatus = "NOT IN EFFECT" |
| 575 | return &policyInstanceStatus, err |
| 576 | } |
naman.gupta | dd7944b | 2022-10-26 14:38:04 +0530 | [diff] [blame] | 577 | metadata, err := rh.getMetaData(policyTypeId, policyInstanceID) |
| 578 | a1.Logger.Debug(" metadata %v", metadata) |
| 579 | if err != nil { |
| 580 | a1.Logger.Error("policy instance error : %v", err) |
| 581 | policyInstanceStatus.InstanceStatus = "NOT IN EFFECT" |
| 582 | return &policyInstanceStatus, err |
| 583 | } |
| 584 | jsonbody, err := json.Marshal(metadata) |
| 585 | if err != nil { |
| 586 | a1.Logger.Error("marshal error : %v", err) |
| 587 | return &policyInstanceStatus, err |
| 588 | } |
| 589 | |
| 590 | if err := json.Unmarshal(jsonbody, &policyInstanceStatus); err != nil { |
| 591 | a1.Logger.Error("unmarshal error : %v", err) |
| 592 | //this error maps to 503 error but can be mapped to 500: internal error |
| 593 | return &policyInstanceStatus, err |
| 594 | } |
| 595 | if policyInstanceStatus.HasBeenDeleted == false { |
| 596 | policyInstanceStatus.InstanceStatus = "IN EFFECT" |
| 597 | } else { |
| 598 | policyInstanceStatus.InstanceStatus = "NOT IN EFFECT" |
| 599 | } |
| 600 | return &policyInstanceStatus, nil |
| 601 | } |
naman.gupta | 52ef1de | 2022-11-02 21:45:05 +0530 | [diff] [blame] | 602 | |
| 603 | func (rh *Resthook) storeDeletedPolicyInstanceMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID, creation_timestamp string) error { |
| 604 | deleted_timestamp := time.Now() |
| 605 | |
| 606 | instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 607 | |
| 608 | a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey) |
| 609 | |
| 610 | var metadatajson interface{} |
| 611 | metadatajson = map[string]string{"created_at": creation_timestamp, "has_been_deleted": "True", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05")} |
| 612 | a1.Logger.Debug("metadatajson to create : %+v", metadatajson) |
| 613 | deletedmetadata, err := json.Marshal(metadatajson) |
| 614 | |
| 615 | a1.Logger.Debug("policyinstanceMetaData to create : %+v", string(deletedmetadata)) |
| 616 | |
| 617 | err = rh.db.Set(a1MediatorNs, instanceMetadataKey, string(deletedmetadata)) |
| 618 | a1.Logger.Debug("deletemetadatacreated") |
| 619 | if err != nil { |
| 620 | a1.Logger.Error("error :%+v", err) |
| 621 | return err |
| 622 | } |
| 623 | |
| 624 | a1.Logger.Error("Policy Instance Meta Data deleted at :%+v", creation_timestamp) |
| 625 | |
| 626 | return nil |
| 627 | } |
| 628 | |
| 629 | func (rh *Resthook) deleteInstancedata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error { |
| 630 | var keys [1]string |
| 631 | instancekey := a1InstancePrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 632 | keys[0] = instancekey |
| 633 | err := rh.db.Remove(a1MediatorNs, keys[:]) |
| 634 | if err != nil { |
| 635 | a1.Logger.Error("error in deleting policy type err: %v", err) |
| 636 | return err |
| 637 | } |
| 638 | return nil |
| 639 | } |
| 640 | |
| 641 | func (rh *Resthook) deleteMetadata(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error { |
| 642 | var keys [1]string |
| 643 | instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 644 | |
| 645 | a1.Logger.Debug("instanceMetadata Key : %+v", instanceMetadataKey) |
| 646 | keys[0] = instanceMetadataKey |
| 647 | err := rh.db.Remove(a1MediatorNs, keys[:]) |
| 648 | if err != nil { |
| 649 | a1.Logger.Error("error in deleting policy metadata err: %v", err) |
| 650 | return err |
| 651 | } |
| 652 | return nil |
| 653 | } |
| 654 | |
| 655 | func (rh *Resthook) DeletePolicyInstance(policyTypeId models.PolicyTypeID, policyInstanceID models.PolicyInstanceID) error { |
| 656 | err := rh.instanceValidity(policyTypeId, policyInstanceID) |
| 657 | if err != nil { |
| 658 | a1.Logger.Error("policy instance error : %v", err) |
| 659 | if err == policyInstanceNotFoundError || err == policyTypeNotFoundError { |
| 660 | return err |
| 661 | } |
| 662 | } |
| 663 | |
| 664 | createdmetadata, err := rh.getMetaData(policyTypeId, policyInstanceID) |
| 665 | if err != nil { |
| 666 | a1.Logger.Error("error : %v", err) |
| 667 | return err |
| 668 | } |
| 669 | a1.Logger.Debug(" created metadata %v", createdmetadata) |
| 670 | instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID) |
| 671 | creation_metadata := createdmetadata[instanceMetadataKey] |
| 672 | var metadata map[string]interface{} |
| 673 | if err = json.Unmarshal([]byte(creation_metadata.(string)), &metadata); err != nil { |
| 674 | a1.Logger.Error("unmarshal error : %v", err) |
| 675 | return err |
| 676 | } |
| 677 | |
| 678 | a1.Logger.Debug(" created metadata created_at %v", metadata["created_at"]) |
| 679 | creation_timestamp := metadata["created_at"] |
| 680 | |
| 681 | rh.deleteMetadata(policyTypeId, policyInstanceID) |
| 682 | |
| 683 | rh.deleteInstancedata(policyTypeId, policyInstanceID) |
| 684 | |
| 685 | rh.storeDeletedPolicyInstanceMetadata(policyTypeId, policyInstanceID, creation_timestamp.(string)) |
| 686 | |
| 687 | message := rmr.Message{} |
naman.gupta | 521fb55 | 2022-12-01 18:49:35 +0530 | [diff] [blame] | 688 | rmrMessage, err1 := message.PolicyMessage(strconv.FormatInt((int64(policyTypeId)), 10), string(policyInstanceID), "", "DELETE") |
| 689 | if err1 != nil { |
| 690 | a1.Logger.Error("error : %v", err1) |
| 691 | return err1 |
naman.gupta | 52ef1de | 2022-11-02 21:45:05 +0530 | [diff] [blame] | 692 | } |
naman.gupta | 159ddb7 | 2022-11-08 19:52:05 +0530 | [diff] [blame] | 693 | isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1PolicyRequest) |
naman.gupta | 52ef1de | 2022-11-02 21:45:05 +0530 | [diff] [blame] | 694 | if isSent { |
| 695 | a1.Logger.Debug("rmrSendToXapp : message sent") |
| 696 | } else { |
| 697 | //TODO:if message not sent need to return error or just log it or retry sending |
| 698 | a1.Logger.Error("rmrSendToXapp : message not sent") |
| 699 | } |
| 700 | |
| 701 | return nil |
| 702 | } |
naman.gupta | 159ddb7 | 2022-11-08 19:52:05 +0530 | [diff] [blame] | 703 | |
| 704 | func (rh *Resthook) DataDelivery(httpBody interface{}) error { |
| 705 | a1.Logger.Debug("httpbody : %+v", httpBody) |
| 706 | mymap := httpBody.(map[string]interface{}) |
| 707 | message := rmr.Message{} |
| 708 | rmrMessage, err := message.A1EIMessage(mymap["job"].(string), mymap["payload"].(string)) |
| 709 | if err != nil { |
| 710 | a1.Logger.Error("error : %v", err) |
| 711 | return err |
| 712 | } |
| 713 | a1.Logger.Debug("rmrSendToXapp :rmrMessage %+v", rmrMessage) |
| 714 | isSent := rh.iRmrSenderInst.RmrSendToXapp(rmrMessage, a1EIDataDelivery) |
| 715 | if isSent { |
| 716 | a1.Logger.Debug("rmrSendToXapp : message sent") |
| 717 | } else { |
| 718 | a1.Logger.Error("rmrSendToXapp : message not sent") |
| 719 | } |
| 720 | return nil |
| 721 | } |