@NTUST
# [Release D & E]Manual of xApp Installation using DMS Tool
- Main Reference:[dms_cli commands](https://docs.o-ran-sc.org/projects/o-ran-sc-it-dep/en/latest/installation-guides.html#ric-applications) & [xApp_Writer_s_Guide_v2](https://wiki.o-ran-sc.org/download/attachments/17269011/xApp_Writer_s_Guide_v2.pdf?version=4&modificationDate=1625642899082&api=v2)
:::info
**Introduction:**
- In Dawn Release, there is **important updates for the Appmgr** (version 0.5.3). Near RT RIC Platform uses a new CLI called **dms_cli to replace the “onboard” and “deploy” functions** in the onboarder and appmgr.
- In E Release, RIC Platform delete the component "xapp onboarder", so the **environment variable "CHART_REPO_URL" will use Helm Repo in RIC Platform** rather than helm repo in xapp onboarder.
**Goals:**
- [x] [Flow of xApp onboarding & deploying & registering](#2-Flow-of-xApp-onboarding-amp-deploying-amp-registering)
- [x] [MSC about DMS](#12-MSC)
- [x] [Test dms_cli commands (ts xApp)](#5-Test-dms_cli-and-helm-repository-commands-ts-xApp)
- [x] [Deploy and Register the hw-go xApp](#6-Deploy-and-Register-the-hw-go-Scenario-1:xApp-using-the-registration-fuction)
- [x] [Deploy and Register the xApps of AD Use Case](#7-Deploy-and-Register-the-xApps-of-AD-Use-Case-Scenario-2:xApp-doesn’t-use-the-registration-fuction)
- [x] [Check the xApp status (AD Use Case)](#76-Check-the-xApp-statuses-of-AD-Use-Case)
- Whether the xApp registration is successful
- Whether the xApp Endpoints of the xApp exists in rtmgr
- Whether the Functions of AD Use Case is normal
:::
[toc]
==[Dawn Release]==
- Please Install [RIC Platform](https://hackmd.io/@Min-xiang/rJDociYTO) first, and verify the pods of RIC Platform is completed or running.
- The dms_cli tools is built from the source code of appmgr in version 0.5.3 (dawn).
``` shell=
kubectl get pod -n ricplt
```

==[E Release]==
- Please Install [RIC Platform](https://hackmd.io/@Yueh-Huan/HyzR8FyRY) first, and verify the pods of RIC Platform is completed or running.
``` shell=
kubectl get pod -n ricplt
```

## 1. Deployment Management Service(DMS)
### 1.1 Architecture

### 1.2 MSC

```mermaid
sequenceDiagram
Person->>SMO: Service Request
SMO->>DMS: Creat Deployment
DMS->>RIC: xApp register with the RIC
```
## 2. Flow of xApp onboarding & deploying & registering
- In dawn release, HW-GO xAppframe provided the **registration fuction** which **register xapp** and **send configurations (e.g. xapp descriptor) to the xapp manager**. If the xapp doesn't use the function, we will extra need to **give the registration command** to xapp manager.
- In dawn release, almost all the xApps by OSC provided didn't use the registration fuction, **only hw-go use the registration fuction**. When we deploy the xApps by OSC provided except hw-go, we will need to give the registration command to xapp manager.
### 2.1 Scenario 1:xApp use the registration fuction

### 2.2 Scenario 2:xApp doesn't use the registration fuction

## 3. Flow of xApp undeploying & deregistering

## 4. dms-cli and helm repository commands
### 4.1 Set up environment variables for CLI connection
- When using the dms-cli commands, we need to **set up the environment variable "CHART_REPO_URL"**.
==Notice==:Environment variables **disappears** when the terminal is close. You need to **set up it again** when you open the new terminal.
#### **4.1.1 Set up the environment variable**
==[Dawn Release]==
- Find the IP of the xapp-onboard:
``` shell=
kubectl get service -n ricplt
```

``` shell=
export CHART_REPO_URL=http://<xapp-onboard IP>:8080
```

- Check the CHART_REPO_URL
``` shell=
echo $CHART_REPO_URL
```

==[E Release]==
``` shell=
export NODE_PORT=$(kubectl get --namespace ricinfra -o jsonpath="{.spec.ports[0].nodePort}" services r4-chartmuseum-chartmuseum)
export NODE_IP=$(kubectl get nodes --namespace ricinfra -o jsonpath="{.items[0].status.addresses[0].address}")
export CHART_REPO_URL=http://$NODE_IP:$NODE_PORT/charts
```

- Check the CHART_REPO_URL
``` shell=
echo $CHART_REPO_URL
```

### 4.2 Commands about onboard/deploy/undeploy
- Commands of xApp onboarding:
``` shell=
dms_cli onboard --config_file_path=<CONFIG_FILE_PATH> --shcema_file_path=<SCHEMA_FILE_PATH>
```
- Commands of downloading the xApp helm charts:
``` shell=
dms_cli download_helm_chart --xapp_chart_name=<XAPP_CHART_NAME> --version=<VERSION> --output_path=<OUTPUT_PATH>
```
- Commands of xApp deploying (1):
- Deploy xApp by using helm chart of helm repository
``` shell=
dms_cli install --xapp_chart_name=<XAPP_CHART_NAME> --version=<VERSION> --namespace=<NAMESPACE>
```
- Commands of xApp deploying (2):
- Deploy xApp by using helm charts which is providing the override values.yaml
``` shell=
#Download the default values.yaml
dms_cli download_values_yaml --xapp_chart_name=<XAPP_CHART_NAME> --version=<VERSION> --output_path=<OUTPUT_PATH>
#Modify values.yaml and provide it as override file
dms_cli install --xapp_chart_name=<XAPP_CHART_NAME> --version=<VERSION> --namespace=<NAMESPACE> --overridefile=<OVERRIDEFILE>
```
- Commands of xApp undeploying:
``` shell=
dms_cli uninstall --xapp_chart_name=<XAPP_CHART_NAME> --namespace=<NAMESPACE>
```
- Commands of xApp upgrading:
``` shell=
dms_cli upgrade --xapp_chart_name=<XAPP_CHART_NAME> --old_version=<OLD_VERSION> --new_version=<NEW_VERSION> --namespace=<NAMESPACE>
```
- Commands of xApp rollbacking:
``` shell=
dms_cli rollback --xapp_chart_name=<XAPP_CHART_NAME> --new_version=<NEW_VERSION> --old_version=<OLD_VERSION> --namespace=<NAMESPACE>
```
- Commands of xApp health checking:
``` shell=
dms_cli health_check --xapp_chart_name=<XAPP_CHART_NAME> --namespace=<NAMESPACE>
```
### 4.3 Commands about helm charts
==[Dawn Release]==
- List all the helm charts from help repository:
``` shell=
curl -X GET http://<xapp-onboard IP>:8080/api/charts | jq .
```
- List details of specific helm chart from helm repository:
``` shell=
curl -X GET http://<xapp-onboard IP>:8080/api/charts/<XAPP_CHART_NAME>/<VERSION>
```
- Delete a specific Chart Version from helm repository:
``` shell=
curl -X DELETE http://<xapp-onboard IP>:8080/api/charts/<XAPP_CHART_NAME>/<VERSION>
```
==[E Release]==
- List all the helm charts from helm repository:
``` shell=
dms_cli get_charts_list
```
- List details of specific helm chart from helm repository:
``` shell=
curl -X GET ${CHART_REPO_URL}/api/charts/<XAPP_CHART_NAME>/<VERSION>
```
- Delete a specific Chart Version from helm repository:
``` shell=
curl -X DELETE ${CHART_REPO_URL}/api/charts/<XAPP_CHART_NAME>/<VERSION>
```
## 5. Test dms_cli and helm repository commands (ts xApp)
In section 5, we will testing dms_cli and helm repository commands by onboarding and deploying the ts xApp, so we need to prepare the xApp descriptor and schema to onboard.
### 5.1 Prepare the ts xApp descriptor and schema
**ts xApp descriptor**
``` shell=
touch ts.json
vim ts.json
```

``` shell=
{
"name": "trafficxapp",
"version": "1.0.0",
"containers": [
{
"name": "trafficxapp",
"image": {
"registry": "nexus3.o-ran-sc.org:10002",
"name": "o-ran-sc/ric-app-ts",
"tag": "1.1.1"
}
}
],
"messaging": {
"ports": [
{
"name": "rmr-data",
"container": "trafficxapp",
"port": 4560,
"rxMessages": [
"TS_QOE_PREDICTION",
"A1_POLICY_REQ",
"TS_ANOMALY_UPDATE"
],
"txMessages": [ "TS_UE_LIST", "TS_ANOMALY_ACK" ],
"policies": [20008],
"description": "rmr receive data port for mcxapp"
},
{
"name": "rmr-route",
"container": "trafficxapp",
"port": 4561,
"description": "rmr route port for mcxapp"
}
]
},
"rmr": {
"protPort": "tcp:4560",
"maxSize": 2072,
"numWorkers": 1,
"txMessages": [
"TS_UE_LIST",
"TS_ANOMALY_ACK"
],
"rxMessages": [
"TS_QOE_PREDICTION",
"A1_POLICY_REQ",
"TS_ANOMALY_UPDATE"
],
"policies": [20008]
},
"controls": {
"fileStrorage": false
},
"db" : {
"waitForSdl": false
}
}
```

**ts xApp schema:**
``` shell=
touch controls.json
vim controls.json
```

``` shell=
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "#/controls",
"type": "object",
"title": "Controls Section Schema",
"required": [
],
"properties": {
}
}
```

### 5.2 Set up environment variables for CLI connection
==[Dawn Release]==
``` shell=
kubectl get service -n ricplt
export CHART_REPO_URL=http://<xapp-onboard IP>:8080
echo $CHART_REPO_URL
```

==[E Release]==
``` shell=
export NODE_PORT=$(kubectl get --namespace ricinfra -o jsonpath="{.spec.ports[0].nodePort}" services r4-chartmuseum-chartmuseum)
export NODE_IP=$(kubectl get nodes --namespace ricinfra -o jsonpath="{.items[0].status.addresses[0].address}")
export CHART_REPO_URL=http://$NODE_IP:$NODE_PORT/charts
echo $CHART_REPO_URL
```

### 5.3 Onboard the ts xApp
- The command "dms_cli onboard" will creat the ts helm chart according to the ts xApp descriptor and schema, and upload it to helm repository.
``` shell=
dms_cli onboard --config_file_path=ts.json --shcema_file_path=controls.json
```

#### 5.3.1 Check the ts xApp helm chart
==[Dawn Release]==
- Method 1:List **all the helm charts** from helm repository
``` shell=
curl -X GET http://<xapp-onboard IP>:8080/api/charts | jq .
```

- Method 2:List details of **ts helm chart** from helm repository
``` shell=
curl -X GET http://<xapp-onboard IP>:8080/api/charts/trafficxapp/1.0.0
```

==[E Release]==
- Method 1:List **all the helm charts** from helm repository
``` shell=
dms_cli get_charts_list
```

- Method 2:List details of **ts helm chart** from helm repository
``` shell=
curl -X GET ${CHART_REPO_URL}/api/charts/<XAPP_CHART_NAME>/<VERSION>
```

### 5.4 Deploy the ts xApp
**Method 1:Helm install**
- You could modify the helm file of ts xApp though **ts helm file which is downloaded** by dms_cli cammand, then you can use ts helm file which you had modified to deploy the ts xApp.
- There aren't modifications of ts helm file in this example.
``` shell=
dms_cli download_helm_chart --xapp_chart_name=trafficxapp --version=1.0.0 --output_path=
ls
helm install --name=trafficxapp ./trafficxapp-1.0.0.tgz --namespace=ricxapp
```

**Method 2:Use the dms_cli installation command**
- It will use the ts xApp helm file from the helm repository to deploy the ts xApp. When the ts xApp had deployed, you could check whether the pod of ts xApp was "running".
``` shell=
dms_cli install --xapp_chart_name=trafficxapp --version=1.0.0 --namespace=ricxapp
kubectl get all -n ricxapp
```

**Method 3:Use the dms_cli installation command and override "values.yaml"**
- Download the "values.yaml" of ts helm file:
- The "values.yaml" is default name.
``` shell=
ls
dms_cli download_values_yaml --xapp_chart_name=trafficxapp --version=1.0.0
ls
```

- The commamd uses override "values.yaml" which is downloaded by dms_cli cammand and other files of ts helm charts to deploy the ts xApp. When the ts xApp had deployed, you could check whether the pod of ts xApp was “running”.
- There aren't modifications of "values.yaml" in this example.
``` shell=
dms_cli install --xapp_chart_name=trafficxapp --version=1.0.0 --namespace=ricxapp --overridefile=values.yaml
kubectl get all -n ricxapp
```

### 5.5 Check the health of ts xApp
``` shell=
dms_cli health_check --xapp_chart_name=trafficxapp --namespace=ricxapp
```

### 5.6 Upgrade & Rollback the ts xApp
- The commands needs at least two helm charts of the ts xApp.
- In this example, we will onboard the old version ts xApp to test the commands.
**Onboard the old version ts xApp**
- Prepare the old version ts xApp descriptor:
``` shell=
touch ts-old.json
vim ts-old.json
```

``` json=
{
"name": "trafficxapp",
"version": "0.0.9",
"containers": [
{
"name": "trafficxapp",
"image": {
"registry": "nexus3.o-ran-sc.org:10002",
"name": "o-ran-sc/ric-app-ts",
"tag": "1.0.13"
}
}
],
"messaging": {
"ports": [
{
"name": "rmr-data",
"container": "trafficxapp",
"port": 4560,
"rxMessages": [
"TS_QOE_PREDICTION",
"A1_POLICY_REQ",
"TS_ANOMALY_UPDATE"
],
"txMessages": [ "TS_UE_LIST", "TS_ANOMALY_ACK" ],
"policies": [20008],
"description": "rmr receive data port for mcxapp"
},
{
"name": "rmr-route",
"container": "trafficxapp",
"port": 4561,
"description": "rmr route port for mcxapp"
}
]
},
"rmr": {
"protPort": "tcp:4560",
"maxSize": 2072,
"numWorkers": 1,
"txMessages": [
"TS_UE_LIST",
"TS_ANOMALY_ACK"
],
"rxMessages": [
"TS_QOE_PREDICTION",
"A1_POLICY_REQ",
"TS_ANOMALY_UPDATE"
],
"policies": [20008]
},
"controls": {
"fileStrorage": false
},
"db" : {
"waitForSdl": false
}
}
```

- Onboard the old version ts xApp:
``` shell=
dms_cli onboard --config_file_path=ts-old.json --shcema_file_path=controls.json
```

- Check all the ts xApp helm chart:
==[Dawn Release]==
``` shell=
curl -X GET http://<xapp-onboard IP>:8080/api/charts | jq .
```

==[E Release]==
``` shell=
dms_cli get_charts_list
```
**Rollback the ts xApp**
- Change the ts xApp to old version, and check the ts xApp current version.
``` shell=
dms_cli rollback --xapp_chart_name=trafficxapp --new_version=1.0.0 --old_version=0.0.9 --namespace=ricxapp
kubectl describe deployment -n ricxapp ricxapp-trafficxapp
```

**Upgrade the ts xApp**
- Change the ts xApp to old version
``` shell=
dms_cli upgrade --xapp_chart_name=trafficxapp --old_version=0.0.9 --new_version=1.0.0 --namespace=ricxapp
```

### 5.7 Undeploy the ts xApp
- When the ts xApp had been undeployed, you could check the namespace "ricxapp".
``` shell=
dms_cli uninstall --xapp_chart_name=trafficxapp --namespace=ricxapp
kubectl get all -n ricxapp
```

### 5.8 Delete a ts helm Chart from helm repository (Optional)
==[Dawn Release]==
``` shell=
curl -X DELETE http://<xapp-onboard IP>:8080/api/charts/trafficxapp/0.0.9
curl -X GET http://<xapp-onboard IP>:8080/api/charts | jq .
curl -X DELETE http://<xapp-onboard IP>:8080/api/charts/trafficxapp/1.0.0
curl -X GET http://<xapp-onboard IP>:8080/api/charts | jq .
```

==[E Release]==
``` shell=
curl -X DELETE ${CHART_REPO_URL}/api/charts/trafficxapp/0.0.9
dms_cli get_charts_list
curl -X DELETE ${CHART_REPO_URL}/api/charts/trafficxapp/1.0.0
dms_cli get_charts_list
```
## 6. Deploy and Register the hw-go [(Scenario 1:xApp using the registration fuction)](#21-Scenario-1:xApp-use-the-registration-fuction)
### 6.1 Prepare the hw-go xApp descriptor and schema
**hw-go xApp descriptor**
```shell=
touch hw-go.json
vim hw-go.json
```
``` json=
{
"name": "hw-go",
"version": "1.0.1",
"containers": [
{
"name": "hw-go",
"image": {
"registry": "nexus3.o-ran-sc.org:10002",
"name": "o-ran-sc/ric-app-hw-go",
"tag": "1.0.1"
}
}
],
"livenessProbe": {
"httpGet": {
"path": "ric/v1/health/alive",
"port": 8080
},
"initialDelaySeconds": 5,
"periodSeconds": 15
},
"readinessProbe": {
"httpGet": {
"path": "ric/v1/health/ready",
"port": 8080
},
"initialDelaySeconds": 5,
"periodSeconds": 15
},
"messaging": {
"ports": [
{
"name": "http",
"container": "hw-go",
"port": 8080,
"description": "http service"
},
{
"name": "rmrroute",
"container": "hw-go",
"port": 4561,
"description": "rmr route port for hw-go xapp"
},
{
"name": "rmrdata",
"container": "hw-go",
"port": 4560,
"rxMessages": ["RIC_SUB_RESP", "RIC_SUB_FAILURE", "RIC_SUB_DEL_RESP", "RIC_INDICATION"],
"txMessages": ["RIC_SUB_REQ", "RIC_SUB_DEL_REQ", "RIC_SGNB_ADDITION_REQ", "RIC_SGNB_ADDITION_ACK"],
"mtypes" : [
{"name":"TESTNAME1","id":55555},
{"name":"TESTNAME2","id":55556}
],
"policies": [1],
"description": "rmr data port for hw-go"
}
]
},
"rmr": {
"protPort": "tcp:4560",
"maxSize": 2072,
"numWorkers": 1,
"txMessages": [
"RIC_SUB_REQ", "A1_POLICY_RESP", "A1_POLICY_QUERY", "RIC_HEALTH_CHECK_RESP"
],
"rxMessages": [
"RIC_SUB_RESP",
"A1_POLICY_REQ", "RIC_HEALTH_CHECK_REQ"
],
"policies": [1]
},
"controls": {
"fileStrorage": false
},
"db" : {
"waitForSdl": false
}
}
```
**hw-go xApp schema**
``` shell=
touch controls.json
vim controls.json
```
``` json=
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "#/controls",
"type": "object",
"title": "Controls Section Schema",
"required": [
],
"properties": {
}
}
```
### 6.2 Onboard and Deploy the hw-go xApp
==[Dawn Release]==
``` shell=
export Service_onboarder=$(kubectl get services -n ricplt | grep "\-onboarder-http" | cut -f1 -d ' ')
export Onboarder_IP=$(kubectl get svc ${Service_onboarder} -n ricplt -o yaml | grep clusterIP | awk '{print $2}')
export CHART_REPO_URL=http://${Onboarder_IP}:8080
dms_cli onboard --config_file_path=hw-go.json --shcema_file_path=controls.json
dms_cli install --xapp_chart_name=hw-go --version=1.0.1 --namespace=ricxapp
```

==[E Release]==
``` shell=
export NODE_PORT=$(kubectl get --namespace ricinfra -o jsonpath="{.spec.ports[0].nodePort}" services r4-chartmuseum-chartmuseum)
export NODE_IP=$(kubectl get nodes --namespace ricinfra -o jsonpath="{.items[0].status.addresses[0].address}")
export CHART_REPO_URL=http://$NODE_IP:$NODE_PORT/charts
dms_cli onboard --config_file_path=hw-go.json --shcema_file_path=controls.json
dms_cli install --xapp_chart_name=hw-go --version=1.0.1 --namespace=ricxapp
```
### 6.3 Check the hw-go xApp status
**Check 1:The pod status of hw-go xApp is Running**
``` shell=
kubectl get pod -n ricxapp
```

**Check 2:Whether the hw-go xApp registration is successful**
``` shell=
kubectl get pod -n ricplt
kubectl logs -f -n ricplt <appmgr pod name>
```

- The log of hw-go xApp registration in the appmgr


**Check 3:Whether the endpoints of the hw-go xApp exists in rtmgr**
``` shell=
kubectl get pod -n ricplt
kubectl logs -f -n ricplt <rtmgr pod name>
export Service_rtmgr=$(kubectl get services -n ricplt | grep "\-rtmgr-http" | cut -f1 -d ' ')
export Rtmgr_IP=$(kubectl get svc ${Service_rtmgr} -n ricplt -o yaml | grep clusterIP | awk '{print $2}')
curl -X GET "http://${Rtmgr_IP}:3800/ric/v1/getdebuginfo" -H "accept: application/json" | jq .
```

- The log of routing table in the rtmgr

### 6.4 Undeploy and Deregister the hw-go xApp (Optional)
**6.4.1 Undeploy the hw-go xApp**
``` shell=
dms_cli uninstall --xapp_chart_name=hw-go --namespace=ricxapp
kubectl get pod -n ricxapp
```

**6.4.2 Deregister the hw-go xApp**
``` shell=
export Service_appmgr=$(kubectl get services -n ricplt | grep "\-appmgr-http" | cut -f1 -d ' ')
export Appmgr_IP=$(kubectl get svc ${Service_appmgr} -n ricplt -o yaml | grep clusterIP | awk '{print $2}')
curl -X 'POST' "http://${Appmgr_IP}:8080/ric/v1/deregister" -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "hw-go",
"appInstanceName": "hw-go"
}'
```

- The log of hw-go xApp deregistration in the appmgr

**6.4.3 Check the rtmgr:there is no endpoint of hw-go xApp in routing table**
``` shell=
kubectl get pod -n ricplt
kubectl logs -f -n ricplt <rtmgr pod name>
```

- The log of routing table in the rtmgr

## 7. Deploy and Register the xApps of AD Use Case [(Scenario 2:xApp doesn’t use the registration fuction)](#22-Scenario-2:xApp-doesn’t-use-the-registration-fuction)
- Because the xApps of AD Use Case don’t use the registration function, we will extra need to give the registration command to xapp manager.
### 7.1 Dawnload codes of xApp to build images
- ad xApp
``` shell=
git clone https://github.com/ToriRobert/ad.git -b master
cd ad
docker build -t nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-ad:0.0.2 .
cd ..
```
- qp xApp
``` shell=
git clone https://github.com/ToriRobert/qp.git -b e-release
cd qp
docker build -t nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-qp:0.0.4 .
cd ..
```
- ts xApp
``` shell=
git clone "https://gerrit.o-ran-sc.org/r/ric-app/ts" -b dawn
cd ts/xapp-descriptor
vim schema.json
```
``` shell=
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "#/controls",
"type": "object",
"title": "Controls Section Schema",
"required": [
],
"properties": {
}
}
```
### 7.2 Onboard the xApps of AD Use Case
- Set the environment variable:
==[Dawn Release]==
``` shell=
export CHART_REPO_URL=http://<xapp-onboard IP>:8080
```
==[E Release]==
``` shell=
export NODE_PORT=$(kubectl get --namespace ricinfra -o jsonpath="{.spec.ports[0].nodePort}" services r4-chartmuseum-chartmuseum)
export NODE_IP=$(kubectl get nodes --namespace ricinfra -o jsonpath="{.items[0].status.addresses[0].address}")
export CHART_REPO_URL=http://$NODE_IP:$NODE_PORT/charts
```
- Onboard the xApps:
``` shell=
cd ~
dms_cli onboard --config_file_path=ad/xapp-descriptor/config.json --shcema_file_path=ad/xapp-descriptor/controls.json
dms_cli onboard --config_file_path=ts/xapp-descriptor/config.json --shcema_file_path=ts/xapp-descriptor/schema.json
dms_cli onboard --config_file_path=qp/xapp-descriptor/config.json --shcema_file_path=qp/xapp-descriptor/schema.json
```

- Check their helm charts from helm repository
==[Dawn Release]==
``` shell=
curl -X GET http://<xapp-onboard IP>:8080/api/charts | jq .
```

==[E Release]==
``` shell=
dms_cli get_charts_list
```
### 7.3 Deploy the xApps of AD Use Case
``` shell=
rm -rf ad
dms_cli install --xapp_chart_name=ad --version=0.0.2 --namespace=ricxapp
dms_cli install --xapp_chart_name=trafficxapp --version=1.0.0 --namespace=ricxapp
dms_cli install --xapp_chart_name=qp --version=0.0.4 --namespace=ricxapp
```

### 7.4 Register the xApps of AD Use Case
- The following figure is the details in registering xApp:

- The hw-go xApp has the HTTP endpoint, so it can use the two methods to get its xApp config.
- Method 1:Use the property "config"
- Method 2 (registry function use it):Use the http://<httpEndpoint><configPath>
- However, there aren't HTTP endpoints of AD Use Case xApps, we only register the xApps using the property "config".

**ad xApp**
``` shell=
curl -X 'POST' 'http://<appmgr IP>:8080/ric/v1/register' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "ad",
"appVersion": "0.0.2",
"appInstanceName": "ad",
"httpEndpoint": "",
"rmrEndpoint": "<RMR IP of ad xApp>:4560",
"config": " {\n \"name\": \"ad\",\n \"version\": \"0.0.2\",\n \"containers\": [{\"image\":{\"name\":\"o-ran-sc/ric-app-ad\",\"registry\":\"nexus3.o-ran-sc.org:10002\",\"tag\":\"0.0.2\"},\"name\":\"ad\"}],\n \"messaging\": {\n \"ports\": [{\"container\":\"ad\",\"description\":\"rmr receive data port for ad\",\"name\":\"rmr-data\",\"policies\":[],\"port\":4560,\"txMessages\":[\"TS_ANOMALY_UPDATE\"],\"rxMessages\":[\"TS_ANOMALY_ACK\"]},{\"container\":\"ad\",\"description\":\"rmr route port for ad\",\"name\":\"rmr-route\",\"port\":4561}]\n },\n \"rmr\": {\n \"protPort\": \"tcp:4560\",\n \"maxSize\": 2072,\n \"numWorkers\": 1,\n \"rxMessages\": [\"TS_ANOMALY_ACK\"],\n \"txMessages\": [\"TS_ANOMALY_UPDATE\"],\n \"policies\": []\n },\n \"controls\": {\n \"fileStrorage\": false\n },\n \"db\": {\n \"waitForSdl\": false\n }\n}\n"} "
}'
```

**ts xApp**
``` shell=
curl -X 'POST' 'http://<appmgr IP>:8080/ric/v1/register' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "trafficxapp",
"appVersion": "1.0.0",
"appInstanceName": "trafficxapp",
"httpEndpoint": "",
"rmrEndpoint": "<RMR IP of ts xApp>:4560",
"config": " {\n \"name\": \"trafficxapp\",\n \"version\": \"1.1.1\",\n \"containers\": [{\"image\":{\"name\":\"o-ran-sc/ric-app-ts\",\"registry\":\"nexus3.o-ran-sc.org:10004\",\"tag\":\"1.0.1\"},\"name\":\"trafficxapp\"}],\n \"messaging\": {\n \"ports\": [{\"container\":\"trafficxapp\",\"description\":\"rmr route port for mc xapp\",\"name\":\"rmr-route\",\"port\":4561},{\"container\":\"trafficxapp\",\"description\":\"rmr receive data port for mcxapp\",\"name\":\"rmr-data\",\"policies\":[20008],\"port\":4560,\"rxMessages\":[\"TS_QOE_PREDICTION\",\"A1_POLICY_REQ\",\"TS_ANOMALY_UPDATE\"],\"txMessages\":[\"TS_UE_LIST\",\"TS_ANOMALY_ACK\"]}]\n },\n \"rmr\": {\n \"protPort\": \"tcp:4560\",\n \"maxSize\": 2072,\n \"numWorkers\": 1,\n \"txMessages\": [\"TS_UE_LIST\",\"TS_ANOMALY_ACK\"],\n \"rxMessages\": [\"TS_QOE_PREDICTION\",\"A1_POLICY_REQ\",\"TS_ANOMALY_UPDATE\"],\n \"policies\": [1]\n },\n \"controls\": {\n \"fileStrorage\": false\n },\n \"db\": {\n \"waitForSdl\": false\n }\n}\n"} "
}'
```

**qp xApp**
``` shell=
curl -X 'POST' 'http://<appmgr IP>:8080/ric/v1/register' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "qp",
"appVersion": "0.0.4",
"appInstanceName": "qp",
"httpEndpoint": "",
"rmrEndpoint": "<RMR IP of qp xApp>:4560",
"config": " {\n \"name\": \"qp\",\n \"version\": \"0.0.4\",\n \"containers\": [{\"image\":{\"name\":\"o-ran-sc/ric-app-qp\",\"registry\":\"nexus3.o-ran-sc.org:10002\",\"tag\":\"0.0.4\"},\"name\":\"qp\"}],\n \"messaging\": {\n \"ports\": [{\"container\":\"qp\",\"description\":\"rmr route port for qp\",\"name\":\"rmr-route\",\"port\":4561},{\"container\":\"qp\",\"description\":\"rmr receive data port for qp\",\"name\":\"rmr-data\",\"policies\":[],\"port\":4560,\"rxMessages\":[\"TS_UE_LIST\"],\"txMessages\":[\"TS_QOE_PREDICTION\"]}]\n },\n \"rmr\": {\n \"protPort\": \"tcp:4560\",\n \"maxSize\": 2072,\n \"numWorkers\": 1,\n \"txMessages\": [\"TS_QOE_PREDICTION\"],\n \"rxMessages\": [\"TS_UE_LIST\"],\n \"policies\": [1]\n },\n \"controls\": {\n \"fileStrorage\": false\n },\n \"db\": {\n \"waitForSdl\": false\n }\n}\n"} "
}'
```

### 7.5 Check the xApp statuses of AD Use Case
**Check 1:The pod status of AD Use Case xApps are Running**
``` shell=
kubectl get pod -n ricxapp
```

**Check 2:Whether the AD Use Case xApp registrations are successful**
``` shell=
kubectl get pod -n ricplt
kubectl logs -f -n ricplt <appmgr pod name>
```

- The log of ad xApp registration in the appmgr

- The log of ts xApp registration in the appmgr

- The log of qp xApp registration in the appmgr

**Check 3:Whether the endpoints of the AD Use Case xApps exist in rtmgr**
``` shell=
kubectl get pod -n ricplt
kubectl logs -f -n ricplt <rtmgr pod name>
```
- The log of routing table in the rtmgr

**Check 4:Whether the Functions of AD Use Case is normal**
**ad xApp**
``` shell=
kubectl logs -f -n ricxapp <your AD xApp pod>
```

- Wait for minutes, you will see the following figure:

**ts xApp**
``` shell=
kubectl logs -f -n ricxapp <your TS xApp pod>
```

- Wait for the rmr message from ad xApp, you will see the following figure:

- ERROR message:In Dawn Release, ts xApp can't connect to E2 Simulator due to lacking a E2 Simulator, so there was error message.
**qp xApp**
``` shell=
kubectl logs -f -n ricxapp <your QP xApp pod>
```

- Wait for the rmr message from ts xApp, you will see the following figure:

### 7.6 Undeploy and Deregister the xApps of AD Use Case (Optional)
**7.6.1 Undeploy the xApps of AD Use Case**
``` shell=
dms_cli uninstall --xapp_chart_name=ad --namespace=ricxapp
dms_cli uninstall --xapp_chart_name=trafficxapp --namespace=ricxapp
dms_cli uninstall --xapp_chart_name=qp --namespace=ricxapp
kubectl get pod -n ricxapp
```

**7.6.2 Deregister the xApps of AD Use Case**
**ad xApp**
``` shell=
curl -X 'POST' 'http://<appmgr IP>:8080/ric/v1/deregister' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "ad",
"appInstanceName": "ad"
}'
```

- The log of ad xApp deregistration in the appmgr

**ts xApp**
``` shell=
curl -X 'POST' 'http://<appmgr IP>:8080/ric/v1/deregister' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "trafficxapp",
"appInstanceName": "trafficxapp"
}'
```

- The log of ts xApp deregistration in the appmgr

**qp xApp**
``` shell=
curl -X 'POST' 'http://<appmgr IP>:8080/ric/v1/deregister' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{
"appName": "qp",
"appInstanceName": "qp"
}'
```

- The log of qp xApp deregistration in the appmgr

**7.6.3 Check the rtmgr:there is no endpoint of xApps of AD Use Case in routing table**
``` shell=
kubectl get pod -n ricplt
kubectl logs -f -n ricplt <rtmgr pod name>
```

- The log of routing table in the rtmgr

---
**Useful command:Check the routing table**
``` shell=
curl -X GET "http://<rtmgr IP>:3800/ric/v1/getdebuginfo" -H "accept: application/json" | jq .
```
---
##### Completion Date of this manual:2021/9/1
##### First modification Date of this manual [E Release]:2022/6/17