Example xApp enhancement
[ric-plt/xapp-frame.git] / examples / cmd / example-xapp.go
index 8fe7873..f2ea456 100755 (executable)
    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.
+
+   This source code is part of the near-RT RIC (RAN Intelligent Controller)
+   platform project (RICP).
 ==================================================================================
 */
 package main
 
 import (
+       "gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/clientmodel"
        "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
        "net/http"
 )
 
 // This could be defined in types.go
 type ExampleXapp struct {
-       msgChan    chan *xapp.RMRParams
-       stats      map[string]xapp.Counter
-       rmrReady   bool
-       waitForSdl bool
+       stats                 map[string]xapp.Counter
+       rmrReady              bool
+       waitForSdl            bool
+       subscriptionInstances []*clientmodel.SubscriptionInstance
+       subscriptionId        *string
 }
 
 func (e *ExampleXapp) handleRICIndication(ranName string, r *xapp.RMRParams) {
@@ -48,27 +54,65 @@ func (e *ExampleXapp) handleRICExampleMessage(ranName string, r *xapp.RMRParams)
        }
 }
 
-func (e *ExampleXapp) messageLoop() {
-       for {
-               msg := <-e.msgChan
-               id := xapp.Rmr.GetRicMessageName(msg.Mtype)
-               defer xapp.Rmr.Free(msg.Mbuf)
-
-               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)
-
-               switch id {
-               case "RIC_INDICATION":
-                       e.handleRICIndication(msg.Meid.RanName, msg)
-               case "RIC_EXAMPLE_MESSAGE":
-                       e.handleRICExampleMessage(msg.Meid.RanName, msg)
-               default:
-                       xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
+func (e *ExampleXapp) Subscribe() {
+       // Setup response callback to handle subscription response from SubMgr
+       xapp.Subscription.SetResponseCB(func(resp *clientmodel.SubscriptionResponse) {
+               if *e.subscriptionId == *resp.SubscriptionID {
+                       for _, s := range resp.SubscriptionInstances {
+                               e.subscriptionInstances = append(e.subscriptionInstances, s)
+                       }
                }
+       })
+
+       // Fill subscription parameters: type=REPORT
+       ranName := "en-gnb:369-11105-aaaaa8"
+       functionId := int64(1)
+       clientEndpoint := "localhost:4560"
+
+       reportParams := clientmodel.ReportParams{
+               Meid:           ranName,
+               RANFunctionID:  &functionId,
+               ClientEndpoint: &clientEndpoint,
+               EventTriggers: clientmodel.EventTriggerList{
+                       &clientmodel.EventTrigger{
+                               InterfaceDirection: int64(0),
+                               ProcedureCode:      int64(27),
+                               TypeOfMessage:      int64(1),
+                       },
+               },
+       }
+
+       // Now subscribe ...
+       if resp, err := xapp.Subscription.SubscribeReport(&reportParams); err == nil {
+               e.subscriptionId = resp.SubscriptionID
+               xapp.Logger.Info("Subscriptions for RanName='%s' [subscriptionId=%s] done!", ranName, *resp.SubscriptionID)
+               return
+       }
+
+       // Subscription failed, raise alarm (only for demo purpose!)
+       if err := xapp.Alarm.Raise(8006, alarm.SeverityCritical, ranName, "subscriptionFailed"); err != nil {
+               xapp.Logger.Info("Raising alarm failed with error: %v", err)
        }
 }
 
-func (e *ExampleXapp) Consume(rp *xapp.RMRParams) (err error) {
-       e.msgChan <- rp
+func (e *ExampleXapp) Consume(msg *xapp.RMRParams) (err error) {
+       id := xapp.Rmr.GetRicMessageName(msg.Mtype)
+
+       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)
+
+       switch id {
+       case "RIC_INDICATION":
+               e.handleRICIndication(msg.Meid.RanName, msg)
+       case "RIC_EXAMPLE_MESSAGE":
+               e.handleRICExampleMessage(msg.Meid.RanName, msg)
+       default:
+               xapp.Logger.Info("Unknown Message Type '%d', discarding", msg.Mtype)
+       }
+
+       defer func() {
+               xapp.Rmr.Free(msg.Mbuf)
+               msg.Mbuf = nil
+       }()
        return
 }
 
@@ -87,7 +131,7 @@ func (u *ExampleXapp) StatusCB() bool {
 
 func (e *ExampleXapp) Run() {
        // Set MDC (read: name visible in the logs)
-       xapp.Logger.SetMdc("example-xapp", "0.1.2")
+       xapp.Logger.SetMdc("example-xapp", "0.1.3")
 
        // Register various callback functions for application management
        xapp.SetReadyCB(func(d interface{}) { e.rmrReady = true }, true)
@@ -97,7 +141,6 @@ func (e *ExampleXapp) Run() {
        // Inject own REST handler for testing purpose
        xapp.Resource.InjectRoute("/ric/v1/testing", e.TestRestHandler, "POST")
 
-       go e.messageLoop()
        xapp.RunWithParams(e, e.waitForSdl)
 }
 
@@ -111,7 +154,6 @@ func GetMetricsOpts() []xapp.CounterOpts {
 func NewExampleXapp(rmrReady bool) *ExampleXapp {
        metrics := GetMetricsOpts()
        return &ExampleXapp{
-               msgChan:    make(chan *xapp.RMRParams),
                stats:      xapp.Metric.RegisterCounterGroup(metrics, "ExampleXapp"),
                rmrReady:   rmrReady,
                waitForSdl: xapp.Config.GetBool("db.waitForSdl"),