---
# System prepended metadata

title: <5G O-RAN 筆記4> A1 介面操作範例
tags: [套件部署, ' 5G O-RAN']

---

---
tags: 套件部署, 5G O-RAN
GA: UA-79596126-4
title: <5G O-RAN 筆記4> A1 介面操作範例
---
{%hackmd BJrTq20hE %}
###### 作者: 史啜林
###### 撰寫日期：2021/11/25
# <5G O-RAN 筆記4> A1 介面操作範例

這次示範的範例是延續前面幾篇的內容，這邊將進行流量閥值控制作為 demo，其中會用到三個 xApp 的服務，分別是：
* QP xApp (QoE Predictor)
* QP Driver xApp
* TS xApp (Traffuc Steering)

整體架構與流程如圖所示
![](https://i.imgur.com/ugdBx8I.png)


## 取得 3 個 xApp 的設定檔

首先透過下列指令分別取得 qp、qp driver、ts 的 xApp config file
```bash
# QP(QoE Predictor) xapp descriptor(using v0.0.4)
$ echo '{"config-file.json_url": "https://gerrit.o-ran-sc.org/r/gitweb?p=ric-app/qp.git;a=blob_plain;f=xapp-descriptor/config.json;hb=HEAD" }' > onboard.qp.url
# QP(QoE Predictor) driver xapp descriptor(using v1.0.9)
$ echo '{"config-file.json_url": "https://gerrit.o-ran-sc.org/r/gitweb?p=ric-app/qp-driver.git;a=blob_plain;f=xapp-descriptor/config.json;h=9bc76b31fa36ffd74200023214ab169b132cf62b;hb=f628e2b58bde028a9b0bd0ee48168fb773814e69" }' > onboard.qpd.url
# TS(traffic steering) xapp descriptor
$ echo '{"config-file.json_url": "https://gerrit.o-ran-sc.org/r/gitweb?p=ric-app/ts.git;a=blob_plain;f=xapp-descriptor/config.json;hb=HEAD" }' > onboard.ts.url
```

上述指令中，qp 的 image 檔案會有問題，所以這邊手動修正
```bash
$ docker pull nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-qp:0.0.2
$ docker tag nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-qp:0.0.2 nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-qp:0.0.4
$ docker rmi nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-qp:0.0.2
$ docker images | grep qp
```
![](https://i.imgur.com/EO4q4La.png)

## 部署 xApp
首先，透過 port-forward 的方式使部署順利
```bash
$ kubectl get pods -A | grep kong 
$ kubectl port-forward r4-infrastructure-kong-646b68bd88-cqzsd 32088:32080 -n ricplt
```

將上述設定檔放入 helm list 中
```bash
$ curl --location --request POST "http://localhost:32088/onboard/api/v1/onboard/download"  --header 'Content-Type: application/json' --data-binary "@./onboard.qp.url" 
$ curl --location --request POST "http://localhost:32088/onboard/api/v1/onboard/download"  --header 'Content-Type: application/json' --data-binary "@./onboard.qpd.url"
$ curl --location --request POST "http://localhost:32088/onboard/api/v1/onboard/download"  --header 'Content-Type: application/json' --data-binary "@./onboard.ts.url"
```
查詢已放上的 xApp 的描述檔
```bash
$ curl --location --request GET "http://localhost:32088/onboard/api/v1/charts"
```
![](https://i.imgur.com/rE4Rfjc.png)

啟動 xApp 
```bash
$ curl --location --request POST "http://localhost:32088/appmgr/ric/v1/xapps"  --header 'Content-Type: application/json'  --data-raw '{"xappName": "hwxapp"}' -v
$ curl --location --request POST "http://localhost:32088/appmgr/ric/v1/xapps"  --header 'Content-Type: application/json'  --data-raw '{"xappName": "qp"}' -v
$ curl --location --request POST "http://localhost:32088/appmgr/ric/v1/xapps"  --header 'Content-Type: application/json'  --data-raw '{"xappName": "qpdriver"}' -v
$ curl --location --request POST "http://localhost:32088/appmgr/ric/v1/xapps"  --header 'Content-Type: application/json'  --data-raw '{"xappName": "trafficxapp"}' -v

$ kubectl get pod -n ricxapp
```
![](https://i.imgur.com/udaEGYO.png)

## 確認環境狀態
首先確認 nonrtric 是否有指向正確的 IP
若無，則需進行修正後重新部署 Non-RT RIC

![](https://i.imgur.com/27ox7d4.jpg)
```bash
$ vim nonrtric/RECIPE_EXAMPLE/example_recipe.yaml
```
```yaml=137
#"baseUrl":"http://192.168.130.80:32080/a1mediator",
"baseUrl":"http://172.31.2.4:32080/a1mediator",
```
![](https://i.imgur.com/c6xv8RR.png)
```bash
$ ./undeploy-nonrtric && ./deploy-nonrtric -f ./nonrtric/RECIPE_EXAMPLE/example_recipe.yaml
$ kubectl get pod -n nonrtric
```
![](https://i.imgur.com/KSEp1Dq.png)

接著，確認運行在 Non-RT RIC 的 policymanagementservice 的 IP 以及他所使用的 port
```bash
$ kubectl get service -n nonrtric
```
![](https://i.imgur.com/AUsq04Z.png)

我們這時可以確認到「policymanagementservice」(Policy-Agent) 的 port 為 9080 而 HTTP 所使用的則是 與 nodeport 為 30093，並且其 Cluster IP 為 10.109.58.175

此時，我們便可以透過 nonrtric 確認是否已取得 ricplt 的訊息
```bash
$ curl -X GET http://10.109.58.175:9080/rics
```
![](https://i.imgur.com/vZQoYlc.png)

根據上圖，我們便可以看到有一個叫做「ric1」的 Near-RT RIC，並且其狀態為「AVAILABLE」
此處的「policyTypes」若為空的，則代表我們尚未創立任何的 policyTypes 至 Near-RT RIC，若已經建立，則可以跳過以下流程

## 建立 policyTypes
首先確認 nonrtric 中運行的 controlpanel 狀態
```bash
$ kubectl get service controlpanel -n nonrtric -o yaml
```
![](https://i.imgur.com/ZRiocOV.png)

根據上圖我們可以看到 controlpanel 的 port 為 8080 而 HTTP 所使用的則是 與 nodeport 為 30092

接著，我們針對 controlpanel 進行 port-forward 功能，使得外部可以存取該資訊
```bash
$ kubectl get pod -n nonrtric
$ kubectl port-forward controlpanel-8bd4748f4-8nb26 8088:8080 -n nonrtric
```
![](https://i.imgur.com/RTb2DZl.png)

接著可以打開瀏覽器查看我們的 UI 介面，```http://localhost:30091```就可以看到我們的 controlpanel 介面，並控制 xApp 的 policyTypes
![](https://i.imgur.com/7jJdk9y.png)
![](https://i.imgur.com/oNELwbC.png)


從 UI 這邊可以看到目前還沒有任何東西，因此我們現在要建立一個 policyTypes，切回 CLI 介面，並建立一個 id 為 20008 的 policyTypes

1. 首先於 ricplt 中確定 port forward 功能有正常啟動
   ```bash
   $ kubectl port-forward r4-infrastructure-kong-646b68bd88-cwrzh 32088:32080 -n ricplt
   ```
   ![](https://i.imgur.com/Md076Sa.png)
2. 接著開始定義 PolicyTypes 狀態
   ```bash
   $ POLICY_TYPE_ID="20008"
   $ echo '{"name": "tsapolicy", "description": "tsa parameters", "policy_type_id": 20008, "create_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "title": "TS Policy", "description": "TS policy type", "type": "object", "properties": {"threshold": {"type": "integer", "default": 0}}, "additionalProperties": false}}' > ts-policy-type-20008.json
   $  curl -v -X PUT "http://localhost:32088/a1mediator/a1-p/policytypes/${POLICY_TYPE_ID}" -H "accept: application/json" -H "Content-Type: application/json" -d @./ts-policy-type-${POLICY_TYPE_ID}.json
   ```
   ![](https://i.imgur.com/2O41Qw6.png)

3. 檢視 a1mediator 的 log 訊息是否成功新增
   ```bash
   $ kubectl logs -f deployment-ricplt-a1mediator-66fcf76c66-ztktp -n ricplt | grep 20008
   ```
   ![](https://i.imgur.com/tkDsIYZ.png)

4.  查看目前的 PolicyTypes
    ```bash
    $ curl -X GET -H "Content-Type: application/json" -H "accept: application/json" http://localhost:32088/a1mediator/a1-p/policytypes
    ```
    ![](https://i.imgur.com/w1SyF0Q.png)

此時，我們再回來看 UI 介面，便可以看到已經建立的 PolicyTypes，並且其 id 為 20008，然而底下仍沒有任何實例可以使用，因此接著將在 20008 底下建立 policy 實例
![](https://i.imgur.com/lNWg8Fz.png)

同時回到 SMO CLI 中查看，原本空的 policyTypes 出現我們剛剛所建立 id 為 20008 在裡面
```bash
$ curl -X GET http://10.109.58.175:9080/rics
```
![](https://i.imgur.com/d1PXlTT.png)


## 建立 policy 實例
我們接下來於 id 為 20008 底下建立一個名為「policyTH15」的 policy 實例，作為流量閥值管理

1. 首先建立一個 Service 名稱為「exampleSvc」
    ```bash
    $ curl -X PUT "http://10.109.58.175:9080/service" -H "Content-Type: application/json" -d '{"callbackUrl": "","keepAliveIntervalSeconds":0,"serviceName":"exampleSvc"}'
    $ curl -X GET --header "Content-Type: application/json" "http://10.109.58.175:9080/services"
    ```
    ![](https://i.imgur.com/AYfR7BU.png)

2. 建立一個名為「policyTH15」的 policy 實例
   ```bash
   $  curl -X PUT --header "Content-Type: application/json" --data "{\"threshold\":15}" "http://10.109.58.175:9080/policy?id=policyTh15&ric=ric1&service=exampleSvc&type=20008"
   ```
3. 查詢是否建立成功
   ```bash
   $  curl -X GET --header "Content-Type: application/json" "http://10.109.58.175:9080/policies"
   ```
    ![](https://i.imgur.com/9TELByk.png)

建立完成後，也可以從 UI 介面查道此實例已建立完成

![](https://i.imgur.com/WCru2Da.png)

同時，若是透過 UI 更新閥值數值，透過 Near-RT RIC 的 CLI 介面也可同樣看到實際變化，以此證明 A1 介面是互通狀態

![](https://i.imgur.com/kxb0ykq.png)

![](https://i.imgur.com/j6pGIBF.png)



