(continued)
HOW-TO: manually build xApps based on Gerrit sources
I will use ric-app-ts as an example.
First, 'git clone' from Gerrit repository: https://gerrit.o-ran-sc.org/r/gitweb?p=ric-app/ts.git;a=summary
git clone https://gerrit.o-ran-sc.org/r/ric-app/ts.git -b bronze
Update Dockerfile:
(00:02 dabs@ricpltbronze ts) > pwd
/home/dabs/oran/dep/ts
(00:02 dabs@ricpltbronze ts) > vim Dockerfile
Build docker image:
$sudo docker build -t ric-app-ts:1.0.11 .
Retag docker image:
(00:08 dabs@ricpltbronze ts) > docker images | grep ric-app-ts
ric-app-ts 1.0.11 526fd0ab56f9 3 hours ago 104MB
nexus3.o-ran-sc.org:10002/o-ran-sc/ric-app-ts 1.0.11 526fd0ab56f9 3 hours ago 104MB
HOW-TO: introduce policy types and policy instances
refer to https://wiki.o-ran-sc.org/display/GS/Hello+World+xApp+Use+Case+Flows
Step 4: Populate the Database with test RAN data
$ pwd
/home/dabs/oran/dep
$git clone http://gerrit.o-ran-sc.org/r/ric-app/ts -b bronze
$cd ts/test/populatedb
update Dockerfile:
#FROM nexus3.o-ran-sc.org:10004/o-ran-sc/bldr-ubuntu18-c-go:8-u18.04 as buildenv
FROM nexus3.o-ran-sc.org:10004/o-ran-sc/bldr-ubuntu18-c-go:9-u18.04 as buildenv
'docker pull' the bldr-ubuntu18-c-go image, which will take some time:
$docker pull nexus3.o-ran-sc.org:10004/o-ran-sc/bldr-ubuntu18-c-go:9-u18.04
(00:19 dabs@ricpltbronze dep) > docker images | grep ubuntu18
nexus3.o-ran-sc.org:10004/o-ran-sc/bldr-ubuntu18-c-go 9-u18.04 d52e6e2ff153 6 days ago 2.16GB
Execute populate_db.sh:
$sudo ./populate_db.sh
Check that the dbprepopjob job is complete:
(14:57 dabs@ricpltbronze populatedb) > sudo kubectl get jobs -A
NAMESPACE NAME COMPLETIONS DURATION AGE
ricinfra tiller-secret-generator 1/1 10s 20d
ricplt dbprepopjob 1/1 19h 19h
Step 5: Create a Policy Type |
---|
make sure port-forwarding is enabled:
(22:49 dabs@ricpltbronze ~) > sudo kubectl port-forward r4-infrastructure-kong-6c7f6db759-skqzc 32088:32080 -n ricplt
(15:00 dabs@ricpltbronze dep) > POLICY_TYPE_ID="20008"
(15:01 dabs@ricpltbronze dep) > 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
(15:01 dabs@ricpltbronze dep) > sudo 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
[sudo] password for dabs:
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 32088 (#0)
> PUT /a1mediator/a1-p/policytypes/20008 HTTP/1.1
> Host: localhost:32088
> User-Agent: curl/7.58.0
> accept: application/json
> Content-Type: application/json
> Content-Length: 329
>
* upload completely sent off: 329 out of 329 bytes
< HTTP/1.1 201 CREATED
< Content-Type: application/json
< Content-Length: 3
< Connection: keep-alive
< Date: Fri, 07 Aug 2020 07:02:53 GMT
< X-Kong-Upstream-Latency: 18
< X-Kong-Proxy-Latency: 5
< Via: kong/1.4.3
<
""
* Connection #0 to host localhost left intact
(15:01 dabs@ricpltbronze ~) > sudo kubectl logs -f deployment-ricplt-a1mediator-66fcf76c66-8dxcj -n ricplt
{"ts": 1596786015418, "crit": "DEBUG", "id": "a1.controller", "mdc": {}, "msg": "Policy type 20008 created."}
(15:02 dabs@ricpltbronze dep) > curl -X GET --header "Content-Type: application/json" --header "accept: application/json" http://localhost:32088/a1mediator/a1-p/policytypes
[
20008
]
Step 7: create a policy instance
(15:23 dabs@ricpltbronze dep) > POLICY_ID="tsapolicy145"
(15:17 dabs@ricpltbronze dep) > sudo curl -X PUT --header "Content-Type: application/json" --data "{\"threshold\" : 5}" http://localhost:32088/a1mediator/a1-p/policytypes/${POLICY_TYPE_ID}/policies/${POLICY_ID}
I have the 'RMR_ERR_NOENDPT' error when creating a policy instance at first:
After hours research on this matter, I think maybe the official docker image don't have callback function for the 20010 message type, so I decide to rebuild ric-app-ts from Gerrit and redeploy the ric-app-ts xApp.
No error happens when using the manually built docker image.
(22:26 dabs@ricpltbronze ~) > sudo kubectl logs -f ricxapp-trafficxapp-96bc7bd6b-t995r -n ricxapp
Policy Callback got a message, type=20010 , length=115
payload is {"operation": "CREATE", "policy_type_id": 20008, "policy_instance_id": "tsapolicy145", "payload": {"threshold": 5}} ], "310-680-200-555003" : [ 800000 , 400000 ] } }
Setting RSRP Threshold to A1-P value: 5
(22:19 dabs@ricpltbronze ~) > sudo kubectl logs -f deployment-ricplt-a1mediator-66fcf76c66-8dxcj -n ricplt
::ffff:10.244.0.61 - - [2020-08-07 14:12:02] "PUT /a1-p/policytypes/20008/policies/tsapolicy145 HTTP/1.1" 202 116 0.008321
{"ts": 1596809522972, "crit": "DEBUG", "id": "a1.a1rmr", "mdc": {}, "msg": "_send_msg: sending: {'payload': b'{\"operation\": \"CREATE\", \"policy_type_id\": 20008, \"policy_instance_id\": \"tsapolicy145\", \"payload\": {\"threshold\": 5}}', 'payload length': 115, 'message type': 20010, 'subscription id': 20008, 'transaction id': b'f769383ad8b711eaacd4cac483485e64', 'message state': 0, 'message status': 'RMR_OK', 'payload max size': 4096, 'meid': b'', 'message source': 'service-ricplt-a1mediator-rmr.ricplt:4562', 'errno': 0}"}
{"ts": 1596809522977, "crit": "DEBUG", "id": "a1.a1rmr", "mdc": {}, "msg": "_send_msg: result message state: 0"}
One problem as discussed at the ORAN-SC dashboard:
I had done some research on this issue, and below is my analysis:
Here is the normal output:
In get_sdl_ue_data()
message body {"UEPredictionSet": ["12345"]}
payload length 30
Prediction Callback got a message, type=30002 , length=182
payload is { "12345" : { "310-680-200-555001" : [ 2000000 , 1200000 ], "310-680-200-555002" : [ 800000 , 400000 ], "310-680-200-555003" : [ 800000 , 400000 ] } }
Prediction for 12345
from the source code:
void send_prediction_request(vector<string> ues_to_predict) {
int mtype = 30000;
// payload updated in place, nothing to copy from, so payload parm is nil
if ( ! msg->Send_msg( mtype, Message::NO_SUBID, strlen( (char *) send_payload.get() ), NULL )) {
fprintf( stderr, "<SNDR> send failed: %d\n", msg->Get_state() );
}}
void prediction_callback( Message& mbuf, int mtype, int subid, int len, Msg_component payload, void* data ) {
cout << "Prediction Callback got a message, type=" << mtype << " , length=" << len << "\n";
cout << "payload is " << payload.get() << "\n";}
which means that prediction_callback is not correctly called.
in tsxapp.main, prediction_callback is binded to MSG_ID=30002.
extern int main( int argc, char** argv ) {
xfw->Add_msg_cb( 20010, policy_callback, NULL );
xfw->Add_msg_cb( 30002, prediction_callback, NULL );
}
RMR will route msg with MSG_ID=30000 to qpdriver xapp. qpdriver will process it , and generate another msg with MSG_ID=30001
rmr_xapp.register_callback(steering_req_handler, 30000)
success = self.rmr_send(payload, 30001)
RMR will further route msg with MSG_ID=30001 to qp xapp. qp will process it, and generate another msg with MSG_ID=30002, which will be routed back to tsxapp by RMR.
qp_xapp.register_callback(qp_predict_handler, 30001)
success = self.rmr_send(mock_msg.encode(), 30002)
Based on above analysis, my best guess is that, qp-driver and qp xapp has not been deployed successfully.
(to be continued)