LN0739_FM_FR12: support for options to dynamically create the AlarmDefinitions
[ric-plt/alarm-go.git] / manager / cmd / restapi.go
1 /*
2  *  Copyright (c) 2020 AT&T Intellectual Property.
3  *  Copyright (c) 2020 Nokia.
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 main
22
23 import (
24         "encoding/json"
25         "gerrit.o-ran-sc.org/r/ric-plt/alarm-go/alarm"
26         app "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
27         "github.com/gorilla/mux"
28         "net/http"
29         "strconv"
30         "time"
31 )
32
33 func (a *AlarmManager) respondWithError(w http.ResponseWriter, code int, message string) {
34         a.respondWithJSON(w, code, map[string]string{"error": message})
35 }
36
37 func (a *AlarmManager) respondWithJSON(w http.ResponseWriter, code int, payload interface{}) {
38         w.Header().Set("Content-Type", "application/json")
39         w.WriteHeader(code)
40         if payload != nil {
41                 response, _ := json.Marshal(payload)
42                 w.Write(response)
43         }
44 }
45
46 func (a *AlarmManager) GetActiveAlarms(w http.ResponseWriter, r *http.Request) {
47         app.Logger.Info("GetActiveAlarms: %+v", a.activeAlarms)
48         a.respondWithJSON(w, http.StatusOK, a.activeAlarms)
49 }
50
51 func (a *AlarmManager) GetAlarmHistory(w http.ResponseWriter, r *http.Request) {
52         app.Logger.Info("GetAlarmHistory: %+v", a.alarmHistory)
53         a.respondWithJSON(w, http.StatusOK, a.alarmHistory)
54 }
55
56 func (a *AlarmManager) RaiseAlarm(w http.ResponseWriter, r *http.Request) {
57         if err := a.doAction(w, r, true); err != nil {
58                 a.respondWithJSON(w, http.StatusOK, err)
59         }
60 }
61
62 func (a *AlarmManager) ClearAlarm(w http.ResponseWriter, r *http.Request) {
63         if err := a.doAction(w, r, false); err != nil {
64                 a.respondWithJSON(w, http.StatusOK, err)
65         }
66 }
67
68 func (a *AlarmManager) SetAlarmDefinition(w http.ResponseWriter, r *http.Request) {
69
70         app.Logger.Debug("POST arrived for creating alarm definition ")
71         /* If body is nil then return error */
72         if r.Body == nil {
73                 app.Logger.Error("POST - body is empty")
74                 a.respondWithError(w, http.StatusBadRequest, "No data in request body.")
75                 return
76         }
77         defer r.Body.Close()
78
79         /* Parameters are available. Check if they are valid */
80         var alarmDefinitions RicAlarmDefinitions
81         err := json.NewDecoder(r.Body).Decode(&alarmDefinitions)
82         if err != nil {
83                 app.Logger.Error("POST - received alarm definition  parameters are invalid - " + err.Error())
84                 a.respondWithError(w, http.StatusBadRequest, "Invalid data in request body.")
85                 return
86         }
87
88         for _, alarmDefinition := range alarmDefinitions.AlarmDefinitions {
89                 _, exists := alarm.RICAlarmDefinitions[alarmDefinition.AlarmId]
90                 if exists {
91                         app.Logger.Error("POST - alarm definition already exists for %v", alarmDefinition.AlarmId)
92                 } else {
93                         ricAlarmDefintion := new(alarm.AlarmDefinition)
94                         ricAlarmDefintion.AlarmId = alarmDefinition.AlarmId
95                         ricAlarmDefintion.AlarmText = alarmDefinition.AlarmText
96                         ricAlarmDefintion.EventType = alarmDefinition.EventType
97                         ricAlarmDefintion.OperationInstructions = alarmDefinition.OperationInstructions
98                         alarm.RICAlarmDefinitions[alarmDefinition.AlarmId] = ricAlarmDefintion
99                 }
100         }
101
102         a.respondWithJSON(w, http.StatusOK, nil)
103         return
104 }
105
106 func (a *AlarmManager) DeleteAlarmDefinition(w http.ResponseWriter, r *http.Request) {
107         pathParams := mux.Vars(r)
108         alarmId, alarmIdok := pathParams["alarmId"]
109         if alarmIdok {
110                 if ialarmId, err := strconv.Atoi(alarmId); err == nil {
111                         delete(alarm.RICAlarmDefinitions, ialarmId)
112                 } else {
113                         app.Logger.Error("DELETE - alarmId string to int conversion failed %v", alarmId)
114                         a.respondWithError(w, http.StatusBadRequest, "Invalid path parameter")
115                         return
116                 }
117         } else {
118                 app.Logger.Error("DELETE - alarmId does not exist %v", alarmId)
119                 a.respondWithError(w, http.StatusBadRequest, "Invalid path parameter")
120                 return
121
122         }
123 }
124
125 func (a *AlarmManager) GetAlarmDefinition(w http.ResponseWriter, r *http.Request) {
126         var ricAlarmDefinitions RicAlarmDefinitions
127         pathParams := mux.Vars(r)
128         alarmId, alarmIdok := pathParams["alarmId"]
129         if alarmIdok {
130                 if ialarmId, err := strconv.Atoi(alarmId); err == nil {
131                         alarmDefinition, ok := alarm.RICAlarmDefinitions[ialarmId]
132                         if ok {
133                                 app.Logger.Debug("Successfully returned alarm defintion for alarm id %v", ialarmId)
134                                 a.respondWithJSON(w, http.StatusOK, alarmDefinition)
135                                 return
136
137                         } else {
138                                 app.Logger.Error("Requested alarm id not found %v", ialarmId)
139                                 a.respondWithError(w, http.StatusBadRequest, "Non existent alarmId")
140                                 return
141                         }
142                 } else {
143                         app.Logger.Error("alarmId string to int conversion failed %v", alarmId)
144                         a.respondWithError(w, http.StatusBadRequest, "Invalid alarmId")
145                         return
146                 }
147         } else {
148                 app.Logger.Debug("GET arrived for all alarm definitions ")
149                 for _, alarmDefinition := range alarm.RICAlarmDefinitions {
150                         ricAlarmDefinitions.AlarmDefinitions = append(ricAlarmDefinitions.AlarmDefinitions, alarmDefinition)
151                 }
152                 app.Logger.Debug("Successfully returned all alarm definitions")
153                 a.respondWithJSON(w, http.StatusOK, ricAlarmDefinitions)
154         }
155 }
156
157 func (a *AlarmManager) doAction(w http.ResponseWriter, r *http.Request, isRaiseAlarm bool) error {
158         app.Logger.Info("doAction: request received = %t", isRaiseAlarm)
159
160         if r.Body == nil {
161                 app.Logger.Error("Error: Invalid message body!")
162                 return nil
163         }
164         defer r.Body.Close()
165
166         var m alarm.AlarmMessage
167         if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
168                 app.Logger.Error("json.NewDecoder failed: %v", err)
169                 return err
170         }
171
172         if m.Alarm.ManagedObjectId == "" || m.Alarm.ApplicationId == "" || m.AlarmAction == "" {
173                 app.Logger.Error("Error: Mandatory parameters missing!")
174                 return nil
175         }
176
177         if m.AlarmTime == 0 {
178                 m.AlarmTime = time.Now().UnixNano()
179         }
180
181         _, err := a.ProcessAlarm(&m)
182         return err
183 }
184
185 func (a *AlarmManager) HandleViaRmr(d alarm.Alarm, isRaiseAlarm bool) error {
186         alarmClient, err := alarm.InitAlarm(d.ManagedObjectId, d.ApplicationId)
187         if err != nil {
188                 app.Logger.Error("json.NewDecoder failed: %v", err)
189                 return err
190         }
191
192         alarmData := alarmClient.NewAlarm(d.SpecificProblem, d.PerceivedSeverity, d.AdditionalInfo, d.IdentifyingInfo)
193         if isRaiseAlarm {
194                 alarmClient.Raise(alarmData)
195         } else {
196                 alarmClient.Clear(alarmData)
197         }
198
199         return nil
200 }
201
202 func (a *AlarmManager) SetAlarmConfig(w http.ResponseWriter, r *http.Request) {
203         var m alarm.AlarmConfigParams
204         if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
205                 app.Logger.Error("json.NewDecoder failed: %v", err)
206         } else {
207                 a.maxActiveAlarms = m.MaxActiveAlarms
208                 a.maxAlarmHistory = m.MaxAlarmHistory
209                 app.Logger.Debug("new maxActiveAlarms = %v", a.maxActiveAlarms)
210                 app.Logger.Debug("new maxAlarmHistory = %v", a.maxAlarmHistory)
211                 a.respondWithJSON(w, http.StatusOK, err)
212         }
213 }
214
215 func (a *AlarmManager) GetAlarmConfig(w http.ResponseWriter, r *http.Request) {
216         var m alarm.AlarmConfigParams
217
218         m.MaxActiveAlarms = a.maxActiveAlarms
219         m.MaxAlarmHistory = a.maxAlarmHistory
220
221         a.respondWithJSON(w, http.StatusOK, m)
222         return
223 }