Submgr REST subscriptions in SDL Database 13/6313/2
authorKonstantinos Archangelof <konstantinos.archangelof@nokia.com>
Mon, 14 Jun 2021 09:24:00 +0000 (12:24 +0300)
committerKonstantinos Archangelof <konstantinos.archangelof@nokia.com>
Mon, 14 Jun 2021 09:52:37 +0000 (12:52 +0300)
   * renamed sdl.go  to sdl_e2SubsDb.go
   * renamed sdl_test.go to sdl_e2SubsDb_test.go
   * New file sdl_restSubsDb.go implements the SDL API for the REST Subscriptions
   * New file sdl_restSubsDb_test.go implements unittests for the SDL API for the REST Subscriptions
   * New db restSubsDb defined under Control object in submgr to hold the SDL DB data structure
   * SDL API for the REST Subscriptions is called from submgr code.

Signed-off-by: Konstantinos Archangelof <konstantinos.archangelof@nokia.com>
Change-Id: I447da9030aba2a582e38d24ef86722894d0c41e1

pkg/control/control.go
pkg/control/registry.go
pkg/control/sdl_e2SubsDb.go [moved from pkg/control/sdl.go with 88% similarity]
pkg/control/sdl_e2SubsDb_test.go [moved from pkg/control/sdl_test.go with 98% similarity]
pkg/control/sdl_restSubsDb.go [new file with mode: 0644]
pkg/control/sdl_restSubsDb_test.go [new file with mode: 0644]
pkg/control/ut_ctrl_submgr_test.go

index 9779498..c74b1a5 100755 (executable)
@@ -74,7 +74,8 @@ type Control struct {
        e2ap          *E2ap
        registry      *Registry
        tracker       *Tracker
-       db            Sdlnterface
+       e2SubsDb      Sdlnterface
+       restSubsDb    Sdlnterface
        CntRecvMsg    uint64
        ResetTestFlag bool
        Counters      map[string]xapp.Counter
@@ -112,7 +113,8 @@ func NewControl() *Control {
        c := &Control{e2ap: new(E2ap),
                registry:    registry,
                tracker:     tracker,
-               db:          CreateSdl(),
+               e2SubsDb:    CreateSdl(),
+               restSubsDb:  CreateRESTSdl(),
                Counters:    xapp.Metric.RegisterCounterGroup(GetMetricsOpts(), "SUBMGR"),
                LoggerLevel: 3,
        }
@@ -140,6 +142,13 @@ func NewControl() *Control {
                c.registry.register = register
                c.HandleUncompletedSubscriptions(register)
        }
+
+       restSubscriptions, err := c.ReadAllRESTSubscriptionsFromSdl()
+       if err != nil {
+               xapp.Logger.Error("%v", err)
+       } else {
+               c.registry.restSubscriptions = restSubscriptions
+       }
        return c
 }
 
@@ -299,9 +308,11 @@ func (c *Control) SubscriptionHandler(params interface{}) (*models.SubscriptionR
                                return &subResp, nil
                        }
                }
-               restSubscription.Md5sumOngoing = md5sum
+               restSubscription.Md5sum = md5sum
        }
 
+       c.WriteRESTSubscriptionToDb(restSubId, restSubscription)
+
        go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId, xAppRmrEndpoint)
 
        c.UpdateCounter(cRestSubRespToXapp)
@@ -324,6 +335,7 @@ func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSu
        }
        // Mark REST subscription request processed.
        restSubscription.SetProcessed()
+       c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
        if trans != nil {
                xapp.Logger.Info("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
                        errorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
@@ -354,6 +366,7 @@ func (c *Control) sendSuccesfullResponseNotification(restSubId *string, restSubs
        }
        // Mark REST subscription request processesd.
        restSubscription.SetProcessed()
+       c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
        xapp.Logger.Info("Sending successful REST notification to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
                clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
 
@@ -373,7 +386,7 @@ func (c *Control) processSubscriptionRequests(restSubscription *RESTSubscription
        var xAppEventInstanceID int64
        var e2EventInstanceID int64
 
-       defer restDuplicateCtrl.TransactionComplete(restSubscription.Md5sumOngoing)
+       defer restDuplicateCtrl.TransactionComplete(restSubscription.Md5sum)
 
        for index := 0; index < len(subReqList.E2APSubscriptionRequests); index++ {
                subReqMsg := subReqList.E2APSubscriptionRequests[index]
@@ -491,6 +504,7 @@ func (c *Control) SubscriptionDeleteHandlerCB(restSubId string) error {
                        restSubscription.DeleteE2InstanceId(instanceId)
                }
                c.registry.DeleteRESTSubscription(&restSubId)
+               c.RemoveRESTSubscriptionFromDb(restSubId)
        }()
 
        c.UpdateCounter(cRestSubDelRespToXapp)
@@ -569,6 +583,7 @@ func (c *Control) TestRestHandler(w http.ResponseWriter, r *http.Request) {
        if s == "emptydb" {
                xapp.Logger.Info("RemoveAllSubscriptionsFromSdl() called")
                c.RemoveAllSubscriptionsFromSdl()
+               c.RemoveAllRESTSubscriptionsFromSdl()
                return
        }
 
@@ -1138,6 +1153,41 @@ func (c *Control) RemoveSubscriptionFromDb(subs *Subscription) {
        }
 }
 
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+func (c *Control) WriteRESTSubscriptionToDb(restSubId string, restSubs *RESTSubscription) {
+       xapp.Logger.Debug("WriteRESTSubscriptionToDb() restSubId = %s", restSubId)
+       err := c.WriteRESTSubscriptionToSdl(restSubId, restSubs)
+       if err != nil {
+               xapp.Logger.Error("%v", err)
+       }
+}
+
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+func (c *Control) UpdateRESTSubscriptionInDB(restSubId string, restSubs *RESTSubscription, removeRestSubscriptionFromDb bool) {
+
+       if removeRestSubscriptionFromDb == true {
+               // Subscription was written in db already when subscription request was sent to BTS, except for merged request
+               c.RemoveRESTSubscriptionFromDb(restSubId)
+       } else {
+               c.WriteRESTSubscriptionToDb(restSubId, restSubs)
+       }
+}
+
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+func (c *Control) RemoveRESTSubscriptionFromDb(restSubId string) {
+       xapp.Logger.Debug("RemoveRESTSubscriptionFromDb() restSubId = %s", restSubId)
+       err := c.RemoveRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               xapp.Logger.Error("%v", err)
+       }
+}
+
 func (c *Control) SendSubscriptionDeleteReq(subs *Subscription) {
 
        const ricRequestorId = 123
index 5259273..671cf51 100644 (file)
@@ -40,7 +40,7 @@ type RESTSubscription struct {
        xAppIdToE2Id     map[int64]int64
        SubReqOngoing    bool
        SubDelReqOngoing bool
-       Md5sumOngoing    string
+       Md5sum           string
 }
 
 func (r *RESTSubscription) AddE2InstanceId(instanceId uint32) {
@@ -65,7 +65,7 @@ func (r *RESTSubscription) DeleteXappIdToE2Id(xAppEventInstanceID int64) {
 
 func (r *RESTSubscription) SetProcessed() {
        r.SubReqOngoing = false
-       r.Md5sumOngoing = ""
+       r.Md5sum = ""
 }
 
 type Registry struct {
similarity index 88%
rename from pkg/control/sdl.go
rename to pkg/control/sdl_e2SubsDb.go
index ac8b8fb..c2526bc 100644 (file)
@@ -22,10 +22,11 @@ package control
 import (
        "encoding/json"
        "fmt"
+       "strconv"
+
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
        sdl "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "strconv"
 )
 
 type SubscriptionInfo struct {
@@ -39,7 +40,7 @@ type SubscriptionInfo struct {
 }
 
 func CreateSdl() Sdlnterface {
-       return sdl.NewSdlInstance("submgr", sdl.NewDatabase())
+       return sdl.NewSdlInstance("submgr_e2SubsDb", sdl.NewDatabase())
 }
 
 func (c *Control) WriteSubscriptionToSdl(subId uint32, subs *Subscription) error {
@@ -63,11 +64,11 @@ func (c *Control) WriteSubscriptionToSdl(subId uint32, subs *Subscription) error
                return fmt.Errorf("SDL: WriteSubscriptionToSdl() json.Marshal error: %s", err.Error())
        }
 
-       if err = c.db.Set(strconv.FormatUint(uint64(subId), 10), jsonData); err != nil {
+       if err = c.e2SubsDb.Set(strconv.FormatUint(uint64(subId), 10), jsonData); err != nil {
                c.UpdateCounter(cSDLWriteFailure)
                return fmt.Errorf("SDL: WriteSubscriptionToSdl(): %s", err.Error())
        } else {
-               xapp.Logger.Debug("SDL: Subscription written in db. subId = %v", subId)
+               xapp.Logger.Debug("SDL: Subscription written in e2SubsDb. subId = %v", subId)
        }
        return nil
 }
@@ -76,12 +77,12 @@ func (c *Control) ReadSubscriptionFromSdl(subId uint32) (*Subscription, error) {
 
        // This function is now just for testing purpose
        key := strconv.FormatUint(uint64(subId), 10)
-       retMap, err := c.db.Get([]string{key})
+       retMap, err := c.e2SubsDb.Get([]string{key})
        if err != nil {
                c.UpdateCounter(cSDLReadFailure)
                return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl(): %s", err.Error())
        } else {
-               xapp.Logger.Debug("SDL: Subscription read from db.  subId = %v", subId)
+               xapp.Logger.Debug("SDL: Subscription read from e2SubsDb.  subId = %v", subId)
        }
 
        subs := &Subscription{}
@@ -134,10 +135,10 @@ func (c *Control) CreateSubscription(subscriptionInfo *SubscriptionInfo, jsonSub
 func (c *Control) RemoveSubscriptionFromSdl(subId uint32) error {
 
        key := strconv.FormatUint(uint64(subId), 10)
-       if err := c.db.Remove([]string{key}); err != nil {
+       if err := c.e2SubsDb.Remove([]string{key}); err != nil {
                return fmt.Errorf("SDL: RemoveSubscriptionfromSdl(): %s\n", err.Error())
        } else {
-               xapp.Logger.Debug("SDL: Subscription removed from db. subId = %v", subId)
+               xapp.Logger.Debug("SDL: Subscription removed from e2SubsDb. subId = %v", subId)
        }
        return nil
 }
@@ -153,10 +154,10 @@ func (c *Control) ReadAllSubscriptionsFromSdl() ([]uint32, map[uint32]*Subscript
 
        retMap := make(map[uint32]*Subscription)
        // Get all keys
-       keys, err := c.db.GetAll()
+       keys, err := c.e2SubsDb.GetAll()
        if err != nil {
                c.UpdateCounter(cSDLReadFailure)
-               return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), GetAll(). Error while reading keys from DBAAS %s\n", err.Error())
+               return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), GetAll(). Error while reading E2 subscriptions  keys from DBAAS %s\n", err.Error())
        }
 
        if len(keys) == 0 {
@@ -164,10 +165,10 @@ func (c *Control) ReadAllSubscriptionsFromSdl() ([]uint32, map[uint32]*Subscript
        }
 
        // Get all subscriptionInfos
-       iSubscriptionMap, err := c.db.Get(keys)
+       iSubscriptionMap, err := c.e2SubsDb.Get(keys)
        if err != nil {
                c.UpdateCounter(cSDLReadFailure)
-               return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), Get():  Error while reading subscriptions from DBAAS %s\n", err.Error())
+               return nil, nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), Get():  Error while reading E2 subscriptions from DBAAS %s\n", err.Error())
        }
 
        for _, iSubscriptionInfo := range iSubscriptionMap {
@@ -209,11 +210,11 @@ func removeNumber(s []uint32, removedNum uint32) ([]uint32, error) {
 }
 func (c *Control) RemoveAllSubscriptionsFromSdl() error {
 
-       if err := c.db.RemoveAll(); err != nil {
+       if err := c.e2SubsDb.RemoveAll(); err != nil {
                c.UpdateCounter(cSDLRemoveFailure)
                return fmt.Errorf("SDL: RemoveAllSubscriptionsFromSdl(): %s\n", err.Error())
        } else {
-               xapp.Logger.Debug("SDL: All subscriptions removed from db")
+               xapp.Logger.Debug("SDL: All subscriptions removed from e2SubsDb")
        }
        return nil
 }
similarity index 98%
rename from pkg/control/sdl_test.go
rename to pkg/control/sdl_e2SubsDb_test.go
index 2fac9b2..2deb4b5 100644 (file)
@@ -46,7 +46,7 @@ const (
 )
 
 type Mock struct {
-       subsDB             map[string]string // Store information as a string like real db does.
+       e2SubsDb           map[string]string // Store information as a string like real db does.
        register           map[uint32]*Subscription
        subIds             []uint32
        lastAllocatedSubId uint32
@@ -63,7 +63,7 @@ func CreateMock() *Mock {
 }
 
 func (m *Mock) ResetTestSettings() {
-       m.subsDB = make(map[string]string)
+       m.e2SubsDb = make(map[string]string)
        m.register = make(map[uint32]*Subscription)
        var i uint32
        for i = 1; i < 65535; i++ {
@@ -490,7 +490,7 @@ func (m *Mock) Set(pairs ...interface{}) error {
        }
 
        if key != "" {
-               m.subsDB[key] = val
+               m.e2SubsDb[key] = val
                subId := m.subIds[0]
                subscriptionInfo := &SubscriptionInfo{}
                err := json.Unmarshal([]byte(val), subscriptionInfo)
@@ -519,7 +519,7 @@ func (m *Mock) Get(keys []string) (map[string]interface{}, error) {
 
        for _, key := range keys {
                if key != "" {
-                       retMap[key] = m.subsDB[key]
+                       retMap[key] = m.e2SubsDb[key]
                } else {
                        return nil, fmt.Errorf("Get() error: key == ''\n")
                }
@@ -534,7 +534,7 @@ func (m *Mock) GetAll() ([]string, error) {
        }
 
        keys := []string{}
-       for key, _ := range m.subsDB {
+       for key, _ := range m.e2SubsDb {
                keys = append(keys, key)
        }
        return keys, nil
@@ -554,7 +554,7 @@ func (m *Mock) Remove(keys []string) error {
        }
 
        subId := uint32(subId64)
-       delete(m.subsDB, keys[0])
+       delete(m.e2SubsDb, keys[0])
        delete(m.register, subId)
        m.subIds = append(m.subIds, subId)
        return nil
@@ -562,14 +562,14 @@ func (m *Mock) Remove(keys []string) error {
 
 func (m *Mock) RemoveAll() error {
 
-       for key := range m.subsDB {
+       for key := range m.e2SubsDb {
                subId64, err := strconv.ParseUint(key, 10, 64)
                if err != nil {
                        return fmt.Errorf("RemoveAll() ParseUint() error: %s\n", err.Error())
                }
 
                subId := uint32(subId64)
-               delete(m.subsDB, key)
+               delete(m.e2SubsDb, key)
                delete(m.register, subId)
                m.subIds = append(m.subIds, subId)
        }
diff --git a/pkg/control/sdl_restSubsDb.go b/pkg/control/sdl_restSubsDb.go
new file mode 100644 (file)
index 0000000..782108f
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+   ==================================================================================
+  Copyright (c) 2019 AT&T Intellectual Property.
+  Copyright (c) 2019 Nokia
+
+   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.
+   ==================================================================================
+*/
+
+package control
+
+import (
+       "encoding/json"
+       "fmt"
+
+       sdl "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+)
+
+type RESTSubscriptionInfo struct {
+       xAppRmrEndPoint  string
+       Meid             string
+       InstanceIds      []uint32
+       xAppIdToE2Id     map[int64]int64
+       SubReqOngoing    bool
+       SubDelReqOngoing bool
+       Md5sum           string
+}
+
+func CreateRESTSdl() Sdlnterface {
+       return sdl.NewSdlInstance("submgr_restSubsDb", sdl.NewDatabase())
+}
+
+func (c *Control) WriteRESTSubscriptionToSdl(restSubId string, restSubs *RESTSubscription) error {
+
+       var restSubscriptionInfo RESTSubscriptionInfo
+       restSubscriptionInfo.xAppRmrEndPoint = restSubs.xAppRmrEndPoint
+       restSubscriptionInfo.Meid = restSubs.Meid
+       restSubscriptionInfo.InstanceIds = restSubs.InstanceIds
+       restSubscriptionInfo.xAppIdToE2Id = restSubs.xAppIdToE2Id
+       restSubscriptionInfo.SubReqOngoing = restSubs.SubReqOngoing
+       restSubscriptionInfo.SubDelReqOngoing = restSubs.SubDelReqOngoing
+       restSubscriptionInfo.Md5sum = restSubs.Md5sum
+
+       jsonData, err := json.Marshal(restSubscriptionInfo)
+       if err != nil {
+               return fmt.Errorf("SDL: WriteSubscriptionToSdl() json.Marshal error: %s", err.Error())
+       }
+
+       if err = c.restSubsDb.Set(restSubId, jsonData); err != nil {
+               c.UpdateCounter(cSDLWriteFailure)
+               return fmt.Errorf("SDL: WriteSubscriptionToSdl(): %s", err.Error())
+       } else {
+               xapp.Logger.Debug("SDL: Subscription written in restSubsDb. restSubId = %v", restSubId)
+       }
+       return nil
+}
+
+func (c *Control) ReadRESTSubscriptionFromSdl(restSubId string) (*RESTSubscription, error) {
+
+       // This function is now just for testing purpose
+       key := restSubId
+       retMap, err := c.restSubsDb.Get([]string{key})
+       if err != nil {
+               c.UpdateCounter(cSDLReadFailure)
+               return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl(): %s", err.Error())
+       } else {
+               xapp.Logger.Debug("SDL: Subscription read from restSubsDb.  restSubId = %v", restSubId)
+       }
+
+       restSubs := &RESTSubscription{}
+       for _, iRESTSubscriptionInfo := range retMap {
+
+               if iRESTSubscriptionInfo == nil {
+                       return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl() REST subscription not found. restSubId = %v\n", restSubId)
+               }
+
+               restSubscriptionInfo := &RESTSubscriptionInfo{}
+               jsonSubscriptionInfo := iRESTSubscriptionInfo.(string)
+
+               if err := json.Unmarshal([]byte(jsonSubscriptionInfo), restSubscriptionInfo); err != nil {
+                       return nil, fmt.Errorf("SDL: ReadSubscriptionFromSdl() json.unmarshal error: %s\n", err.Error())
+               }
+
+               restSubs = c.CreateRESTSubscription(restSubscriptionInfo, &jsonSubscriptionInfo)
+       }
+       return restSubs, nil
+}
+
+func (c *Control) CreateRESTSubscription(restSubscriptionInfo *RESTSubscriptionInfo, jsonSubscriptionInfo *string) *RESTSubscription {
+
+       restSubs := &RESTSubscription{}
+       restSubs.xAppRmrEndPoint = restSubscriptionInfo.xAppRmrEndPoint
+       restSubs.Meid = restSubscriptionInfo.Meid
+       restSubs.InstanceIds = restSubscriptionInfo.InstanceIds
+       restSubs.xAppIdToE2Id = restSubscriptionInfo.xAppIdToE2Id
+       restSubs.SubReqOngoing = restSubscriptionInfo.SubReqOngoing
+       restSubs.SubDelReqOngoing = restSubscriptionInfo.SubDelReqOngoing
+       restSubs.Md5sum = restSubscriptionInfo.Md5sum
+
+       return restSubs
+}
+
+func (c *Control) RemoveRESTSubscriptionFromSdl(restSubId string) error {
+
+       key := restSubId
+       if err := c.restSubsDb.Remove([]string{key}); err != nil {
+               return fmt.Errorf("SDL: RemoveSubscriptionfromSdl(): %s\n", err.Error())
+       } else {
+               xapp.Logger.Debug("SDL: Subscription removed from restSubsDb. restSubId = %v", restSubId)
+       }
+       return nil
+}
+
+func (c *Control) ReadAllRESTSubscriptionsFromSdl() (map[string]*RESTSubscription, error) {
+
+       retMap := make(map[string]*RESTSubscription)
+       // Get all keys
+       keys, err := c.restSubsDb.GetAll()
+       if err != nil {
+               c.UpdateCounter(cSDLReadFailure)
+               return nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), GetAll(). Error while reading REST subscriptions keys from DBAAS %s\n", err.Error())
+       }
+
+       if len(keys) == 0 {
+               return retMap, nil
+       }
+
+       // Get all subscriptionInfos
+       iRESTSubscriptionMap, err := c.restSubsDb.Get(keys)
+       if err != nil {
+               c.UpdateCounter(cSDLReadFailure)
+               return nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl(), Get():  Error while reading REST subscriptions from DBAAS %s\n", err.Error())
+       }
+
+       for iRESTSubId, iRESTSubscriptionInfo := range iRESTSubscriptionMap {
+
+               if iRESTSubscriptionInfo == nil {
+                       return nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl() iRESTSubscriptionInfo = nil\n")
+               }
+
+               restSubscriptionInfo := &RESTSubscriptionInfo{}
+               jsonSubscriptionInfo := iRESTSubscriptionInfo.(string)
+
+               if err := json.Unmarshal([]byte(jsonSubscriptionInfo), restSubscriptionInfo); err != nil {
+                       return nil, fmt.Errorf("SDL: ReadAllSubscriptionsFromSdl() json.unmarshal error: %s\n", err.Error())
+               }
+
+               restSubs := c.CreateRESTSubscription(restSubscriptionInfo, &jsonSubscriptionInfo)
+               retMap[iRESTSubId] = restSubs
+       }
+       return retMap, nil
+}
+
+func (c *Control) RemoveAllRESTSubscriptionsFromSdl() error {
+
+       if err := c.restSubsDb.RemoveAll(); err != nil {
+               c.UpdateCounter(cSDLRemoveFailure)
+               return fmt.Errorf("SDL: RemoveAllSubscriptionsFromSdl(): %s\n", err.Error())
+       } else {
+               xapp.Logger.Debug("SDL: All subscriptions removed from e2SubsDb")
+       }
+       return nil
+}
diff --git a/pkg/control/sdl_restSubsDb_test.go b/pkg/control/sdl_restSubsDb_test.go
new file mode 100644 (file)
index 0000000..ac3c8e3
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+   ==================================================================================
+  Copyright (c) 2019 AT&T Intellectual Property.
+  Copyright (c) 2019 Nokia
+
+   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.
+   ==================================================================================
+*/
+
+package control
+
+import (
+       "encoding/json"
+       "fmt"
+       "reflect"
+       "strings"
+       "sync"
+       "testing"
+
+       "github.com/segmentio/ksuid"
+       "github.com/stretchr/testify/assert"
+)
+
+var sdlRestShouldReturnError bool = false
+
+const sdlRestTestErrorString string = "Test sdl REST returned error on purpose"
+
+type RestSubsDbMock struct {
+       restSubsDb             map[string]string // Store information as a string like real db does.
+       restSubscriptions      map[string]*RESTSubscription
+       lastAllocatedRestSubId string
+       restSubIdsInDb         []string
+       marshalLock            sync.Mutex
+}
+
+var restSubsDbMock *RestSubsDbMock
+
+func CreateRestSubsDbMock() *RestSubsDbMock {
+       fmt.Println("Test CreateRestSubsDbMock()")
+       restSubsDbMock = new(RestSubsDbMock)
+       restSubsDbMock.ResetTestSettings()
+       restSubsDbMock.lastAllocatedRestSubId = ""
+       return restSubsDbMock
+}
+
+func (m *RestSubsDbMock) ResetTestSettings() {
+       m.restSubsDb = make(map[string]string)
+       m.restSubscriptions = make(map[string]*RESTSubscription)
+}
+
+func (m *RestSubsDbMock) AllocNextRestSubId() string {
+       m.lastAllocatedRestSubId = ksuid.New().String()
+       return m.lastAllocatedRestSubId
+}
+
+func (m *RestSubsDbMock) GetLastAllocatedRestSubId() string {
+       return m.lastAllocatedRestSubId
+}
+
+func (m *RestSubsDbMock) AddRestSubIdsInDb(restSubId string) {
+       m.restSubIdsInDb = append(m.restSubIdsInDb, restSubId)
+}
+
+func (m *RestSubsDbMock) DeleteRestSubIdsFromDb(restSubId string) {
+       newrestSubIdsInDb := []string{}
+       for _, i := range m.restSubIdsInDb {
+               if i != restSubId {
+                       newrestSubIdsInDb = append(newrestSubIdsInDb, i)
+               }
+       }
+       m.restSubIdsInDb = newrestSubIdsInDb
+}
+
+func (m *RestSubsDbMock) EmptyRestSubIdsFromDb() {
+       m.restSubIdsInDb = nil
+}
+
+func CreateRESTSubscription(t *testing.T) *RESTSubscription {
+       t.Log("TEST: Creating REST subscription")
+
+       restSubscription := &RESTSubscription{}
+       restSubscription.xAppRmrEndPoint = "localhost:13560"
+       restSubscription.Meid = "RAN_NAME_1"
+       restSubscription.SubReqOngoing = true
+       restSubscription.SubDelReqOngoing = false
+       restSubscription.xAppIdToE2Id = make(map[int64]int64)
+       restSubscription.Md5sum = "856e9546f6f7b65a13a86996f2d1686a"
+       return restSubscription
+}
+
+func PrintRESTSubscriptionData(t *testing.T, restSubs *RESTSubscription) {
+       t.Log("TEST: RESTSubscription data")
+       t.Logf("TEST: restSubs.xAppRmrEndPoint = %v", restSubs.xAppRmrEndPoint)
+       t.Logf("TEST: restSubs.Meid = %v", restSubs.Meid)
+       t.Logf("TEST: restSubs.InstanceIds = %v", restSubs.InstanceIds)
+       t.Logf("TEST: restSubs.xAppIdToE2Id = %v", restSubs.xAppIdToE2Id)
+       t.Logf("TEST: restSubs.SubReqOngoing = %v", restSubs.SubReqOngoing)
+       t.Logf("TEST: restSubs.SubDelReqOngoing = %v", restSubs.SubDelReqOngoing)
+}
+
+func TestWriteRESTSubscriptionToSdl(t *testing.T) {
+
+       // Write one subscription
+       restSubId := restSubsDbMock.AllocNextRestSubId()
+       restSubs := CreateRESTSubscription(t)
+       PrintRESTSubscriptionData(t, restSubs)
+       t.Logf("TEST: Writing subId = %v\n", restSubId)
+       err := mainCtrl.c.WriteRESTSubscriptionToSdl(restSubId, restSubs)
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+       }
+       restSubsDbMock.AddRestSubIdsInDb(restSubId)
+}
+
+func TestReadRESTSubscriptionFromSdl(t *testing.T) {
+
+       restSubId := restSubsDbMock.GetLastAllocatedRestSubId()
+       t.Logf("Reading restSubId = %v\n", restSubId)
+       restSubs, err := mainCtrl.c.ReadRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       PrintRESTSubscriptionData(t, restSubs)
+       assert.Equal(t, restSubsDbMock.restSubscriptions[restSubId], restSubs)
+}
+
+func TestRemoveRESTSubscriptionFromSdl(t *testing.T) {
+
+       restSubId := restSubsDbMock.GetLastAllocatedRestSubId()
+       err := mainCtrl.c.RemoveRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       delete(restSubsDbMock.restSubscriptions, restSubId)
+       t.Logf("TEST: REST subscription removed from db. subId = %v", restSubId)
+       restSubsDbMock.DeleteRestSubIdsFromDb(restSubId)
+}
+
+func TestReadNotExistingRESTSubscriptionFromSdl(t *testing.T) {
+
+       restSubId := ""
+       restSubs, err := mainCtrl.c.ReadRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               t.Logf("TEST: REST subscription not found from db. restSubId = %v", restSubId)
+               return
+       }
+       t.Errorf("TEST: REST subscription read from db. %v", restSubs)
+       PrintRESTSubscriptionData(t, restSubs)
+}
+
+func TestReadNotExistingRESTSubscriptionFromSdl2(t *testing.T) {
+
+       restSubId := "NotExistingSubsId"
+       restSubs, err := mainCtrl.c.ReadRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               t.Logf("TEST: REST subscription not found from db. restSubId = %v", restSubId)
+               return
+       }
+       t.Errorf("TEST: REST subscription read from db. %v", restSubs)
+       PrintRESTSubscriptionData(t, restSubs)
+}
+
+func TestRemoveNotExistingRESTSubscriptionFromSdl(t *testing.T) {
+
+       restSubId := ""
+       err := mainCtrl.c.RemoveRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               t.Logf("TEST: %s", err.Error())
+               return
+       }
+       t.Logf("TEST: REST subscription removed from db. subId = %v", restSubId)
+}
+
+func TestWriteRESTSubscriptionsToSdl(t *testing.T) {
+
+       // Write 1st subscription
+       restSubId := restSubsDbMock.AllocNextRestSubId()
+       t.Logf("TEST: Writing restSubId = %v\n", restSubId)
+       restSubs := CreateRESTSubscription(t)
+       PrintRESTSubscriptionData(t, restSubs)
+       err := mainCtrl.c.WriteRESTSubscriptionToSdl(restSubId, restSubs)
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       restSubsDbMock.AddRestSubIdsInDb(restSubId)
+       t.Logf("TEST: REST subscription written in db = %v", restSubs)
+
+       // Write 2nd subscription
+       restSubId = restSubsDbMock.AllocNextRestSubId()
+       t.Logf("TEST:Writing restSubId = %v\n", restSubId)
+       restSubs = CreateRESTSubscription(t)
+       PrintRESTSubscriptionData(t, restSubs)
+       err = mainCtrl.c.WriteRESTSubscriptionToSdl(restSubId, restSubs)
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       restSubsDbMock.AddRestSubIdsInDb(restSubId)
+       t.Logf("TEST: REST subscription written in db = %v", restSubs)
+
+       // Write 3rd subscription
+       restSubId = restSubsDbMock.AllocNextRestSubId()
+       t.Logf("TEST: Writing restSubId = %v\n", restSubId)
+       restSubs = CreateRESTSubscription(t)
+       PrintRESTSubscriptionData(t, restSubs)
+       err = mainCtrl.c.WriteRESTSubscriptionToSdl(restSubId, restSubs)
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       restSubsDbMock.AddRestSubIdsInDb(restSubId)
+       t.Logf("TEST: REST subscription written in db = %v", restSubs)
+}
+
+func TestReadRESTSubscriptionsFromSdl(t *testing.T) {
+
+       for _, restSubId := range restSubsDbMock.restSubIdsInDb {
+               restSubs, err := mainCtrl.c.ReadRESTSubscriptionFromSdl(restSubId)
+               if err != nil {
+                       t.Errorf("TEST: %s", err.Error())
+                       return
+               }
+               PrintRESTSubscriptionData(t, restSubs)
+       }
+}
+
+func TestReadAllRESTSubscriptionsFromSdl(t *testing.T) {
+
+       register, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl()
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+
+       for _, restSubs := range register {
+               PrintRESTSubscriptionData(t, restSubs)
+       }
+
+       assert.Equal(t, len(register), 3)
+}
+
+func TestRemoveAllRESTSubscriptionsFromSdl(t *testing.T) {
+
+       err := mainCtrl.c.RemoveAllRESTSubscriptionsFromSdl()
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       t.Log("TEST: All subscription removed from db")
+       restSubsDbMock.EmptyRestSubIdsFromDb()
+}
+
+func TestReadAllRESTSubscriptionsFromSdl2(t *testing.T) {
+
+       register, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl()
+       if err != nil {
+               t.Errorf("TEST: %s", err.Error())
+               return
+       }
+       for _, restSubs := range restSubsDbMock.restSubscriptions {
+               PrintRESTSubscriptionData(t, restSubs)
+       }
+       assert.Equal(t, len(register), 0)
+}
+
+func TestWriteRESTSubscriptionToSdlFail(t *testing.T) {
+
+       // Try to write one subscription.
+       // Test db should return test error string
+       MakeNextSdlRestCallFail()
+       restsubId := restSubsDbMock.AllocNextRestSubId()
+       restSubs := CreateRESTSubscription(t)
+       PrintRESTSubscriptionData(t, restSubs)
+       t.Logf("TEST: Writing subId = %v\n", restsubId)
+       err := mainCtrl.c.WriteRESTSubscriptionToSdl(restsubId, restSubs)
+       if err != nil {
+               if !strings.Contains(fmt.Sprintf("%s", err), sdlRestTestErrorString) {
+                       t.Errorf("TEST: %s", err.Error())
+               }
+       } else {
+               t.Errorf("TEST: This test case should return error")
+       }
+}
+
+func TestReadRESTSubscriptionFromSdlFail(t *testing.T) {
+
+       // Try to read one subscription.
+       // Test db should return test error string
+       MakeNextSdlRestCallFail()
+       restSubId := restSubsDbMock.GetLastAllocatedRestSubId()
+       t.Logf("Reading restSubId = %v\n", restSubId)
+       restSubs, err := mainCtrl.c.ReadRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               if !strings.Contains(fmt.Sprintf("%s", err), sdlRestTestErrorString) {
+                       t.Errorf("TEST: %s", err.Error())
+               }
+               return
+       } else {
+               t.Errorf("TEST: This test case should return error")
+       }
+       PrintRESTSubscriptionData(t, restSubs)
+}
+
+func TestRemoveRESTSubscriptionFromSdlFail(t *testing.T) {
+
+       // Try to remove one subscription.
+       // Test db should return test error string
+       MakeNextSdlRestCallFail()
+       restSubId := restSubsDbMock.GetLastAllocatedRestSubId()
+       err := mainCtrl.c.RemoveRESTSubscriptionFromSdl(restSubId)
+       if err != nil {
+               if !strings.Contains(fmt.Sprintf("%s", err), sdlRestTestErrorString) {
+                       t.Errorf("TEST: %s", err.Error())
+               }
+               return
+       } else {
+               t.Errorf("TEST: This test case should return error")
+       }
+       t.Logf("TEST: subscription removed from db. subId = %v", restSubId)
+}
+
+func TestReadAllRESTSubscriptionsFromSdlFail(t *testing.T) {
+
+       // Try to read all subscriptions.
+       // Test db should return test error string
+       MakeNextSdlRestCallFail()
+       register, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl()
+       if err != nil {
+               if !strings.Contains(fmt.Sprintf("%s", err), sdlRestTestErrorString) {
+                       t.Errorf("TEST: %s", err.Error())
+               }
+               return
+       } else {
+               t.Errorf("TEST: This test case should return error")
+       }
+
+       for _, restSubs := range register {
+               PrintRESTSubscriptionData(t, restSubs)
+       }
+}
+
+func TestRemoveAllRESTSubscriptionsFromSdlFail(t *testing.T) {
+
+       // Try to remove all subscriptions.
+       // Test db should return test error string
+       MakeNextSdlRestCallFail()
+       err := mainCtrl.c.RemoveAllRESTSubscriptionsFromSdl()
+       if err != nil {
+               if !strings.Contains(fmt.Sprintf("%s", err), sdlRestTestErrorString) {
+                       t.Errorf("TEST: %s", err.Error())
+               }
+               return
+       } else {
+               t.Errorf("TEST: This test case should return error")
+       }
+       t.Log("TEST: All subscription removed from db")
+}
+
+func (m *RestSubsDbMock) Set(pairs ...interface{}) error {
+       var key string
+       var val string
+
+       m.marshalLock.Lock()
+       defer m.marshalLock.Unlock()
+
+       if sdlRestShouldReturnError == true {
+               return GetSdlRestError()
+       }
+
+       for _, v := range pairs {
+               reflectType := reflect.TypeOf(v)
+               switch reflectType.Kind() {
+               case reflect.Slice:
+                       val = fmt.Sprintf("%s", v.([]uint8))
+               default:
+                       switch v.(type) {
+                       case string:
+                               key = v.(string)
+                       default:
+                               return fmt.Errorf("Set() error: Unexpected type\n")
+                       }
+               }
+       }
+
+       if key != "" {
+               m.restSubsDb[key] = val
+               restSubId := key
+               restSubscriptionInfo := &RESTSubscriptionInfo{}
+               err := json.Unmarshal([]byte(val), restSubscriptionInfo)
+               if err != nil {
+                       return fmt.Errorf("Set() json.unmarshal error: %s\n", err.Error())
+               }
+
+               restSubs := mainCtrl.c.CreateRESTSubscription(restSubscriptionInfo, &val)
+               m.restSubscriptions[restSubId] = restSubs
+       } else {
+               return fmt.Errorf("Set() error: key == ''\n")
+       }
+       return nil
+}
+
+func (m *RestSubsDbMock) Get(keys []string) (map[string]interface{}, error) {
+       retMap := make(map[string]interface{})
+       if len(keys) == 0 {
+               return nil, fmt.Errorf("Get() error: len(key) == 0\n")
+       }
+
+       if sdlRestShouldReturnError == true {
+               return nil, GetSdlRestError()
+       }
+
+       for _, key := range keys {
+               if key != "" {
+                       retMap[key] = m.restSubsDb[key]
+               } else {
+                       return nil, fmt.Errorf("Get() error: key == ''\n")
+               }
+       }
+       return retMap, nil
+}
+
+func (m *RestSubsDbMock) GetAll() ([]string, error) {
+
+       if sdlRestShouldReturnError == true {
+               return nil, GetSdlRestError()
+       }
+
+       keys := []string{}
+       for key, _ := range m.restSubsDb {
+               keys = append(keys, key)
+       }
+       return keys, nil
+}
+
+func (m *RestSubsDbMock) Remove(keys []string) error {
+       if len(keys) == 0 {
+               return fmt.Errorf("Remove() error: len(key) == 0\n")
+       }
+
+       if sdlRestShouldReturnError == true {
+               return GetSdlRestError()
+       }
+
+       restSubId := keys[0]
+       delete(m.restSubsDb, restSubId)
+       delete(m.restSubscriptions, restSubId)
+       return nil
+}
+
+func (m *RestSubsDbMock) RemoveAll() error {
+
+       for key := range m.restSubsDb {
+
+               restSubId := key
+               delete(m.restSubsDb, restSubId)
+               delete(m.restSubscriptions, restSubId)
+       }
+
+       if sdlRestShouldReturnError == true {
+               return GetSdlRestError()
+       }
+
+       return nil
+}
+
+func MakeNextSdlRestCallFail() {
+       sdlRestShouldReturnError = true
+}
+
+func GetSdlRestError() error {
+       sdlRestShouldReturnError = false
+       return fmt.Errorf(sdlRestTestErrorString)
+}
index bd81127..ee7bc82 100644 (file)
@@ -56,7 +56,8 @@ func createSubmgrControl(srcId teststub.RmrSrcId, rtgSvc teststub.RmrRtgSvc) *te
        mainCtrl.RmrControl.Init("SUBMGRCTL", srcId, rtgSvc)
        mainCtrl.c = NewControl()
        xapp.Logger.Debug("Replacing real db with test db")
-       mainCtrl.c.db = CreateMock() // This overrides real database for testing
+       mainCtrl.c.e2SubsDb = CreateMock()             // This overrides real E2 Subscription database for testing
+       mainCtrl.c.restSubsDb = CreateRestSubsDbMock() // This overrides real REST Subscription database for testing
        xapp.SetReadyCB(mainCtrl.ReadyCB, nil)
        go xapp.RunWithParams(mainCtrl.c, false)
        mainCtrl.WaitCB()