The A1 Mediator listens on the northbound interface of the RIC for policy guidance. The caller (e.g., non RT RIC, SMO, etc.) creates policy types and policy instances through A1, and subsequently A1 exchanges messages with xApps via RMR.
Please see here for the docs: https://docs.o-ran-sc.org/projects/o-ran-sc-ric-plt-a1/en/latest/index.html
This wiki page may be useful for discussion about the A1 Mediator, feel free to post comments here.
22 Comments
Dongho Kim
Hi Chris Lott, I was reading this part: https://docs.o-ran-sc.org/projects/o-ran-sc-ric-plt-a1/en/latest/installation-guide.html#local-docker .
I realized that i need localrt file and ricmanifest.
I tried to find an example for those files.. but couldn't find one. can you please share examples for them?
Thanks
Dongho
Chris Lott
The "local.rt" argument is an RMR routing table. For examples please see the RMR documentation: https://docs.o-ran-sc.org/projects/o-ran-sc-ric-plt-lib-rmr/en/latest/overview.html
I don't understand the question about "ricmanifest"
Dongho Kim
docker run -dt -p 10000:10000 -v /path/to/localrt:/opt/route/local.rt -v /path/to/ricmanifest:/opt/ricmanifest.json a1:X.Y.Z -v
above command is from the instruction about running a docker container.
here, is ricmanifest not needed to run container?
Chris Lott
Thanks, I see it now. Correct, ricmanifest is not needed to run the container. I will update the document.
Dongho Kim
$ docker run -dt -p 10000:10000 -v /home/dk5913/a1_mediator/localrt:/opt/route/local.rt a1:2.1.7
4be8c7a60dc81b97c61c9d9fb8a69511db6f204b12e867c5c27c92fad66b7729
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4be8c7a60dc8 a1:2.1.7 "/bin/sh -c run.py" 2 seconds ago Exited (1) 1 second ago dreamy_bassi
$ docker logs -f 4be8c7a60dc8
Traceback (most recent call last):
File "/home/a1user/.local/bin/run.py", line 5, in <module>
from a1.run import main
ModuleNotFoundError: No module named 'a1'
I got above error once i ran the container..
Do you have any clue? i am using the version of code as below.
---- git log
Author: Lott, Christopher (cl778h) <cl778h@att.com>
Date: Wed Apr 22 10:54:20 2020 -0400
Upgrade xapp-frame-go module in integration tests
...
Change-Id: I9df1dce576b083674290857f1c23d9b3a25ab5c6
Sandeep Shah
Hi Dongho - did you build a docker image? Do "docker images | ls a1" and see if you see any images...Otherwise, you need to build a docker locally:
Go to a1/ric-plt/a1 and run command "docker build --no-cache -t a1:1.0.0 ."
This should create a docker image a1:1.0.0 that you can run locally...Hope this helps...
Dongho Kim
yes, here is output..
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
a1 2.1.7 c3a7905c8568 4 days ago 154MB
Chris Lott
It's very difficult for me to guess what happened here, especially without details of the routing table that you used. I think the command-line arguments -d (detach) and -t (allocate tty) should not be used together. Trying to reproduce your result, I built a docker image from the same commit and launched it, the result is below.
Instead of introducing the uncertainty of building, please try running the released image like this:
Dongho Kim
let me try to go with the released image and see.
Thanks for help!!
Dongho
Dongho Kim
now release image seems to be up.
when I did healthcheck as an initial testing, I find follow error in log.
Traceback (most recent call last):
File "/home/a1user/.local/lib/python3.8/site-packages/redis/connection.py", line 1179, in get_connection
connection = self._available_connections.pop()
IndexError: pop from empty list
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/a1user/.local/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/home/a1user/.local/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/a1user/.local/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/a1user/.local/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/a1user/.local/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/home/a1user/.local/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/a1user/.local/lib/python3.8/site-packages/connexion/decorators/decorator.py", line 48, in wrapper
response = function(request)
File "/home/a1user/.local/lib/python3.8/site-packages/connexion/decorators/uri_parsing.py", line 144, in wrapper
response = function(request)
File "/home/a1user/.local/lib/python3.8/site-packages/connexion/decorators/parameter.py", line 121, in wrapper
return function(**kwargs)
File "/home/a1user/.local/lib/python3.8/site-packages/a1/controller.py", line 68, in get_healthcheck
if not data.SDL.healthcheck():
File "/home/a1user/.local/lib/python3.8/site-packages/ricxappframe/xapp_sdl.py", line 149, in healthcheck
return self._sdl.is_active()
File "/home/a1user/.local/lib/python3.8/site-packages/ricsdl/syncstorage.py", line 137, in is_active
return self.__dbbackend.is_connected()
File "/home/a1user/.local/lib/python3.8/site-packages/ricsdl/backend/redis.py", line 95, in is_connected
return self.__redis.ping()
File "/home/a1user/.local/lib/python3.8/site-packages/redis/client.py", line 1351, in ping
return self.execute_command('PING')
File "/home/a1user/.local/lib/python3.8/site-packages/redis/client.py", line 875, in execute_command
conn = self.connection or pool.get_connection(command_name, **options)
File "/home/a1user/.local/lib/python3.8/site-packages/redis/connection.py", line 1181, in get_connection
connection = self.make_connection()
File "/home/a1user/.local/lib/python3.8/site-packages/redis/connection.py", line 1220, in make_connection
return self.connection_class(**self.connection_kwargs)
File "/home/a1user/.local/lib/python3.8/site-packages/redis/connection.py", line 502, in __init__
self.port = int(port)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
::ffff:172.17.0.1 - - [2020-04-28 23:06:51] "GET /a1-p/healthcheck HTTP/1.1" 500 387 0.011661
my localrt looks like this (I got this from Amber release's integration_test directory)
newrt|start
rte|20000|devarchwork:4560
rte|20001|devarchwork:4563
rte|21024|devarchwork:4562
newrt|end
should I install something else?
Chris Lott
Please explain how you performed the healthcheck - for example, did you run a curl or wget command? How did you start the A1 mediator docker container; most importantly, what environment variables are active?
The A1 Mediator requires access to a running SDL (Redis) instance, which it uses as a persistent store. Is it possible that maybe you started an A1 container only, without launching a Redis container also? Also see https://pypi.org/project/ricsdl/
The tests mock the SDL (Redis) instance to avoid the need for running one, like this:
Dongho Kim
ok, I was running only A1 mediator container. I did not know I needed to run redis container. that might be the issue.
I'm wondering if i can find a comprehensive document which explains all required modules or containers.
anyhow, here is what i did. hoping you can know anything else i am missing.
-----
before this, i did not have anything relevant to a1mediator..
$ cat localrt2
newrt|start
rte|20000|devarchwork:4560
rte|20001|devarchwork:4563
rte|21024|devarchwork:4562
newrt|end
$ docker run -dt -p 10000:10000 --name=a1med -v /home/dk5913/a1_mediator/localrt2:/opt/route/local.rt nexus3.o-ran-sc.org:10002/o-ran-sc/ric-plt-a1:2.1.6
$ docker logs a1med
{"ts": 1588118114047, "crit": "DEBUG", "id": "a1.run", "mdc": {}, "msg": "Initializing rmr thread. A1s webserver will not start until rmr initialization is complete."}
{"ts": 1588118114047, "crit": "DEBUG", "id": "a1.a1rmr", "mdc": {}, "msg": "Waiting for rmr to initialize.."}
1588118114 1/RMR [INFO] ric message routing library on SI95/g mv=3 flg=02 (338fe5e 3.6.3 built: Apr 4 2020)
{"ts": 1588118114549, "crit": "DEBUG", "id": "a1.a1rmr", "mdc": {}, "msg": "Work loop starting"}{"ts": 1588118114549, "crit": "DEBUG", "id": "a1.run", "mdc": {}, "msg": "Starting gevent server"}
1588118115 1/RMR [INFO] sends: ts=1588118115 src=e19786a5ee4e:4562 target=devarchwork:4563 open=0 succ=0 fail=0 (hard=0 soft=0)
$ curl -X GET http://172.17.0.2:10000/a1-p/healthcheck -H 'Accept: application/json' -H 'Cache-Control: no-cache' -H 'Content-Type: application/json'
{
"detail": "The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.",
"status": 500,
"title": "Internal Server Error",
"type": "about:blank"
}
---
for environment variables, I did not set anything extra..
Chris Lott
The A1 Mediator is just one component of a large deployment that constitutes the RIC. The Redis server is deployed under the name "database as a service" (dbaas) using this image:
registry: "nexus3.o-ran-sc.org:10002/o-ran-sc"
name: ric-plt-dbaas
tag: 0.2.2
It would help if you explain a bit more about what you're trying to do. I don't have documentation ready that explains how to pull the A1 Mediator out and use it outside the context of the RIC deployment environment.
Dongho Kim
Thanks again Chris.
I want to have a1mediator get a A1 policy instance and return a response.
for A1 policy, whatever schema should be fine.
I don't need to see interactions between a1mediator and xAPPs if it is not needed to get a response..
if a1mediator has a kind of simulation mode (just getting whatever a1policy and returning response), it is also fine for me.
Please let me know whether for this purpose dbaas is needed or anything else is needed..
if dbaas or other modules are needed, I hope to get information on how to stitch together with a1mediator..
Chris Lott
I think being able to start A1 easily in "mock" mode, i.e., without requiring SDL, will probably help multiple people. Please open a Jira ticket as a new user story and I'll look into it. The tests already do exactly this, I just have to figure out how to expose that feature in the main module, possibly via a different invocation sequence.
Deena Md
hi Chris,
i wanted to know if it is possible to simulate A1_POLICY_REQ towards xapp through curl command. Please let me know.
Thanks
Dongho Kim
ok, I created one.. but not sure if I can get such mock mode in near term (e.g. 2-3 wks)
Dongho Kim
Thanks Chris.. I saw you already commit the code.. I tested your new code in my setup and found it worked fine for me now..
John Keeney
Hi Dongho Kim , all,
You might find the OSC A1 simulator useful:
It's a lightweight stateful multi-version A1 test stub that maintains A1 policy types and instances - so provides a realistic test environment for functions that use A1.
Note it is not intended to act as a near-rt-ric simulator - just a realistic A1 test stub.
Ketan Parikh
Please explain how A1 Mediator will be able to POST Feedback Notification to Non-RT RIC as defined in specification.
In current dawn release, I am not sure if there is any support for A1 mediator to act as HTTP Client.
Also need some more clarity on the notifcationDestination that NON-RT RIC will send to which later on Feedback would be posted.
Deena Md
Are there any working sample xapp implementation which is able to receive A1_POLICY_REQ from a1mediator ?
SANDEEP KUMAR
Chris Lott Tommy Carpenter
I was trying to integrate A1-mediator to ts xapp(wrtitten on c++ framework).
A1-mediator is not able to send the policy to ts xaap. showing rmr send failed
Below are the steps that I followed.
1)routing file created for a1-mediator( policy_type_id 9999)


2)created policy schema with policy_type_id 9999
3)created the policy type 9999 by posting this schema to a1mediator using command
4)created policy instance of policy type 9999 using the command
5)below are the a1mediator logs
6)Ts xapp is already listening at message type 20010
Kindly let me know am I missing something.
Kindly point me to the right direction.