From 6ace6b57e9cb5411f24c90c5b2c233a8c17274f4 Mon Sep 17 00:00:00 2001 From: Murilo Silva Date: Mon, 4 Mar 2024 14:40:43 -0300 Subject: [PATCH] add ueClient pkg --- go.mod | 6 +- go.sum | 15 +- pkg/manager/manager.go | 25 ++-- pkg/manager/options.go | 4 +- pkg/ueclient/options.go | 17 +++ pkg/ueclient/ueclient.go | 300 +++++++++++++++++++++++++++++++++++++++ pkg/uemgr/manager.go | 169 ---------------------- pkg/uemgr/options.go | 22 --- 8 files changed, 342 insertions(+), 216 deletions(-) create mode 100644 pkg/ueclient/options.go create mode 100644 pkg/ueclient/ueclient.go delete mode 100644 pkg/uemgr/manager.go delete mode 100644 pkg/uemgr/options.go diff --git a/go.mod b/go.mod index 6404ae3..84f01ef 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,11 @@ require ( github.com/onosproject/onos-api/go v0.10.31 github.com/onosproject/onos-lib-go v0.10.24 github.com/onosproject/onos-ric-sdk-go v0.8.12 - google.golang.org/grpc v1.62.0 ) require ( github.com/Shopify/sarama v1.31.1 // indirect github.com/atomix/atomix/api v0.8.0 // indirect - github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/eapache/go-resiliency v1.2.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect @@ -33,6 +31,7 @@ require ( github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/klauspost/compress v1.14.2 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect @@ -42,11 +41,13 @@ require ( github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.11.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/subosito/gotenv v1.2.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect @@ -58,6 +59,7 @@ require ( golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect + google.golang.org/grpc v1.62.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/square/go-jose.v1 v1.1.2 // indirect diff --git a/go.sum b/go.sum index ddc1d30..797f751 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,6 @@ github.com/atomix/atomix/api v0.8.0 h1:KJVf3xY/8+Dd+CsAp7sUMJGsWW3DtRoIWmRIMCoWH github.com/atomix/atomix/api v0.8.0/go.mod h1:Fz8zXQH6n28U0NTu5xctKhkNrN5RsWgX56lrMhqXlPg= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -196,8 +194,9 @@ github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -223,6 +222,7 @@ github.com/pelletier/go-toml/v2 v2.0.0-beta.8 h1:dy81yyLYJDwMTifq24Oi/IslOslRrDS github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -236,8 +236,9 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -261,8 +262,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= diff --git a/pkg/manager/manager.go b/pkg/manager/manager.go index 7b67bdb..9dfb463 100644 --- a/pkg/manager/manager.go +++ b/pkg/manager/manager.go @@ -1,9 +1,11 @@ package manager import ( + "context" + appConfig "github.com/gercom-ufpa/iqos-xapp/pkg/config" "github.com/gercom-ufpa/iqos-xapp/pkg/southbound/e2" - "github.com/gercom-ufpa/iqos-xapp/pkg/uemgr" + ueclient "github.com/gercom-ufpa/iqos-xapp/pkg/ueclient" "github.com/onosproject/onos-lib-go/pkg/logging" ) @@ -18,20 +20,22 @@ func NewManager(config Config) *Manager { log.Warn(err) } - // Creates App Managers - // UE-NIB Manager - uemgrConfig := uemgr.Config{ + // Creates App Clients + // UE-NIB Client + ueClientConfig := ueclient.Config{ UeNibEndpoint: config.UeNibEndpoint, UeNibPort: config.UeNibPort, + CertPath: config.CertPath, + KeyPath: config.KeyPath, } - ueManager, err := uemgr.NewManager(uemgrConfig) + ueClient, err := ueclient.NewClient(context.Background(), ueClientConfig) if err != nil { log.Warn(err) } // R-NIB Manager (TODO) - // A1 Manager (TODO) + // A1 Manager (or client?? - TODO) // E2 manager e2config := e2.Config{ @@ -56,7 +60,7 @@ func NewManager(config Config) *Manager { appConfig: appCfg, config: config, E2Manager: e2Manager, - UeManager: ueManager, + UeClient: ueClient, } return manager @@ -78,13 +82,6 @@ func (mgr *Manager) start() error { return err } - // starts UEManager Module (TODO) - // err := mgr.UEManager.Start(); - // if err != nil { - // log.Warnf("Fail to start UEManager: %v", err) - // return err - // } - // starts Slice Module (TODO) return nil diff --git a/pkg/manager/options.go b/pkg/manager/options.go index 2f11acb..0b1350c 100644 --- a/pkg/manager/options.go +++ b/pkg/manager/options.go @@ -3,7 +3,7 @@ package manager import ( appConfig "github.com/gercom-ufpa/iqos-xapp/pkg/config" "github.com/gercom-ufpa/iqos-xapp/pkg/southbound/e2" - "github.com/gercom-ufpa/iqos-xapp/pkg/uemgr" + ueclient "github.com/gercom-ufpa/iqos-xapp/pkg/ueclient" ) // manager configuration @@ -30,5 +30,5 @@ type Manager struct { appConfig appConfig.Config config Config E2Manager e2.Manager - UeManager uemgr.Manager + UeClient ueclient.Client } diff --git a/pkg/ueclient/options.go b/pkg/ueclient/options.go new file mode 100644 index 0000000..483bd01 --- /dev/null +++ b/pkg/ueclient/options.go @@ -0,0 +1,17 @@ +package ueclient + +import ( + "github.com/onosproject/onos-api/go/onos/uenib" +) + +type Client struct { + ueClient uenib.UEServiceClient + config Config +} + +type Config struct { + UeNibEndpoint string + UeNibPort int + CertPath string + KeyPath string +} diff --git a/pkg/ueclient/ueclient.go b/pkg/ueclient/ueclient.go new file mode 100644 index 0000000..18d29eb --- /dev/null +++ b/pkg/ueclient/ueclient.go @@ -0,0 +1,300 @@ +package ueclient + +import ( + "context" + "fmt" + "io" + "strconv" + + "github.com/onosproject/onos-api/go/onos/uenib" + "github.com/onosproject/onos-lib-go/pkg/errors" + "github.com/onosproject/onos-lib-go/pkg/logging" + "github.com/onosproject/onos-lib-go/pkg/southbound" +) + +var log = logging.GetLogger("iqos-xapp", "uemgr") + +// creates a new UE Client +func NewClient(ctx context.Context, config Config) (Client, error) { + // onos-uenib address + ueNibServiceAddress := config.UeNibEndpoint + ":" + strconv.Itoa(config.UeNibPort) + // connects to UE NIB service + conn, err := southbound.Connect(ctx, ueNibServiceAddress, config.CertPath, config.KeyPath) + if err != nil { + return Client{}, err + } + // creates a ue-nib client + ueClient := uenib.NewUEServiceClient(conn) + + return Client{ + ueClient: ueClient, + config: config, + }, nil +} + +// <--- To Slice Manager module ----> + +// Gets UE through your global ID | return an UE +func (c *Client) getUEWithGlobalID(ctx context.Context, ueGlobalId string) (uenib.UE, error) { + // creates an UE request + req := &uenib.GetUERequest{ + ID: uenib.ID(ueGlobalId), + } + + // gets an UE response + resp, err := c.ueClient.GetUE(ctx, req) + if err != nil { + return uenib.UE{}, err + } + + // return an UE + return resp.GetUE(), nil +} + +// Gets UEs on the network | return RsmUeInfo aspect of each UE +func (c *Client) GetRsmUEs(ctx context.Context) ([]*uenib.RsmUeInfo, error) { + // creates a result with RsmUeInfo aspect format + result := make([]*uenib.RsmUeInfo, 0) + + // creates a list UEs stream + stream, err := c.ueClient.ListUEs(ctx, &uenib.ListUERequest{}) + if err != nil { + return []*uenib.RsmUeInfo{}, err + } + + // iterate over the stream + for { + // get a stream item + response, err := stream.Recv() + if err == io.EOF { + break + } else if err != nil { + return []*uenib.RsmUeInfo{}, err + } + // gets UE + ue := response.GetUE() + // RsmUeInfo aspect + rsmUE := &uenib.RsmUeInfo{} + err = ue.GetAspect(rsmUE) + if err != nil { + return []*uenib.RsmUeInfo{}, err + } + + result = append(result, rsmUE) + } + return result, nil +} + +// Checks if a RSM UE already exists +func (c *Client) HasRsmUE(ctx context.Context, rsmUeAspect *uenib.RsmUeInfo) bool { + // gets a list of UEs with RSM aspects + rsmUes, err := c.GetRsmUEs(ctx) + if err != nil { + log.Debug("onos-uenib has no UE") + return false + } + + // iterate of UEs + for _, item := range rsmUes { + // TODO: Is it necessary to check all these values? + if item.GetGlobalUeID() == rsmUeAspect.GetGlobalUeID() && + item.GetUeIdList().GetDuUeF1apID().Value == rsmUeAspect.GetUeIdList().GetDuUeF1apID().Value && + item.GetUeIdList().GetCuUeF1apID().Value == rsmUeAspect.GetUeIdList().GetCuUeF1apID().Value && + item.GetUeIdList().GetRANUeNgapID().Value == rsmUeAspect.GetUeIdList().GetRANUeNgapID().Value && + item.GetUeIdList().GetEnbUeS1apID().Value == rsmUeAspect.GetUeIdList().GetEnbUeS1apID().Value && // for 4G + item.GetUeIdList().GetAMFUeNgapID().Value == rsmUeAspect.GetUeIdList().GetAMFUeNgapID().Value && // for 5G + item.GetUeIdList().GetPreferredIDType().String() == rsmUeAspect.GetUeIdList().GetPreferredIDType().String() && + item.GetCellGlobalId() == rsmUeAspect.GetCellGlobalId() && + item.GetCuE2NodeId() == rsmUeAspect.GetCuE2NodeId() && item.GetDuE2NodeId() == rsmUeAspect.GetDuE2NodeId() { + return true + } + } + + log.Debugf("onos-uenib has UE %v", *rsmUeAspect) + return false +} + +// Adds an RSM UE with RsmUEInfo aspect +func (c *Client) AddRsmUE(ctx context.Context, rsmUeAspect *uenib.RsmUeInfo) error { + log.Debugf("received ue: %v", rsmUeAspect) + + // checks if UE already exist + if c.HasRsmUE(ctx, rsmUeAspect) { + return errors.NewAlreadyExists(fmt.Sprintf("UE already exists - UE: %v", *rsmUeAspect)) + } + + // creates an obj UE + uenibObj := uenib.UE{ + ID: uenib.ID(rsmUeAspect.GetGlobalUeID()), + } + + // sets aspect + uenibObj.SetAspect(rsmUeAspect) + + // creates an UE create request + req := &uenib.CreateUERequest{ + UE: uenibObj, + } + + // creates UE + resp, err := c.ueClient.CreateUE(ctx, req) + if err != nil { + log.Warn(err) + } + + log.Debugf("AddRsmUE Resp: %v", resp) + return nil +} + +// Updates an existing RSM UE +func (c *Client) UpdateRsmUE(ctx context.Context, rsmUeAspect *uenib.RsmUeInfo) error { + // checks if UE already exist + if !c.HasRsmUE(ctx, rsmUeAspect) { + return errors.NewNotFound(fmt.Sprintf("UE not found - UE: %v", *rsmUeAspect)) + } + + // creates an obj UE + uenibObj := uenib.UE{ + ID: uenib.ID(rsmUeAspect.GetGlobalUeID()), + } + + // sets aspect + uenibObj.SetAspect(rsmUeAspect) + + // creates an UE create request + req := &uenib.UpdateUERequest{ + UE: uenibObj, + } + + // updates UE + resp, err := c.ueClient.UpdateUE(ctx, req) + if err != nil { + return err + } + + log.Debugf("UpdateUE Resp: %v", resp) + + return nil +} + +// Deletes an existing UE +func (c *Client) DeleteUE(ctx context.Context, ueGlobalId string) error { + log.Debugf("received UeGlobalID: %v", ueGlobalId) + + // Gets UE through your global ID + ue, err := c.getUEWithGlobalID(ctx, ueGlobalId) + if err != nil { + return err + } + + // creates a rsmUeInfo aspect + rsmUE := &uenib.RsmUeInfo{} + // gets rsmUeInfo aspect from UE + err = ue.GetAspect(rsmUE) + if err != nil { + return err + } + + // checks if UE exist + if !c.HasRsmUE(ctx, rsmUE) { + return errors.NewNotFound(fmt.Sprintf("UE not found - UE: %v", *rsmUE)) + } + + // creates a requisition to delete UE + req := &uenib.DeleteUERequest{ + ID: uenib.ID(rsmUE.GetGlobalUeID()), + } + + // deletes UE + resp, err := c.ueClient.DeleteUE(ctx, req) + if err != nil { + return err + } + + log.Debugf("DeleteUE Resp: %v", resp) + return nil +} + +// deletes an RSM UE from specific infrastructure/technology +func (c *Client) DeleteRsmUEWithPreferredID(ctx context.Context, cuNodeID string, preferredType uenib.UeIdType, ueConnectionTypeID int64) error { + log.Debugf("received CUID: %v, preferredType: %v, ueID: %v", cuNodeID, preferredType, ueConnectionTypeID) + // gets UE + rsmUE, err := c.GetRsmUEWithPreferredID(ctx, cuNodeID, preferredType, ueConnectionTypeID) + if err != nil { + return err + } + // deletes UE + return c.DeleteUE(ctx, rsmUE.GetGlobalUeID()) +} + +// deletes UE by E2 Node ID +func (c *Client) DeleteUEWithE2NodeID(ctx context.Context, e2NodeID string) error { + // get UEs with RSM aspect + rsmUes, err := c.GetRsmUEs(ctx) + if err != nil { + return err + } + + for _, ue := range rsmUes { + // checks if the UE is connected to a CU or DU + if ue.GetDuE2NodeId() == e2NodeID || ue.GetCuE2NodeId() == e2NodeID { + // deletes UE + err = c.DeleteUE(ctx, ue.GetGlobalUeID()) + if err != nil { + log.Warn(err) + } + } + } + return err +} + +// gets an RSM UE from specific infrastructure/technology | return RsmUeInfo aspect from UE +func (c *Client) GetRsmUEWithPreferredID(ctx context.Context, cuNodeID string, preferredType uenib.UeIdType, ueConnectionTypeID int64) (uenib.RsmUeInfo, error) { + var result uenib.RsmUeInfo + hasUE := false + + // gets RSM UEs + rsmUes, err := c.GetRsmUEs(ctx) + if err != nil { + return uenib.RsmUeInfo{}, err + } + + // for each RSM UEs checks connection technology (is nomenclature right?) + for _, rsmUE := range rsmUes { + switch preferredType { + case uenib.UeIdType_UE_ID_TYPE_CU_UE_F1_AP_ID: + if rsmUE.GetCuE2NodeId() == cuNodeID && rsmUE.GetUeIdList().GetCuUeF1apID().Value == ueConnectionTypeID { + result = *rsmUE + hasUE = true + } + case uenib.UeIdType_UE_ID_TYPE_DU_UE_F1_AP_ID: + if rsmUE.GetCuE2NodeId() == cuNodeID && rsmUE.GetUeIdList().GetDuUeF1apID().Value == ueConnectionTypeID { + result = *rsmUE + hasUE = true + } + case uenib.UeIdType_UE_ID_TYPE_RAN_UE_NGAP_ID: + if rsmUE.GetCuE2NodeId() == cuNodeID && rsmUE.GetUeIdList().GetRANUeNgapID().Value == ueConnectionTypeID { + result = *rsmUE + hasUE = true + } + case uenib.UeIdType_UE_ID_TYPE_AMF_UE_NGAP_ID: + if rsmUE.GetCuE2NodeId() == cuNodeID && rsmUE.GetUeIdList().GetAMFUeNgapID().Value == ueConnectionTypeID { + result = *rsmUE + hasUE = true + } + case uenib.UeIdType_UE_ID_TYPE_ENB_UE_S1_AP_ID: + if rsmUE.GetCuE2NodeId() == cuNodeID && rsmUE.GetUeIdList().GetEnbUeS1apID().Value == int32(ueConnectionTypeID) { + result = *rsmUE + hasUE = true + } + default: + return uenib.RsmUeInfo{}, errors.NewNotSupported(fmt.Sprintf("ID type %v is not allowed", preferredType.String())) + } + } + + // checks if UE was not found + if !hasUE { + return uenib.RsmUeInfo{}, errors.NewNotFound(fmt.Sprintf("UE Connection %v, with ID %v, does not exist in CU %v", preferredType.String(), ueConnectionTypeID, cuNodeID)) + } + return result, nil +} diff --git a/pkg/uemgr/manager.go b/pkg/uemgr/manager.go deleted file mode 100644 index a179078..0000000 --- a/pkg/uemgr/manager.go +++ /dev/null @@ -1,169 +0,0 @@ -package uemgr - -import ( - "context" - "io" - "strconv" - - "github.com/onosproject/onos-api/go/onos/uenib" - "github.com/onosproject/onos-lib-go/pkg/grpc/retry" - "github.com/onosproject/onos-lib-go/pkg/logging" - "github.com/onosproject/onos-ric-sdk-go/pkg/e2/creds" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -var log = logging.GetLogger("iqos-xapp", "uemgr") - -// creates a new UE Manager -func NewManager(config Config) (Manager, error) { - // onos-uenib address - ueNibServiceAddress := config.UeNibEndpoint + ":" + strconv.Itoa(config.UeNibPort) - // connects to UE NIB service - conn, err := connectUeNibServiceHost(ueNibServiceAddress) - if err != nil { - return Manager{}, err - } - // creates a ue-nib client - ueClient := uenib.CreateUEServiceClient(conn) - - return Manager{ - ueClient: ueClient, - }, nil -} - -// starts UE Manager -func (m *Manager) Start() error { - // go routine - go func() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - err := m.watchUEConnections(ctx) - if err != nil { - log.Warn(err) - return - } - }() - - return nil -} - -// watch UEs changes -func (m *Manager) watchUEConnections(ctx context.Context) error { - // list UEs - m.listUEs(ctx) - - // watch changes - log.Info("Starting to watch the UEs changes") - stream, err := m.ueClient.WatchUEs(ctx, &uenib.WatchUERequest{AspectTypes: defaultAspectTypes}) - if err != nil { - log.Warn(err) - return err - } - - for { - msg, err := stream.Recv() - if err == io.EOF { - break - } - if err != nil { - log.Warn(err) - } - - log.Debug(msg.Event.Type.String(), msg.Event.UE.String()) - // processEvent(); (TODO) - } - - return nil -} - -// list all UEs -func (m *Manager) listUEs(ctx context.Context) { - log.Info("Starting UEs listing") - // get UEs stream - stream, err := m.ueClient.ListUEs(ctx, &uenib.ListUERequest{AspectTypes: defaultAspectTypes}) - if err != nil { - log.Warn(err) - return - } - - // Number of UEs - num_ues := 0 - - for { - response, err := stream.Recv() - if err == io.EOF { - break - } - if err != nil { - log.Warn(err) - } - - // increment num of UEs - num_ues++ - - // print UE num and UE ID - log.Debugf("UE-%d with ID %v connected", num_ues, response.UE.ID) - - // get UE aspectTypes - aspects := m.getUEAspects(ctx, response.UE.ID) - log.Debugf("Available aspects of UE-%d: %s", num_ues, aspects) - } - - log.Infof("Total connected UEs: %d", num_ues) -} - -// func (m *Manager) getUes() (uenib.UE, error) { // TODO -// } - -// getUE gets UE aspects -func (m *Manager) getUEAspects(ctx context.Context, ueID uenib.ID) []string { - response, err := m.ueClient.GetUE(ctx, &uenib.GetUERequest{ID: ueID}) - if err != nil { - log.Warn(err) - return nil - } - - var aspects []string - - for k := range response.UE.GetAspects() { - aspects = append(aspects, k) - } - - return aspects -} - -func (m *Manager) createUEAspect(ctx context.Context) { -} - -// TODO: it is not necessary for now -func (m *Manager) updateUEAspects(ctx context.Context, ue uenib.UE) { - log.Debug("Updating UE aspects") - - // uncomment me to set aspect to existing UE - ue.SetAspect(&uenib.CellInfo{ServingCell: &uenib.CellConnection{ - ID: "e2:4/e00/2/64/e0000", - SignalStrength: 11.0, - }}) - - _, err := m.ueClient.UpdateUE(ctx, &uenib.UpdateUERequest{ - UE: ue, - }) - - if err != nil { - log.Warn(err) - } -} - -// ConnectUeNibServiceHost connects to UE NIB service -func connectUeNibServiceHost(UeNibServiceAddress string) (*grpc.ClientConn, error) { - tlsConfig, err := creds.GetClientCredentials() - if err != nil { - return nil, err - } - opts := []grpc.DialOption{ - grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), - } - opts = append(opts, grpc.WithUnaryInterceptor(retry.RetryingUnaryClientInterceptor())) - return grpc.DialContext(context.Background(), UeNibServiceAddress, opts...) -} diff --git a/pkg/uemgr/options.go b/pkg/uemgr/options.go deleted file mode 100644 index 1d0b978..0000000 --- a/pkg/uemgr/options.go +++ /dev/null @@ -1,22 +0,0 @@ -package uemgr - -import "github.com/onosproject/onos-api/go/onos/uenib" - -// default aspect types to get of UEs -var defaultAspectTypes = []string{} - -type Manager struct { - ueClient uenib.UEServiceClient -} - -type Config struct { - UeNibEndpoint string - UeNibPort int -} - -type UE struct { - ID string - aspectTypes []string -} - -type UEs []UE