From: ychacon Date: Tue, 15 Feb 2022 08:07:33 +0000 (+0100) Subject: O-DU Slice Assurance App towards latest O-DU implementation X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=43b5864e8e5d8fad832c308301dd81ed02fbc2f5;p=nonrtric.git O-DU Slice Assurance App towards latest O-DU implementation Issue-ID: NONRTRIC-706 Signed-off-by: ychacon Change-Id: I733101159fec2011af2d45572180201c12c9dbc2 --- diff --git a/test/usecases/odusliceassurance/goversion/internal/restclient/client.go b/test/usecases/odusliceassurance/goversion/internal/restclient/client.go index 3983840b..c31fa1d8 100644 --- a/test/usecases/odusliceassurance/goversion/internal/restclient/client.go +++ b/test/usecases/odusliceassurance/goversion/internal/restclient/client.go @@ -26,22 +26,42 @@ import ( "fmt" "io" "net/http" + "net/http/httputil" log "github.com/sirupsen/logrus" ) +type RequestError struct { + StatusCode int + Body []byte +} + +func (e RequestError) Error() string { + return fmt.Sprintf("error response with status: %v and body: %v", e.StatusCode, string(e.Body)) +} + type Client struct { httpClient *http.Client + verbose bool } -func New(httpClient *http.Client) *Client { +func New(httpClient *http.Client, verbose bool) *Client { return &Client{ httpClient: httpClient, + verbose: verbose, } } -func (c *Client) Get(path string, v interface{}) error { - req, err := c.newRequest(http.MethodGet, path, nil) +func (c *Client) Get(path string, v interface{}, userInfo ...string) error { + var req *http.Request + var err error + + if len(userInfo) > 1 { + req, err = c.newRequest(http.MethodGet, path, nil, userInfo[0], userInfo[1]) + } else { + req, err = c.newRequest(http.MethodGet, path, nil) + } + if err != nil { return fmt.Errorf("failed to create GET request: %w", err) } @@ -53,12 +73,16 @@ func (c *Client) Get(path string, v interface{}) error { return nil } -func (c *Client) Post(path string, payload interface{}, v interface{}) error { +func (c *Client) Post(path string, payload interface{}, v interface{}, userInfo ...string) error { + var req *http.Request + var err error - s, _ := json.MarshalIndent(payload, "", "\t") - log.Debugf("Post request payload: " + string(s)) + if len(userInfo) > 1 { + req, err = c.newRequest(http.MethodPost, path, payload, userInfo[0], userInfo[1]) + } else { + req, err = c.newRequest(http.MethodPost, path, payload) + } - req, err := c.newRequest(http.MethodPost, path, payload) if err != nil { return fmt.Errorf("failed to create POST request: %w", err) } @@ -70,8 +94,22 @@ func (c *Client) Post(path string, payload interface{}, v interface{}) error { return nil } -func (c *Client) newRequest(method, path string, payload interface{}) (*http.Request, error) { +func (c *Client) Put(path string, payload interface{}, v interface{}, userName string, password string) error { + req, err := c.newRequest(http.MethodPut, path, payload, userName, password) + if err != nil { + return fmt.Errorf("failed to create PUT request: %w", err) + } + + if err := c.doRequest(req, v); err != nil { + return err + } + + return nil +} + +func (c *Client) newRequest(method, path string, payload interface{}, userInfo ...string) (*http.Request, error) { var reqBody io.Reader + if payload != nil { bodyBytes, err := json.Marshal(payload) if err != nil { @@ -81,14 +119,27 @@ func (c *Client) newRequest(method, path string, payload interface{}) (*http.Req } req, err := http.NewRequest(method, path, reqBody) + if err != nil { return nil, fmt.Errorf("failed to create HTTP request: %w", err) } + if len(userInfo) > 0 { + req.SetBasicAuth(userInfo[0], userInfo[1]) + } + if reqBody != nil { - req.Header.Set("Content-Type", "application/json; charset=utf-8") + req.Header.Set("Content-Type", "application/json") } - log.Debugf("Http Client Request: [%s:%s]\n", req.Method, req.URL) + + if c.verbose { + if reqDump, error := httputil.DumpRequest(req, true); error != nil { + fmt.Println(err) + } else { + fmt.Println(string(reqDump)) + } + } + return req, nil } @@ -108,7 +159,7 @@ func (c *Client) doRequest(r *http.Request, v interface{}) error { } dec := json.NewDecoder(resp.Body) - if err := dec.Decode(v); err != nil { + if err := dec.Decode(&v); err != nil { return fmt.Errorf("could not parse response body: %w [%s:%s]", err, r.Method, r.URL.String()) } log.Debugf("Http Client Response: %v\n", v) @@ -121,11 +172,25 @@ func (c *Client) do(r *http.Request) (*http.Response, error) { return nil, fmt.Errorf("failed to make request [%s:%s]: %w", r.Method, r.URL.String(), err) } + if c.verbose { + if responseDump, error := httputil.DumpResponse(resp, true); error != nil { + fmt.Println(err) + } else { + fmt.Println(string(responseDump)) + } + } + if resp.StatusCode >= http.StatusOK && resp.StatusCode <= 299 { return resp, nil } defer resp.Body.Close() + responseData, _ := io.ReadAll(resp.Body) + + putError := RequestError{ + StatusCode: resp.StatusCode, + Body: responseData, + } - return resp, fmt.Errorf("failed to do request, %d status code received", resp.StatusCode) + return resp, putError } diff --git a/test/usecases/odusliceassurance/goversion/internal/restclient/client_test.go b/test/usecases/odusliceassurance/goversion/internal/restclient/client_test.go index f2899dfa..de66e5d0 100644 --- a/test/usecases/odusliceassurance/goversion/internal/restclient/client_test.go +++ b/test/usecases/odusliceassurance/goversion/internal/restclient/client_test.go @@ -27,6 +27,7 @@ import ( "net/http/httptest" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -83,7 +84,7 @@ func TestNewRequest(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - client := New(&http.Client{}) + client := New(&http.Client{}, false) req, err := client.newRequest(tt.args.method, tt.args.path, tt.args.payload) if tt.wantErr != nil { @@ -91,7 +92,7 @@ func TestNewRequest(t *testing.T) { assertions.EqualError(tt.wantErr, err.Error()) } else { assertions.Equal("url", req.URL.Path) - assertions.Equal("application/json; charset=utf-8", req.Header.Get("Content-Type")) + assertions.Equal("application/json", req.Header.Get("Content-Type")) assertions.Empty(req.Header.Get("Authorization")) assertions.Nil(err) } @@ -128,7 +129,7 @@ func TestGet(t *testing.T) { respCode: http.StatusBadRequest, resp: nil, }, - wantErr: "failed to do request, 400 status code received", + wantErr: "error response with status: 400 and body:", }, } @@ -136,6 +137,7 @@ func TestGet(t *testing.T) { t.Run(tt.name, func(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assertions.Equal(http.MethodGet, r.Method) response, _ := json.Marshal(tt.args.resp) w.Header().Set("Content-Type", tt.args.header) w.WriteHeader(tt.args.respCode) @@ -143,12 +145,12 @@ func TestGet(t *testing.T) { })) defer srv.Close() - client := New(&http.Client{}) + client := New(&http.Client{}, false) var res interface{} err := client.Get(srv.URL, &res) if err != nil { - assertions.Equal(tt.wantErr, err.Error()) + assertions.Contains(err.Error(), tt.wantErr) } assertions.Equal(tt.args.resp, res) }) @@ -156,55 +158,63 @@ func TestGet(t *testing.T) { } func TestPost(t *testing.T) { - assertions := require.New(t) - type args struct { - header string - respCode int - resp interface{} - } - tests := []struct { - name string - args args - wantErr string - }{ - { - name: "successful Post request", - args: args{ - header: "application/json", - respCode: http.StatusOK, - resp: "Success!", - }, - wantErr: "", - }, + header := "application/json" + respCode := http.StatusOK + resp := "Success!" + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + assert.Equal(t, http.MethodPost, r.Method) + assert.Contains(t, r.Header.Get("Content-Type"), "application/json") + + var reqBody string + decoder := json.NewDecoder(r.Body) + decoder.Decode(&reqBody) + assert.Equal(t, reqBody, `json:"example"`) + + response, _ := json.Marshal(resp) + w.Header().Set("Content-Type", header) + w.WriteHeader(respCode) + w.Write(response) + })) + defer srv.Close() + + client := New(&http.Client{}, false) + payload := `json:"example"` + err := client.Post(srv.URL, payload, nil, "admin", "pass") + + if err != nil { + assert.Equal(t, "", err.Error()) } +} - for _, tt := range tests { +func TestPut(t *testing.T) { + header := "application/json" + respCode := http.StatusOK + resp := "Success!" - t.Run(tt.name, func(t *testing.T) { - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - assertions.Equal(http.MethodPost, r.Method) - assertions.Contains(r.Header.Get("Content-Type"), "application/json") + assert.Equal(t, http.MethodPut, r.Method) + assert.Contains(t, r.Header.Get("Content-Type"), "application/json") - var reqBody interface{} - decoder := json.NewDecoder(r.Body) - decoder.Decode(&reqBody) - assertions.Equal(reqBody, `json:"example"`) + var reqBody string + decoder := json.NewDecoder(r.Body) + decoder.Decode(&reqBody) + assert.Equal(t, reqBody, `json:"example"`) - response, _ := json.Marshal(tt.args.resp) - w.Header().Set("Content-Type", tt.args.header) - w.WriteHeader(tt.args.respCode) - w.Write(response) - })) - defer srv.Close() + response, _ := json.Marshal(resp) + w.Header().Set("Content-Type", header) + w.WriteHeader(respCode) + w.Write(response) + })) + defer srv.Close() - client := New(&http.Client{}) - payload := `json:"example"` - err := client.Post(srv.URL, payload, nil) + client := New(&http.Client{}, false) + payload := `json:"example"` + err := client.Put(srv.URL, payload, nil, "admin", "pass") - if err != nil { - assertions.Equal(tt.wantErr, err.Error()) - } - }) + if err != nil { + assert.Equal(t, "", err.Error()) } } diff --git a/test/usecases/odusliceassurance/goversion/internal/sliceassurance/app.go b/test/usecases/odusliceassurance/goversion/internal/sliceassurance/app.go index 4266508a..c4a4d65b 100644 --- a/test/usecases/odusliceassurance/goversion/internal/sliceassurance/app.go +++ b/test/usecases/odusliceassurance/goversion/internal/sliceassurance/app.go @@ -21,9 +21,12 @@ package sliceassurance import ( + "encoding/json" + "fmt" "net/http" "time" + "oransc.org/usecase/oduclosedloop/internal/config" "oransc.org/usecase/oduclosedloop/internal/restclient" "oransc.org/usecase/oduclosedloop/internal/structures" "oransc.org/usecase/oduclosedloop/messages" @@ -32,10 +35,10 @@ import ( ) const ( - THRESHOLD_TPUT = 700 - DEFAULT_DEDICATED_RATIO = 40 - NEW_DEDICATED_RATIO = 50 - NODE_ID = "O-DU-1211" + THRESHOLD_TPUT = 7000 + DEFAULT_DEDICATED_RATIO = 15 + NEW_DEDICATED_RATIO = 25 + NODE_ID = "O-DU-1122" ) type App struct { @@ -45,12 +48,16 @@ type App struct { var dmaapMRUrl string var sDNRUrl string +var sDNRUsername string +var sDNRPassword string -func (a *App) Initialize(dmaapUrl string, sdnrUrl string) { - dmaapMRUrl = dmaapUrl - sDNRUrl = sdnrUrl +func (a *App) Initialize(config *config.Config) { + dmaapMRUrl = config.MRHost + ":" + config.MRPort + sDNRUrl = config.SDNRAddress + sDNRUsername = config.SDNRUser + sDNRPassword = config.SDNPassword - a.client = restclient.New(&http.Client{}) + a.client = restclient.New(&http.Client{}, false) a.metricsPolicies = structures.NewSliceAssuranceMeas() } @@ -67,37 +74,63 @@ func (a *App) Run(topic string, pollTime int) { } } -func (a *App) getMessagesFromDmaap(url string) { - var stdMessage messages.StdDefinedMessage - a.client.Get(url, &stdMessage) - log.Infof("Polling new messages from DmaapMR") - for _, meas := range stdMessage.GetMeasurements() { - //Create sliceMetric and check if metric exist and update existing one or create new one - if _, err := a.metricsPolicies.AddOrUpdateMetric(meas); err != nil { - log.Error("Metric could not be added ", err) +func (a *App) getMessagesFromDmaap(path string) { + log.Infof("Polling new messages from DmaapMR %v", path) + + //Added to work with onap-Dmaap + var messageStrings []string + if error := a.client.Get(path, &messageStrings); error != nil { + log.Warn("Send of Get messages from DmaapMR failed! ", error) + } + + for _, msgString := range messageStrings { + var message messages.StdDefinedMessage + if err := json.Unmarshal([]byte(msgString), &message); err == nil { + for _, meas := range message.GetMeasurements() { + log.Infof("Create sliceMetric and check if metric exist and update existing one or create new one measurement: %+v\n", meas) + //Create sliceMetric and check if metric exist and update existing one or create new one + if _, err := a.metricsPolicies.AddOrUpdateMetric(meas); err != nil { + log.Error("Metric could not be added ", err) + } + } + } else { + log.Warn(err) } } } func (a *App) getRRMInformation(duid string) { var duRRMPolicyRatio messages.ORanDuRestConf - a.client.Get(getUrlForDistributedUnitFunctions(sDNRUrl, duid), &duRRMPolicyRatio) - policies := duRRMPolicyRatio.DistributedUnitFunction.RRMPolicyRatio - for _, policy := range policies { - a.metricsPolicies.AddNewPolicy(duid, policy) + log.Infof("Get RRM Information from SDNR url: %v", sDNRUrl) + if error := a.client.Get(getUrlForDistributedUnitFunctions(sDNRUrl, duid), &duRRMPolicyRatio, sDNRUsername, sDNRPassword); error == nil { + prettyPrint(duRRMPolicyRatio.DistributedUnitFunction) + } else { + log.Warn("Send of Get RRM Information failed! ", error) + } + + for _, odu := range duRRMPolicyRatio.DistributedUnitFunction { + for _, policy := range odu.RRMPolicyRatio { + log.Infof("Add or Update policy: %+v from DU id: %v", policy.Id, duid) + a.metricsPolicies.AddNewPolicy(duid, policy) + } } } func (a *App) updateDedicatedRatio() { - for _, metric := range a.metricsPolicies.Metrics { policy, check := a.metricsPolicies.Policies[metric.RRMPolicyRatioId] //TODO What happened if dedicated ratio is already higher that default and threshold is exceed? if check && policy.PolicyDedicatedRatio <= DEFAULT_DEDICATED_RATIO { - log.Infof("Send Post Request to update DedicatedRatio for DU id: %v Policy id: %v", metric.DUId, policy.PolicyRatioId) - url := getUrlUpdatePolicyDedicatedRatio(sDNRUrl, metric.DUId, policy.PolicyRatioId) - a.client.Post(url, policy.GetUpdateDedicatedRatioMessage(metric.SliceDiff, metric.SliceServiceType, NEW_DEDICATED_RATIO), nil) + log.Infof("Send Request to update DedicatedRatio for DU id: %v Policy id: %v", metric.DUId, policy.PolicyRatioId) + path := getUrlUpdatePolicyDedicatedRatio(sDNRUrl, metric.DUId, policy.PolicyRatioId) + updatePolicyMessage := policy.GetUpdateDedicatedRatioMessage(metric.SliceDiff, metric.SliceServiceType, NEW_DEDICATED_RATIO) + prettyPrint(updatePolicyMessage) + if error := a.client.Put(path, updatePolicyMessage, nil, sDNRUsername, sDNRPassword); error == nil { + log.Infof("Policy Dedicated Ratio for PolicyId: %v was updated to %v", policy.PolicyRatioId, NEW_DEDICATED_RATIO) + } else { + log.Warn("Send of Put Request to update DedicatedRatio failed! ", error) + } } } } @@ -109,3 +142,11 @@ func getUrlForDistributedUnitFunctions(host string, duid string) string { func getUrlUpdatePolicyDedicatedRatio(host string, duid string, policyid string) string { return host + "/rests/data/network-topology:network-topology/topology=topology-netconf/node=" + NODE_ID + "/yang-ext:mount/o-ran-sc-du-hello-world:network-function/distributed-unit-functions=" + duid + "/radio-resource-management-policy-ratio=" + policyid } + +func prettyPrint(jsonStruct interface{}) { + b, err := json.MarshalIndent(jsonStruct, "", " ") + if err != nil { + fmt.Println("error:", err) + } + fmt.Print(string(b)) +} diff --git a/test/usecases/odusliceassurance/goversion/internal/structures/measurements.go b/test/usecases/odusliceassurance/goversion/internal/structures/measurements.go index f58d714b..7842916f 100644 --- a/test/usecases/odusliceassurance/goversion/internal/structures/measurements.go +++ b/test/usecases/odusliceassurance/goversion/internal/structures/measurements.go @@ -59,11 +59,11 @@ func NewPolicyRatio(id string, max_ratio int, min_ratio int, ded_ratio int) *Pol return &pr } -func (pr *PolicyRatio) GetUpdateDedicatedRatioMessage(sd int, sst int, dedicatedRatio int) []messages.RRMPolicyRatio { +func (pr *PolicyRatio) GetUpdateDedicatedRatioMessage(sd int, sst int, dedicatedRatio int) interface{} { message := messages.RRMPolicyRatio{ Id: pr.PolicyRatioId, - AdmState: "Locked", - UserLabel: "Some user label", + AdmState: "unlocked", + UserLabel: pr.PolicyRatioId, RRMPolicyMaxRatio: pr.PolicyMaxRatio, RRMPolicyMinRatio: pr.PolicyMinRatio, RRMPolicyDedicatedRatio: dedicatedRatio, @@ -77,5 +77,12 @@ func (pr *PolicyRatio) GetUpdateDedicatedRatioMessage(sd int, sst int, dedicated }, }, } - return []messages.RRMPolicyRatio{message} + rrmPolicies := []messages.RRMPolicyRatio{message} + + return struct { + RRMPolicies []messages.RRMPolicyRatio `json:"radio-resource-management-policy-ratio"` + }{ + RRMPolicies: rrmPolicies, + } + } diff --git a/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance.go b/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance.go index 1f9c8604..d7c25569 100644 --- a/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance.go +++ b/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance.go @@ -79,7 +79,7 @@ func (sa *SliceAssuranceMeas) AddOrUpdateMetric(meas messages.Measurement) (stri var duid string var sd, sst int - regex := *regexp.MustCompile(`\/(.*)network-function\/distributed-unit-functions\[id=\'(.*)\'\]\/cell\[id=\'(.*)\'\]\/supported-measurements\/performance-measurement-type=\'(.*)\'\]\/supported-snssai-subcounter-instances\[slice-differentiator=\'(\d+)\'\]\[slice-service-type=\'(\d+)\'\]`) + regex := *regexp.MustCompile(`\/(.*)network-function\/distributed-unit-functions\[id=\'(.*)\'\]\/cell\[id=\'(.*)\'\]\/supported-measurements\[performance-measurement-type=\'(.*)\'\]\/supported-snssai-subcounter-instances\[slice-differentiator=\'(\d+)\'\]\[slice-service-type=\'(\d+)\'\]`) res := regex.FindAllStringSubmatch(meas.MeasurementTypeInstanceReference, -1) if res != nil && len(res[0]) == 7 { diff --git a/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance_test.go b/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance_test.go index 792f4753..9ed35fb2 100644 --- a/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance_test.go +++ b/test/usecases/odusliceassurance/goversion/internal/structures/sliceassurance_test.go @@ -41,7 +41,7 @@ func TestAddMetric(t *testing.T) { name: "Test adding new metric", args: args{ meas: messages.Measurement{ - MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 51232, Unit: "kbit/s", }, @@ -51,7 +51,7 @@ func TestAddMetric(t *testing.T) { name: "Test with invalid input", args: args{ meas: messages.Measurement{ - MeasurementTypeInstanceReference: "/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 51232, Unit: "kbit/s", }, @@ -83,13 +83,13 @@ func TestAddMetric(t *testing.T) { func TestUpdateExistingMetric(t *testing.T) { assertions := require.New(t) meas := messages.Measurement{ - MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 51232, Unit: "kbit/s", } updateMeas := messages.Measurement{ - MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 897, Unit: "kbit/s", } @@ -115,13 +115,13 @@ func TestUpdateExistingMetric(t *testing.T) { func TestDeleteMetricWhenValueLessThanThreshold(t *testing.T) { meas := messages.Measurement{ - MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 51232, Unit: "kbit/s", } newMeas := messages.Measurement{ - MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 50, Unit: "kbit/s", } @@ -140,7 +140,7 @@ func TestDeleteMetricWhenValueLessThanThreshold(t *testing.T) { func TestAddPolicy(t *testing.T) { meas := messages.Measurement{ - MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements/performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", + MeasurementTypeInstanceReference: "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='O-DU-1211']/cell[id='cell-1']/supported-measurements[performance-measurement-type='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances[slice-differentiator='1'][slice-service-type='1']", Value: 51232, Unit: "kbit/s", } diff --git a/test/usecases/odusliceassurance/goversion/main.go b/test/usecases/odusliceassurance/goversion/main.go index 4497cfb5..337e4e02 100644 --- a/test/usecases/odusliceassurance/goversion/main.go +++ b/test/usecases/odusliceassurance/goversion/main.go @@ -41,14 +41,12 @@ func main() { log.Debug("Using configuration: ", configuration) - dmaapUrl := configuration.MRHost + ":" + configuration.MRPort - if err := validateConfiguration(configuration); err != nil { log.Fatalf("Unable to start consumer due to configuration error: %v", err) } a := sliceassurance.App{} - a.Initialize(dmaapUrl, configuration.SDNRAddress) + a.Initialize(configuration) go a.Run(TOPIC, configuration.Polltime) http.HandleFunc("/status", statusHandler) diff --git a/test/usecases/odusliceassurance/goversion/messages/policyRatio.go b/test/usecases/odusliceassurance/goversion/messages/policyRatio.go index 502e867c..eeba22e5 100644 --- a/test/usecases/odusliceassurance/goversion/messages/policyRatio.go +++ b/test/usecases/odusliceassurance/goversion/messages/policyRatio.go @@ -21,12 +21,16 @@ package messages type ORanDuRestConf struct { - DistributedUnitFunction DistributedUnitFunction `json:"distributed-unit-functions"` + DistributedUnitFunction []DistributedUnitFunction `json:"o-ran-sc-du-hello-world:distributed-unit-functions"` } type DistributedUnitFunction struct { - Id string `json:"id"` - RRMPolicyRatio []RRMPolicyRatio `json:"radio-resource-management-policy-ratio"` + Id string `json:"id"` + OperationalState string `json:"operational-state"` + AdmState string `json:"administrative-state"` + UserLabel string `json:"user-label"` + RRMPolicyRatio []RRMPolicyRatio `json:"radio-resource-management-policy-ratio"` + Cell []Cell `json:"cell"` } type RRMPolicyRatio struct { @@ -46,3 +50,56 @@ type RRMPolicyMember struct { SliceDifferentiator int `json:"slice-differentiator"` SliceServiceType int `json:"slice-service-type"` } + +type Cell struct { + Id string `json:"id"` + LocalId int `json:"local-id"` + PhysicalCellId int `json:"physical-cell-id"` + BaseStationChannelBandwidth BaseStationChannelBandwidth `json:"base-station-channel-bandwidth"` + OperationalState string `json:"operational-state"` + TrackingAreaCode int `json:"tracking-area-code"` + AdmState string `json:"administrative-state"` + PublicLandMobileNetworks []PublicLandMobileNetworks `json:"public-land-mobile-networks"` + SupportedMeasurements []SupportedMeasurements `json:"supported-measurements"` + TrafficState string `json:"traffic-state"` + AbsoluteRadioFrequencyChannelNumber AbsoluteRadioFrequencyChannelNumber `json:"absolute-radio-frequency-channel-number"` + UserLabel string `json:"user-label"` + SynchronizationSignalBlock SynchronizationSignalBlock `json:"synchronization-signal-block"` +} + +type BaseStationChannelBandwidth struct { + Uplink int `json:"uplink"` + Downlink int `json:"downlink"` + SupplementaryUplink int `json:"supplementary-uplink"` +} + +type PublicLandMobileNetworks struct { + SliceDifferentiator int `json:"slice-differentiator"` + SliceServiceType int `json:"slice-service-type"` + MobileCountryCode string `json:"mobile-country-code"` + MobileNetworkCode string `json:"mobile-network-code"` +} + +type SupportedMeasurements struct { + PerformanceMeasurementType string `json:"performance-measurement-type"` + SupportedSnssaiSubcounterInstances []SupportedSnssaiSubcounterInstances `json:"supported-snssai-subcounter-instances"` +} + +type SupportedSnssaiSubcounterInstances struct { + SliceDifferentiator int `json:"slice-differentiator"` + SliceServiceType int `json:"slice-service-type"` +} + +type AbsoluteRadioFrequencyChannelNumber struct { + Uplink int `json:"uplink"` + Downlink int `json:"downlink"` + SupplementaryUplink int `json:"supplementary-uplink"` +} + +type SynchronizationSignalBlock struct { + Duration int `json:"duration"` + FrequencyChannelNumber int `json:"frequency-channel-number"` + Periodicity int `json:"periodicity"` + SubcarrierSpacing int `json:"subcarrier-spacing"` + Offset int `json:"offset"` +} diff --git a/test/usecases/odusliceassurance/goversion/messages/stdVesMessage_test.go b/test/usecases/odusliceassurance/goversion/messages/stdVesMessage_test.go index 2904d49f..3524ba19 100644 --- a/test/usecases/odusliceassurance/goversion/messages/stdVesMessage_test.go +++ b/test/usecases/odusliceassurance/goversion/messages/stdVesMessage_test.go @@ -22,9 +22,12 @@ package messages import ( "testing" + + "github.com/stretchr/testify/require" ) func TestGetMeasurements(t *testing.T) { + assertions := require.New(t) type fields struct { Event Event } @@ -68,9 +71,16 @@ func TestGetMeasurements(t *testing.T) { message := StdDefinedMessage{ Event: tt.fields.Event, } - if got := message.GetMeasurements(); len(got) != len(tt.want) { + var got []Measurement + if got = message.GetMeasurements(); len(got) != len(tt.want) { t.Errorf("Message.GetMeasurements() = %v, want %v", got, tt.want) } + + for _, meas := range got { + assertions.Equal(51232, meas.Value) + assertions.Contains(meas.MeasurementTypeInstanceReference, "user-equipment-average-throughput-uplink") + } + }) } } diff --git a/test/usecases/odusliceassurance/goversion/stub/mrproducer/mrstub.go b/test/usecases/odusliceassurance/goversion/stub/mrproducer/mrstub.go deleted file mode 100644 index e7591255..00000000 --- a/test/usecases/odusliceassurance/goversion/stub/mrproducer/mrstub.go +++ /dev/null @@ -1,130 +0,0 @@ -// - -// ========================LICENSE_START================================= -// O-RAN-SC -// %% -// Copyright (C) 2021: Nordix Foundation -// %% -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ========================LICENSE_END=================================== -// - -package main - -import ( - "encoding/json" - "flag" - "fmt" - "math/rand" - "net/http" - "time" - - "github.com/gorilla/mux" - "oransc.org/usecase/oduclosedloop/messages" -) - -func main() { - rand.Seed(time.Now().UnixNano()) - port := flag.Int("port", 3905, "The port this message router will listen on") - flag.Parse() - - r := mux.NewRouter() - r.HandleFunc("/events/unauthenticated.PERFORMANCE_MEASUREMENTS", sendStdMessage).Methods(http.MethodGet) - - fmt.Println("Starting mr on port: ", *port) - - http.ListenAndServe(fmt.Sprintf(":%v", *port), r) - -} - -// Variables :: -// DU-ID: ERICSSON-O-DU-11220 -// Cell-ID: cell1 -// Slice-Diff: 2 -// Value: 300 -func sendStdMessage(w http.ResponseWriter, r *http.Request) { - message := fetchMessage() - fmt.Println("-----------------------------------------------------------------------------") - fmt.Println("Sending message: ", message) - fmt.Println("-----------------------------------------------------------------------------") - response, _ := json.Marshal(message) - time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - w.Write(response) -} - -func fetchMessage() messages.StdDefinedMessage { - - index := rand.Intn(5) - fmt.Println(index) - - measurements := [5][]messages.Measurement{meas1, meas2, meas3, meas4, meas5} - - message := messages.StdDefinedMessage{ - Event: messages.Event{ - CommonEventHeader: messages.CommonEventHeader{ - Domain: "stndDefined", - StndDefinedNamespace: "o-ran-sc-du-hello-world-pm-streaming-oas3", - }, - StndDefinedFields: messages.StndDefinedFields{ - StndDefinedFieldsVersion: "1.0", - SchemaReference: "https://gerrit.o-ran-sc.org/r/gitweb?p=scp/oam/modeling.git;a=blob_plain;f=data-model/oas3/experimental/o-ran-sc-du-hello-world-oas3.json;hb=refs/heads/master", - Data: messages.Data{ - DataId: "id", - Measurements: measurements[index], - }, - }, - }, - } - return message -} - -var meas1 = []messages.Measurement{ - { - MeasurementTypeInstanceReference: "/network-function/distributed-unit-functions[id='ERICSSON-O-DU-11220']/cell[id='cell1']/supported-measurements/performance-measurement-type[.='user-equipment-average-throughput-downlink']/supported-snssai-subcounter-instances/slice-differentiator[.=2][slice-service-type=1]", - Value: 300, - Unit: "kbit/s", - }, -} - -var meas2 = []messages.Measurement{ - { - MeasurementTypeInstanceReference: "/network-function/distributed-unit-functions[id='ERICSSON-O-DU-11220']/cell[id='cell1']/supported-measurements/performance-measurement-type[.='user-equipment-average-throughput-downlink']/supported-snssai-subcounter-instances/slice-differentiator[.=1]", - Value: 400, - Unit: "kbit/s", - }, -} - -var meas3 = []messages.Measurement{ - { - MeasurementTypeInstanceReference: "/network-function/distributed-unit-functions[id='ERICSSON-O-DU-11220']/cell[id='cell1']/supported-measurements/performance-measurement-type[.='user-equipment-average-throughput-uplink']/supported-snssai-subcounter-instances/slice-differentiator[.=2][slice-service-type=2]", - Value: 800, - Unit: "kbit/s", - }, -} - -var meas4 = []messages.Measurement{ - { - MeasurementTypeInstanceReference: "/network-function/distributed-unit-functions[id='ERICSSON-O-DU-11220']/cell[id='cell1']/supported-measurements/performance-measurement-type[.='user-equipment-average-throughput-downlink']/supported-snssai-subcounter-instances/slice-differentiator[.=1]", - Value: 750, - Unit: "kbit/s", - }, -} - -var meas5 = []messages.Measurement{ - { - MeasurementTypeInstanceReference: "/network-function/distributed-unit-functions[id='ERICSSON-O-DU-11220']/cell[id='cell1']/supported-measurements/performance-measurement-type[.='user-equipment-average-throughput-downlink']/supported-snssai-subcounter-instances/[slice-differentiator[.=2]][slice-service-type=1]", - Value: 900, - Unit: "kbit/s", - }, -} diff --git a/test/usecases/odusliceassurance/goversion/stub/sdnr/sdnrstub.go b/test/usecases/odusliceassurance/goversion/stub/sdnr/sdnrstub.go deleted file mode 100644 index 41cc928f..00000000 --- a/test/usecases/odusliceassurance/goversion/stub/sdnr/sdnrstub.go +++ /dev/null @@ -1,142 +0,0 @@ -// - -// ========================LICENSE_START================================= -// O-RAN-SC -// %% -// Copyright (C) 2021: Nordix Foundation -// %% -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ========================LICENSE_END=================================== -// - -package main - -import ( - "encoding/json" - "flag" - "fmt" - "net/http" - - "github.com/gorilla/mux" - "oransc.org/usecase/oduclosedloop/messages" -) - -func main() { - port := flag.Int("port", 3904, "The port this SDNR stub will listen on") - flag.Parse() - - r := mux.NewRouter() - r.HandleFunc("/rests/data/network-topology:network-topology/topology=topology-netconf/node={NODE-ID}/yang-ext:mount/o-ran-sc-du-hello-world:network-function/distributed-unit-functions={O-DU-ID}", getDistributedUnitFunctions).Methods(http.MethodGet) - r.HandleFunc("/rests/data/network-topology:network-topology/topology=topology-netconf/node={NODE-ID}/yang-ext:mount/o-ran-sc-du-hello-world:network-function/distributed-unit-functions={O-DU-ID}/radio-resource-management-policy-ratio={POLICY-ID}", updateRRMPolicyDedicatedRatio).Methods(http.MethodPost) - - fmt.Println("Starting SDNR on port: ", *port) - http.ListenAndServe(fmt.Sprintf(":%v", *port), r) - -} - -func getDistributedUnitFunctions(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - - message := messages.ORanDuRestConf{ - DistributedUnitFunction: messages.DistributedUnitFunction{ - Id: vars["O-DU-ID"], - RRMPolicyRatio: []messages.RRMPolicyRatio{ - { - Id: "rrm-pol-1", - AdmState: "locked", - UserLabel: "rrm-pol-1", - RRMPolicyMaxRatio: 100, - RRMPolicyMinRatio: 0, - RRMPolicyDedicatedRatio: 0, - ResourceType: "prb", - RRMPolicyMembers: []messages.RRMPolicyMember{ - { - MobileCountryCode: "046", - MobileNetworkCode: "651", - SliceDifferentiator: 1, - SliceServiceType: 0, - }, - }, - }, - { - Id: "rrm-pol-2", - AdmState: "unlocked", - UserLabel: "rrm-pol-2", - RRMPolicyMaxRatio: 20, - RRMPolicyMinRatio: 10, - RRMPolicyDedicatedRatio: 15, - ResourceType: "prb", - RRMPolicyMembers: []messages.RRMPolicyMember{ - { - MobileCountryCode: "046", - MobileNetworkCode: "651", - SliceDifferentiator: 2, - SliceServiceType: 1, - }, - }, - }, - { - Id: "rrm-pol-3", - AdmState: "unlocked", - UserLabel: "rrm-pol-3", - RRMPolicyMaxRatio: 30, - RRMPolicyMinRatio: 10, - RRMPolicyDedicatedRatio: 5, - ResourceType: "prb", - RRMPolicyMembers: []messages.RRMPolicyMember{ - { - MobileCountryCode: "310", - MobileNetworkCode: "150", - SliceDifferentiator: 2, - SliceServiceType: 2, - }, - }, - }, - }, - }, - } - - respondWithJSON(w, http.StatusOK, message) -} - -func updateRRMPolicyDedicatedRatio(w http.ResponseWriter, r *http.Request) { - var prMessage messages.DistributedUnitFunction - decoder := json.NewDecoder(r.Body) - - if err := decoder.Decode(&prMessage); err != nil { - respondWithError(w, http.StatusBadRequest, "Invalid request payload") - return - } - defer r.Body.Close() - - fmt.Println("prMessage: ", prMessage) - - respondWithJSON(w, http.StatusOK, map[string]string{"status": "200"}) -} - -func respondWithError(w http.ResponseWriter, code int, message string) { - fmt.Println("-----------------------------------------------------------------------------") - fmt.Println("Sending error message: ", message) - fmt.Println("-----------------------------------------------------------------------------") - respondWithJSON(w, code, map[string]string{"error": message}) -} - -func respondWithJSON(w http.ResponseWriter, code int, payload interface{}) { - fmt.Println("-----------------------------------------------------------------------------") - fmt.Println("Sending message: ", payload) - fmt.Println("-----------------------------------------------------------------------------") - response, _ := json.Marshal(payload) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(code) - w.Write(response) -} diff --git a/test/usecases/odusliceassurance/goversion/stub/simulator.go b/test/usecases/odusliceassurance/goversion/stub/simulator.go index c8c747a6..aef85d80 100644 --- a/test/usecases/odusliceassurance/goversion/stub/simulator.go +++ b/test/usecases/odusliceassurance/goversion/stub/simulator.go @@ -38,7 +38,7 @@ import ( log "github.com/sirupsen/logrus" ) -const THRESHOLD_TPUT int = 700 +const THRESHOLD_TPUT int = 7000 type SliceAssuranceInformation struct { duId string @@ -117,7 +117,7 @@ func main() { r := mux.NewRouter() r.HandleFunc("/rests/data/network-topology:network-topology/topology=topology-netconf/node={NODE-ID}/yang-ext:mount/o-ran-sc-du-hello-world:network-function/distributed-unit-functions={O-DU-ID}", getSdnrResponseMessage).Methods(http.MethodGet) - r.HandleFunc("/rests/data/network-topology:network-topology/topology=topology-netconf/node={NODE-ID}/yang-ext:mount/o-ran-sc-du-hello-world:network-function/distributed-unit-functions={O-DU-ID}/radio-resource-management-policy-ratio={POLICY-ID}", updateRRMPolicyDedicatedRatio).Methods(http.MethodPost) + r.HandleFunc("/rests/data/network-topology:network-topology/topology=topology-netconf/node={NODE-ID}/yang-ext:mount/o-ran-sc-du-hello-world:network-function/distributed-unit-functions={O-DU-ID}/radio-resource-management-policy-ratio={POLICY-ID}", updateRRMPolicyDedicatedRatio).Methods(http.MethodPut) fmt.Println("Starting SDNR stub on port: ", *portSdnr) @@ -143,55 +143,133 @@ func getSdnrResponseMessage(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) log.Info("Get messages for RRM Policy Ratio information for O-Du ID ", vars["O-DU-ID"]) - message := messages.ORanDuRestConf{ - DistributedUnitFunction: messages.DistributedUnitFunction{ - Id: vars["O-DU-ID"], - RRMPolicyRatio: getPolicyRatioMessage(), - }, - } - respondWithJSON(w, http.StatusOK, message) + distUnitFunctions := getDistributedUnitFunctionMessage(vars["O-DU-ID"]) + + respondWithJSON(w, http.StatusOK, distUnitFunctions) } -func getPolicyRatioMessage() []messages.RRMPolicyRatio { +func getDistributedUnitFunctionMessage(oduId string) messages.ORanDuRestConf { + var policies []messages.RRMPolicyRatio + keys := make(map[string]bool) + for _, entry := range data { + if _, value := keys[entry.policyRatioId]; !value { + keys[entry.policyRatioId] = true + message := messages.RRMPolicyRatio{ + + Id: entry.policyRatioId, + AdmState: "locked", + UserLabel: entry.policyRatioId, + RRMPolicyMaxRatio: entry.policyMaxRatio, + RRMPolicyMinRatio: entry.policyMinRatio, + RRMPolicyDedicatedRatio: entry.policyDedicatedRatio, + ResourceType: "prb", + RRMPolicyMembers: []messages.RRMPolicyMember{ + { + MobileCountryCode: "310", + MobileNetworkCode: "150", + SliceDifferentiator: entry.sd, + SliceServiceType: entry.sst, + }, + }, + } + policies = append(policies, message) + } + } + var publicLandMobileNetworks []messages.PublicLandMobileNetworks for _, entry := range data { + publicLandMobileNetwork := messages.PublicLandMobileNetworks{ + MobileCountryCode: "310", + MobileNetworkCode: "150", + SliceDifferentiator: entry.sd, + SliceServiceType: entry.sst, + } + publicLandMobileNetworks = append(publicLandMobileNetworks, publicLandMobileNetwork) + } - message := messages.RRMPolicyRatio{ - Id: entry.policyRatioId, - AdmState: "locked", - UserLabel: entry.policyRatioId, - RRMPolicyMaxRatio: entry.policyMaxRatio, - RRMPolicyMinRatio: entry.policyMinRatio, - RRMPolicyDedicatedRatio: entry.policyDedicatedRatio, - ResourceType: "prb", - RRMPolicyMembers: []messages.RRMPolicyMember{ - { - MobileCountryCode: "046", - MobileNetworkCode: "651", - SliceDifferentiator: entry.sd, - SliceServiceType: entry.sst, - }, - }, + var supportedSnssaiSubcounterInstances []messages.SupportedSnssaiSubcounterInstances + for _, entry := range data { + supportedSnssaiSubcounterInstance := messages.SupportedSnssaiSubcounterInstances{ + SliceDifferentiator: entry.sd, + SliceServiceType: entry.sst, } - policies = append(policies, message) + supportedSnssaiSubcounterInstances = append(supportedSnssaiSubcounterInstances, supportedSnssaiSubcounterInstance) + } + + cell := messages.Cell{ + Id: "cell-1", + LocalId: 1, + PhysicalCellId: 1, + BaseStationChannelBandwidth: messages.BaseStationChannelBandwidth{ + Uplink: 83000, + Downlink: 80000, + SupplementaryUplink: 84000, + }, + OperationalState: "enabled", + TrackingAreaCode: 10, + AdmState: "unlocked", + PublicLandMobileNetworks: publicLandMobileNetworks, + SupportedMeasurements: []messages.SupportedMeasurements{ + { + PerformanceMeasurementType: "o-ran-sc-du-hello-world:user-equipment-average-throughput-uplink", + SupportedSnssaiSubcounterInstances: supportedSnssaiSubcounterInstances, + }, + { + PerformanceMeasurementType: "o-ran-sc-du-hello-world:user-equipment-average-throughput-downlink", + SupportedSnssaiSubcounterInstances: supportedSnssaiSubcounterInstances, + }, + }, + TrafficState: "active", + AbsoluteRadioFrequencyChannelNumber: messages.AbsoluteRadioFrequencyChannelNumber{ + Uplink: 14000, + Downlink: 15000, + SupplementaryUplink: 14500, + }, + UserLabel: "cell-1", + SynchronizationSignalBlock: messages.SynchronizationSignalBlock{ + Duration: 2, + FrequencyChannelNumber: 12, + Periodicity: 10, + SubcarrierSpacing: 30, + Offset: 3, + }, } - return policies + + distUnitFunction := messages.DistributedUnitFunction{ + Id: oduId, + OperationalState: "enabled", + AdmState: "unlocked", + UserLabel: oduId, + Cell: []messages.Cell{ + cell, + }, + RRMPolicyRatio: policies, + } + + duRRMPolicyRatio := messages.ORanDuRestConf{ + DistributedUnitFunction: []messages.DistributedUnitFunction{ + distUnitFunction, + }, + } + + return duRRMPolicyRatio } func updateRRMPolicyDedicatedRatio(w http.ResponseWriter, r *http.Request) { - - var prMessages []messages.RRMPolicyRatio + var policies struct { + RRMPolicies []messages.RRMPolicyRatio `json:"radio-resource-management-policy-ratio"` + } decoder := json.NewDecoder(r.Body) - if err := decoder.Decode(&prMessages); err != nil { + if err := decoder.Decode(&policies); err != nil { respondWithError(w, http.StatusBadRequest, "Invalid request payload") return } defer r.Body.Close() + prMessages := policies.RRMPolicies log.Infof("Post request to update RRMPolicyDedicatedRatio %+v", prMessages) - findAndUpdatePolicy(prMessages) respondWithJSON(w, http.StatusOK, map[string]string{"status": "200"}) } @@ -233,14 +311,14 @@ func sendDmaapMRMessages(w http.ResponseWriter, r *http.Request) { log.Info("Using tput value higher than THRESHOLD_TPUT ", randomTput) entry.metricValue = randomTput } - + randomEventId := rand.Intn(10000) messagesToSend = append(messagesToSend, generateMeasurementEntry(entry)) message := messages.StdDefinedMessage{ Event: messages.Event{ CommonEventHeader: messages.CommonEventHeader{ Domain: "stndDefined", - EventId: "pm-1_1644252450", + EventId: "pm-1_16442" + strconv.Itoa(randomEventId), EventName: "stndDefined_performanceMeasurementStreaming", EventType: "performanceMeasurementStreaming", Sequence: 825, @@ -275,17 +353,20 @@ func sendDmaapMRMessages(w http.ResponseWriter, r *http.Request) { }, } - fmt.Printf("Send Dmaap messages\n %+v\n", message) + fmt.Printf("Sending Dmaap message:\n %+v\n", message) + + messageAsByteArray, _ := json.Marshal(message) + response := [1]string{string(messageAsByteArray)} time.Sleep(time.Duration(rand.Intn(3)) * time.Second) - respondWithJSON(w, http.StatusOK, message) + respondWithJSON(w, http.StatusOK, response) messagesToSend = nil } func generateMeasurementEntry(entry *SliceAssuranceInformation) messages.Measurement { - measurementTypeInstanceReference := "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='" + entry.duId + "']/cell[id='" + entry.cellId + "']/supported-measurements/performance-measurement-type='(urn:o-ran-sc:yang:o-ran-sc-du-hello-world?revision=2021-11-23)" + entry.metricName + "']/supported-snssai-subcounter-instances[slice-differentiator='" + strconv.Itoa(entry.sd) + "'][slice-service-type='" + strconv.Itoa(entry.sst) + "']" + measurementTypeInstanceReference := "/o-ran-sc-du-hello-world:network-function/distributed-unit-functions[id='" + entry.duId + "']/cell[id='" + entry.cellId + "']/supported-measurements[performance-measurement-type='(urn:o-ran-sc:yang:o-ran-sc-du-hello-world?revision=2021-11-23)" + entry.metricName + "']/supported-snssai-subcounter-instances[slice-differentiator='" + strconv.Itoa(entry.sd) + "'][slice-service-type='" + strconv.Itoa(entry.sst) + "']" meas := messages.Measurement{ MeasurementTypeInstanceReference: measurementTypeInstanceReference, diff --git a/test/usecases/odusliceassurance/goversion/stub/test-data.csv b/test/usecases/odusliceassurance/goversion/stub/test-data.csv index 98335199..6c499b10 100644 --- a/test/usecases/odusliceassurance/goversion/stub/test-data.csv +++ b/test/usecases/odusliceassurance/goversion/stub/test-data.csv @@ -1,10 +1,10 @@ -O-DU-1211,cell-1,1,1,user-equipment-average-throughput-downlink,300,rrm-pol-1,20,10,15 -O-DU-1211,cell-1,1,1,user-equipment-average-throughput-uplink,500,rrm-pol-1,20,10,15 -O-DU-1211,cell-1,1,2,user-equipment-average-throughput-downlink,700,rrm-pol-2,20,10,15 -O-DU-1211,cell-1,1,2,user-equipment-average-throughput-uplink,400,rrm-pol-2,20,10,15 -O-DU-1211,cell-1,2,1,user-equipment-average-throughput-downlink,800,rrm-pol-3,20,10,15 -O-DU-1211,cell-1,2,1,user-equipment-average-throughput-uplink,100,rrm-pol-3,20,10,15 -O-DU-1211,cell-1,2,2,user-equipment-average-throughput-downlink,900,rrm-pol-4,20,10,15 -O-DU-1211,cell-1,2,2,user-equipment-average-throughput-uplink,500,rrm-pol-4,20,10,15 -O-DU-1211,cell-1,3,1,user-equipment-average-throughput-downlink,800,rrm-pol-5,20,10,15 -O-DU-1211,cell-1,3,1,user-equipment-average-throughput-uplink,100,rrm-pol-5,20,10,15 \ No newline at end of file +O-DU-1122,cell-1,1,1,user-equipment-average-throughput-downlink,3761,rrm-pol-1,20,10,15 +O-DU-1122,cell-1,1,1,user-equipment-average-throughput-uplink,5861,rrm-pol-1,20,10,15 +O-DU-1122,cell-1,1,2,user-equipment-average-throughput-downlink,7791,rrm-pol-2,20,10,15 +O-DU-1122,cell-1,1,2,user-equipment-average-throughput-uplink,4539,rrm-pol-2,20,10,15 +O-DU-1122,cell-1,2,1,user-equipment-average-throughput-downlink,8987,rrm-pol-3,20,10,15 +O-DU-1122,cell-1,2,1,user-equipment-average-throughput-uplink,1134,rrm-pol-3,20,10,15 +O-DU-1122,cell-1,2,2,user-equipment-average-throughput-downlink,9123,rrm-pol-4,20,10,15 +O-DU-1122,cell-1,2,2,user-equipment-average-throughput-uplink,5368,rrm-pol-4,20,10,15 +O-DU-1122,cell-1,3,1,user-equipment-average-throughput-downlink,8764,rrm-pol-5,20,10,15 +O-DU-1122,cell-1,3,1,user-equipment-average-throughput-uplink,1367,rrm-pol-5,20,10,15 \ No newline at end of file