13 "gerrit.o-ran-sc.org/r/ric-plt/alarm-go/alarm"
14 "github.com/jedib0t/go-pretty/table"
15 "github.com/thatisuday/commando"
19 type CliAlarmDefinitions struct {
20 AlarmDefinitions []*alarm.AlarmDefinition `json:"alarmdefinitions"`
23 type AlarmClient struct {
24 alarmer *alarm.RICAlarm
27 type RicPerfAlarmObjects struct {
28 AlarmObjects []*alarm.Alarm `json:"alarmobjects"`
31 var CLIPerfAlarmObjects map[int]*alarm.Alarm
35 var CliPerfAlarmDefinitions CliAlarmDefinitions
38 Raise string = "RAISE"
39 Clear string = "CLEAR"
41 PeakTestDuration int = 60
42 OneSecondDuration int = 1
49 SetExecutableName("alarm-cli").
51 SetDescription("This CLI tool provides management interface to SEP alarm system")
56 SetShortDescription("Displays the SEP active alarms").
57 SetDescription("This command displays more information about the SEP active alarms").
58 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
59 AddFlag("port", "Alarm manager host address", commando.String, "8080").
60 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
61 displayAlarms(getAlarms(flags, "active"), false)
67 SetShortDescription("Displays the SEP alarm history").
68 SetDescription("This command displays more information about the SEP alarm history").
69 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
70 AddFlag("port", "Alarm manager host address", commando.String, "8080").
71 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
72 displayAlarms(getAlarms(flags, "history"), true)
78 SetShortDescription("Raises alarm with given parameters").
79 AddFlag("moid", "Managed object Id", commando.String, nil).
80 AddFlag("apid", "Application Id", commando.String, nil).
81 AddFlag("sp", "Specific problem Id", commando.Int, nil).
82 AddFlag("severity", "Perceived severity", commando.String, nil).
83 AddFlag("iinfo", "Application identifying info", commando.String, nil).
84 AddFlag("aai", "Application additional info", commando.String, "-").
85 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
86 AddFlag("port", "Alarm manager host address", commando.String, "8080").
87 AddFlag("if", "http or rmr used as interface", commando.String, "http").
88 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
89 postAlarm(flags, readAlarmParams(flags, false), alarm.AlarmActionRaise, nil)
95 SetShortDescription("Raises alarm with given parameters").
96 AddFlag("moid", "Managed object Id", commando.String, nil).
97 AddFlag("apid", "Application Id", commando.String, nil).
98 AddFlag("sp", "Specific problem Id", commando.Int, nil).
99 AddFlag("iinfo", "Application identifying info", commando.String, nil).
100 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
101 AddFlag("port", "Alarm manager host address", commando.String, "8080").
102 AddFlag("if", "http or rmr used as interface", commando.String, "http").
103 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
104 postAlarm(flags, readAlarmParams(flags, true), alarm.AlarmActionClear, nil)
107 // Configure an alarm manager
109 Register("configure").
110 SetShortDescription("Configure alarm manager with given parameters").
111 AddFlag("mal", "max active alarms", commando.Int, nil).
112 AddFlag("mah", "max alarm history", commando.Int, nil).
113 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
114 AddFlag("port", "Alarm manager host address", commando.String, "8080").
115 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
116 postAlarmConfig(flags)
118 // Create alarm definition
121 SetShortDescription("Define alarm with given parameters").
122 AddFlag("aid", "alarm identifier", commando.Int, nil).
123 AddFlag("atx", "alarm text", commando.String, nil).
124 AddFlag("ety", "event type", commando.String, nil).
125 AddFlag("oin", "operation instructions", commando.String, nil).
126 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
127 AddFlag("port", "Alarm manager host address", commando.String, "8080").
128 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
129 postAlarmDefinition(flags)
131 // Delete alarm definition
133 Register("undefine").
134 SetShortDescription("Define alarm with given parameters").
135 AddFlag("aid", "alarm identifier", commando.Int, nil).
136 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
137 AddFlag("port", "Alarm manager host address", commando.String, "8080").
138 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
139 deleteAlarmDefinition(flags)
141 // Conduct performance test for alarm-go
144 SetShortDescription("Conduct performance test with given parameters").
145 AddFlag("prf", "performance profile id", commando.Int, nil).
146 AddFlag("nal", "number of alarms", commando.Int, nil).
147 AddFlag("aps", "alarms per sec", commando.Int, nil).
148 AddFlag("tim", "total time of test", commando.Int, nil).
149 AddFlag("host", "Alarm manager host address", commando.String, "localhost").
150 AddFlag("port", "Alarm manager host address", commando.String, "8080").
151 AddFlag("if", "http or rmr used as interface", commando.String, "http").
152 SetAction(func(args map[string]commando.ArgValue, flags map[string]commando.FlagValue) {
153 conductperformancetest(flags)
156 // parse command-line arguments
160 func readAlarmParams(flags map[string]commando.FlagValue, clear bool) (a alarm.Alarm) {
161 a.ManagedObjectId, _ = flags["moid"].GetString()
162 a.ApplicationId, _ = flags["apid"].GetString()
163 a.SpecificProblem, _ = flags["sp"].GetInt()
164 a.IdentifyingInfo, _ = flags["iinfo"].GetString()
167 s, _ := flags["severity"].GetString()
168 a.PerceivedSeverity = alarm.Severity(s)
172 a.AdditionalInfo, _ = flags["aai"].GetString()
177 func getAlarms(flags map[string]commando.FlagValue, action alarm.AlarmAction) (alarms []alarm.AlarmMessage) {
178 host, _ := flags["host"].GetString()
179 port, _ := flags["port"].GetString()
180 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/%s", host, port, action)
181 resp, err := http.Get(targetUrl)
182 if err != nil || resp == nil || resp.Body == nil {
183 fmt.Println("Couldn't fetch active alarm list due to error: ", err)
187 defer resp.Body.Close()
189 body, err := ioutil.ReadAll(resp.Body)
191 fmt.Println("ioutil.ReadAll failed: ", err)
195 json.Unmarshal([]byte(body), &alarms)
199 func postAlarmWithRmrIf(a alarm.Alarm, action alarm.AlarmAction, alarmClient *AlarmClient) {
200 if alarmClient == nil {
201 alarmClient = NewAlarmClient("my-pod", "my-app")
203 if alarmClient == nil {
207 // Wait until RMR is up-and-running
208 for !alarmClient.alarmer.IsRMRReady() {
209 time.Sleep(100 * time.Millisecond)
212 if action == alarm.AlarmActionRaise {
213 alarmClient.alarmer.Raise(a)
216 if action == alarm.AlarmActionClear {
217 alarmClient.alarmer.Clear(a)
222 func postAlarmWithHttpIf(targetUrl string, a alarm.Alarm, action alarm.AlarmAction) {
223 m := alarm.AlarmMessage{Alarm: a, AlarmAction: action}
224 jsonData, err := json.Marshal(m)
226 fmt.Println("json.Marshal failed: ", err)
230 resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
231 if err != nil || resp == nil {
232 fmt.Println("Couldn't fetch active alarm list due to error: ", err)
237 func postAlarm(flags map[string]commando.FlagValue, a alarm.Alarm, action alarm.AlarmAction, alarmClient *AlarmClient) {
238 // Check the interface to be used for raise or clear the alarm
239 rmr_or_http, _ := flags["if"].GetString()
240 if rmr_or_http == "rmr" {
241 postAlarmWithRmrIf(a, action, alarmClient)
244 host, _ := flags["host"].GetString()
245 port, _ := flags["port"].GetString()
246 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms", host, port)
247 postAlarmWithHttpIf(targetUrl, a, action)
251 func displayAlarms(alarms []alarm.AlarmMessage, isHistory bool) {
252 t := table.NewWriter()
253 t.SetOutputMirror(os.Stdout)
255 t.AppendHeader(table.Row{"SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "ACTION", "TIME"})
257 t.AppendHeader(table.Row{"SP", "MOID", "APPID", "IINFO", "SEVERITY", "AAI", "TIME"})
260 for _, a := range alarms {
261 alarmTime := time.Unix(0, a.AlarmTime).Format("02/01/2006, 15:04:05")
263 t.AppendRows([]table.Row{
264 {a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, a.AlarmAction, alarmTime},
267 t.AppendRows([]table.Row{
268 {a.SpecificProblem, a.ManagedObjectId, a.ApplicationId, a.IdentifyingInfo, a.PerceivedSeverity, a.AdditionalInfo, alarmTime},
273 t.SetStyle(table.StyleColoredBright)
277 func postAlarmConfig(flags map[string]commando.FlagValue) {
278 host, _ := flags["host"].GetString()
279 port, _ := flags["port"].GetString()
280 maxactivealarms, _ := flags["mal"].GetInt()
281 maxalarmhistory, _ := flags["mah"].GetInt()
282 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/config", host, port)
284 m := alarm.AlarmConfigParams{MaxActiveAlarms: maxactivealarms, MaxAlarmHistory: maxalarmhistory}
285 jsonData, err := json.Marshal(m)
287 fmt.Println("json.Marshal failed: ", err)
291 resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
292 if err != nil || resp == nil {
293 fmt.Println("Couldn't fetch post alarm configuration due to error: ", err)
298 func postAlarmDefinition(flags map[string]commando.FlagValue) {
299 host, _ := flags["host"].GetString()
300 port, _ := flags["port"].GetString()
301 alarmid, _ := flags["aid"].GetInt()
302 alarmtxt, _ := flags["atx"].GetString()
303 etype, _ := flags["ety"].GetString()
304 operation, _ := flags["oin"].GetString()
305 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define", host, port)
307 var alarmdefinition alarm.AlarmDefinition
308 alarmdefinition.AlarmId = alarmid
309 alarmdefinition.AlarmText = alarmtxt
310 alarmdefinition.EventType = etype
311 alarmdefinition.OperationInstructions = operation
313 m := CliAlarmDefinitions{AlarmDefinitions: []*alarm.AlarmDefinition{&alarmdefinition}}
314 jsonData, err := json.Marshal(m)
316 fmt.Println("json.Marshal failed: ", err)
320 resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
321 if err != nil || resp == nil {
322 fmt.Println("Couldn't post alarm definition due to error: ", err)
327 func deleteAlarmDefinition(flags map[string]commando.FlagValue) {
328 host, _ := flags["host"].GetString()
329 port, _ := flags["port"].GetString()
330 alarmid, _ := flags["aid"].GetInt()
331 salarmid := strconv.FormatUint(uint64(alarmid), 10)
332 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define/%s", host, port, salarmid)
334 client := &http.Client{}
335 req, err := http.NewRequest("DELETE", targetUrl, nil)
336 if err != nil || req == nil {
337 fmt.Println("Couldn't make delete request due to error: ", err)
340 resp, errr := client.Do(req)
341 if errr != nil || resp == nil {
342 fmt.Println("Couldn't send delete request due to error: ", err)
347 // NewAlarmClient returns a new AlarmClient.
348 func NewAlarmClient(moId, appId string) *AlarmClient {
349 alarmInstance, err := alarm.InitAlarm(moId, appId)
352 alarmer: alarmInstance,
355 fmt.Println("Failed to create alarmInstance", err)
359 // Conduct performance testing
360 func conductperformancetest(flags map[string]commando.FlagValue) {
363 var readobjerror error
364 host, _ := flags["host"].GetString()
365 port, _ := flags["port"].GetString()
366 targetUrl := fmt.Sprintf("http://%s:%s/ric/v1/alarms/define", host, port)
367 readerror = readPerfAlarmDefinitionFromJson()
368 if readerror == nil {
369 senderror = sendPerfAlarmDefinitionToAlarmManager(targetUrl)
370 if senderror == nil {
371 fmt.Println("sent performance alarm definitions to alarm manager")
372 CLIPerfAlarmObjects = make(map[int]*alarm.Alarm)
373 readobjerror = readPerfAlarmObjectFromJson()
374 if readobjerror == nil {
375 profile, _ := flags["prf"].GetInt()
377 fmt.Println("starting peak performance test")
378 peakPerformanceTest(flags)
379 } else if profile == 2 {
380 fmt.Println("starting endurance test")
383 fmt.Println("Unknown profile, received profile = ", profile)
386 fmt.Println("reading performance alarm objects from json file failed ")
389 fmt.Println("sending performance alarm definitions to alarm manager failed ")
393 fmt.Println("reading performance alarm definitions from json file failed ")
398 func peakPerformanceTest(flags map[string]commando.FlagValue) {
399 nalarms, _ := flags["nal"].GetInt()
401 for aid, obj := range CLIPerfAlarmObjects {
403 if count <= nalarms {
404 fmt.Println("peakPerformanceTest: invoking worker routine ", count, aid, *obj)
406 go raiseClearAlarmOnce(obj, flags)
411 fmt.Println("peakPerformanceTest: Waiting for workers to finish")
413 fmt.Println("peakPerformanceTest: Wait completed")
416 func enduranceTest(flags map[string]commando.FlagValue) {
417 alarmspersec, _ := flags["aps"].GetInt()
419 for aid, obj := range CLIPerfAlarmObjects {
421 if count <= alarmspersec {
422 fmt.Println("enduranceTest: invoking worker routine ", count, aid, *obj)
424 go raiseClearAlarmOverPeriod(obj, flags)
429 fmt.Println("enduranceTest: Waiting for workers to finish")
431 fmt.Println("enduranceTest: Wait completed")
434 func readPerfAlarmObjectFromJson() error {
435 filename := os.Getenv("PERF_OBJ_FILE")
436 file, err := ioutil.ReadFile(filename)
438 data := RicPerfAlarmObjects{}
439 err = json.Unmarshal([]byte(file), &data)
441 for _, alarmObject := range data.AlarmObjects {
442 ricAlarmObject := new(alarm.Alarm)
443 ricAlarmObject.ManagedObjectId = alarmObject.ManagedObjectId
444 ricAlarmObject.ApplicationId = alarmObject.ApplicationId
445 ricAlarmObject.SpecificProblem = alarmObject.SpecificProblem
446 ricAlarmObject.PerceivedSeverity = alarmObject.PerceivedSeverity
447 ricAlarmObject.AdditionalInfo = alarmObject.AdditionalInfo
448 ricAlarmObject.IdentifyingInfo = alarmObject.IdentifyingInfo
449 CLIPerfAlarmObjects[alarmObject.SpecificProblem] = ricAlarmObject
452 fmt.Println("readPerfAlarmObjectFromJson: json.Unmarshal failed with error ", err)
456 fmt.Println("readPerfAlarmObjectFromJson: ioutil.ReadFile failed with error ", err)
462 func readPerfAlarmDefinitionFromJson() error {
463 filename := os.Getenv("PERF_DEF_FILE")
464 file, err := ioutil.ReadFile(filename)
466 data := CliAlarmDefinitions{}
467 err = json.Unmarshal([]byte(file), &data)
469 for _, alarmDefinition := range data.AlarmDefinitions {
470 _, exists := alarm.RICAlarmDefinitions[alarmDefinition.AlarmId]
472 fmt.Println("ReadPerfAlarmDefinitionFromJson: alarm definition already exists for ", alarmDefinition.AlarmId)
474 fmt.Println("ReadPerfAlarmDefinitionFromJson: alarm ", alarmDefinition.AlarmId)
475 ricAlarmDefintion := new(alarm.AlarmDefinition)
476 ricAlarmDefintion.AlarmId = alarmDefinition.AlarmId
477 ricAlarmDefintion.AlarmText = alarmDefinition.AlarmText
478 ricAlarmDefintion.EventType = alarmDefinition.EventType
479 ricAlarmDefintion.OperationInstructions = alarmDefinition.OperationInstructions
480 CliPerfAlarmDefinitions.AlarmDefinitions = append(CliPerfAlarmDefinitions.AlarmDefinitions, ricAlarmDefintion)
484 fmt.Println("ReadPerfAlarmDefinitionFromJson: json.Unmarshal failed with error: ", err)
488 fmt.Println("ReadPerfAlarmDefinitionFromJson: ioutil.ReadFile failed with error: ", err)
494 func sendPerfAlarmDefinitionToAlarmManager(targetUrl string) error {
496 jsonData, err := json.Marshal(CliPerfAlarmDefinitions)
498 fmt.Println("sendPerfAlarmDefinitionToAlarmManager: json.Marshal failed: ", err)
502 resp, err := http.Post(targetUrl, "application/json", bytes.NewBuffer(jsonData))
503 if err != nil || resp == nil {
504 fmt.Println("sendPerfAlarmDefinitionToAlarmManager: Couldn't post alarm definition to targeturl due to error: ", targetUrl, err)
510 func wakeUpAfterTime(timeinseconds int, chn chan string, action string) {
511 time.Sleep(time.Second * time.Duration(timeinseconds))
515 func raiseClearAlarmOnce(alarmobject *alarm.Alarm, flags map[string]commando.FlagValue) {
516 var alarmClient *AlarmClient = nil
518 chn := make(chan string, 1)
519 rmr_or_http, _ := flags["if"].GetString()
520 if rmr_or_http == "rmr" {
521 alarmClient = NewAlarmClient("my-pod", "my-app")
523 postAlarm(flags, *alarmobject, alarm.AlarmActionRaise, alarmClient)
524 go wakeUpAfterTime(PeakTestDuration, chn, Clear)
528 postAlarm(flags, *alarmobject, alarm.AlarmActionClear, alarmClient)
529 go wakeUpAfterTime(PeakTestDuration, chn, End)
530 } else if res == End {
536 func raiseClearAlarmOverPeriod(alarmobject *alarm.Alarm, flags map[string]commando.FlagValue) {
537 var alarmClient *AlarmClient = nil
539 timeinminutes, _ := flags["tim"].GetInt()
540 timeinseconds := timeinminutes * 60
541 chn := make(chan string, 1)
542 rmr_or_http, _ := flags["if"].GetString()
543 if rmr_or_http == "rmr" {
544 alarmClient = NewAlarmClient("my-pod", "my-app")
546 postAlarm(flags, *alarmobject, alarm.AlarmActionRaise, alarmClient)
547 go wakeUpAfterTime(OneSecondDuration, chn, Clear)
548 go wakeUpAfterTime(timeinseconds, chn, End)
553 postAlarm(flags, *alarmobject, alarm.AlarmActionRaise, alarmClient)
554 go wakeUpAfterTime(OneSecondDuration, chn, Clear)
555 } else if res == Clear {
556 postAlarm(flags, *alarmobject, alarm.AlarmActionClear, alarmClient)
557 go wakeUpAfterTime(OneSecondDuration, chn, Raise)
558 } else if res == End {