Juha Hyttinen | 4896a40 | 2019-11-08 11:29:34 +0200 | [diff] [blame] | 1 | /* |
| 2 | ================================================================================== |
Abukar Mohamed | bf6780b | 2020-03-19 13:08:53 +0000 | [diff] [blame] | 3 | Copyright (c) 2020 AT&T Intellectual Property. |
| 4 | Copyright (c) 2020 Nokia |
Juha Hyttinen | 4896a40 | 2019-11-08 11:29:34 +0200 | [diff] [blame] | 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. |
Mohamed Abukar | 9f08bbc | 2020-04-06 21:15:45 +0300 | [diff] [blame] | 17 | |
| 18 | This source code is part of the near-RT RIC (RAN Intelligent Controller) |
| 19 | platform project (RICP). |
Juha Hyttinen | 4896a40 | 2019-11-08 11:29:34 +0200 | [diff] [blame] | 20 | ================================================================================== |
| 21 | */ |
Mohamed Abukar | 2e78e42 | 2019-06-02 11:45:52 +0300 | [diff] [blame] | 22 | package main |
| 23 | |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 24 | import ( |
Mohamed Abukar | 9f08bbc | 2020-04-06 21:15:45 +0300 | [diff] [blame] | 25 | "gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm" |
| 26 | "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/clientmodel" |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 27 | "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" |
| 28 | "net/http" |
| 29 | ) |
Mohamed Abukar | 2e78e42 | 2019-06-02 11:45:52 +0300 | [diff] [blame] | 30 | |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 31 | // This could be defined in types.go |
| 32 | type ExampleXapp struct { |
Mohamed Abukar | 9f08bbc | 2020-04-06 21:15:45 +0300 | [diff] [blame] | 33 | msgChan chan *xapp.RMRParams |
| 34 | stats map[string]xapp.Counter |
| 35 | rmrReady bool |
| 36 | waitForSdl bool |
| 37 | subscriptionInstances []*clientmodel.SubscriptionInstance |
| 38 | subscriptionId *string |
Mohamed Abukar | 2e78e42 | 2019-06-02 11:45:52 +0300 | [diff] [blame] | 39 | } |
| 40 | |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 41 | func (e *ExampleXapp) handleRICIndication(ranName string, r *xapp.RMRParams) { |
| 42 | // Just update metrics and store RMR message payload to SDL |
| 43 | e.stats["E2APIndicationsRx"].Inc() |
Mohamed Abukar | 2e78e42 | 2019-06-02 11:45:52 +0300 | [diff] [blame] | 44 | |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 45 | xapp.Sdl.Store("myKey", r.Payload) |
| 46 | } |
| 47 | |
| 48 | func (e *ExampleXapp) handleRICExampleMessage(ranName string, r *xapp.RMRParams) { |
| 49 | // Just update metrics and echo the message back (update the message type) |
| 50 | e.stats["RICExampleMessageRx"].Inc() |
| 51 | |
| 52 | r.Mtype = r.Mtype + 1 |
| 53 | if ok := xapp.Rmr.SendMsg(r); !ok { |
| 54 | xapp.Logger.Info("Rmr.SendMsg failed ...") |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | func (e *ExampleXapp) messageLoop() { |
| 59 | for { |
| 60 | msg := <-e.msgChan |
| 61 | id := xapp.Rmr.GetRicMessageName(msg.Mtype) |
| 62 | defer xapp.Rmr.Free(msg.Mbuf) |
| 63 | |
| 64 | xapp.Logger.Info("Message received: name=%s meid=%s subId=%d txid=%s len=%d", id, msg.Meid.RanName, msg.SubId, msg.Xid, msg.PayloadLen) |
| 65 | |
| 66 | switch id { |
| 67 | case "RIC_INDICATION": |
| 68 | e.handleRICIndication(msg.Meid.RanName, msg) |
| 69 | case "RIC_EXAMPLE_MESSAGE": |
| 70 | e.handleRICExampleMessage(msg.Meid.RanName, msg) |
| 71 | default: |
| 72 | xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype) |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
Mohamed Abukar | 9f08bbc | 2020-04-06 21:15:45 +0300 | [diff] [blame] | 77 | func (e *ExampleXapp) Subscribe() { |
| 78 | // Setup response callback to handle subscription response from SubMgr |
| 79 | xapp.Subscription.SetResponseCB(func(resp *clientmodel.SubscriptionResponse) { |
| 80 | if *e.subscriptionId == *resp.SubscriptionID { |
| 81 | for _, s := range resp.SubscriptionInstances { |
| 82 | e.subscriptionInstances = append(e.subscriptionInstances, s) |
| 83 | } |
| 84 | } |
| 85 | }) |
| 86 | |
| 87 | // Fill subscription parameters: type=REPORT |
| 88 | ranName := "en-gnb:369-11105-aaaaa8" |
| 89 | functionId := int64(1) |
| 90 | clientEndpoint := "localhost:4560" |
| 91 | |
| 92 | reportParams := clientmodel.ReportParams{ |
| 93 | Meid: ranName, |
| 94 | RANFunctionID: &functionId, |
| 95 | ClientEndpoint: &clientEndpoint, |
| 96 | EventTriggers: clientmodel.EventTriggerList{ |
| 97 | &clientmodel.EventTrigger{ |
| 98 | InterfaceDirection: int64(0), |
| 99 | ProcedureCode: int64(27), |
| 100 | TypeOfMessage: int64(1), |
| 101 | }, |
| 102 | }, |
| 103 | } |
| 104 | |
| 105 | // Now subscribe ... |
| 106 | if resp, err := xapp.Subscription.SubscribeReport(&reportParams); err == nil { |
| 107 | e.subscriptionId = resp.SubscriptionID |
| 108 | xapp.Logger.Info("Subscriptions for RanName='%s' [subscriptionId=%s] done!", ranName, *resp.SubscriptionID) |
| 109 | return |
| 110 | } |
| 111 | |
| 112 | // Subscription failed, raise alarm (only for demo purpose!) |
| 113 | if err := xapp.Alarm.Raise(8006, alarm.SeverityCritical, ranName, "subscriptionFailed"); err != nil { |
| 114 | xapp.Logger.Info("Raising alarm failed with error: %v", err) |
| 115 | } |
| 116 | } |
| 117 | |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 118 | func (e *ExampleXapp) Consume(rp *xapp.RMRParams) (err error) { |
| 119 | e.msgChan <- rp |
| 120 | return |
| 121 | } |
| 122 | |
| 123 | func (u *ExampleXapp) TestRestHandler(w http.ResponseWriter, r *http.Request) { |
| 124 | xapp.Logger.Info("TestRestHandler called!") |
| 125 | } |
| 126 | |
| 127 | func (u *ExampleXapp) ConfigChangeHandler(f string) { |
| 128 | xapp.Logger.Info("Config file changed, do something meaningful!") |
| 129 | } |
| 130 | |
| 131 | func (u *ExampleXapp) StatusCB() bool { |
| 132 | xapp.Logger.Info("Status callback called, do something meaningful!") |
| 133 | return true |
| 134 | } |
| 135 | |
| 136 | func (e *ExampleXapp) Run() { |
| 137 | // Set MDC (read: name visible in the logs) |
| 138 | xapp.Logger.SetMdc("example-xapp", "0.1.2") |
| 139 | |
| 140 | // Register various callback functions for application management |
| 141 | xapp.SetReadyCB(func(d interface{}) { e.rmrReady = true }, true) |
| 142 | xapp.AddConfigChangeListener(e.ConfigChangeHandler) |
| 143 | xapp.Resource.InjectStatusCb(e.StatusCB) |
| 144 | |
| 145 | // Inject own REST handler for testing purpose |
| 146 | xapp.Resource.InjectRoute("/ric/v1/testing", e.TestRestHandler, "POST") |
| 147 | |
| 148 | go e.messageLoop() |
Abukar Mohamed | bf6780b | 2020-03-19 13:08:53 +0000 | [diff] [blame] | 149 | xapp.RunWithParams(e, e.waitForSdl) |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | func GetMetricsOpts() []xapp.CounterOpts { |
| 153 | return []xapp.CounterOpts{ |
| 154 | {Name: "RICIndicationsRx", Help: "The total number of RIC inidcation events received"}, |
| 155 | {Name: "RICExampleMessageRx", Help: "The total number of RIC example messages received"}, |
| 156 | } |
| 157 | } |
| 158 | |
Abukar Mohamed | bf6780b | 2020-03-19 13:08:53 +0000 | [diff] [blame] | 159 | func NewExampleXapp(rmrReady bool) *ExampleXapp { |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 160 | metrics := GetMetricsOpts() |
| 161 | return &ExampleXapp{ |
Abukar Mohamed | bf6780b | 2020-03-19 13:08:53 +0000 | [diff] [blame] | 162 | msgChan: make(chan *xapp.RMRParams), |
| 163 | stats: xapp.Metric.RegisterCounterGroup(metrics, "ExampleXapp"), |
| 164 | rmrReady: rmrReady, |
| 165 | waitForSdl: xapp.Config.GetBool("db.waitForSdl"), |
Mohamed Abukar | 96be509 | 2020-02-04 19:31:51 +0200 | [diff] [blame] | 166 | } |
Mohamed Abukar | 2e78e42 | 2019-06-02 11:45:52 +0300 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | func main() { |
Abukar Mohamed | bf6780b | 2020-03-19 13:08:53 +0000 | [diff] [blame] | 170 | NewExampleXapp(true).Run() |
Mohamed Abukar | 2e78e42 | 2019-06-02 11:45:52 +0300 | [diff] [blame] | 171 | } |