--- /dev/null
+# misc cruft
+*.log
+log.txt
+rmr/*
+docs_and_diagrams/
+
+# documentation
+.tox
+docs/_build/
+
+# standard python ignore template
+.pytest_cache/
+xunit-results.xml
+.DS_Store
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+venv-tox/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*,cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# IPython Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# dotenv
+.env
+
+# virtualenv
+venv/
+ENV/
+
+# Spyder project settings
+.spyderproject
+
+# Rope project settings
+.ropeproject
+
+# Test report
+xunit-reports
+coverage-reports
--- /dev/null
+---
+# .readthedocs.yml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+# Required
+version: 2
+
+formats:
+ - htmlzip
+
+build:
+ image: latest
+
+python:
+ version: 3.7
+ install:
+ - requirements: docs/requirements-docs.txt
+
+sphinx:
+ configuration: docs/conf.py
--- /dev/null
+# ==================================================================================
+# Copyright (c) 2018-2020 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==================================================================================
+FROM python:3.7-alpine
+
+# RMR setup
+RUN mkdir -p /opt/route/
+COPY --from=nexus3.o-ran-sc.org:10004/bldr-alpine3-go:1-rmr1.13.1 /usr/local/lib64/libnng.so /usr/local/lib64/libnng.so
+COPY --from=nexus3.o-ran-sc.org:10004/bldr-alpine3-go:1-rmr1.13.1 /usr/local/lib64/librmr_nng.so /usr/local/lib64/librmr_nng.so
+ENV LD_LIBRARY_PATH /usr/local/lib/:/usr/local/lib64
+
+# sdl needs gcc
+RUN apk update && apk add gcc musl-dev bash
+
+# Install
+COPY setup.py /tmp
+COPY LICENSE.txt /tmp/
+COPY qpdriver/ /tmp/qpdriver
+RUN pip install /tmp
+
+# Run
+ENV PYTHONUNBUFFERED 1
+CMD start.py
--- /dev/null
+
+ Unless otherwise specified, all software contained herein is licensed
+ under the Apache License, Version 2.0 (the "Software License");
+ you may not use this software except in compliance with the Software
+ License. You may obtain a copy of the Software License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the Software License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the Software License for the specific language governing permissions
+ and limitations under the Software License.
+
+
+
+ Unless otherwise specified, all documentation contained herein is licensed
+ under the Creative Commons License, Attribution 4.0 Intl. (the
+ "Documentation License"); you may not use this documentation except in
+ compliance with the Documentation License. You may obtain a copy of the
+ Documentation License at
+
+ https://creativecommons.org/licenses/by/4.0/
+
+ Unless required by applicable law or agreed to in writing, documentation
+ distributed under the Documentation License is distributed on an "AS IS"
+ BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the Documentation License for the specific language governing
+ permissions and limitations under the Documentation License.
--- /dev/null
+# The Jenkins job uses this string for the tag in the image name
+# for example nexus3.o-ran-sc.org:10004/my-image-name:my-tag
+---
+tag: 0.0.1
--- /dev/null
+from docs_conf.conf import *
+
+linkcheck_ignore = ["http://localhost.*", "http://127.0.0.1.*", "https://gerrit.o-ran-sc.org.*"]
--- /dev/null
+---
+project_cfg: oran
+project: ric-app-qp-driver
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. SPDX-License-Identifier: CC-BY-4.0
+.. Copyright (C) 2020 AT&T Intellectual Property
+
+
+Welcome to O-RAN SC qp-driver Documentation
+============================================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ overview.rst
+ release-notes.rst
+ installation-guide.rst
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. SPDX-License-Identifier: CC-BY-4.0
+.. Copyright (C) 2020 AT&T Intellectual Property
+
+
+Installation Guide
+==================
+
+.. contents::
+ :depth: 3
+ :local:
+
+Installation
+------------
+
+[to come]
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. SPDX-License-Identifier: CC-BY-4.0
+.. Copyright (C) 2020 AT&T Intellectual Property
+
+qp-driver Overview
+==================
+
+[to come]
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. SPDX-License-Identifier: CC-BY-4.0
+.. Copyright (C) 2020 AT&T Intellectual Property
+
+Release Notes
+===============
+
+All notable changes to this project will be documented in this file.
+
+The format is based on `Keep a Changelog <http://keepachangelog.com/>`__
+and this project adheres to `Semantic Versioning <http://semver.org/>`__.
+
+.. contents::
+ :depth: 3
+ :local:
+
+[0.0.1] - 3/17/2020
+-------------------
+::
+
+ * inital skeleton creation
--- /dev/null
+sphinx
+sphinx-rtd-theme
+sphinxcontrib-httpdomain
+recommonmark
+lfdocs-conf
--- /dev/null
+# ==================================================================================
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==================================================================================
+from ricxappframe.xapp_frame import RMRXapp
+
+
+"""
+This is only a stencil for now, will be filled in!
+What is currently here was only for initial skeleton and test creation.
+"""
+
+
+def post_init(self):
+ self.def_hand_called = 0
+ self.traffic_steering_requests = 0
+
+
+def default_handler(self, summary, sbuf):
+ self.def_hand_called += 1
+ print(summary)
+ self.rmr_free(sbuf)
+
+
+def steering_req_handler(self, summary, sbuf):
+ self.traffic_steering_requests += 1
+ print(summary)
+ self.rmr_free(sbuf)
+
+
+# obv some of these flags have to change
+rmr_xapp = RMRXapp(default_handler, post_init=post_init, rmr_port=4562, use_fake_sdl=True)
+rmr_xapp.register_callback(steering_req_handler, 60000) # no idea (yet) what the real int is here
+
+
+def start(thread=False):
+ rmr_xapp.run(thread)
+
+
+def stop():
+ """can only be called if thread=True when started"""
+ rmr_xapp.stop()
+
+
+def get_stats():
+ # hacky for now, will evolve
+ return {"DefCalled": rmr_xapp.def_hand_called, "SteeringRequests": rmr_xapp.traffic_steering_requests}
--- /dev/null
+# CI script installs RMR from PackageCloud using this version
+---
+version: 1.13.1
--- /dev/null
+# ==================================================================================
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==================================================================================
+from os.path import dirname, abspath, join as path_join
+from setuptools import setup, find_packages
+
+SETUP_DIR = abspath(dirname(__file__))
+
+
+def _long_descr():
+ """Yields the content of documentation files for the long description"""
+ try:
+ doc_path = path_join(SETUP_DIR, "docs/overview.rst")
+ with open(doc_path) as f:
+ return f.read()
+ except FileNotFoundError: # this happens during unit testing, we don't need it
+ return ""
+
+
+setup(
+ name="qpdriver",
+ version="0.0.1",
+ packages=find_packages(exclude=["tests.*", "tests"]),
+ author="Tommy Carpenter",
+ description="QP Driver Xapp for traffic steering",
+ url="https://gerrit.o-ran-sc.org/r/admin/repos/ric-app/qp-driver",
+ install_requires=["ricxappframe>=0.4.0"],
+ entry_points={"console_scripts": ["start.py=qpdriver.main:start"]}, # adds a magical entrypoint for Docker
+ classifiers=[
+ "Development Status :: 4 - Beta",
+ "Intended Audience :: Telecommunications Industry",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.7",
+ "License :: OSI Approved :: Apache Software License",
+ "Operating System :: POSIX :: Linux",
+ "Topic :: Communications",
+ ],
+ python_requires=">=3.7",
+ keywords="RIC xapp",
+ license="Apache 2.0",
+ data_files=[("", ["LICENSE.txt"])],
+ long_description=_long_descr(),
+ long_description_content_type="text/x-rst",
+)
--- /dev/null
+# do NOT use localhost, seems unresolved on jenkins VMs
+newrt|start
+mse| 60000 | -1 | 127.0.0.1:4562
+mse| 60001 | -1 | 127.0.0.1:4562
+newrt|end
--- /dev/null
+# ==================================================================================
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==================================================================================
+import json
+import time
+from contextlib import suppress
+from qpdriver import main
+from ricxappframe.xapp_frame import Xapp
+
+test_sender = None
+
+
+def test_flow():
+ """
+ just a skeleton for now.. this will evolve when qpd evolves
+ """
+
+ # start qpd
+ main.start(thread=True)
+
+ # define a test sender
+ def entry(self):
+
+ val = json.dumps({"test send 60000": 1}).encode()
+ self.rmr_send(val, 60000)
+
+ val = json.dumps({"test send 60001": 2}).encode()
+ self.rmr_send(val, 60001)
+
+ global test_sender
+ test_sender = Xapp(entrypoint=entry, rmr_port=4564, use_fake_sdl=True)
+ test_sender.run()
+
+ time.sleep(1)
+
+ assert main.get_stats() == {"DefCalled": 1, "SteeringRequests": 1}
+
+
+def teardown_module():
+ """
+ this is like a "finally"; the name of this function is pytest magic
+ safer to put down here since certain failures above can lead to pytest never returning
+ for example if an exception gets raised before stop is called in any test function above, pytest will hang forever
+ """
+ with suppress(Exception):
+ test_sender.stop()
+ with suppress(Exception):
+ main.stop()
--- /dev/null
+# ==================================================================================
+# Copyright (c) 2020 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ==================================================================================
+[tox]
+envlist = code,flake8,docs,docs-linkcheck
+minversion = 2.0
+
+[testenv:code]
+basepython = python3.7
+deps=
+ pytest
+ coverage
+ pytest-cov
+setenv =
+ LD_LIBRARY_PATH = /usr/local/lib/:/usr/local/lib64
+ RMR_SEED_RT = tests/fixtures/test_local.rt
+ RMR_ASYNC_CONN = 0
+
+commands =
+ pytest --cov qpdriver --cov-report xml --cov-report term-missing --cov-report html
+# --cov-fail-under=70
+ coverage xml -i
+
+[testenv:flake8]
+basepython = python3.7
+skip_install = true
+deps = flake8
+commands = flake8 setup.py qpdriver tests
+
+[flake8]
+extend-ignore = E501,E741,E731
+
+# doc jobs
+[testenv:docs]
+whitelist_externals = echo
+skipsdist = true
+basepython = python3.7
+deps =
+ sphinx
+ sphinx-rtd-theme
+ sphinxcontrib-httpdomain
+ recommonmark
+ lfdocs-conf
+commands =
+ sphinx-build -W -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html
+ echo "Generated docs available in {toxinidir}/docs/_build/html"
+
+[testenv:docs-linkcheck]
+skipsdist = true
+basepython = python3.7
+deps = sphinx
+ sphinx-rtd-theme
+ sphinxcontrib-httpdomain
+ recommonmark
+ lfdocs-conf
+commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck