RICPLT-2801 Implement Subscription Request timer, RICPLT-2801 Implement Subscription... 48/2048/1
authorAnssi Mannila <anssi.mannila@nokia.com>
Tue, 17 Dec 2019 13:29:55 +0000 (15:29 +0200)
committerAnssi Mannila <anssi.mannila@nokia.com>
Tue, 17 Dec 2019 13:30:14 +0000 (15:30 +0200)
Change-Id: Ib1610cfa806d38bff7dc0ebad8f0b599a0919d34
Signed-off-by: Anssi Mannila <anssi.mannila@nokia.com>
Dockerfile
go.mod
pkg/control/control.go
pkg/control/timer.go [new file with mode: 0644]
pkg/control/timers.go [deleted file]

index 6b719d1..d29864c 100644 (file)
@@ -25,9 +25,9 @@ FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:2-u18.04-nng as submgrbuild
 WORKDIR /tmp
 
 # Install RMr shared library
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.9.0_amd64.deb/download.deb && dpkg -i rmr_1.9.0_amd64.deb && rm -rf rmr_1.9.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.10.0_amd64.deb/download.deb && dpkg -i rmr_1.10.0_amd64.deb && rm -rf rmr_1.10.0_amd64.deb
 # Install RMr development header files
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.9.0_amd64.deb/download.deb && dpkg -i rmr-dev_1.9.0_amd64.deb && rm -rf rmr-dev_1.9.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.10.0_amd64.deb/download.deb && dpkg -i rmr-dev_1.10.0_amd64.deb && rm -rf rmr-dev_1.10.0_amd64.deb
 
 # "PULLING LOG and COMPILING LOG"
 RUN git clone "https://gerrit.o-ran-sc.org/r/com/log" /opt/log && cd /opt/log && \
diff --git a/go.mod b/go.mod
index 1b1b362..eaf5baa 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ go 1.12
 module gerrit.o-ran-sc.org/r/ric-plt/submgr
 
 require (
-       gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.20
+       gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.23
        github.com/go-openapi/runtime v0.19.7
        github.com/go-openapi/strfmt v0.19.3
        github.com/spf13/viper v1.4.0
@@ -11,6 +11,6 @@ require (
 
 replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.2.0
 
-replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.20
+replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.23
 
 replace gerrit.o-ran-sc.org/r/com/golog => gerrit.o-ran-sc.org/r/com/golog.git v0.0.1
index db39f7b..34dd6a0 100644 (file)
@@ -34,8 +34,8 @@ import (
        "sync"  
 )
 
-var subReqTime time.Duration = 2 * time.Second
-var SubDelReqTime time.Duration = 2 * time.Second
+var subReqTime time.Duration = 5 * time.Second
+var SubDelReqTime time.Duration = 5 * time.Second
 
 type Control struct {
        e2ap        *E2ap
@@ -138,6 +138,8 @@ func (c *Control) Consume(msg *xapp.RMRParams) (err error) {
                go c.handleSubscriptionDeleteRequest(msg)
        case xapp.RICMessageTypes["RIC_SUB_DEL_RESP"]:
                go c.handleSubscriptionDeleteResponse(msg)
+       case xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]:
+               go c.handleSubscriptionDeleteFailure(msg)
        default:
                xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
        }
@@ -192,9 +194,9 @@ func (c *Control) handleSubscriptionRequest(params *xapp.RMRParams) {
        err = c.rmrSend(params)
        if err != nil {
                xapp.Logger.Error("SubReq: Failed to send request to E2T %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
-       } /*else {
-               c.timerMap.StartTimer(newSubId, subReqTime, c.handleSubscriptionRequestTimer)
-       }*/
+       } else {
+               c.timerMap.StartTimer("RIC_SUB_REQ", int(newSubId), subReqTime, c.handleSubscriptionRequestTimer)
+       }
        xapp.Logger.Debug("SubReq: Debugging transaction table = %v", c.tracker.transactionTable)
        return
 }
@@ -216,7 +218,7 @@ func (c *Control) handleSubscriptionResponse(params *xapp.RMRParams) {
                return
        }
 
-//     c.timerMap.StopTimer(payloadSeqNum)
+       c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum))
 
        c.registry.setSubscriptionToConfirmed(payloadSeqNum)
        var transaction Transaction
@@ -257,7 +259,7 @@ func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) {
        }
        xapp.Logger.Info("SubFail: Received payloadSeqNum: %v", payloadSeqNum)
 
-//     c.timerMap.StopTimer(payloadSeqNum)
+       c.timerMap.StopTimer("RIC_SUB_REQ", int(payloadSeqNum))
 
        var transaction Transaction
        transaction, err = c.tracker.RetriveTransaction(payloadSeqNum, CREATE)
@@ -285,7 +287,7 @@ func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) {
                xapp.Logger.Error("SubFail: Failed to update routing manager. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
        }
 
-       xapp.Logger.Info("SubFail: Deleting trancaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       xapp.Logger.Info("SubFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
        if c.registry.releaseSequenceNumber(payloadSeqNum) {
                transaction, err = c.tracker.completeTransaction(payloadSeqNum, CREATE)
                if err != nil {
@@ -299,51 +301,72 @@ func (c *Control) handleSubscriptionFailure(params *xapp.RMRParams) {
        return
 }
 
-func (c *Control) handleSubscriptionRequestTimer(subId uint16) {
-       xapp.Logger.Info("Subscription Request timer expired. SubId: %v",subId)
-/*     
+func (c *Control) handleSubscriptionRequestTimer(strId string, nbrId int) {
+       newSubId := uint16(nbrId)
+       xapp.Logger.Info("SubReq timer expired. newSubId: %v", newSubId)
+//     var causeContent uint8 = 1  // just some random cause. To be checked later. Should be no respose or something
+//     var causeVal uint8 = 1  // just some random val. To be checked later. Should be no respose or something
+//     c.sendSubscriptionFailure(newSubId, causeContent, causeVal)
+}
+
+/*
+func (c *Control) sendSubscriptionFailure(subId uint16, causeContent uint8, causeVal uint8) {
+
        transaction, err := c.tracker.completeTransaction(subId, CREATE)
        if err != nil {
-               xapp.Logger.Error("Failed to delete a Subscription Request transaction record due to %v", err)
+               xapp.Logger.Error("SendSubFail: Failed to delete transaction record. Err:%v. SubId: %v", err, subId)
                return
        }
-       xapp.Logger.Info("SubId: %v, Xid %v, Meid: %v",subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid)
+       xapp.Logger.Info("SendSubFail: SubId: %v, Xid %v, Meid: %v", subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid)
 
        var params xapp.RMRParams
        params.Mtype = 12012 //xapp.RICMessageTypes["RIC_SUB_FAILURE"]
        params.SubId = int(subId)
        params.Meid = transaction.OrigParams.Meid
        params.Xid = transaction.OrigParams.Xid
-       payload := []byte("40C9408098000003EA7E00050000010016EA6300020021EA6E00808180EA6F000400000000EA6F000400010040EA6F000400020080EA6F0004000300C0EA6F000400040100EA6F000400050140EA6F000400060180EA6F0004000701C0EA6F000400080200EA6F000400090240EA6F0004000A0280EA6F0004000B02C0EA6F0004000C0300EA6F0004000D0340EA6F0004000E0380EA6F0004000F03C0")
-       params.PayloadLen = len(payload)
-       params.Payload = payload
+       
+//     newPayload, packErr := c.e2ap.PackSubscriptionFailure(transaction.OrigParams.Payload, subId, causeContent, causeVal)
+//     if packErr != nil {
+//             xapp.Logger.Error("SendSubFail: PackSubscriptionFailure() due to %v", packErr)
+//             return
+//     }
+       
+       newPayload := []byte("40CA4018000003EA7E00050000010016EA6300020021EA74000200C0")  // Temporary solution
+
+       params.PayloadLen = len(newPayload)
+       params.Payload = newPayload
 
-       xapp.Logger.Info("Forwarding Subscription Failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid)
+       xapp.Logger.Info("SendSubFail: Forwarding failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid)
        err = c.rmrReplyToSender(&params)
        if err != nil {
-               xapp.Logger.Error("Failed to send response to requestor %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid)
+               xapp.Logger.Error("SendSubFail: Failed to send response to xApp. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
        }
-*/
-/*
+
        time.Sleep(3 * time.Second)
 
-       xapp.Logger.Info("Subscription ID: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort)
+       xapp.Logger.Info("SendSubFail: SubId: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort)
 
-       xapp.Logger.Info("Starting routing manager update")
-       subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, payloadSeqNum}
-       c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
+       xapp.Logger.Info("SubReqTimer: Starting routing manager update. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, subId}
+       err = c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
+       if err != nil {
+               xapp.Logger.Error("SendSubFail: Failed to update routing manager %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid)
+               return
+       }
 
-       xapp.Logger.Info("Deleting trancaction record")
-       if c.registry.releaseSequenceNumber(payloadSeqNum) {
-               transaction, err = c.tracker.completeTransaction(payloadSeqNum, CREATE)
+       xapp.Logger.Info("SendSubFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       if c.registry.releaseSequenceNumber(subId) {
+               transaction, err = c.tracker.completeTransaction(subId, CREATE)
                if err != nil {
-                       xapp.Logger.Error("Failed to delete a Subscription Request transaction record due to %v", err)
+                       xapp.Logger.Error("SendSubFail: Failed to delete transaction record. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
                        return
                }
+       } else {
+               xapp.Logger.Error("SendSubFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid)
        }
-*/
        return
 }
+*/
 
 func (act Action) String() string {
        actions := [...]string{
@@ -396,9 +419,9 @@ func (c *Control) handleSubscriptionDeleteRequest(params *xapp.RMRParams) {
        c.rmrSend(params)
        if err != nil {
                xapp.Logger.Error("SubDelReq: Failed to send request to E2T. Err %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
-       } /*else {
-               c.timerMap.StartTimer(payloadSeqNum, SubDelReqTime, c.handleSubscriptionDeleteRequestTimer)
-       }*/
+       } else {
+               c.timerMap.StartTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum), subReqTime, c.handleSubscriptionDeleteRequestTimer)
+       }
        return
 }
 
@@ -425,8 +448,8 @@ func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err
        }
        xapp.Logger.Info("SubDelResp: Received payloadSeqNum: %v", payloadSeqNum)
 
-//     c.timerMap.StopTimer(payloadSeqNum)
-       
+       c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum))
+
        var transaction Transaction
        transaction, err = c.tracker.RetriveTransaction(payloadSeqNum, DELETE)
        if  err != nil {
@@ -454,7 +477,7 @@ func (c *Control) handleSubscriptionDeleteResponse(params *xapp.RMRParams) (err
                return
        }
 
-       xapp.Logger.Info("SubDelResp: Deleting trancaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       xapp.Logger.Info("SubDelResp: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
        if c.registry.releaseSequenceNumber(payloadSeqNum) {
                transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE)
                if err != nil {
@@ -480,7 +503,7 @@ func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) {
        }
        xapp.Logger.Info("SubDelFail: Received payloadSeqNum: %v", payloadSeqNum)
 
-//     c.timerMap.StopTimer(payloadSeqNum)
+       c.timerMap.StopTimer("RIC_SUB_DEL_REQ", int(payloadSeqNum))
 
        var transaction Transaction
        transaction, err = c.tracker.RetriveTransaction(payloadSeqNum, DELETE)
@@ -509,7 +532,7 @@ func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) {
                return
        }
 
-       xapp.Logger.Info("SubDelFail: Deleting trancaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       xapp.Logger.Info("SubDelFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
        if c.registry.releaseSequenceNumber(payloadSeqNum) {
                transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE)
                if err != nil {
@@ -523,47 +546,68 @@ func (c *Control) handleSubscriptionDeleteFailure(params *xapp.RMRParams) {
        return
 }
 
-func (c *Control) handleSubscriptionDeleteRequestTimer(subId uint16) {
-       xapp.Logger.Info("Subscription Delete Request timer expired. SubId: %v",subId)
-/*     
+func (c *Control) handleSubscriptionDeleteRequestTimer(strId string, nbrId int) {
+       newSubId := uint16(nbrId)
+       xapp.Logger.Info("SubDelReq timer expired. newSubId: %v", newSubId)
+//     var causeContent uint8 = 1  // just some random cause. To be checked later. Should be no respose or something
+//     var causeVal uint8 = 1  // just some random val. To be checked later. Should be no respose or something
+//     c.sendSubscriptionDeleteFailure(newSubId, causeContent, causeVal)
+}
+
+/*
+func (c *Control) sendSubscriptionDeleteFailure(subId uint16, causeContent uint8, causeVal uint8) {
        transaction, err := c.tracker.completeTransaction(subId, DELETE)
        if err != nil {
-               xapp.Logger.Error("Failed to delete a Subscription Delete Request transaction record due to %v", err)
+               xapp.Logger.Error("SendSubDelFail: Failed to delete transaction record. Err: %v, newSubId: %v", err, subId)
                return
        }
-       xapp.Logger.Info("SubId: %v, Xid %v, Meid: %v",subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid)
+       xapp.Logger.Info("SendSubDelFail: SubId: %v, Xid %v, Meid: %v",subId, transaction.OrigParams.Xid, transaction.OrigParams.Meid)
 
        var params xapp.RMRParams
        params.Mtype = 12022 //xapp.RICMessageTypes["RIC_SUB_DEL_FAILURE"]
        params.SubId = int(subId)
        params.Meid = transaction.OrigParams.Meid
        params.Xid = transaction.OrigParams.Xid
-       payload := []byte("40CA4018000003EA7E00050000010016EA6300020021EA74000200C0")
-       params.PayloadLen = len(payload)
-       params.Payload = payload
+       
+//     newPayload, packErr := c.e2ap.PackSubscriptionDeleteFailure(transaction.OrigParams.Payload, subId, causeContent, causeVal)
+//     if packErr != nil {
+//             xapp.Logger.Error("SendSubDelFail: PackSubscriptionDeleteFailure(). Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid))
+//             return
+//     }
+
+       newPayload := []byte("40CA4018000003EA7E00050000010016EA6300020021EA74000200C0")  // Temporary solution
+
+       params.PayloadLen = len(newPayload)
+       params.Payload = newPayload
 
-       xapp.Logger.Info("Forwarding Subscription Delete Failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid)
+       xapp.Logger.Info("SendSubDelFail: Forwarding failure to xApp: Mtype: %v, SubId: %v, Xid: %s, Meid: %v",params.Mtype, params.SubId, params.Xid, params.Meid)
        err = c.rmrReplyToSender(&params)
        if err != nil {
-               xapp.Logger.Error("Failed to send response to requestor %v. SubId: %v, Xid: %s", err, params.SubId, params.Xid)
+               xapp.Logger.Error("SendSubDelFail: Failed to send response to xApp: Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
        }
-*/     
-/*
+       
        time.Sleep(3 * time.Second)
-       xapp.Logger.Info("Subscription ID: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort)
+       
+       xapp.Logger.Info("SendSubDelFail: SubId: %v, from address: %v:%v. Deleting transaction record", int(subId), transaction.XappInstanceAddress, transaction.XappPort)
 
-       xapp.Logger.Info("Starting routing manager update")
-       subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, payloadSeqNum}
-       c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
+       xapp.Logger.Info("SendSubDelFail: Starting routing manager update. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       subRouteAction := SubRouteInfo{DELETE, transaction.XappInstanceAddress, transaction.XappPort, subId}
+       err = c.rtmgrClient.SubscriptionRequestUpdate(subRouteAction)
+       if err != nil {
+               xapp.Logger.Error("SendSubDelFail: Failed to update routing manager. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
+               return
+       }
 
-       xapp.Logger.Info("Deleting trancaction record")
-       if c.registry.releaseSequenceNumber(payloadSeqNum) {
-               transaction, err = c.tracker.completeTransaction(payloadSeqNum, DELETE)
+       xapp.Logger.Info("SendSubDelFail: Deleting transaction record. SubId: %v, Xid: %s", params.SubId, params.Xid)
+       if c.registry.releaseSequenceNumber(subId) {
+               transaction, err = c.tracker.completeTransaction(subId, DELETE)
                if err != nil {
-                       xapp.Logger.Error("Failed to delete a Subscription Delete Request transaction record due to %v", err)
+                       xapp.Logger.Error("SendSubDelFail: Failed to delete transaction record. Err: %v, SubId: %v, Xid: %s", err, params.SubId, params.Xid)
                        return
                }
+       } else {
+               xapp.Logger.Error("SendSubDelFail: Failed to release sequency number. SubId: %v, Xid: %s", params.SubId, params.Xid)
        }
-*/
        return
-       }
+}
+*/
\ No newline at end of file
diff --git a/pkg/control/timer.go b/pkg/control/timer.go
new file mode 100644 (file)
index 0000000..5d48464
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+==================================================================================
+  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.
+==================================================================================
+*/
+/*
+Timer takes four parameters:
+        1) strId                       string                          'string format timerMap key'
+        2) nbrId                       int                             'numeric format timerMap key'
+        3) timerDuration       time.Duration           'timer duration'
+        4) timerFunction       func(string, int)       'function to be executed when timer expires'
+
+       Timer function is put inside in-build time.AfterFunc() Go function, where it is run inside own Go routine
+       when the timer expires. Timer are two key values. Both are used always, but the other one can be left
+       "empty", i.e. strId = "" or  nbrId = 0. Fourth parameter, the timer function is bare function name without
+       any function parameters and parenthesis! Filling first parameter strId with related name can improve
+       code readability and robustness, even the numeric Id would be enough from functionality point of view.
+
+       TimerStart() function starts the timer. If TimerStart() function is called again with same key values
+       while earlier started timer is still in the timerMap, i.e. it has not been stopped or the timer has not
+       yet expired, the old timer is deleted and new timer is started with the given time value.
+
+       StopTimer() function stops the timer. There is no need to call StopTimer() function after the timer has
+       expired. Timer is removed automatically from the timeMap. Calling StopTimer() function with key values not
+       existing in the timerMap, has no effect.
+
+       NOTE: Each timer is run in separate Go routine. Therefore, the function that is executed when timer expires
+       MUST be designed to be able run concurrently! Also, function run order of simultaneously expired timers cannot
+       guaranteed anyway!
+
+       If you need to transport more information to the timer function, consider to use another map to store the
+       information with same key value, as the started timer.
+
+       Init timerMap example:
+               timerMap := new(TimerMap)
+               timerMap.Init()
+
+       StartTimer() and StartTimer() function usage examples.
+       1)
+               subReqTime := 2 * time.Second
+               subId := 123
+               timerMap.StartTimer("RIC_SUB_REQ", int(subId), subReqTime, handleSubscriptionRequestTimer)
+               timerMap.StopTimer("RIC_SUB_REQ", int(subId))
+               
+       2)
+               subReqTime := 2 * time.Second
+               strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF"
+               timerMap.StartTimer(strId, 0, subReqTime, handleSubscriptionRequestTimer)
+               timerMap.StopTimer(strId, 0)
+
+       3)
+               subReqTime := 2 * time.Second
+               strId := "1UHSUwNqxiVgUWXvC4zFaatpZFF"
+               timerMap.StartTimer(RIC_SUB_REQ_" + strId, 0, subReqTime, handleSubscriptionRequestTimer)
+               timerMap.timerMap.StopTimer("RIC_SUB_REQ_" + strId, 0)
+
+       Timer function example. This is run if any of the above started timer expires.
+               func handleSubscriptionRequestTimer1(strId string, nbrId int) {
+                       fmt.Printf("Subscription Request timer expired. Name: %v, SubId: %v\n",strId, nbrId)
+               }
+*/
+
+package control
+
+import (
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+       "sync"
+       "time"
+)
+
+type TimerKey struct {
+       strId  string
+       nbrId  int
+}
+
+type TimerInfo struct {
+       timerAddress *time.Timer        
+       timerFunctionAddress func()
+}
+
+type TimerMap struct {
+       timer map[TimerKey] TimerInfo
+       mutex sync.Mutex
+}
+
+// This method should run as a constructor
+func (t *TimerMap) Init() {
+       t.timer = make(map[TimerKey] TimerInfo)
+}
+
+func (t *TimerMap) StartTimer(strId string, nbrId int, expireAfterTime time.Duration, timerFunction func(srtId string, nbrId int)) bool {
+       t.mutex.Lock()
+       defer t.mutex.Unlock()
+       if (timerFunction == nil) {
+               xapp.Logger.Error("StartTimer() timerFunc == nil\n")
+               return false
+       }
+       timerKey := TimerKey{strId, nbrId}
+       // Stop timer if there is already timer running with the same id
+       if val, ok := t.timer[timerKey]; ok {
+               xapp.Logger.Debug("StartTimer() old timer found")
+               if val.timerAddress != nil {
+                       xapp.Logger.Debug("StartTimer() deleting old timer")
+                       val.timerAddress.Stop()
+               }
+               delete(t.timer, timerKey)
+       }
+
+       // Store in timerMap in-build Go "timer", timer function executor, and the function to be executed when the timer expires
+       t.timer[timerKey] = TimerInfo{timerAddress: time.AfterFunc(expireAfterTime, func(){t.timerFunctionExecutor(strId,nbrId)}),
+                                           timerFunctionAddress: func(){timerFunction(strId,nbrId)}}
+       return true
+}
+
+func (t *TimerMap) StopTimer(strId string, nbrId int) bool {
+       t.mutex.Lock()
+       defer t.mutex.Unlock()
+       timerKey := TimerKey{strId, nbrId}
+       if val, ok := t.timer[timerKey]; ok {
+               if val.timerAddress != nil {
+                       val.timerAddress.Stop()
+                       delete(t.timer, timerKey)
+                       return true
+               } else {
+                       xapp.Logger.Error("StopTimer() timerAddress == nil")
+                       return false
+               }
+       } else {
+               xapp.Logger.Debug("StopTimer() Timer not found. May be expired or stopped already. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId)
+               return false
+       }
+}
+
+func (t *TimerMap) timerFunctionExecutor(strId string, nbrId int) {
+       t.mutex.Lock()
+       timerKey := TimerKey{strId, nbrId}
+       if val, ok := t.timer[timerKey]; ok {
+               if val.timerFunctionAddress != nil {
+                       // Take local copy of timer function address
+                       f := val.timerFunctionAddress
+                       // Delete timer instance from map
+                       delete(t.timer, timerKey)
+                       t.mutex.Unlock()
+                       // Execute the timer function
+                       f()
+                       return
+               } else {
+                       xapp.Logger.Error("timerExecutorFunc() timerFunctionAddress == nil")
+                       t.mutex.Unlock()
+                       return
+               }
+       } else {
+               xapp.Logger.Error("timerExecutorFunc() Timer is not anymore in map. timerKey.strId: %v, timerKey.strId: %v\n", timerKey.strId, timerKey.nbrId)
+               t.mutex.Unlock()
+               return
+       }
+}
diff --git a/pkg/control/timers.go b/pkg/control/timers.go
deleted file mode 100644 (file)
index 6f64c5b..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-==================================================================================
-  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 (
-       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
-       "sync"
-       "time"
-)
-
-var timerMutex = &sync.Mutex{}
-
-type TimerInfo struct {
-       timerAddress *time.Timer        
-       timerFunctionAddress func()
-}
-
-type TimerMap struct {
-       timer map[uint16] TimerInfo
-}
-
-// This method should run as a constructor
-func (t *TimerMap) Init() {
-       t.timer = make(map[uint16] TimerInfo)
-}
-
-func (t *TimerMap) StartTimer(subId uint16, expireAfterTime time.Duration, timerFunction func(subId uint16)) bool {
-       timerMutex.Lock()
-       defer timerMutex.Unlock()
-       if (timerFunction == nil) {
-               xapp.Logger.Error("StartTimer() timerFunc == nil")
-               return false
-       }
-
-       // Stop timer if there is already timer running with the same id
-       if val, ok := t.timer[subId]; ok {
-               xapp.Logger.Error("StartTimer() old timer found")
-               if val.timerAddress != nil {
-                       xapp.Logger.Error("StartTimer() deleting old timer")
-                       val.timerAddress.Stop()
-               }
-               delete(t.timer, subId)
-       }
-
-       // Store timer + timer function excecutor function and the function to be excecuted when timer expires, in map
-       t.timer[subId] = TimerInfo{timerAddress: time.AfterFunc(expireAfterTime, func(){t.timerFunctionExcecutor(subId)}),
-                                                          timerFunctionAddress: func(){timerFunction(subId)}}
-       return true
-}
-
-func (t *TimerMap) StopTimer(subId uint16) bool {
-       timerMutex.Lock()
-       defer timerMutex.Unlock()
-       if val, ok := t.timer[subId]; ok {
-               if val.timerAddress != nil {
-                       val.timerAddress.Stop()
-                       delete(t.timer, subId)
-                       return true
-               } else {
-                       xapp.Logger.Error("StopTimer() timerAddress == nil")
-                       return false
-               }
-       } else {
-               xapp.Logger.Info("StopTimer() Timer not found. May be expired or stopped already. subId: %v",subId)
-               return false
-       }
-}
-
-func (t *TimerMap) timerFunctionExcecutor(subId uint16) {
-       timerMutex.Lock()
-       if val, ok := t.timer[subId]; ok {
-               if val.timerFunctionAddress != nil {
-                       // Take local copy of timer function address
-                       f := val.timerFunctionAddress
-                       // Delete timer instance from map
-                       delete(t.timer, subId)
-                       timerMutex.Unlock()
-                       // Excecute the timer function
-                       f()
-                       return
-               } else {
-                       xapp.Logger.Error("timerExcecutorFunc() timerFunctionAddress == nil")
-                       timerMutex.Unlock()
-                       return
-               }
-       } else {
-               xapp.Logger.Error("timerExcecutorFunc() Timer not anymore in map. subId: %v",subId)
-               timerMutex.Unlock()
-               return
-       }
-}