b2ae40a04a627f824174a4bdd21b3d2203bb8219
[it/test.git] / ric_robot_suite / xapp / src / robot-xapp.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
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 */
18 package main
19
20 import "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
21 import "encoding/json"
22 import "strconv"
23        
24
25 type robotPolicy struct {
26   Message string  `json:"message"`
27 }
28
29 type A1Policy struct {
30   Operation  string       `json:"operation"`
31   Type       int          `json:"policy_type_id"`
32   Instance   string       `json:"policy_instance_id"`
33   Payload    robotPolicy  `json:"payload"`
34 }
35
36 type A1Response struct {
37   Type       int          `json:"policy_type_id"`
38   Instance   string       `json:"policy_instance_id"`
39   Handler    string       `json:"handler_id"`
40   Status     string       `json:"status"`
41 }
42
43 type robotXApp struct {
44   metrics map[string]xapp.Counter  
45 }
46
47 func sdlKey(t int, i string) (key string) {
48   return strconv.Itoa(t) +"|"+ i
49 }
50
51 func (r robotXApp) SendA1Response (t int, i string, handler string, status string)  {
52   /* A1_POLICY_RESP, _ := xapp.Rmr.GetRicMessageId("A1_POLICY_RESP") */
53   A1_POLICY_RESP := 20011
54   msg, _ := json.Marshal(A1Response {
55                                       Type: t,
56                                       Instance: i,
57                                       Handler: handler,
58                                       Status: status,
59                                       })
60                                          
61    xapp.Logger.Debug("Outgoing A1 Response %s (length %d)", string(msg), len(msg))
62    /* fixme: check response for errors */
63    xapp.Rmr.SendMsg(&xapp.RMRParams {
64                                     Mtype: A1_POLICY_RESP,
65                                     Payload: msg,
66                                     PayloadLen: len(msg),
67                                     Xid: "",
68                                     SubId: t,
69                                    })
70    r.metrics["MessagesSent"].Inc()
71 }
72
73 func (r robotXApp) CreatePolicy(t int, i string, policy robotPolicy)  {
74   k := sdlKey(t, i)
75   err := xapp.Sdl.Store(k, policy.Message)
76   if err == nil {
77     xapp.Logger.Debug("Created instance %s of policy %d", i, t)
78     r.metrics["PolicyCreates"].Inc()
79     r.metrics["dbStores"].Inc()
80     r.SendA1Response(t, i, "robot", "OK")
81   } else {
82     xapp.Logger.Error("Failed to create DB record for instance %s of policy %d: %v", i, t, err)
83     r.metrics["dbStoreFailures"].Inc()
84     r.SendA1Response(t, i, "robot", "ERROR")
85   }
86 }
87
88 func (r robotXApp) DeletePolicy(t int, i string)  {
89   k := sdlKey(t, i)
90   
91   policies, _  := xapp.Sdl.Read(k)
92   existingPolicy, _ := policies[k]
93
94   if existingPolicy != nil {
95     err := xapp.Sdl.Delete([]string{k})
96     if err == nil {
97       xapp.Logger.Debug("Deleted instance %s of policy %d, old value: %s", i, t, existingPolicy)
98       r.metrics["PolicyDeletes"].Inc()
99       r.metrics["dbDeletes"].Inc()
100       r.SendA1Response(t, i, "robot", "DELETED")
101     } else {
102       xapp.Logger.Error("Failed to delete DB record for instance %s of policy %d: %v", i, t, err)
103       r.metrics["dbDeleteFailures"].Inc()
104       r.SendA1Response(t, i, "robot", "ERROR")
105     }
106   } else {
107     xapp.Logger.Error("Attempt to delete nonexistent instance %s of policy %d", i, t)
108     r.metrics["NonexistentPolicyDeletes"].Inc()
109     r.SendA1Response(t, i, "robot", "ERROR")
110   }  
111 }
112
113 func (r robotXApp) Consume(msg *xapp.RMRParams) (err error) {
114   /* this is returning 0.  will investigate and fix someday. */
115   /* A1_POLICY_REQ, _ := xapp.Rmr.GetRicMessageId("A1_POLICY_REQ") */
116   A1_POLICY_REQ := 20010
117
118   xapp.Logger.Debug("Message received - type=%d, Src=%s (%s), payload=%s",
119                     msg.Mtype, xapp.Rmr.GetRicMessageName(msg.Mtype), msg.Src, string(msg.Payload))
120
121   /* this is bogus right now, but we'll eventually support more than one message
122      also, xapps really should handle messages in a separate goroutine, but there's 
123      no real need in this one as we're not latency bound */
124   if msg.Mtype == A1_POLICY_REQ {
125     var a1Msg A1Policy
126     err := json.Unmarshal(msg.Payload, &a1Msg)
127     
128     xapp.Logger.Debug("... Policy request - err=%v|op=%s|type=%d|instance=%s",
129                       err, a1Msg.Operation, a1Msg.Type, a1Msg.Instance)
130     switch a1Msg.Operation {
131     case "CREATE":
132       go r.CreatePolicy(a1Msg.Type, a1Msg.Instance, a1Msg.Payload)
133     case "DELETE":
134       go r.DeletePolicy(a1Msg.Type, a1Msg.Instance)
135     }
136   }
137   return nil
138 }
139
140 func main() {
141   counters := []xapp.CounterOpts {
142     { Name: "PolicyCreates", Help: "A1 policies created" },
143     { Name: "DuplicatePolicyCreates",
144       Help: "A1 CREATE requests received for existing policy instances" },
145     { Name: "PolicyUpdates", Help: "A1 policies updateded" },
146     { Name: "NonexistentPolicyUpdates",
147       Help: "A1 UPDATE requests received for nonexistent policy instances" },
148     { Name: "PolicyDeletes", Help: "A1 policies deleted" },
149     { Name: "NonexistentPolicyDeletes",
150       Help: "A1 DELETE requests received for nonexistent policy instances" },
151     { Name: "dbStores",
152       Help: "SDL store requests" },
153     { Name: "dbStoreFailures",
154       Help: "SDL store request failures" },
155     { Name: "dbDeletes",
156       Help: "SDL delete requests" },
157     { Name: "dbDeleteFailures",
158       Help: "SDL delete request failures" },
159     { Name: "MessagesReceived",
160       Help: "Total RMR messages received" },
161     { Name: "MessagesSent",
162       Help: "Total RMR messages sent" },
163   }
164   xapp.Run(robotXApp{ metrics: xapp.Metric.RegisterCounterGroup(counters, "robotXApp")})
165 }