Giter Club home page Giter Club logo

rt-5gms-application-server's Introduction

5GMS Application Server

Under Development Version License

Introduction

The 5GMS Application Server (AS) is a Network Function that forms part of the 5G Media Services framework as defined in ETSI TS 126.501.

Additional information can be found at: https://5g-mag.github.io/Getting-Started/pages/5g-media-streaming/

5GMS Downlink Application Server

A 5GMS Downlink Application Server (5GMSd AS), which can be deployed in the 5G Core Network or in an External Data Network, provides 5G Downlink Media Streaming services to 5GMSd Clients. This logical function embodies the data plane aspects of the 5GMSd System that deals with proxying media content (similar to a Content Delivery Network). The content is ingested from 5GMSd Application Providers at reference point M2d. Both push- and pull-based ingest methods are supported, based on HTTP. Ingested content is distributed to 5GMSd clients at reference point M4d (after possible manipulation by the 5GMSd AS). Standard pull-based content retrieval protocols (e.g. DASH) are supported at this reference point.

About the implementation

This implementation is comprised of a small Python daemon process which implements the 5GMS AS configuration service at interface M3, and which also manages an external HTTP(S) Web Server/Proxy daemon subprocess to ingest content (pull ingest only) at interface M2d and serve it to 5GMSd Clients at interface M4d.

The 5GMSd AS is configured via the M3 interface, therefore you will need an appropriate M3 client to configure the 5GMSd AS. Such a client is the 5GMS AF (release v1.1.0 and above).

The web server or reverse proxy functionality is provided by an external daemon. This 5GMSd AS manages the external daemon by dynamically writing its configuration files and managing the daemon process lifecycle. At present the only daemon that can be controlled by the AS is Openresty (based on nginx) (website).

Install dependencies

sudo apt install git python3-pip python3-venv
sudo python3 -m pip install --upgrade pip build setuptools

Downloading

Release sdist tar files can be downloaded from the releases page.

The source can be obtained by cloning the github repository.

cd ~
git clone --recurse-submodules https://github.com/5G-MAG/rt-5gms-application-server.git

Building a Python distribution

Prerequisites for building

You will additionally need wget and java to build a distribution.

sudo apt install wget default-jdk

Building a distribution tar

To build a Python sdist distribution tar do the following.

cd ~/rt-5gms-application-server
python3 -m build --sdist

The distribution sdist tar file can then be found in the dist subdirectory.

Installing

Install from sdist

This application can be installed using pip with a distribution sdist tar file:

sudo python3 -m pip install rt-5gms-application-server-<version>.tar.gz

If installing as a unprivileged user, the installed files will be added to a local installation place in your home directory. A warning is shown indicating that the directory where the application is installed should be added to your path with a command like PATH="${PATH}:${HOME}/.local/bin" export PATH.

Install direct from source

Alternatively, to install the 5GMS Application Server directly from the source you will first need the build prerequisites, wget and java, indicated above in the Prerequisites for building section. After installing these the application can bi install directly using these commands:

cd ~/rt-5gms-application-server
sudo python3 -m pip install .

Installing in a virtual Python environment

If you are testing out this project then you may wish to install in a Python virtual environment instead so that you do not disturb you present system packages.

You will need the wget and java prerequisites, see the Prerequisites for building section above for details.

After installing the prerequisites, you can install the 5GMS Application Server using the commands:

cd ~/rt-5gms-application-server
python3 -m venv venv
venv/bin/python3 -m pip install .

When using the virtual environment approach, then you can run the application directly using venv/bin/5gms-application-server instead of just 5gms-application-server in the following instructions, or you can activate the virtual environment using source venv/bin/activate to automatically add the venv/bin directory early in the executable search path and just use the 5gms-application-server command.

Running

Once installed, the application server can be run using the following command syntax:

Syntax: 5gms-application-server [-c <configuration-file>]

Please note that the application server requires a suitable web proxy server to be installed. At present the only web proxy server that the application server can use is Openresty. This means you should install the openresty package on your distribution, instruction to do so can be found on the Openresty website for linux distributions and Microsoft Windows. The Openresty version of nginx should also be the first version on the system path.

PATH="/usr/local/openresty/nginx/sbin:$PATH" export PATH

Most distributions will install the Nginx service to start on boot and some will even immediately start the Nginx service daemon when nginx/openresty is installed. A running default configuration of nginx will interfere with the operation of the application server by claiming TCP port 80 to listen on, thus denying the use of the TCP port to the application server. To avoid this it is best to disable and stop the nginx and openresty services, for example:

systemctl disable --now nginx.service openresty.service

(If either of these services are not present then an error will be displayed, which is safe to ignore)

Command line help can be obtained using the -h flag:

5gms-application-server -h

Please note that the default configuration will require the application server to be run as the root user as it uses the privileged port 80 and stores logs and caches in root owned directories. If you wish to run this as an unprivileged user you will need to follow the instructions for creating and using an alternative configuration file. These instructions can be found in the development documentation.

Once running you will need an M3 client, such as the 5GMS AF, to manage the running AS. For standalone configuration for testing, see the "Testing without the Application Function" section of the development documentation.

Development

This project follows the Gitflow workflow. The development branch of this project serves as an integration branch for new features. Consequently, please make sure to switch to the development branch before starting the implementation of a new feature. Please check this page file for further project development and testing information.

rt-5gms-application-server's People

Contributors

jordijoangimenez avatar rjb1000 avatar davidjwbbc avatar dsilhavy avatar

Stargazers

 avatar DivK avatar Christopher Adigun avatar  avatar

Watchers

 avatar  avatar Thomas Stockhammer avatar Imed Bouazizi avatar  avatar  avatar  avatar  avatar Vuk Stojkovic avatar

rt-5gms-application-server's Issues

Add source file metadata

The source file metadata (authors, licence, copyright, etc.) is missing from the Python source files. This metadata needs adding to each .py file.

Development branch: Missing Nginx mime.types after clean installation

Description

I am doing a clean installation of the Application Server on a freshy installed Ubuntu 22 machine using the current development branch. Latest commit: 4ebaa7b

I ran into an issue with missing nginx mime.types when starting the Application Server with sudo 5gms-application-server

The following error occured:

ERROR:NginxWebProxy:nginx: [emerg] open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /tmp/rt_5gms_as.conf:53

INFO:rt-5gms-as:Web proxy process exited, has been restarted

I did not have a previous version of nginx installed and only installed openresty (which includes nginx).

Solution

The solution is to include the mime.types located in the nginx installation of openresty. For that reason we need to adjust nginx.conf.tmpl prior to the installation of the Application Server:

include             /usr/local/openresty/nginx/conf/mime.types;

Application Server crash on certificate upload

When POSTing the certificate via M3, the Application Server seems to create / add the certificate successfully as it tries to send response with status 201. But it crashes when sending the response, with the following message. Same error happens when trying to update the certificate through the PUT method.

venv/bin/5gms-application-server -c local.conf
INFO:rt-5gms-as:Getting list of certificates...
INFO:rt-5gms-as:Getting list of content hosting configurations...
DEBUG:rt-5gms-as:Context.haveCertificate('d54a1fcc-d411-4e32-807b-2c60dbaeaf5f:testcert1') = False
INFO:rt-5gms-as:Adding certificate d54a1fcc-d411-4e32-807b-2c60dbaeaf5f:testcert1...
[2022-11-14 18:06:15 +0000] [348937] [ERROR] Error in ASGI Framework
Traceback (most recent call last):
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/asyncio/task_group.py", line 23, in _handle
    await app(scope, receive, send, sync_spawn, call_soon)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/app_wrappers.py", line 33, in __call__
    await self.app(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/applications.py", line 270, in __call__
    await super().__call__(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
    raise exc
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
    await self.app(scope, receive, sender)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 680, in __call__
    await route.handle(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 275, in handle
    await self.app(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 65, in app
    response = await func(request)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 231, in app
    raw_response = await run_endpoint_function(
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 160, in run_endpoint_function
    return await dependant.call(**values)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/openapi_5g/apis/default_api.py", line 75, in create_server_certificate
    await rt_5gms_as_svr_ifc.create_server_certificate(provisioningSessionId,certificateId,body, request=request)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/server.py", line 90, in create_server_certificate
    raise NoProblemException(status_code=201, media_type='application/json', headers={'Location': request.url.path})
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/exceptions.py", line 71, in __init__
    headers['Server'] = '5GMSd-AS/'+__pkg_version
NameError: name '_NoProblemException__pkg_version' is not defined
ERROR:hypercorn.error:Error in ASGI Framework
Traceback (most recent call last):
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/asyncio/task_group.py", line 23, in _handle
    await app(scope, receive, send, sync_spawn, call_soon)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/app_wrappers.py", line 33, in __call__
    await self.app(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/applications.py", line 270, in __call__
    await super().__call__(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
    raise exc
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
    await self.app(scope, receive, sender)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 680, in __call__
    await route.handle(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 275, in handle
    await self.app(scope, receive, send)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 65, in app
    response = await func(request)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 231, in app
    raw_response = await run_endpoint_function(
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 160, in run_endpoint_function
    return await dependant.call(**values)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/openapi_5g/apis/default_api.py", line 75, in create_server_certificate
    await rt_5gms_as_svr_ifc.create_server_certificate(provisioningSessionId,certificateId,body, request=request)
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/server.py", line 90, in create_server_certificate
    raise NoProblemException(status_code=201, media_type='application/json', headers={'Location': request.url.path})
  File "/home/ubuntu/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/exceptions.py", line 71, in __init__
    headers['Server'] = '5GMSd-AS/'+__pkg_version
NameError: name '_NoProblemException__pkg_version' is not defined

Documentation updates after review on 23 Jan 2023

After testing the latest development branch, @jordijoangimenez, has suggested a couple of improvements to the documentation:

  1. Recommend the need to do python3 -m pip install --upgrade pip build setuptools before python3 -m pip install .
  2. mention the need to update $PATH after having installed 5gms-application-server (as an unprivileged user).
  3. Make it clearer in docs/README.md how to "Install both the 5GMS Application Server and Application Function".
  4. Add example command lines for "Start the Application Server" and "Start the Application Function".

Redirection fails with recent OpenResty version

Description

When the AS learns about a redirection from the media origin it generates a redirection path element to identify redirected object requests. However in recent versions of OpenResty, when the redirection path is requested, with the same path suffix as the non-redirected request, no response or a 404 response is returned.

After investigation, this appears to be an issue which is a combination of the way the cache is managed and the redirection rewriting. The redirection mapping takes the provisioning session path prefix, the original media origin url and the request URL path after the provisioning session part (e.g. "/m4d/provisioning-session-1/", "http://media.exmaple.com/", "/redir-2/manifest.mpd") it then uses the provisioning session prefix and the URL path to find a redirection lookup in its internal table. If the redirection is found then the redirection URL is returned along with the URL path suffix that is needed to obtain the requested object. If the mapping is not found then the original origin media URL is returned along with the URL path. This means that you get returned two strings that when concatenated form the full request URL for the object from the original media origin or a redirected origin (e.g. "https://media2.example.com/","/manifest.mpd").

The URL rewrite operator then passes the full object URL (by concatenating the return values) to the proxy_pass operator and sets the request URI path to the URL path returned.

The cache key is made up of the provisioning session id a ":u=" and the URL path of the request.

Previously this didn't matter as the cache key was generated before the rewrite rules (using the URL path with the redirection identfier in it), but it seems that later versions of OpenResty now create the key later meaning that the original pre-redirection request and the redirected version now equate to the same cache key, meaning that the OpenResty nginx thinks it has a cached result for the redirected object which is the original redirection. The upshot being that nginx either crashes out during the attempt to rehandle the recursive redirection or thinks that the URL path must refer to a local file which it can't find.

Remedy

The fix is simple, just include the redirection identfier (if present) in URL path part of the cache key and nginx is happy again.

5gms-application-server reports `Path parameters cannot have a default value`

Describe the bug
I compiled the 5gms-application-server on release rt-5gms-application-server-1.1.0 following the guild on Arch Linux. Every went fine until running 5gms-application-server. It reports Path parameters cannot have a default value. Any idea about this?

To Reproduce
Steps to reproduce the behavior:

  1. 5gms-application-server -h

Expected behavior
Print out the help info.

Screenshots
Screenshot 2023-04-14 at 13 53 47

Desktop (please complete the following information):

  • OS: Arch Linux
  • Version: 6.2.10-arch1-1

Smartphone (please complete the following information):
Not applicable.

Additional context
None.

CI/CD - Automated deployment of 5GMS AS to Linode instance

Feature description

5G-MAG provides a Linode instance to host the Application Server (AS). This enables 5GMS Client components to talk against the provided interface M4 without setting up the AS on a dedicated machine.

The deployment of the latest version of the AS should be integrated into a CI/CD workflow. That way it is always available on the Linode instance without requiring a manual update and installation.

As a first step, the build process for the AS should be performed in the Github cluster for each new pull request and once code is added to the development branch.

Uplift to TS 26.512 v17.4.0: Update M3 interface with new ContentHostingConfiguration structure

Context

3GPP SA4 has agreed CR0032r1 [S4-230267] to update TS 26.512 Rel-17. This will hopefully be approved at SA#99 Plenary as part of the CR Pack SP-230253.

One part of these changes is the introduction of multiple entry point paths, up to one per distributionConfiguration, instead of just a single entryPointPath in the ContentHostingConfiguration. This is a compatibility breaking change in the specification which affects the interface at reference point M1.

The new OpenAPI YAML for TS26512_M1_ContentHostingProvisioning.yaml removes entryPointPath at the top level on the ContentHostingConfiguration object and introduces a new optional distributionConfigurations[].entryPoint object. This new entryPoint object has 3 properties:

  • relativePath - This is a mandatory property which is the per distributionConfiguration equivalent to the old entryPointPath from the top level.
  • contentType - This describes the MIME type for the relativePath and is also mandatory.
  • profiles - An optional array of media profile URIs which describe the media profiles used by this entry point.

The interface at reference point M3 refers to the ContentHostingConfiguration object structure from TS26512_M1_ContentHostingProvisioning.yaml and will therefore be updated by these changes.

Changes to the Application Server

Although the ContentHostingConfiguration structure is changing, the parts that are changing do not directly affect the Application Server. Therefore this ticket is more about checking that the 5GMS Application Server and M3 test client still work with the new structures. It is not expected that there will be any code changes necessary.

Related issues

This requires 5G-MAG/rt-common-shared#22 and 5G-MAG/rt-5gms-application-function#51 to be implemented first.

Implement M3 test client

Feature description

Using OpenAPI YAML interface definition files, implement an M3 test client for the M3 server developed in #30.

  • Provision and manage Server Certificate resources available to the test client as local X.509 PEM files.
    • Create, Retrieve, Update, Destroy.
  • Provision and manage Content Hosting Configuration resources available to the test client as local JSON files.
    • Create, Retrieve, Update, Destroy.
    • Purge the associated content cache.

Relevant specifications and corresponding sections

TS 26.512 plus pre-standardisation M3 Open API YAML interface definition files.

Additional context

This test client effectively replaces the need for the 5GMS AS to load its Content Hosting Configuration from a local file.

The test client allows multiple Content Hosting Configurations to be provisioned and managed.

It may be advantageous to develop the M3 test client in C so that some of the code can be reused as part of the M3 client in the 5GMSd AF - see 5G-MAG/rt-5gms-application-function#7.

Implement M3 server

Feature description

Using OpenAPI YAML interface definition files, implement an M3 server for the Python-based Application Server

  • Provision and manage the life-cycle of Server Certificate resources.
    • Create, Retrieve, Update, Destroy.
  • Provision and manage the life-cycle of Content Hosting Configuration resources.
    • Create, Retrieve, Update, Destroy.
    • Purge the associated content cache.

Cache purge

For the purposes of the reference implementation using Nginx (which only supports purging individual cache objects, all cache objects under a URL prefix, or all cache objects) only the following very limited subset of regular expressions is supported:

  • Most regular expression reserved characters not allowed.
    • Only terminal .* allowed, '.' or '*' is not allowed anywhere else in the regular expression unless escaped with \.
    • Regular expression not allowed to start with ^ (start of string anchor).
    • \ may be used to escape characters that would normally be interpreted as regular expression operators.
  • Regular expression must be a relative path, not an absolute path.
    • Regular expression is evaluated relative to the AF-defined base URL path.

In case the regular expression does not meet the constrained specification above, a suitable error message (e.g. 400 Bad Request) should be returned at M3 along with a human-readable error message, e.g. "Regular expression not supported by this implementation". (This error will, in future, be propagated by the 5GMS AF to the M1 client.)

Relevant specifications and corresponding sections

TS 26.512 plus pre-standardisation M3 Open API YAML interface definition files.

Additional context

This will allow the 5GMSd AS to be managed by a 5GMSd AF (see 5G-MAG/rt-5gms-application-function#7) or by a test client (see #31). As a consequence, the ability to read a Content Hosting Configuration from a local file should be removed from the 5GMSd AS as part of the scope.

It will be possible for multiple Content Hosting Configurations to be simultaneously provisioned in the 5GMSd AS.

Media ingest at reference point M2d

Feature description

The M2d interface supports the ingest of the following types of content:

  • Live streaming content.
  • On-demand streaming content.
  • Static files such as images, scene descriptions, etc.

Relevant specifications and corresponding sections

26.501 - 5G Media Streaming (5GMS); General description and architecture (Release 17)
26.512 - 5G Media Streaming (5GMS); Protocols (Release 17)

Additional context

For MVP#1, only pull-based content ingest is required.

Enhancement: Return number of cache entries purged in M3 response

Content

We wish to inform the Application Function about the number of cache entries that were purged during a purge request.

Enhancement specification

The AS shall respond with:

  • 204 (No Content) if the request was valid but no cache entries were purged (none matched the request),
  • 200 (OK) response if one or more entries were purged, with the body being an integer number of cache entries purged.

Relevant specifications and corresponding sections

5G-MAG/rt-common-shared#17

asyncio.create_task(..., name=...) doesn't work with Python 3.7

Description

The code is supposed to be compatible with Python 3.7 and above, however the name parameter was only introduced to the asyncio.create_task() function in Python 3.8 and this name parameter is used in the code to make debugging easier.

To Reproduce

Steps to reproduce the behavior:

  1. Run the 5gms-application-server with Python 3.7
  2. Exception shows extra "name" parameter is not understood.

Expected behavior

There should not be an exception when using Python 3.7.

Possible fixes

  1. Change the minimum Python version to 3.8.
    • This would ensure that the minimum requirements are met for the name parameter, but may not be compatible with older OS distributions that don't have a more recent Python 3 version.
  2. Remove the name parameter
    • makes task debugging a little harder due to the use of automatically generated task names.
    • Will make the code work with Python 3.7.
  3. Detect the python version and only pass the name parameter if the version is 3.8 or above.
    • Adds a little more complexity to the code, best achieved by wrapping the asyncio.create_task() in a wrapper function and have different wrapper functions for python 3.7 and python 3.8+ which are chosen at start-up of the program.
  4. Find a backward compatible way to achieve the same effect as using the name parameter.
    • Same code works on Python 3.7 upwards.
    • Code may be more complex, having extra steps when tasks are created in order to set the task name.

Failure to start nginx server

Description of the bug
The nginx server fails to start due to a missing import and self reference in the nginx proxy handling class.

To Reproduce
Steps to reproduce the behavior:

  1. Run the example from the docs directory
  2. See error

Expected behavior
Server should start up.

System setup where issue was found:

  • OS: CentOS 8

MVP#1 Application Server installation issues/observations

This ticket is meant to collect issues and observations that occurred during the installation of the Application Server

Installation on MacOS Monterey Version 12.5.1

Missing module

Following the installation guide I ran into the following error when running 5gms-application-server -h:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/bin/5gms-application-server", line 5, in <module>
    from rt_5gms_as.app import main
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/rt_5gms_as/app.py", line 32, in <module>
    from .context import Context
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/rt_5gms_as/context.py", line 34, in <module>
    from .openapi_5g.model.content_hosting_configuration import ContentHostingConfiguration
ModuleNotFoundError: No module named 'rt_5gms_as.openapi_5g'

Installation on Linux Ubuntu 20.04

Missing folders

Strictly following the installation guide I ran into a problem of missing folders. The following commands are required to create the folders:

mkdir /var/cache/rt-5gms
mkdir /var/log/rt-5gms
mkdir /run/rt-5gms

Nginx port bindings

Binding to port 80 is only possible with root privileges. Running 5gms-application-server external/rt-common-shared/5gms/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest.json lead to a nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied) error.

This can be solved by following the instructions in the development documentation and creating an adjusted configuration using other ports:

[DEFAULT]
log_dir = /tmp/rt-5gms-as/logs
run_dir = /tmp/rt-5gms-as

### 5GMS Application Server specific configurations
[5gms_as]
cache_dir = /tmp/rt-5gms-as/cache
http_port = 8080
https_port = 8443

### 5GMS Application Server nginx specific configuration
[5gms_as.nginx]
root_temp = /tmp/rt-5gms-as

The new config can be provided via 5gms-application-server -c custom-application-server.conf external/rt-common-shared/5gms/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest.json

Afterwards the sample MPD is available at http://localhost:8080/m4d/provisioning-session-d54a1fcc-d411-4e32-807b-2c60dbaeaf5f/BigBuckBunny_4s_onDemand_2014_05_09.mpd

MVP#2 Application Server installation/running issues/observations

I'm testing AF (development brach) and AS (1.0.1-rc). I've deleted all repos and re-started from scratch. The AF is up and running. When trying to run the AS after having installed it I got:

fivegmag@NUC1:~/rt-5gms-application-server$ 5gms-application-server 
Traceback (most recent call last):
  File "/home/fivegmag/.local/bin/5gms-application-server", line 8, in <module>
    sys.exit(main())
  File "/home/fivegmag/.local/lib/python3.10/site-packages/rt_5gms_as/app.py", line 257, in main
    context = Context(config)
  File "/home/fivegmag/.local/lib/python3.10/site-packages/rt_5gms_as/context.py", line 87, in __init__
    self.__loadConfiguration(force=True)
  File "/home/fivegmag/.local/lib/python3.10/site-packages/rt_5gms_as/context.py", line 374, in __loadConfiguration
    os.makedirs(directory)
  File "/usr/lib/python3.10/os.py", line 225, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '/run/rt-5gms'

Not sure if my issue is now even more fundamental as the AS fails to run entirely before launching the AF. I launch the AS as 5gms-application-server (ie without a -c configfile). What is the AS doing when no config file is specified? For MVP#2 I understand it should wait for receiving info from the AF?

Updating PATH for launching Openresty

Describe the bug
When running the Application Server following the instructions it looks like the export PATH is not taking effect and running the AS produces the error of the "lua_package_path" missing.

Talking to @aaronmontilla, he experienced the same issue, just reported here:

aamonvi@aamonvi:~/rt-5gms-application-server$ sudo 5gms-application-server
[2024-05-22 13:26:53 +0200] [3977] [INFO] Running on http://127.0.0.1:7777/ (CTRL + C to quit)
INFO:hypercorn.error:Running on http://127.0.0.1:7777/ (CTRL + C to quit)
INFO:NginxWebProxy:
ERROR:NginxWebProxy:nginx: [emerg] unknown directive "lua_package_path" in /tmp/rt_5gms_as.conf:48
INFO:rt-5gms-as:Web proxy process exited, has been restarted

Remedy
We are able to solve this by executing the following:
sudo PATH="/usr/local/openresty/nginx/sbin:$PATH" 5gms-application-server (probably also works without sudo).

Not sure if we are doing something wrong that makes executing PATH="/usr/local/openresty/nginx/sbin:$PATH" export PATH have no effect.

ContentHostingConfiguration file for static DASH assets

Feature description

For a static DASH asset define a JSON configuration file according to TS26.512 Clause C3.5. Such json files should be processable by the config translator as defined in issue #13

Relevant specifications and corresponding sections

26.501 - 5G Media Streaming (5GMS); General description and architecture (Release 17)
26.512 - 5G Media Streaming (5GMS); Protocols (Release 17)

GanttLab

GanttStart: 2022-09-19
GanttDue: 2022-10-04

URL signing at M4d

Feature description
The URL signing procedure allows the 5GMSd Application Provider to prevent deep linking and unauthorized access to M4d media resources. It works by cryptographically signing some elements of the M4d request URL and then appending this authentication token to the URL as an additional query parameters.

Relevant specifications and corresponding sections
26.501 - 5G Media Streaming (5GMS); General description and architecture (Release 17)
26.512 - 5G Media Streaming (5GMS); Protocols (Release 17)

Update in line with ServiceAccessInformation example in 5G-MAG/rt-common-shared

Feature description

Issue 5G-MAG/rt-common-shared#5 adds a ServiceAccessInformation example with a UUID for the Provisioning Session ID. Bring
the default configuration and documentation into line with this example.

As part of this, move the provisioning_session_id from a hard coded value in the source to a configurable value in the application configuration and set it to the same value as in the example ServiceAccessInformation. This information is used in hosting URL path prefix.

Relevant issues, specifications and corresponding sections

Issue arises from 5G-MAG/rt-common-shared#5

Geofencing

Feature description
Geographic restrictions on content access by the Media Player at reference point M4d. The 5GMSd Application Provider may wish to limit access to its media content at interface M2d to UEs located in certain geographical zones. Geofencing is used to configure the zone from which content is accessible.

Relevant specifications and corresponding sections
26.501 - 5G Media Streaming (5GMS); General description and architecture (Release 17)
26.512 - 5G Media Streaming (5GMS); Protocols (Release 17)

Add instructions for generating the 5G API python modules

Feature description
The instructions to generate the 5G API modules from the OpenAPI YAML files is not present. These need adding to the developer docs.

Additional context
This is documenting what was done to generate the initial rt_5gms_as/openapi_5g modules. We may decide in future to automate this process as part of the build.

5GMS Application Server: Core Development Plan & Questions

This issue is supposed to be used to discuss and answer the following questions

  • Which programming language do we want to use to implement the AS
  • What would be the MVP?
  • Which web server should we use?
    • Apache
    • Nginx
    • Varnish
    • node.js express

GanttLab

GanttStart: 2022-08-31
GanttDue: 2022-09-19

change in pydantic v2

:~/b/rt-5gms-application-server$ sudo -E PATH="/usr/local/openresty/nginx/sbin:$PATH" venv/bin/5gms-application-server -c local-dev.conf
[2023-12-13 16:33:26 +0530] [88543] [INFO] Running on http://192.168.47.63:7777 (CTRL + C to quit)
INFO:hypercorn.error:Running on http://192.168.47.63:7777 (CTRL + C to quit)
INFO:rt-5gms-as:Adding content hosting configuration ps1...
DEBUG:rt-5gms-as:provisioning_session_id = ps1, chc = ContentHostingConfiguration(name='Big Buck Bunny', ingest_configuration=IngestConfiguration(pull=True, protocol='urn:3gpp:5gms:content-protocol:http-pull-ingest', base_url=Url('https://ftp.itec.aau.at/datasets/DASHDataset2014/BigBuckBunny/4sec/')), distribution_configurations=[DistributionConfiguration(entry_point=None, content_preparation_template_id=None, canonical_domain_name='localhost', domain_name_alias=None, base_url=Url('http://localhost/m4d/provisioning-session-d54a1fcc-d411-4e32-807b-2c60dbaeaf5f/'), path_rewrite_rules=None, caching_configurations=None, geo_fencing=None, url_signature=None, certificate_id=None, supplementary_distribution_networks=None)])
[2023-12-13 16:33:33 +0530] [88543] [INFO] 192.168.13.27:58036 - - [13/Dec/2023:16:33:33 +0530] "POST /3gpp-m3/v1/content-hosting-configurations/ps1 1.1" 500 3383 "-" "5GMSdAF-nexus.naveen.local/testing"
[2023-12-13 16:33:33 +0530] [88543] [INFO] 192.168.13.27:58036 - - [13/Dec/2023:16:33:33 +0530] "POST /3gpp-m3/v1/content-hosting-configurations/ps1 1.1" - - "-" "5GMSdAF-nexus.naveen.local/testing"
[2023-12-13 16:33:33 +0530] [88543] [ERROR] Error in ASGI Framework
Traceback (most recent call last):
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/asyncio/task_group.py", line 27, in _handle
await app(scope, receive, send, sync_spawn, call_soon)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/app_wrappers.py", line 33, in call
await self.app(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/applications.py", line 1106, in call
await super().call(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/applications.py", line 122, in call
await self.middleware_stack(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in call
raise exc
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in call
await self.app(scope, receive, _send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 79, in call
raise exc
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 68, in call
await self.app(scope, receive, sender)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in call
raise e
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in call
await self.app(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 718, in call
await route.handle(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 66, in app
response = await func(request)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 274, in app
raw_response = await run_endpoint_function(
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
return await dependant.call(**values)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/openapi_5g/apis/default_api.py", line 53, in create_content_hosting_configuration
await rt_5gms_as_svr_ifc.create_content_hosting_configuration(provisioningSessionId,content_hosting_configuration, request=request)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/server.py", line 66, in create_content_hosting_configuration
self.__context.addContentHostingConfiguration(provisioningSessionId, content_hosting_configuration)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/context.py", line 202, in addContentHostingConfiguration
self.__addContentHostingConfiguration(provisioning_session_id, content_hosting_configuration, force=True)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/context.py", line 351, in __addContentHostingConfiguration
chc_hash = self.__hashOpenAPIObject(chc)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/context.py", line 512, in __hashOpenAPIObject
return hash(obj.json(sort_keys=True))
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/typing_extensions.py", line 2499, in wrapper
return arg(*args, **kwargs)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/pydantic/main.py", line 1011, in json
raise TypeError('dumps_kwargs keyword arguments are no longer supported.')
TypeError: dumps_kwargs keyword arguments are no longer supported.
ERROR:hypercorn.error:Error in ASGI Framework
Traceback (most recent call last):
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/asyncio/task_group.py", line 27, in _handle
await app(scope, receive, send, sync_spawn, call_soon)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/hypercorn/app_wrappers.py", line 33, in call
await self.app(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/applications.py", line 1106, in call
await super().call(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/applications.py", line 122, in call
await self.middleware_stack(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in call
raise exc
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in call
await self.app(scope, receive, _send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 79, in call
raise exc
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 68, in call
await self.app(scope, receive, sender)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in call
raise e
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in call
await self.app(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 718, in call
await route.handle(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/starlette/routing.py", line 66, in app
response = await func(request)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 274, in app
raw_response = await run_endpoint_function(
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/fastapi/routing.py", line 191, in run_endpoint_function
return await dependant.call(**values)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/openapi_5g/apis/default_api.py", line 53, in create_content_hosting_configuration
await rt_5gms_as_svr_ifc.create_content_hosting_configuration(provisioningSessionId,content_hosting_configuration, request=request)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/server.py", line 66, in create_content_hosting_configuration
self.__context.addContentHostingConfiguration(provisioningSessionId, content_hosting_configuration)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/context.py", line 202, in addContentHostingConfiguration
self.__addContentHostingConfiguration(provisioning_session_id, content_hosting_configuration, force=True)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/context.py", line 351, in __addContentHostingConfiguration
chc_hash = self.__hashOpenAPIObject(chc)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/rt_5gms_as/context.py", line 512, in __hashOpenAPIObject
return hash(obj.json(sort_keys=True))
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/typing_extensions.py", line 2499, in wrapper
return arg(*args, **kwargs)
File "/home/naveen/b/rt-5gms-application-server/venv/lib/python3.8/site-packages/pydantic/main.py", line 1011, in json
raise TypeError('dumps_kwargs keyword arguments are no longer supported.')
TypeError: dumps_kwargs keyword arguments are no longer supported.

@m3682029:/b/rt-5gms-application-server$ tests/m3_client_cli.py -H 192.168.47.63:7777 add ps1 tests/examples/ContentHostingConfiguration_Big-Buck-Bunny_pull-ingest.json
There was a problem with the server: [500] Internal Server Error@m3682029:
/b/rt-5gms-application-server$

Desktop (please complete the following information):

  • OS:ubuntu 20.04

Upstream redirects are passed to client

Description

When the AS receives an HTTP redirect from an upstream origin server it is incorrectly passed on to the UE rather than being processed by the AS. If this happens on the manifest, this effectively diverts the UE away from the AS for playback of the media. This means that control over network slicing and network policies may be bypassed (UE registers policy against the AS connection at the start of the session).

Reproducing

Steps to reproduce the behavior:

  1. Configure the AF with an upstream ingest server that sends redirects on manifest request.
  2. Check the result of requesting a manifest via the interface at M4d, it will contain a 3XX response redirecting the client away from the AS.

Expected behaviour

Media streaming session at M4d remains served via the AS.

Suggested behaviour

The AS should intercept the redirects and set up a path through the same provisioning session prefix path for M4d. The AS can then issue the redirect to the entity in the new M4d path.

Additional context

Observed on the BBC 5G testbed when using a ingest CDN that redirects requests.

ContentHostingConfiguration JSON to Python data structure parser

Feature description
This is a the generic component of #14 which reads a ContentHostingConfiguration JSON structure and parses into an internal Python data structure. The parser should perform validation against fields present in the JSON and reject any JSON which doesn't conform to the 5G Release 17 YAML description in TS26512_M1_ContentHostingProvisioning.yaml (part of TS 26.512).

This internal structure can then be passed to the configuration writer component, from #13, in order to create the web server configuration to be used in the AS.

Relevant specifications and corresponding sections
TS 26.512 - Clause C.3.5

Framework for content preparation

Feature description
For downlink media streaming, the 5GMSd AS may be required to process content ingested at interface M2d before serving it on interface M4d. Examples for content processing are repackaging, encryption, ABR transcoding.

Relevant specifications and corresponding sections
26.501 - 5G Media Streaming (5GMS); General description and architecture (Release 17)
26.512 - 5G Media Streaming (5GMS); Protocols (Release 17)

Additional context
to be filled by you

Python-based Application Server

Feature description

We are going to start with a simple Python application as the 5GMS Application Server (AS).

This application will take a static JSON configuration, use it to create the necessary configuration files to control an external web server/proxy and then control the lifecycle of the external web server/proxy. This represents the minimum necessary to provide a 5GMS AS capable of pull-ingest as required by MVP#1 and MVP#2.

The configuration file will be a ContentHostingConfiguration object, as defined in TS 26.512 C.3.5 and described in Section 7.6, written in JSON with content as though the 5GMS application function had output it from a Read Content Hosting Configuration request (TS 26.512 Section 4.3.3.3).

The AS will find a locally installed web server from its list of known web servers. Initially the only known web server will be nginx, but the Python application shall be easily extended to allow other external web server and proxy applications to be used.

Once a suitable web server is identified the AS will write out a configuration for that web server which will provide the M2d interface and start the web server as a child process. It will then wait for the web server to exit (or be killed) before it reports errors and web server outputs and exits itself.

Relevant specifications and corresponding sections

  • TS 26.512 clauses 4.3.3, 7.6, 8.2, B.1, C.3.5.

Additional context

This is only an initial, simple application which is intended to be developed and expanded to add more features of a full 5GMS Application Server.

Feature: Media Streaming Data Reporting at reference point R4

Feature Description

As part of the data collection and exposure framework in 5GMS, the Application Server can report media stream access to the Data Collection AF subfunction of the 5GMS Application Function. This then allows the easy dissemination of media access logs from the Data Collection AF to interested parties as part of the 5G Media Streaming framework.

This work includes:

  • Transfer of Data Collection AF URL via M3 from the 5GMS AF.
  • Registration as a Data Collection Client with the DCAF via R4:
    • If configuration return from DCAF registration contains Media Streaming Access configuration:
      • Access data is collected and reports are sent, via R4, according to the configuration received.

Relevant Specifications

3GPP TS 26.512 (v17.4.0)

  • Clause 4.11 Data collection and reporting procedures at reference point R4.
  • Clause 17 Media Streaming data reporting at R4.
  • Clause C.5.

3GPP TS 26.532 (v17.0.1)

  • Clause 7 Ndcaf_DataReporting service.
  • Clause B.4.

Additional Information

At present there is no effort to implement this in the 5G-MAG Reference Tools; this issue is here as a placeholder for the future implementation of this feature.

Implement Server Health Check endpoint

Feature description
It requires a health check endpoint for the Server so that it can be monitored for service availability. That also helps the client to invoke that simple health check endpoint (which doesn't require any payload) to verify the service is available to consume or not before it hits the main endpoints with the payload. It will also help during testing and as well as post deployment verification of the Server.

Relevant specifications and corresponding sections
General Service Health check implementation.

Additional context
It is discovered that there is no health check endpoint implemented currently in server.py due to which it is not helping to verify if the server has been deployed and running as expected during testing. Hence raised this issue as a backlog to implement.

Incorrect error response status code for M1_ContentHostingProvisioning_purgeContentHostingCache operation

Description

If the purge regex pattern is invalid, the Application Server raises an exception and produces a local error log. However, the Application Server returns a response with status code 200 (OK) to the invoking client.

I think the response should have status code 422 (Unprocessable Entity) indicating that there is something wrong with the request message body.

Additional context

This bug arises from 5G-MAG/rt-5gms-application-function#18.

Use OpenAPI to bindings script from 5G-MAG/rt-common-shared repository.

Enhancement

This project has a script at build_scripts/generate_openapi which is used to generate the python bindings from the 5G APIs OpenAPI YAML.

Once PR #33 has been merged, there will be a more generic version of this script at docs/rt-common-shared/5gms/scripts/generate_openapi.

When this script is available the build_scripts/generate_openapi should be modified to call the more generic script, from rt-common-shared, with appropriate parameters to build the bindings.

Requirements

PR #33 will need to be merged before this can be done.

Improve life-cycle management of web proxy server

Feature description

Extending #14, maintain a watchdog to restart it after a crash or if the configuration changes.

Relevant specifications and corresponding sections

See #1

GanttLab

GanttStart: 2022-09-19
GanttDue: 2022-09-26

Content Hosting Configuration handling uplift in 5GMSd AS

Context

The syntax of the Content Hosting Configuration has been modified to take into account implementation feedback from 5G-MAG:

The purpose of this issue is to modify the handling of the Content Hosting Configuration in the 5GMSd AF.

Specification

TS 26.512 V17.3.0 includes an updated TS26512_M1_ContentHostingProvisioning.yaml in annex C.3.5.
The internal data structures in the 5GMS AS need to be adjusted to take into account these changes, namely:

  • IngestConfiguration.path and IngestConfiguration.entryPoint replaced by IngestConfiguration.baseURL. (Requests at M4d are mapped to this base URL at M4d for pull requests at M2d.)
  • DistributionConfiguration.baseURL added. (M4d requests are made to this base URL assigned by the 5GMSd AF.)
  • DistributionConfiguration.supplementaryDistributionNetworks redefined. (Rel-17 and later only. Only relevant to the 5GMSd AS when it is later integrated with MBMS, MBS, etc.)
  • PathRewriteRule.requestPattern renamed to PathRewriteRules.requestPathPattern.
  • ContentHostingConfiguration.entryPointPath added. (Not relevant to 5GMSd AS.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.