Additions to measurements 05/4905/3
authorMohamed Abukar <abukar.mohamed@nokia.com>
Thu, 22 Oct 2020 16:31:01 +0000 (19:31 +0300)
committerMohamed Abukar <abukar.mohamed@nokia.com>
Thu, 22 Oct 2020 20:04:17 +0000 (23:04 +0300)
Change-Id: Idba0234209e57ed02c93b8aa027f90c6c6d5ddfb
Signed-off-by: Mohamed Abukar <abukar.mohamed@nokia.com>
cmd/vesmgr/config.go
cmd/vesmgr/config_test.go
cmd/vesmgr/vesmgr.go
container-tag.yaml
test/xApp_config_test_output.json

index e6e48d9..b79d19b 100755 (executable)
@@ -23,6 +23,7 @@ package main
 
 import (
        "encoding/json"
+       "fmt"
        "io"
        "io/ioutil"
        "os"
@@ -71,9 +72,9 @@ func basicVespaConf() VESAgentConfiguration {
                        ReportingEntityID:   readSystemUUID(),
                        MaxSize:             2000000,
                        NfNamingCode:        getNFNamingCode(),
-                       NfcNamingCodes: []NfcNamingCode{},
-                       RetryInterval: time.Second * 5,
-                       MaxMissed:     2,
+                       NfcNamingCodes:      []NfcNamingCode{},
+                       RetryInterval:       time.Second * 5,
+                       MaxMissed:           2,
                },
                Measurement: MeasurementConfiguration{
                        // Domain abbreviation has to be set to “Mvfs” for VES 5.3,
@@ -96,10 +97,13 @@ func basicVespaConf() VESAgentConfiguration {
 
 // AppMetricsStruct contains xapplication metrics definition
 type AppMetricsStruct struct {
+       MoId           string
+       MeasType       string
+       MeasId         string
+       MeasInterval   string
        ObjectName     string
        ObjectInstance string
-       MeasId         string
-       MeasObject     string
+       CounterId      string
 }
 
 // AppMetrics contains metrics definitions for all Xapps
@@ -138,14 +142,18 @@ func parseMetricsFromXAppDescriptor(descriptor []byte, appMetrics AppMetrics) Ap
                }
 
                for _, m := range measurements.([]interface{}) {
+                       moId, moIdOk := m.(map[string]interface{})["moId"].(string)
+                       measType, measTypeOk := m.(map[string]interface{})["measType"].(string)
                        measId, measIdOk := m.(map[string]interface{})["measId"].(string)
-                       measObject, objectOk := m.(map[string]interface{})["object"].(string)
+                       measInterval, measIntervalOk := m.(map[string]interface{})["measInterval"].(string)
                        metrics, metricsOk := m.(map[string]interface{})["metrics"]
-                       if !metricsOk || !measIdOk || !objectOk {
-                               logger.Info("No metrics found for measId=%s Object=%s", measId, measObject)
+                       if !metricsOk || !measTypeOk || !measIdOk || !moIdOk || !measIntervalOk {
+                               logger.Info("No metrics found for moId=%s measType=%s measId=%s measInterval=%s", moId, measId, measType, measInterval)
                                continue
                        }
-                       parseMetricsRules(metrics.([]interface{}), appMetrics, measId, measObject)
+                       logger.Info("Parsed measurement: moId=%s type=%s id=%s interval=%s", moId, measType, measId, measInterval)
+
+                       parseMetricsRules(metrics.([]interface{}), appMetrics, moId, measType, measId, measInterval)
                }
        }
        return appMetrics
@@ -155,16 +163,17 @@ func parseMetricsFromXAppDescriptor(descriptor []byte, appMetrics AppMetrics) Ap
 // of the following format:
 //    { "name": xxx, "objectName": yyy, "objectInstance": zzz }
 // Entries, which do not have all the necessary fields, are ignored.
-func parseMetricsRules(metricsMap []interface{}, appMetrics AppMetrics, measId, measObject string) AppMetrics {
+func parseMetricsRules(metricsMap []interface{}, appMetrics AppMetrics, moId, measType, measId, measInterval string) AppMetrics {
        for _, element := range metricsMap {
                name, nameOk := element.(map[string]interface{})["name"].(string)
                if nameOk {
                        _, alreadyFound := appMetrics[name]
                        objectName, objectNameOk := element.(map[string]interface{})["objectName"].(string)
                        objectInstance, objectInstanceOk := element.(map[string]interface{})["objectInstance"].(string)
-                       if !alreadyFound && objectNameOk && objectInstanceOk {
-                               appMetrics[name] = AppMetricsStruct{objectName, objectInstance, measId, measObject}
-                               logger.Info("parsed counter %s %s %s", name, objectName, objectInstance)
+                       counterId, counterIdOk := element.(map[string]interface{})["counterId"].(string)
+                       if !alreadyFound && objectNameOk && objectInstanceOk && counterIdOk {
+                               appMetrics[name] = AppMetricsStruct{moId, measType, measId, measInterval, objectName, objectInstance, counterId}
+                               logger.Info("Parsed counter name=%s %s/%s  M%sC%s", name, objectName, objectInstance, measId, counterId)
                        }
                        if alreadyFound {
                                logger.Info("skipped duplicate counter %s", name)
@@ -174,26 +183,19 @@ func parseMetricsRules(metricsMap []interface{}, appMetrics AppMetrics, measId,
        return appMetrics
 }
 
-func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) {
+func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) bool {
        makeRule := func(expr string, value AppMetricsStruct) MetricRule {
                return MetricRule{
                        Target:         "AdditionalObjects",
                        Expr:           expr,
-                       ObjectInstance: value.ObjectInstance,
+                       ObjectInstance: fmt.Sprintf("%s:%s", value.ObjectInstance, value.CounterId),
                        ObjectName:     value.ObjectName,
                        ObjectKeys: []Label{
-                               Label{
-                                       Name: "ricComponentName",
-                                       Expr: "'{{.labels.kubernetes_name}}'",
-                               },
-                               Label{
-                                       Name: "measObject",
-                                       Expr: value.MeasObject,
-                               },
-                               Label{
-                                       Name: "measId",
-                                       Expr: value.MeasId,
-                               },
+                               {Name: "ricComponentName", Expr: "'{{.labels.kubernetes_name}}'"},
+                               {Name: "moId", Expr: value.MoId},
+                               {Name: "measType", Expr: value.MeasType},
+                               {Name: "measId", Expr: value.MeasId},
+                               {Name: "measInterval", Expr: value.MeasInterval},
                        },
                }
        }
@@ -207,6 +209,8 @@ func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) {
        if len(vespaconf.Measurement.Prometheus.Rules.Metrics) == 0 {
                logger.Info("vespa config with empty metrics")
        }
+
+       return len(vespaconf.Measurement.Prometheus.Rules.Metrics) > 0
 }
 
 func getCollectorConfiguration(vespaconf *VESAgentConfiguration) {
@@ -217,12 +221,14 @@ func getCollectorConfiguration(vespaconf *VESAgentConfiguration) {
        vespaconf.PrimaryCollector.ServerRoot = os.Getenv("VESMGR_PRICOLLECTOR_SERVERROOT")
        vespaconf.PrimaryCollector.Topic = os.Getenv("VESMGR_PRICOLLECTOR_TOPIC")
        portStr := os.Getenv("VESMGR_PRICOLLECTOR_PORT")
+
        if portStr == "" {
                vespaconf.PrimaryCollector.Port = 8443
        } else {
                port, _ := strconv.Atoi(portStr)
                vespaconf.PrimaryCollector.Port = port
        }
+
        secureStr := os.Getenv("VESMGR_PRICOLLECTOR_SECURE")
        if secureStr == "true" {
                vespaconf.PrimaryCollector.Secure = true
@@ -233,8 +239,11 @@ func getCollectorConfiguration(vespaconf *VESAgentConfiguration) {
 
 func createVespaConfig(writer io.Writer, xAppStatus []byte) {
        vespaconf := basicVespaConf()
+
        getRules(&vespaconf, xAppStatus)
+
        getCollectorConfiguration(&vespaconf)
+
        err := yaml.NewEncoder(writer).Encode(vespaconf)
        if err != nil {
                logger.Error("Cannot write vespa conf file: %s", err.Error())
index ac1b7d6..da135b4 100755 (executable)
@@ -157,15 +157,15 @@ func metricsStringToInterfaceArray(metrics string) []interface{} {
 
 func TestParseMetricsRules(t *testing.T) {
        metricsJSON := `{"metrics": [
-                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" },
-                       { "name": "ricxapp_RMR_ReceiveError", "objectName": "ricxappRMRReceiveErrorCounter", "objectInstance": "ricxappRMRReceiveError" },
-                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" },
-                       { "name": "ricxapp_RMR_TransmitError", "objectName": "ricxappRMRTransmitErrorCounter", "objectInstance": "ricxappRMRTransmitError" },
-                       { "name": "ricxapp_SDL_Stored", "objectName": "ricxappSDLStoredCounter", "objectInstance": "ricxappSDLStored" },
-                       { "name": "ricxapp_SDL_StoreError", "objectName": "ricxappSDLStoreErrorCounter", "objectInstance": "ricxappSDLStoreError" } ]}`
+                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" },
+                       { "name": "ricxapp_RMR_ReceiveError", "objectName": "ricxappRMRReceiveErrorCounter", "objectInstance": "ricxappRMRReceiveError", "counterId": "0011" },
+                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" },
+                       { "name": "ricxapp_RMR_TransmitError", "objectName": "ricxappRMRTransmitErrorCounter", "objectInstance": "ricxappRMRTransmitError", "counterId": "0011" },
+                       { "name": "ricxapp_SDL_Stored", "objectName": "ricxappSDLStoredCounter", "objectInstance": "ricxappSDLStored", "counterId": "0011" },
+                       { "name": "ricxapp_SDL_StoreError", "objectName": "ricxappSDLStoreErrorCounter", "objectInstance": "ricxappSDLStoreError", "counterId": "0011" } ]}`
        appMetrics := make(AppMetrics)
        m := metricsStringToInterfaceArray(metricsJSON)
-       appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+       appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
        assert.Len(t, appMetrics, 6)
        assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
        assert.Equal(t, "ricxappRMRTransmitErrorCounter", appMetrics["ricxapp_RMR_TransmitError"].ObjectName)
@@ -176,16 +176,16 @@ func TestParseMetricsRulesNoMetrics(t *testing.T) {
        appMetrics := make(AppMetrics)
        metricsJSON := `{"metrics": []`
        m := metricsStringToInterfaceArray(metricsJSON)
-       appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+       appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
        assert.Empty(t, appMetrics)
 }
 
 func TestParseMetricsRulesAdditionalFields(t *testing.T) {
        appMetrics := make(AppMetrics)
        metricsJSON := `{"metrics": [
-                       { "additionalField": "valueIgnored", "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" }]}`
+                       { "additionalField": "valueIgnored", "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" }]}`
        m := metricsStringToInterfaceArray(metricsJSON)
-       appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+       appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
        assert.Len(t, appMetrics, 1)
        assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
        assert.Equal(t, "ricxappRMRReceived", appMetrics["ricxapp_RMR_Received"].ObjectInstance)
@@ -194,11 +194,11 @@ func TestParseMetricsRulesAdditionalFields(t *testing.T) {
 func TestParseMetricsRulesMissingFields(t *testing.T) {
        appMetrics := make(AppMetrics)
        metricsJSON := `{"metrics": [
-                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" },
+                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" },
                        { "name": "ricxapp_RMR_ReceiveError", "objectInstance": "ricxappRMRReceiveError" },
-                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" }]}`
+                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" }]}`
        m := metricsStringToInterfaceArray(metricsJSON)
-       appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+       appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
        assert.Len(t, appMetrics, 2)
        assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
        assert.Equal(t, "ricxappRMRTransmittedCounter", appMetrics["ricxapp_RMR_Transmitted"].ObjectName)
@@ -209,11 +209,11 @@ func TestParseMetricsRulesMissingFields(t *testing.T) {
 func TestParseMetricsRulesDuplicateDefinitionIsIgnored(t *testing.T) {
        appMetrics := make(AppMetrics)
        metricsJSON := `{"metrics": [
-                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" },
-                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounterXXX", "objectInstance": "ricxappRMRReceivedXXX" },
-                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" }]}`
+                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" },
+                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounterXXX", "objectInstance": "ricxappRMRReceivedXXX", "counterId": "0011" },
+                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" }]}`
        m := metricsStringToInterfaceArray(metricsJSON)
-       appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+       appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
        assert.Len(t, appMetrics, 2)
        assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
        assert.Equal(t, "ricxappRMRReceived", appMetrics["ricxapp_RMR_Received"].ObjectInstance)
@@ -222,13 +222,13 @@ func TestParseMetricsRulesDuplicateDefinitionIsIgnored(t *testing.T) {
 func TestParseMetricsRulesIncrementalFillOfAppMetrics(t *testing.T) {
        appMetrics := make(AppMetrics)
        metricsJSON1 := `{"metrics": [
-                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" }]}`
+                       { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" }]}`
        metricsJSON2 := `{"metrics": [
-                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" }]}`
+                       { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" }]}`
        m1 := metricsStringToInterfaceArray(metricsJSON1)
        m2 := metricsStringToInterfaceArray(metricsJSON2)
-       appMetrics = parseMetricsRules(m1, appMetrics, "M1234", "App-1")
-       appMetrics = parseMetricsRules(m2, appMetrics,  "M1234", "App-1")
+       appMetrics = parseMetricsRules(m1, appMetrics, "SEP/XAPP", "X2", "1234", "60")
+       appMetrics = parseMetricsRules(m2, appMetrics, "SEP/XAPP", "X2", "1234", "60")
        assert.Len(t, appMetrics, 2)
        assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
        assert.Equal(t, "ricxappRMRReceived", appMetrics["ricxapp_RMR_Received"].ObjectInstance)
index e292307..c093359 100755 (executable)
@@ -187,9 +187,15 @@ func queryXAppsConfig(appmgrURL string, timeout time.Duration) ([]byte, error) {
        return emptyConfig, errors.New(resp.Status)
 }
 
-func queryConf() ([]byte, error) {
-       return queryXAppsConfig("http://"+appmgrDomain+":"+appmgrPort+appmgrXAppConfigPath,
-               10*time.Second)
+func queryConf() (appConfig []byte, err error) {
+       for i := 0; i < 10; i++ {
+               appConfig, err = queryXAppsConfig("http://"+appmgrDomain+":"+appmgrPort+appmgrXAppConfigPath, 10*time.Second)
+               if len(appConfig) > 0 {
+                       break
+               }
+               time.Sleep(5 * time.Second)
+       }
+       return appConfig, err
 }
 
 func (vesmgr *VesMgr) emptyNotificationsChannel() {
@@ -250,11 +256,17 @@ func (vesmgr *VesMgr) waitSubscriptionLoop() {
 // Run the vesmgr process main loop
 func (vesmgr *VesMgr) Run() {
        logger.Info("vesmgr main loop ready")
+
        vesmgr.httpServer.start(vesmgrXappNotifPath, vesmgr.chXAppNotifications, vesmgr.chSupervision)
+
        vesmgr.subscribeXAppNotifications()
+
        vesmgr.waitSubscriptionLoop()
+
        xappConfig, _ := queryConf()
+
        createConf(vespaConfigFile, xappConfig)
+
        vesmgr.startVesagent()
        for {
                vesmgr.servRequest()
index c28c94d..b7c6ac8 100644 (file)
@@ -1,4 +1,4 @@
 # The Jenkins job uses this string for the tag in the image name
 # for example nexus3.o-ran-sc.org:10004/my-image-name:0.0.1
 ---
-tag: 0.5.0
+tag: 0.5.1
index c74bac9..204398b 100755 (executable)
             },
             "measurements": [
                 {
-                    "measId": "M9001",
-                    "object": "XAPP-xApp1",
+                    "moId": "SEP-12/XAPP-1",
+                    "measType": "X2",
+                    "measId": "9001",
+                    "measInterval": "60",
                     "metrics": [
                         {
-                            "description": "Example counter 1",
-                            "enabled": true,
                             "name": "App1ExampleCounterOne",
-                            "type": "counter",
                             "objectName": "App1ExampleCounterOneObject",
-                            "objectInstance": "App1ExampleCounterOneObjectInstance"
+                            "objectInstance": "App1ExampleCounterOneObjectInstance",
+                            "counterId": "0011",
+                            "type": "counter",
+                            "description": "Example counter 1"
                         },
                         {
-                            "description": "Example counter 2",
-                            "enabled": true,
                             "name": "App1ExampleCounterTwo",
-                            "type": "counter",
                             "objectName": "App1ExampleCounterTwoObject",
-                            "objectInstance": "App1ExampleCounterTwoObjectInstance"
+                            "objectInstance": "App1ExampleCounterTwoObjectInstance",
+                            "counterId": "0012",
+                            "type": "counter",
+                            "description": "Example counter 2"
                         }
                     ]
                 }
             },
             "measurements": [
                 {
-                    "measId": "M9001",
-                    "object": "XAPP-xApp2",
+                    "moId": "SEP-12/XAPP-2",
+                    "measType": "X2",
+                    "measId": "9002",
+                    "measInterval": "60",
                     "metrics": [
                         {
-                            "description": "Example counter",
-                            "enabled": true,
                             "name": "App2ExampleCounterOne",
-                            "type": "counter",
                             "objectName": "App2ExampleCounterOneObject",
-                            "objectInstance": "App2ExampleCounterOneObjectInstance"
+                            "objectInstance": "App2ExampleCounterOneObjectInstance",
+                            "counterId": "0021",
+                            "type": "counter",
+                            "description": "Example counter 1"
                         },
                         {
-                            "description": "Another example counter",
-                            "enabled": true,
                             "name": "App2ExampleCounterTwo",
-                            "type": "counter",
                             "objectName": "App2ExampleCounterTwoObject",
-                            "objectInstance": "App2ExampleCounterTwoObjectInstance"
+                            "objectInstance": "App2ExampleCounterTwoObjectInstance",
+                            "counterId": "0022",
+                            "type": "counter",
+                            "description": "Example counter 2"
                         }
                     ]
                 }