Developing and Testing the 5GMSd Application Server
Here you will find information to assist with development and testing of the 5G-MAG Reference Tools 5GMS Application Server (AS).
Files in the 5GMS AS repository include:
- ATTRIBUTION_NOTICE - List of 3rd party software used when running the 5GMS application server.
- LICENSE - The software license for this project.
- README.md - Project README file.
- pyproject.toml - The Python project description for building and installing the application.
- build_scripts/ - Scripts used when building the python project.
- api.mustache - openapi-generator template file to pass operations onto methods in the class defined in src/rt_5gms_as/server.py.
- backend.py - build backend wrapper to trigger extra build actions.
- generate_5gms_as_openapi - Will generate the OpenAPI python modules if not already present.
- M3_merged.yaml - OpenAPI YAML wrapper file to merge the M3 interface files into one for API bindings generation.
- openapi-generator-config.yaml.in - openapi-generator configuration file template.
- docs/ - Development documentation and examples.
- example-application-server.conf - An application configuration which documents the defaults and meaning for each application configuration option.
- external/ - Directory containing submodule mount points.
- rt-common-shared/ - The common shared examples and scripts.
- src/ - The application source modules.
- rt_5gms_as/ - The main Python module for this application
- app.py - Application entry point.
- exceptions.py - Application specific Exception class definitions.
- context.py - Module for the application Context class.
- openapi_5g/ - Python bindings generated by openapi-generator-cli from the 5G APIs. Note: This directory is not present in the tree until
build_scripts/generate_openapi
is run. - proxies/ - Contains the web server/proxy detection and configuration classes and any data files they need.
- proxy_factory.py - Factory module to pick a suitable web server/proxy.
- server.py - M3 Server implementation.
- utils.py - Common utility functions for the web server/proxy classes.
- rt_5gms_as/ - The main Python module for this application
- tests/ - Regression and build acceptance tests and other testing tools.
- examples/ - Example configurations to go along with the tests.
While the instructions in the main project README tell you how to install the 5GMSd Application Server as a system-wide application, during development it is usually more appropriate to have one or more local clones of the repository that are being used for development and testing. This page provides details of one suggested way to arrange your development environment to ensure separation from the main system during development and testing.
Prerequisites
There are some packages that will need to be installed system wide that the build and install system relies on. These prerequisite packages are:
- Commands
- Git
- Java
- Python 3
- Wget
- Python 3 modules
- pip
- venv
These can usually be installed as system packages, for example: Debian/Ubuntu Linux and derivatives
sudo apt -y install git default-jdk python3 wget python3-pip python3-venv
RHEL/CentOS/Fedora/Rocky
sudo dnf -y install git java-latest-openjdk python3 wget python3-pip python3-venv
Checking out the project code
Since this will be used for development and testing, the instructions here will show you how to check out the latest development branch.
Checkout for development
- Create a fork
- Login to GitHub (create a GitHub account and set an SSH key if you haven’t already done so).
- On the main GitHub project page click on the “Fork” label in the top right of the page, then untick “Copy the
main
branch only” on the page that appears and select the “Create fork” button. - On your new fork page select the
Settings
option just below the main repository title. Then select “Branches” under the “Code and automation” topic from the sections on the left, and edit the “Default branch” to change it todevelopment
. - Clone the repository
cd git clone --recurse-submodules git@github.com:<your-github-user>/rt-5gms-application-server.git
Where
<your-github-user>
is the username of your GitHub login.
Checkout for testing only
- Clone the 5G-MAG repository
cd git clone -b development --recurse-submodules https://github.com/5G-MAG/rt-5gms-application-server.git
Creating the virtual Python environment
By using a Python virtual environment you can use upgraded versions of existing system Python modules and automatically install project module dependencies without having to install or upgrade modules system wide.
-
Create the virtual Python environment
cd ~/rt-5gms-application-server python3 -m venv venv
-
Update base modules and test script dependencies
cd ~/rt-5gms-application-server venv/bin/python3 -m pip install --upgrade pip build setuptools docopt PyYAML
Build and install the 5GMSd Application Server
cd ~/rt-5gms-application-server
venv/bin/python3 -m pip install .
Create a local-user friendly configuration
Save these configuration file contents as ~/rt-5gms-application-server/local-dev.conf
:
### Defaults for the 5G-MAG Reference Tools: 5GMSd applications
[DEFAULT]
log_dir = /tmp/rt-5gms-as/logs
run_dir = /tmp/rt-5gms-as
### 5GMSd Application Server specific configurations
[5gms_as]
log_level = debug
cache_dir = /tmp/rt-5gms-as/cache
certificates_cache = /tmp/rt-5gms-as/certificates
http_port = 8080
https_port = 8443
#m3_listen = localhost
#m3_port = 7777
#access_log = %(log_dir)s/application-server-access.log
#error_log = %(log_dir)s/application-server-error.log
#pid_path = %(run_dir)s/application-server.pid
### 5GMSd Application Server nginx specific configuration
[5gms_as.nginx]
root_temp = /tmp/rt-5gms-as
#client_body_temp = %(root_temp)s/client-body-tmp
#proxy_temp = %(root_temp)s/proxy-tmp
#fastcgi_temp = %(root_temp)s/fastcgi-tmp
#uwsgi_temp = %(root_temp)s/uwsgi-tmp
#scgi_temp = %(root_temp)s/scgi-tmp
#pid_path = %(root_temp)s/5gms-as-nginx.pid
Using this configuration will:
- Place all 5GMSd Application Server cache directories and other temporary files and logs under the
/tmp/rt-5gms-as
directory for testing. - Change the default ports used for the 5GMSd distribution service at reference point M4d. Note that this means that all URLs output by the 5GMSd Application Function with respect to M4d will need to be manually modified to insert the new port numbers before use, e.g. if the AF publishes a URL starting
http://your.hostname/...
you will need to change that tohttp://your.hostname:8080/...
in order to use the URL. This is necessary as the default ports of 80 and 443 are not available to normal unprivileged users. A normal user has to use ports with a number greater than 1024. - Turn on
debug
level output from the 5GMSd Application Server in order to better see what it happening. - Some settings above are commented out but may be useful while testing and so have been left in with their default values and prefixed with
#
to comment them out. If you wish to change one then remove the#
and change the value to your desired setting.
Running the installed 5GMSd Application server
To run the version of the 5GMSd Application Server installed in the virtual environment with the local-dev.conf
configuration (above), use:
cd ~/rt-5gms-application-server
PATH="/usr/local/openresty/nginx/sbin:$PATH" venv/bin/5gms-application-server -c local-dev.conf
Testing
Running the example without building
Make sure that git, java, wget and nginx are installed on the local system and can be found on the current command path ($PATH
).
sudo apt install git wget nginx default-jdk python3-regex
Generate the OpenAPI python modules (these are not part of the source distribution). Read documentation below on “Regenerating the 5G API bindings”:
cd ~/rt-5gms-application-server
build_scripts/generate_5gms_as_openapi
Create a configuration to run the application server as a local, unprivileged, user.
mkdir ~/.rt_5gms
cat > ~/.rt_5gms/application-server.conf <<EOF
[DEFAULT]
log_dir = /tmp/rt-5gms-as/logs
run_dir = /tmp/rt-5gms-as
### 5GMS Application Server specific configurations
[5gms_as]
log_level = info
cache_dir = /tmp/rt-5gms-as/cache
certificates_cache = /tmp/rt-5gms-as/certificates
http_port = 8080
https_port = 8443
m3_listen = localhost
m3_port = 7777
m4d_path_prefix = /m4d/provisioning-session-{provisioningSessionId}/
### 5GMS Application Server nginx specific configuration
[5gms_as.nginx]
root_temp = /tmp/rt-5gms-as
EOF
mkdir -p /tmp/rt-5gms-as/cache
mkdir /tmp/rt-5gms-as/logs
Run the example directly:
cd ~/rt-5gms-application-server/src
python3 -m rt_5gms_as.app
This will start nginx with a default configuration that will respond with a 404 to any request on http://localhost:8080/.
At this point the 5GMS Application Server is ready for configuration by an M3 client such as the 5GMS Application Function or the m3_client_cli.py
test script.
Testing with the Application Function
- Install both the 5GMS Application Server and Application Function.
- To install the 5GMS Application Server follow either the sdist, direct from source or in a virtual environment instructions from the Installing section of the main README.
- To install the 5GMS Application Function follow the directions to install the dependencies, retrieve, build and install the 5GMS Application Function from the 5GMS Application Function documentation.
- Configure the Application Function with the M3 port number of the Application Server (i.e. 7777) in the
msaf.applicationServers
section of themsaf.yaml
file.
- This is an example
applicationServers
entry from themsaf.yaml
configuration file with them3Port
set.msaf: ... applicationServers: - canonicalHostname: localhost urlPathPrefixFormat: /m4d/provisioning-session-{provisioningSessionId}/ m3Port: 7777 ...
- In one terminal window, start the Application Server.
- e.g. use the command
5gms-application-server
- In another terminal window, start the Application Function.
- e.g. use the command
~/rt-5gms-application-function/install/bin/open5gs-msafd
The Application Function should then configure the Application Server using the Server Certificates and Content Hosting Configuration it has been configured with. This should be evident from log messages from the Application Server and Application Function and from the /tmp/rt_5gms_as.conf NGINX configuration.
See the 5GMS Application Function documentation for more details on configuring it with Certificates and a Content Hosting Configuration.
Testing without the Application Function
To enable debugging and testing, a simple M3 client command can be found the the tests
subdirectory:
Usage:
m3_client_cli.py -h | --help
m3_client_cli.py -c | --certificate <connect>
m3_client_cli.py -c | --certificate <connect> (add|update) <certificate-id> <pem-file>
m3_client_cli.py -c | --certificate <connect> delete <certificate-id>
m3_client_cli.py -H | --content-hosting-configuration <connect>
m3_client_cli.py -H | --content-hosting-configuration <connect> (add|update) <provisioning-session-id> <content-hosting-configuration-json-file>
m3_client_cli.py -H | --content-hosting-configuration <connect> delete <provisioning-session-id>
m3_client_cli.py -H | --content-hosting-configuration <connect> purge <provisioning-session-id> [<pattern>]
Parameters:
connect Hostname:Port of the server providing M3.
provisioning-session-id Provisioning Session Identifier.
certificate-id Certificate Identifier.
pem-file Server PEM format X.509 public certificate, private key and intermediate CA certificates.
content-hosting-configuration-json-file
Filename of a ContentHostingConfiguration in JSON format.
pattern Regular expression to match the cache entry URL paths to delete.
Options:
-h --help Display the command help
-v --version Display command version
-c --certificate List known certificates or perform a certificate operation.
-H --content-hosting-configuration
List known ContentHostingConfigurations or perform an operation on ContentHostingConfigurations.
This can be used instead of the AF to configure a running AS.
Prerequisite packages
These testing scripts require a few more Python 3 modules to be installed, beyond what is brought in as requirements when the when the application server is installed.
The extra modules are: docopt
, aiofiles
and httpx[http2]
.
These can be installed on ubuntu using:
apt install python3-docopt python3-aiofiles python3-httpx python3-h2
…or on most distributions by using the python pip
module:
python3 -m pip install docopt aiofiles 'httpx[http2]'
Running the Application Server for testing with m3_client_cli.py
When running any of the following tests the Application Server must be running first. The exact command will depend on how you installed the Application Server or whether you are running directly without building.
Running from a virtual Python environment installation
If the AS you are testing has been installed in a virtual Python environment, as described in the Development and Testing wiki page, then you would simply run the AS from the virtual environment using your local configuration file. For example:
cd ~/rt-5gms-application-server
venv/bin/5gms-application-server -c local-dev.conf
Running a system wide AS installation
If the Application Server under test has been installed as a system process, using a command like sudo python3 -m pip install .
or sudo python3 -m pip install rt-5gms-application-server-1.X.X.tar.gz
, then you can run the AS as root. For example:
sudo 5gms-application-server
To configure a simple HTTP Application Server
Make sure the AS is running first (see “Running the Application Server for testing with m3_client_cli.py
” above).
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 add ps1 tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest.json
This should respond with a “Success!” message, and NGINX should now be running on port 8080 using the example Big Buck Bunny configuration. You can check the NGINX configuration in /tmp/rt_5gms_as.conf
.
To configure an HTTPS Application Server
Make sure the AS is running first (see “Running the Application Server for testing with m3_client_cli.py
” above).
This requires that the server certificate is pushed to the Application Server before the content hosting configuration is.
To generate server certificates, ensure that openssl
is installed (e.g. apt -y install openssl
), and then:
cd ~/rt-5gms-application-server
external/rt-common-shared/5gms/scripts/make_self_signed_certs.py tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest_https.json tests/examples/Certificates.json
The 5GMS Application Server stores the certificates it has been configured with in a certificates cache. This cache is reloaded when the Application Server starts up, so it will remember certificates from previous runs.
The 5GMS Application Server can be checked for what certificates it already has by using the command:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777
To push a new certificate (with id “testcert1” using the generated certificate file):
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777 add testcert1 tests/examples/certificate-1.pem
…or to update an existing certificate:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777 update testcert1 tests/examples/certificate-1.pem
Now the Content Hosting Configuration can be pushed:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 add ps1 tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest_https.json
This should result in “Success!” and NGINX will now be listening on “https://localhost:8443/…”.
To start both HTTPS and HTTP reverse proxies for the Big Buck Bunny content, substitute the ContentHostingConfiguration above for the tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest_http_and_https.json
file, or update the configuration using:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 update ps1 tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest_http_and_https.json
Note: Following these instructions will create a self-signed certificate for localhost in ~/rt-5gms-application-server/tests/examples/certificate-1.pem
, this certificate will not pass normal CA verification so to access the URL you need to turn off SSL validation or accept the self-signed certificate in your browser or media player application.
Runtime configuration
The 5GMSd Application Server is configured at run-time for distribution of media via the interface at reference point M3. This is usually done by the 5GMSd Application Function, but this project also contains a simple M3 client that can be used to push run-time configuration for testing.
M3 test client
This client script provides a simple command line interface to issue M3 API calls and see the result from the response.
The script can be run as:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -h|{<command> <hostaddr:port> [<command-parameters>...]}
If the default values for m3_listen
and m3_port
are used in the configuration file the <hostaddr:port>
will be localhost:7777
.
To see the command line help use:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -h
M3 Certificates API
List known certificates
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777
Add a new certificate
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777 add testcert1 tests/examples/certificate-1.pem
Update an existing certificate
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777 update testcert1 tests/examples/certificate-1.pem
Delete a certificate
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -c localhost:7777 delete testcert1
M3 ContentHostingConfiguration API
List known ContentHostingConfigurations
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777
Add a new ContentHostingConfiguration
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 add prov-sess-1 tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest_http_and_https.json
Update an existing ContentHostingConfiguration
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 update prov-sess-1 tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest_https.json
Delete a ContentHostingConfiguration
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 delete prov-sess-1
Purge all cached objects for a ContentHostingConfiguration
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 purge prov-sess-1
Purge cached objects using a path regex for a ContentHostingConfiguration
For example to purge all DASH manifests:
cd ~/rt-5gms-application-server
tests/m3_client_cli.py -H localhost:7777 purge prov-sess-1 '\.mpd$'
Regenerating the 5G API bindings
The build_scripts/generate_5gms_as_openapi
script will use wget, git and java to download the openapi-generator tool, the 5G OpenAPI YAML and generate the rt_5gms_as.openapi_5g
Python module package. The script will only do this if the src/rt_5gms_as/openapi_5g
directory does not already exist.
Therefore to regenerate the API bindings you first need to remove the old bindings:
cd ~/rt-5gms-application-server
rm -rf src/rt_5gms_as/openapi_5g
Then run the generator script:
~/rt-5gms-application-server/build_scripts/generate_5gms_as_openapi
For reference (or if it is desirable to recreate the steps manually) the generate_5gms_as_openapi
script performs the following actions:
- Uses
wget
to fetch version 6.0.1 of the openapi-generator-cli.- e.g.
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.0.1/openapi-generator-cli-6.0.1.jar -O openapi-generator-cli.jar
- e.g.
- Uses
git
to clone the 5G OpenAPI repository.- e.g.
git clone -b REL-17 https://forge.3gpp.org/rep/all/5G_APIs.git
- e.g.
- Copies in the API override files
- e.g.
cp -f ~/rt-5gms-application-server/external/rt-common-shared/5gms/5G_APIs-overrides/*.yaml ~/rt-5gms-application-server/build_scripts/M3_merged.yaml 5G_APIs/
- e.g.
- Uses the openapi-generator-cli, downloaded in the first step, to generate the API bindings.
- e.g.
mkdir 5g-api-python; java -jar openapi-generator-cli.jar generate -i 5G_APIs/TS26512_M1_ContentHostingProvisioning.yaml -g python --additional-properties packageName=rt_5gms_as.openapi_5g,projectName=openapi-5g -o 5g-api-python; java -jar openapi-generator-cli.jar generate -t ~/rt-5gms-application-server/build_scripts -i 5G_APIs/M3_merged.yaml -g python --additional-properties packageName=rt_5gms_as.openapi_5g,projectName=openapi-5g -o 5g-api-python
- e.g.
- Copies the API Python package to the
src/rt_5gms_as/openapi_5g
directory.