Submgr REST subscriptions in SDL Database
   * 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
diff --git a/pkg/control/control.go b/pkg/control/control.go
index 9779498..c74b1a5 100755
--- a/pkg/control/control.go
+++ b/pkg/control/control.go
@@ -74,7 +74,8 @@
 	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 @@
 	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 @@
 		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 @@
 				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 @@
 	}
 	// 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 @@
 	}
 	// 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 @@
 	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 @@
 			restSubscription.DeleteE2InstanceId(instanceId)
 		}
 		c.registry.DeleteRESTSubscription(&restSubId)
+		c.RemoveRESTSubscriptionFromDb(restSubId)
 	}()
 
 	c.UpdateCounter(cRestSubDelRespToXapp)
@@ -569,6 +583,7 @@
 	if s == "emptydb" {
 		xapp.Logger.Info("RemoveAllSubscriptionsFromSdl() called")
 		c.RemoveAllSubscriptionsFromSdl()
+		c.RemoveAllRESTSubscriptionsFromSdl()
 		return
 	}
 
@@ -1138,6 +1153,41 @@
 	}
 }
 
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+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
diff --git a/pkg/control/registry.go b/pkg/control/registry.go
index 5259273..671cf51 100644
--- a/pkg/control/registry.go
+++ b/pkg/control/registry.go
@@ -40,7 +40,7 @@
 	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) SetProcessed() {
 	r.SubReqOngoing = false
-	r.Md5sumOngoing = ""
+	r.Md5sum = ""
 }
 
 type Registry struct {
diff --git a/pkg/control/sdl.go b/pkg/control/sdl_e2SubsDb.go
similarity index 87%
rename from pkg/control/sdl.go
rename to pkg/control/sdl_e2SubsDb.go
index ac8b8fb..c2526bc 100644
--- a/pkg/control/sdl.go
+++ b/pkg/control/sdl_e2SubsDb.go
@@ -22,10 +22,11 @@
 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 @@
 }
 
 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 @@
 		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 @@
 
 	// 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) 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 @@
 
 	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 @@
 	}
 
 	// 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 (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
 }
diff --git a/pkg/control/sdl_test.go b/pkg/control/sdl_e2SubsDb_test.go
similarity index 98%
rename from pkg/control/sdl_test.go
rename to pkg/control/sdl_e2SubsDb_test.go
index 2fac9b2..2deb4b5 100644
--- a/pkg/control/sdl_test.go
+++ b/pkg/control/sdl_e2SubsDb_test.go
@@ -46,7 +46,7 @@
 )
 
 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 (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 @@
 	}
 
 	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 @@
 
 	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 @@
 	}
 
 	keys := []string{}
-	for key, _ := range m.subsDB {
+	for key, _ := range m.e2SubsDb {
 		keys = append(keys, key)
 	}
 	return keys, nil
@@ -554,7 +554,7 @@
 	}
 
 	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) 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
index 0000000..782108f
--- /dev/null
+++ b/pkg/control/sdl_restSubsDb.go
@@ -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
index 0000000..ac3c8e3
--- /dev/null
+++ b/pkg/control/sdl_restSubsDb_test.go
@@ -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)
+}
diff --git a/pkg/control/ut_ctrl_submgr_test.go b/pkg/control/ut_ctrl_submgr_test.go
index bd81127..ee7bc82 100644
--- a/pkg/control/ut_ctrl_submgr_test.go
+++ b/pkg/control/ut_ctrl_submgr_test.go
@@ -56,7 +56,8 @@
 	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()