Update README, etc 16/2816/3
authorMohamed Abukar <abukar.mohamed@nokia.com>
Tue, 17 Mar 2020 07:31:55 +0000 (09:31 +0200)
committerMohamed Abukar <abukar.mohamed@nokia.com>
Tue, 17 Mar 2020 08:55:47 +0000 (10:55 +0200)
Change-Id: I599678d05a66d3f2ddf11ebbcd632931106ffc23
Signed-off-by: Mohamed Abukar <abukar.mohamed@nokia.com>
README.md
adapter/cmd/adapter.go
adapter/container-tag.yaml
alarm/alarm.go
alarm/alarm_test.go

index 5e42c3d..a9d1595 100755 (executable)
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Architecture
 
 The **Alarm Library** provides a simple interface for RIC applications (both platform application and xApps) to raise, clear and re-raise. The **Alarm Library** interacts with the **Alarm Adapter** via RMR interface.
 
-The **Alarm Adapter** is reponsible for managing alarm situations in RIC cluster and interfacing with **Northboubd** applications such as **Prometheus AlertManager** to pass the alarms.
+The **Alarm Adapter** is responsible for managing alarm situations in RIC cluster and interfacing with **Northboubd** applications such as **Prometheus AlertManager** to post the alarms as alerts. AlertManager takes care of deduplicating, silencing and inhibition (suppressing) of alerts, and routing them to the VESAgent, which, in turn, takes care of converting alerts to fault and send to ONAP as VES events.
 
 Overview for Alarm Adapter
 --------------------------
@@ -34,12 +34,19 @@ The Alarm object contains following parameters:
  * *AdditionalInfo*: Additional information given by the application
  * *IdentifyingInfo*: Identifying additional information, which is part of alarm identity
 
+ *ManagedObjectId* (mo), *SpecificProblem* (sp), *ApplicationId* (ap) and *IdentifyingInfo* (IdentifyingInfo) make up the identity of the alarm. All parameters must be according to the alarm definition, i.e. all mandatory parameters should be present, and parameters should have correct value type or be from some predefined range. Addressing the same alarm instance in a clear() or reraise() call is done by making sure that all four values are the same is in the original raise / reraise call. 
+
 ## Alarm APIs
 * *Raise*: Raises the alarm instance given as a parameter
 * *Clear*: Clears the alarm instance given as a parameter, if it the alarm active
 * *Reraise*: Attempts to re-raise the alarm instance given as a parameter
 * *ClearAll*: Clears all alarms matching moId and appId given as parameters
 
+## Aux. Alarm APIs
+* *SetManagedObjectId*: Sets the default MOId
+* *SetApplicationId*: Sets the default AppId
+
+
 ## Example
 -------
 
@@ -67,7 +74,7 @@ func main() {
        err := alarmer.Reraise(alarm)
 
        // Clear all alarms raised by the application
-       err := alarmer.Reraise()
+       err := alarmer.ClearAll()
 }
 ```
 
index 73b6882..fb9e85d 100755 (executable)
@@ -23,8 +23,8 @@ package main
 import (
        "encoding/json"
        "fmt"
-       "time"
        "sync"
+       "time"
 
        clientruntime "github.com/go-openapi/runtime/client"
        "github.com/go-openapi/strfmt"
@@ -37,14 +37,22 @@ import (
        app "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 )
 
+type AlertStatus string
+
+const (
+       AlertStatusActive   = "active"
+       AlertStatusResolved = "resolved"
+)
+
 type AlarmAdapter struct {
        amHost        string
        amBaseUrl     string
        amSchemes     []string
        alertInterval int
        activeAlarms  []alarm.Alarm
-       mutex             sync.Mutex
+       mutex         sync.Mutex
        rmrReady      bool
+       postClear     bool
 }
 
 var Version string
@@ -84,6 +92,7 @@ func (a *AlarmAdapter) Run(sdlcheck bool) {
        app.Resource.InjectRoute("/ric/v1/alarms", a.ClearAlarm, "DELETE")
 
        // Start background timer for re-raising alerts
+       a.postClear = sdlcheck
        go a.StartAlertTimer()
 
        app.RunWithParams(a, sdlcheck)
@@ -95,7 +104,7 @@ func (a *AlarmAdapter) StartAlertTimer() {
                a.mutex.Lock()
                for _, m := range a.activeAlarms {
                        app.Logger.Info("Re-raising alarm: %v", m)
-                       a.PostAlert(a.GenerateAlertLabels(m))
+                       a.PostAlert(a.GenerateAlertLabels(m, AlertStatusActive))
                }
                a.mutex.Unlock()
        }
@@ -140,16 +149,19 @@ func (a *AlarmAdapter) HandleAlarms(rp *app.RMRParams) (*alert.PostAlertsOK, err
                if found {
                        a.activeAlarms = a.RemoveAlarm(a.activeAlarms, idx)
                        app.Logger.Info("Active alarm cleared!")
-               } else {
-                       app.Logger.Info("No matching alarm found, ignoring!")
+
+                       if a.postClear {
+                               return a.PostAlert(a.GenerateAlertLabels(m.Alarm, AlertStatusResolved))
+                       }
                }
+               app.Logger.Info("No matching alarm found, ignoring!")
                return nil, nil
        }
 
        // New alarm -> update active alarms and post to Alert Manager
        if m.AlarmAction == alarm.AlarmActionRaise {
                a.UpdateActiveAlarms(m.Alarm)
-               return a.PostAlert(a.GenerateAlertLabels(m.Alarm))
+               return a.PostAlert(a.GenerateAlertLabels(m.Alarm, AlertStatusActive))
        }
 
        return nil, nil
@@ -181,9 +193,10 @@ func (a *AlarmAdapter) UpdateActiveAlarms(newAlarm alarm.Alarm) {
        a.activeAlarms = append(a.activeAlarms, newAlarm)
 }
 
-func (a *AlarmAdapter) GenerateAlertLabels(newAlarm alarm.Alarm) (models.LabelSet, models.LabelSet) {
+func (a *AlarmAdapter) GenerateAlertLabels(newAlarm alarm.Alarm, status AlertStatus) (models.LabelSet, models.LabelSet) {
        alarmDef := alarm.RICAlarmDefinitions[newAlarm.SpecificProblem]
        amLabels := models.LabelSet{
+               "status":      string(status),
                "alertname":   alarmDef.AlarmText,
                "severity":    string(newAlarm.PerceivedSeverity),
                "service":     fmt.Sprintf("%s:%s", newAlarm.ManagedObjectId, newAlarm.ApplicationId),
index 3308c36..2af355a 100644 (file)
@@ -2,4 +2,4 @@
 # By default this file is in the docker build directory,
 # but the location can configured in the JJB template.
 ---
-tag: 0.4.1
+tag: 0.4.3
index e0bd93b..3291621 100755 (executable)
@@ -72,6 +72,14 @@ func (r *RICAlarm) NewAlarmMessage(a Alarm, alarmAction AlarmAction) AlarmMessag
        return AlarmMessage{a, alarmAction, alarmTime}
 }
 
+func (r *RICAlarm) SetManagedObjectId(mo string) {
+       r.moId = mo
+}
+
+func (r *RICAlarm) SetApplicationId(app string) {
+       r.appId = app
+}
+
 // Raise a RIC alarm
 func (r *RICAlarm) Raise(a Alarm) error {
        r.mutex.Lock()
index d5eb740..ab5953c 100755 (executable)
@@ -84,3 +84,17 @@ func TestAlarmSendSuccess(t *testing.T) {
        err := alarmer.Raise(a)
        assert.Nil(t, err, "send failed")
 }
+
+func TestSetManagedObjectIdSuccess(t *testing.T) {
+       alarmer.SetManagedObjectId("new-pod")
+
+       a := alarmer.NewAlarm(1234, alarm.SeverityMajor, "Some App data", "eth 0 1")
+       assert.Equal(t, a.ManagedObjectId, "new-pod")
+}
+
+func TestSetApplicationIdSuccess(t *testing.T) {
+       alarmer.SetApplicationId("new-app")
+
+       a := alarmer.NewAlarm(1234, alarm.SeverityMajor, "Some App data", "eth 0 1")
+       assert.Equal(t, a.ApplicationId, "new-app")
+}