65f816ee6cd037a193d67c7ae0211fc742d95b13
[ric-plt/submgr.git] / pkg / control / tracker.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package control
21
22 import (
23         "fmt"
24         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
25         "sync"
26 )
27
28 type TransactionKey struct {
29         SubID     uint16 // subscription id / sequence number
30         TransType Action // action ongoing (CREATE/DELETE etc)
31 }
32
33 type TransactionXappKey struct {
34         Addr string // xapp addr
35         Port uint16 // xapp port
36         Xid  string // xapp xid in req
37 }
38
39 type Transaction struct {
40         tracker    *Tracker           // tracker instance
41         Key        TransactionKey     // action key
42         Xappkey    TransactionXappKey // transaction key
43         OrigParams *xapp.RMRParams    // request orginal params
44 }
45
46 func (t *Transaction) SubRouteInfo() SubRouteInfo {
47         return SubRouteInfo{t.Key.TransType, t.Xappkey.Addr, t.Xappkey.Port, t.Key.SubID}
48 }
49
50 /*
51 Implements a record of ongoing transactions and helper functions to CRUD the records.
52 */
53 type Tracker struct {
54         transactionTable     map[TransactionKey]*Transaction
55         transactionXappTable map[TransactionXappKey]*Transaction
56         mutex                sync.Mutex
57 }
58
59 func (t *Tracker) Init() {
60         t.transactionTable = make(map[TransactionKey]*Transaction)
61         t.transactionXappTable = make(map[TransactionXappKey]*Transaction)
62 }
63
64 /*
65 Checks if a tranascation with similar type has been ongoing. If not then creates one.
66 Returns error if there is similar transatcion ongoing.
67 */
68 func (t *Tracker) TrackTransaction(subID uint16, act Action, addr string, port uint16, params *xapp.RMRParams) (*Transaction, error) {
69         key := TransactionKey{subID, act}
70         xappkey := TransactionXappKey{addr, port, params.Xid}
71         trans := &Transaction{t, key, xappkey, params}
72         t.mutex.Lock()
73         defer t.mutex.Unlock()
74         if _, ok := t.transactionTable[key]; ok {
75                 // TODO: Implement merge related check here. If the key is same but the value is different.
76                 err := fmt.Errorf("transaction tracker: Similar transaction with sub id %d and type %s is ongoing", key.SubID, key.TransType)
77                 return nil, err
78         }
79         if _, ok := t.transactionXappTable[xappkey]; ok {
80                 // TODO: Implement merge related check here. If the key is same but the value is different.
81                 err := fmt.Errorf("transaction tracker: Similar transaction with xapp key %v is ongoing", xappkey)
82                 return nil, err
83         }
84         t.transactionTable[key] = trans
85         t.transactionXappTable[xappkey] = trans
86         return trans, nil
87 }
88
89 /*
90 Retreives the transaction table entry for the given request.
91 Returns error in case the transaction cannot be found.
92 */
93 func (t *Tracker) RetriveTransaction(subID uint16, act Action) (*Transaction, error) {
94         key := TransactionKey{subID, act}
95         t.mutex.Lock()
96         defer t.mutex.Unlock()
97         if trans, ok := t.transactionTable[key]; ok {
98                 return trans, nil
99         }
100         err := fmt.Errorf("transaction record for Subscription ID %d and action %s does not exist", subID, act)
101         return nil, err
102 }
103
104 /*
105 Deletes the transaction table entry for the given request and returns the deleted xapp's address and port for reference.
106 Returns error in case the transaction cannot be found.
107 */
108 func (t *Tracker) completeTransaction(subID uint16, act Action) (*Transaction, error) {
109         key := TransactionKey{subID, act}
110         t.mutex.Lock()
111         defer t.mutex.Unlock()
112         if trans, ok1 := t.transactionTable[key]; ok1 {
113                 if _, ok2 := t.transactionXappTable[trans.Xappkey]; ok2 {
114                         delete(t.transactionXappTable, trans.Xappkey)
115                 }
116                 delete(t.transactionTable, key)
117                 return trans, nil
118         }
119         err := fmt.Errorf("transaction record for Subscription ID %d and action %s does not exist", subID, act)
120         return nil, err
121 }