From 02cb601e28586dee95122e9fd8e19f77dedb5e08 Mon Sep 17 00:00:00 2001 From: elinuxhenrik Date: Mon, 4 Apr 2022 13:07:36 +0200 Subject: [PATCH] Seed code Issue-ID: NONRTRIC-712 Signed-off-by: elinuxhenrik Change-Id: I064f034842fafe0fe59f5cce8f5389a619583616 --- .gitignore | 22 ++ .gitmodules | 3 + .readthedocs.yaml | 16 ++ Dockerfile | 48 +++++ LICENSE.txt | 201 ++++++++++++++++++ README.md | 93 +++++++++ config/README | 42 ++++ config/application.yaml | 80 ++++++++ config/application_configuration.json | 24 +++ config/keystore.jks | Bin 0 -> 4779 bytes config/truststore.jks | Bin 0 -> 3587 bytes docs/_static/logo.png | Bin 0 -> 43935 bytes docs/conf.py | 19 ++ docs/conf.yaml | 3 + docs/developer-guide.rst | 24 +++ docs/favicon.ico | Bin 0 -> 15086 bytes docs/index.rst | 17 ++ docs/installation-guide.rst | 41 ++++ docs/overview.rst | 32 +++ docs/release-notes.rst | 185 +++++++++++++++++ docs/requirements-docs.txt | 12 ++ dpo/blueprints/k8s-policy-agent.yaml | 111 ++++++++++ onap/oran | 1 + pom.xml | 377 ++++++++++++++++++++++++++++++++++ src | 1 + tox.ini | 37 ++++ 26 files changed, 1389 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .readthedocs.yaml create mode 100644 Dockerfile create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 config/README create mode 100644 config/application.yaml create mode 100644 config/application_configuration.json create mode 100644 config/keystore.jks create mode 100644 config/truststore.jks create mode 100644 docs/_static/logo.png create mode 100644 docs/conf.py create mode 100644 docs/conf.yaml create mode 100644 docs/developer-guide.rst create mode 100644 docs/favicon.ico create mode 100644 docs/index.rst create mode 100644 docs/installation-guide.rst create mode 100644 docs/overview.rst create mode 100644 docs/release-notes.rst create mode 100644 docs/requirements-docs.txt create mode 100644 dpo/blueprints/k8s-policy-agent.yaml create mode 160000 onap/oran create mode 100644 pom.xml create mode 120000 src create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5915080 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Documentation +.idea/ +.tox +docs/_build/ +.DS_STORE +.swagger* +docs/offeredapis/swagger/README.md + +# Eclipse +.checkstyle +.classpath +target/ +.sts4-cache +.project +.settings +.pydevproject +infer-out/ + +.vscode +.factorypath + +coverage.* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5056419 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "onap/oran"] + path = onap/oran + url = https://gerrit.onap.org/r/ccsdk/oran diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..095222a --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,16 @@ +--- +version: 2 + +formats: + - htmlzip + +build: + image: latest + +python: + version: 3.7 + install: + - requirements: docs/requirements-docs.txt + +sphinx: + configuration: docs/conf.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6f8387e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,48 @@ +# +# ============LICENSE_START======================================================= +# Copyright (C) 2019 Nordix Foundation. +# ================================================================================ +# 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. +# +# SPDX-License-Identifier: Apache-2.0 +# ============LICENSE_END========================================================= +# +FROM openjdk:11-jre-slim + +ARG JAR + +EXPOSE 8081 8433 + + +WORKDIR /opt/app/policy-agent +RUN mkdir -p /var/log/policy-agent +RUN mkdir -p /opt/app/policy-agent/etc/cert/ +EXPOSE 8081 8433 + +ADD /config/application.yaml /opt/app/policy-agent/config/application.yaml +ADD /config/application_configuration.json /opt/app/policy-agent/data/application_configuration.json_example +ADD /config/keystore.jks /opt/app/policy-agent/etc/cert/keystore.jks +ADD /config/truststore.jks /opt/app/policy-agent/etc/cert/truststore.jks + +ARG user=nonrtric +ARG group=nonrtric + +RUN groupadd $user && \ + useradd -r -g $group $user +RUN chown -R $user:$group /opt/app/policy-agent +RUN chown -R $user:$group /var/log/policy-agent + +USER ${user} + +ADD target/${JAR} /opt/app/policy-agent/policy-agent.jar +CMD ["java", "-jar", "/opt/app/policy-agent/policy-agent.jar"] \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..96589bf --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d660df9 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# O-RAN-SC Non-RT RIC Policy Agent + +The O-RAN Non-RT RIC PolicyAgent provides a REST API for management of policices. +It provides support for: + -Supervision of clients (R-APPs) to eliminate stray policies in case of failure + -Consistency monitoring of the SMO view of policies and the actual situation in the RICs + -Consistency monitoring of RIC capabilities (policy types) + -Policy configuration. This includes: + -One REST API towards all RICs in the network + -Query functions that can find all policies in a RIC, all policies owned by a service (R-APP), + all policies of a type etc. + -Maps O1 resources (ManagedElement) as defined in O1 to the controlling RIC + +The Policy Agent uses the default keystore and truststore that are built into the container. The paths and passwords for these stores are located in a yaml file: +nonrtric/policy-agent/config/application.yaml + +The default truststore includes a1simulator cert as a trusted cert which is located here: +https://gerrit.o-ran-sc.org/r/gitweb?p=sim/a1-interface.git;a=tree;f=near-rt-ric-simulator/certificate;h=172c1e5aacd52d760e4416288dc5648a5817ce65;hb=HEAD + +The default truststore also includes a1controller cert as a trusted cert which is located here (keystore.jks file): +https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=sdnc-a1-controller/oam/installation/sdnc-a1/src/main/resources;h=17fdf6cecc7a866c5ce10a35672b742a9f0c4acf;hb=HEAD + +There is also Policy Agent's own cert in the default truststore for mocking purposes and unit-testing (ApplicationTest.java). + +The default keystore, truststore, and application.yaml files can be overridden by mounting new files using the "volumes" field of docker-compose or docker run command. + +Assuming that the keystore, truststore, and application.yaml files are located in the same directory as docker-compose, the volumes field should have these entries: + +volumes: + - ./new_keystore.jks:/opt/app/policy-agent/etc/cert/keystore.jks:ro + - ./new_truststore.jks:/opt/app/policy-agent/etc/cert/truststore.jks:ro + - ./new_application.yaml:/opt/app/policy-agent/config/application.yaml:ro + +The target paths in the container should not be modified. + +Example docker run command for mounting new files (assuming they are located in the current directory): +docker run -p 8081:8081 -p 8433:8433 --name=policy-agent-container --network=nonrtric-docker-net --volume "$PWD/new_keystore.jks:/opt/app/policy-agent/etc/cert/keystore.jks" --volume "$PWD/new_truststore.jks:/opt/app/policy-agent/etc/cert/truststore.jks" --volume "$PWD/new_application.yaml:/opt/app/policy-agent/config/application.yaml" o-ran-sc/nonrtric-policy-agent:2.2.0-SNAPSHOT + + +To Run Policy Agent in Local: +In the folder /opt/app/policy-agent/config/, create a soft link with below command, +ln -s application_configuration.json + +To Run Policy Agent in Local with the DMaaP polling turned on: +In the folder /opt/app/policy-agent/config/, create a soft link with below command, +ln -s application_configuration.json + +The agent can be run stand alone in a simulated test mode. Then it simulates RICs. +The REST API is published on port 8081 and it is started by command: +mvn -Dtest=MockPolicyAgent test + +The backend server publishes live API documentation at the +URL `http://your-host-name-here:8081/swagger-ui.html` + +PolicyAgent uses A1-POLICY-AGENT-READ & A1-POLICY-AGENT-WRITE topic for subscribe & Publish to the DMaap. +Sample Request Message to DMaaP: +{ + "type": "request", + "target": "policy-agent", + "timestamp": "2019-05-14T11:44:51.36Z", + "operation": "GET", + "correlationId": "c09ac7d1-de62-0016-2000-e63701125557-201", + "apiVersion": "1.0", + "originatorId": "849e6c6b420", + "requestId": "23343221", + "url": "/policies?type=type1&ric=ric1&service=service1" +} + +Sample Response Message to DMaaP: +{ + "type": "response", + "timestamp": "2019-05-14T11:44:51.36Z", + "correlationId": "c09ac7d1-de62-0016-2000-e63701125557-201", + "originatorId": "849e6c6b420", + "requestId": "23343221", + "status": "200 OK", + "message": [] +} + +## License + +Copyright (C) 2019 Nordix Foundation. All rights reserved. +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. diff --git a/config/README b/config/README new file mode 100644 index 0000000..b54a675 --- /dev/null +++ b/config/README @@ -0,0 +1,42 @@ +The keystore.jks and truststore.jks files are created by using the following commands (note that this is an example): + +1) Create a CA certificate and a private key: + +openssl genrsa -des3 -out CA-key.pem 2048 +openssl req -new -key CA-key.pem -x509 -days 1000 -out CA-cert.pem + +2) Create a keystore with a private key entry that is signed by the CA: + +keytool -genkeypair -alias policy_agent -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650 -storepass policy_agent +keytool -certreq -alias policy_agent -file request.csr -keystore keystore.jks -ext san=dns:your.domain.com -storepass policy_agent +openssl x509 -req -days 365 -in request.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out ca_signed-cert.pem +keytool -importcert -alias ca_cert -file CA-cert.pem -keystore keystore.jks -trustcacerts -storepass policy_agent +keytool -importcert -alias policy_agent -file ca_signed-cert.pem -keystore keystore.jks -trustcacerts -storepass policy_agent + + +3) Create a trust store containing the CA cert (to trust all certs signed by the CA): + +keytool -genkeypair -alias not_used -keyalg RSA -keysize 2048 -keystore truststore.jks -validity 3650 -storepass policy_agent +keytool -importcert -alias ca_cert -file CA-cert.pem -keystore truststore.jks -trustcacerts -storepass policy_agent + + +4) Command for listing of the contents of jks files, examples: +keytool -list -v -keystore keystore.jks -storepass policy_agent +keytool -list -v -keystore truststore.jks -storepass policy_agent + +## License + +ONAP : ccsdk oran +Copyright (C) 2020 Nordix Foundation. All rights reserved. +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. + diff --git a/config/application.yaml b/config/application.yaml new file mode 100644 index 0000000..5684c46 --- /dev/null +++ b/config/application.yaml @@ -0,0 +1,80 @@ +# +# ============LICENSE_START======================================================= +# ONAP : ccsdk oran +# ================================================================================ +# Copyright (C) 2020 Nordix Foundation. All rights reserved. +# ================================================================================ +# 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. +# +# SPDX-License-Identifier: Apache-2.0 +# ============LICENSE_END========================================================= +# +spring: + profiles: + active: prod + main: + allow-bean-definition-overriding: true + aop: + auto: false +management: + endpoints: + web: + exposure: + # Enabling of springboot actuator features. See springboot documentation. + include: "loggers,logfile,health,info,metrics,threaddump,heapdump" +springdoc: + show-actuator: true +logging: + # Configuration of logging + level: + ROOT: ERROR + org.springframework: ERROR + org.springframework.data: ERROR + org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR + org.onap.ccsdk.oran.a1policymanagementservice: INFO + # org.onap.ccsdk.oran.a1policymanagementservice.tasks: TRACE + file: + name: /var/log/policy-agent/application.log +server: + # Configuration of the HTTP/REST server. The parameters are defined and handeled by the springboot framework. + # See springboot documentation. + port : 8433 + http-port: 8081 + ssl: + key-store-type: JKS + key-store-password: policy_agent + key-store: /opt/app/policy-agent/etc/cert/keystore.jks + key-password: policy_agent + key-alias: policy_agent +app: + # Location of the component configuration file. + filepath: /opt/app/policy-agent/data/application_configuration.json + webclient: + # Configuration of the trust store used for the HTTP client (outgoing requests) + # The file location and the password for the truststore is only relevant if trust-store-used == true + # Note that the same keystore as for the server is used. + trust-store-used: false + trust-store-password: policy_agent + trust-store: /opt/app/policy-agent/etc/cert/truststore.jks + # Configuration of usage of HTTP Proxy for the southbound accesses. + # The HTTP proxy (if configured) will only be used for accessing NearRT RIC:s + # proxy-type can be either HTTP, SOCKS4 or SOCKS5 + http.proxy-host: + http.proxy-port: 0 + http.proxy-type: HTTP + # path where the service can store data + vardata-directory: /var/policy-management-service + # the config-file-schema-path referres to a location in the jar file. If this property is empty or missing, + # no schema validation will be executed. + config-file-schema-path: /application_configuration_schema.json + diff --git a/config/application_configuration.json b/config/application_configuration.json new file mode 100644 index 0000000..6187c86 --- /dev/null +++ b/config/application_configuration.json @@ -0,0 +1,24 @@ +{ + "description": "Application configuration", + "config": { + "controller": [ + { + "name": "controller1", + "baseUrl": "http://a1controller:8282", + "userName": "admin", + "password": "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U" + } + ], + "ric": [ + { + "name": "ric1", + "baseUrl": "http://ric1:8085/", + "controller": "controller1", + "managedElementIds": [ + "kista_1", + "kista_2" + ] + } + ] + } +} diff --git a/config/keystore.jks b/config/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..48c3b33c0dfb61f1679df3f0f3b3503321bbd21c GIT binary patch literal 4779 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 literal 0 HcmV?d00001 diff --git a/docs/_static/logo.png b/docs/_static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c3b6ce56468d87a3d9463ee75297b3895fc9a414 GIT binary patch literal 43935 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

r@f1gRWk|A*%4`3la7*fhEBO++ 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 literal 0 HcmV?d00001 diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..94affba --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,19 @@ +from docs_conf.conf import * + +#branch configuration + +branch = 'latest' + +linkcheck_ignore = [ + 'http://localhost.*', + 'http://127.0.0.1.*', + 'https://gerrit.o-ran-sc.org.*' +] + +extensions = ['sphinx.ext.intersphinx',] + +#intershpinx mapping with other projects +intersphinx_mapping = {} + +intersphinx_mapping['nonrtric-controlpanel'] = ('https://docs.o-ran-sc.org/projects/o-ran-sc-portal-nonrtric-controlpanel/en/%s' % branch, None) +intersphinx_mapping['sim-a1-interface'] = ('https://docs.o-ran-sc.org/projects/o-ran-sc-sim-a1-interface/en/%s' % branch, None) diff --git a/docs/conf.yaml b/docs/conf.yaml new file mode 100644 index 0000000..f730bc0 --- /dev/null +++ b/docs/conf.yaml @@ -0,0 +1,3 @@ +--- +project_cfg: oran +project: nonrtric-plt-a1policymanagementservice diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst new file mode 100644 index 0000000..d3bb426 --- /dev/null +++ b/docs/developer-guide.rst @@ -0,0 +1,24 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. Copyright (C) 2021 Nordix + +=============== +Developer Guide +=============== + +This document provides a quickstart for developers of the Non-RT RIC A1 Policy Managent Service. + +The A1 Policy Management Service is implemented in ONAP. For documentation see `ONAP CCSDK documentation `_. +and `wiki `_. + +Kubernetes deployment +===================== + +Non-RT RIC can be also deployed in a Kubernetes cluster, `it/dep repository `_. +hosts deployment and integration artifacts. Instructions and helm charts to deploy the Non-RT-RIC functions in the +OSC NONRTRIC integrated test environment can be found in the *./nonrtric* directory. + +For more information on installation of NonRT-RIC in Kubernetes, see `Deploy NONRTRIC in Kubernetes `_. + +For more information see `Integration and Testing documentation on the O-RAN-SC wiki `_. + diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..00b0fd0ef0b4e78fbb8cdb413ce84561dfeb404f GIT binary patch literal 15086 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

4K$ruCE1 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 XY+}&}KC=mD;X?Iq*l*cA?B4$ePY*3q literal 0 HcmV?d00001 diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..d1438e3 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,17 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. Copyright (C) 2021 Nordix + +Non-RT RIC A1 Policy Managent Service +===================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + ./overview.rst + ./developer-guide.rst + ./installation-guide.rst + ./release-notes.rst + +* :ref:`search` diff --git a/docs/installation-guide.rst b/docs/installation-guide.rst new file mode 100644 index 0000000..1837152 --- /dev/null +++ b/docs/installation-guide.rst @@ -0,0 +1,41 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. Copyright (C) 2021 Nordix + +Installation Guide +================== + +Abstract +-------- + +This document describes how to install the Non-RT RIC components, their dependencies and required system resources. + +Software Installation and Deployment +------------------------------------ + +Install with Docker ++++++++++++++++++++ + +Docker compose files are provided, in the "docker-compose" folder, to install the components. Run the following +command to start the components: + + .. code-block:: bash + + docker-compose -f docker-compose.yaml + -f policy-service/docker-compose.yaml + -f ics/docker-compose.yaml + +The example above is just an example to start some of the components. +For more information on running and configuring the functions can be found in the README file in the "`docker-compose `__" folder, and on the `wiki page `_ + +Install with Helm ++++++++++++++++++ + +Helm charts and an example recipe are provided in the `it/dep repo `_, +under "nonrtric". By modifying the variables named "installXXX" in the beginning of the example recipe file, which +components that will be installed can be controlled. Then the components can be installed and started by running the +following command: + + .. code-block:: bash + + bin/deploy-nonrtric -f nonrtric/RECIPE_EXAMPLE/example_recipe.yaml diff --git a/docs/overview.rst b/docs/overview.rst new file mode 100644 index 0000000..773b872 --- /dev/null +++ b/docs/overview.rst @@ -0,0 +1,32 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. Copyright (C) 2021 Nordix + +A1 Policy Management Service (from ONAP CCSDK) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A1 Controller Service above A1 Controller/Adaptor that provides: + +* Unified REST & DMaaP NBI APIs for managing A1 Policies in all near-RT-RICs. + + + Query A1 Policy Types in near-RT-RICs. + + Create/Query/Update/Delete A1 Policy Instances in near-RT-RICs. + + Query Status for A1 Policy Instances. + +* Maintains (persistent) cache of RAN's A1 Policy information. + + * Support RAN-wide view of A1 Policy information. + * Streamline A1 traffic. + * Enable (optional) re-synchronization after inconsistencies / near-RT-RIC restarts. + * Supports a large number of near-RT-RICs (& multi-version support). + +* Converged ONAP & O-RAN-SC A1 Adapter/Controller functions in ONAP SDNC/CCSDK (Optionally deploy without A1 Adaptor to connect direct to near-RT-RICs). +* Support for different Southbound connectors per near-RT-RIC - e.g. different A1 versions, different near-RT-RIC version, different A1 adapter/controllers supports different or proprietary A1 controllers/EMSs. + +See also: `A1 Policy Management Service in ONAP `_ . + +Implementation: + +* Implemented as a Java Spring Boot application. + + diff --git a/docs/release-notes.rst b/docs/release-notes.rst new file mode 100644 index 0000000..39111bd --- /dev/null +++ b/docs/release-notes.rst @@ -0,0 +1,185 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 +.. Copyright (C) 2021 Nordix + +============= +Release-Notes +============= + + +This document provides the release notes for the release of the Non-RT RIC A1 Policy Management Service. + + +Version history A1 Policy Management Service (A1 Policy Agent) +============================================================== + ++------------+----------+------------------+--------------------+ +| **Date** | **Ver.** | **Author** | **Comment** | +| | | | | ++------------+----------+------------------+--------------------+ +| 2020-02-03 | 1.0.0 | Henrik Andersson | First version | +| | | | Amber Maintenance | +| | | | Release | ++------------+----------+------------------+--------------------+ +| 2020-06-18 | 2.0.0 | Henrik Andersson | Bronze Release | +| | | | | ++------------+----------+------------------+--------------------+ +| 2020-07-29 | 2.0.1 | Henrik Andersson | Bronze Maintenance | +| | | | Release | +| | | | | ++------------+----------+------------------+--------------------+ +| 2020-12-03 | 2.1.0 | Henrik Andersson | Cherry Release | +| | | | | ++------------+----------+------------------+--------------------+ +| 2021-06-23 | 2.2.0 | Henrik Andersson | D Release | +| | | | | ++------------+----------+------------------+--------------------+ +| 2021-08-10 | 2.2.1 | Henrik Andersson | D Maintenance | +| | | | Release | +| | | | | ++------------+----------+------------------+--------------------+ +| 2021-12-13 | 2.3.0 | Henrik Andersson | E Release | +| | | | Renamed and minor | +| | | | improvements | ++------------+----------+------------------+--------------------+ +| 2022-02-07 | 2.3.1 | Henrik Andersson | E Maintenance | +| | | | Release | +| | | | Non root user in | +| | | | Docker | ++------------+----------+------------------+--------------------+ + +Release Data +============ + +Bronze +------ ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/2466f9d370214b578efedd1d3e38b1de17e6ca1c | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | Bronze | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2020-06-18 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | Improved stability | +| | | ++-----------------------------+---------------------------------------------------+ + +Bronze Maintenance +------------------ ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/5d4f252a530a0d9abbf2a363354c5e56e8f2f33e | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | Bronze | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2020-07-29 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | Introduce configuration of certificates | +| | | ++-----------------------------+---------------------------------------------------+ + +Cherry +------ ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/90ce16238dd6970153e1c0fbddb15e32c68c504f | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | Cherry | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2020-12-03 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | | +| | | ++-----------------------------+---------------------------------------------------+ + +D +- ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/dd3ebfd784e96919a00ddd745826f8a8e074c66f | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | D | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2021-06-23 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | Improvements | +| | | ++-----------------------------+---------------------------------------------------+ + +D Maintenance +------------- ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/973ae56894fb29a929fba9e344cae42e7607087b | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | D | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2021-08-10 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | Minor bug fixes | ++-----------------------------+---------------------------------------------------+ + +E Release +--------- ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/b472c167413a55a42fc7bfa08d2138f967a204fb | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | E | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2021-12-13 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | Improvements and renaming. | +| | | ++-----------------------------+---------------------------------------------------+ + +E Maintenance Release +--------------------- ++-----------------------------+---------------------------------------------------+ +| **Project** | Non-RT RIC | +| | | ++-----------------------------+---------------------------------------------------+ +| **Repo/commit-ID** | nonrtric/4df1f9ca4cd1ebc21e0c5ea57bcb0b7ef096d067 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release designation** | E | +| | | ++-----------------------------+---------------------------------------------------+ +| **Release date** | 2022-02-09 | +| | | ++-----------------------------+---------------------------------------------------+ +| **Purpose of the delivery** | Improvements and bug fixes | +| | | ++-----------------------------+---------------------------------------------------+ + diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt new file mode 100644 index 0000000..692a79f --- /dev/null +++ b/docs/requirements-docs.txt @@ -0,0 +1,12 @@ +tox +Sphinx +doc8 +docutils +setuptools +six +sphinx_rtd_theme +sphinxcontrib-needs +sphinxcontrib-swaggerdoc +sphinx_bootstrap_theme +sphinxcontrib-redoc +lfdocs-conf \ No newline at end of file diff --git a/dpo/blueprints/k8s-policy-agent.yaml b/dpo/blueprints/k8s-policy-agent.yaml new file mode 100644 index 0000000..aa09ff3 --- /dev/null +++ b/dpo/blueprints/k8s-policy-agent.yaml @@ -0,0 +1,111 @@ + +#description: Docker application of Policy Agent managing policies +#blueprint_version: 1.0.0 +--- +tosca_definitions_version: cloudify_dsl_1_3 +description: Docker application to collect log file from PNF +imports: + - http://www.getcloudify.org/spec/cloudify/4.3.1/types.yaml + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R5/k8splugin/1.6.0/k8splugin_types.yaml + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.ccsdk.platform.plugins/type_files/dmaap/dmaap.yaml +inputs: + policy-agent_cpu_limit: + type: string + default: "250m" + policy-agent_cpu_request: + type: string + default: "250m" + policy-agent_memory_limit: + type: string + default: "256Mi" + policy-agent_memory_request: + type: string + default: "256Mi" + envs: + default: {} + external_port: + type: string + default: ":0" + publish_topic_name: + type: string + default: "A1-POLICY-AGENT-WRITE" + subscribe_topic_name: + type: string + default: "A1-POLICY-AGENT-READ" + consumer_group: + type: string + default: "users" + consumer_id: + type: string + default: "policy-agent" + log_directory: + type: string + default: "/var/log/policy-agent" + replicas: + type: integer + description: number of instances + default: 1 + tag_version: + type: string + default: "nexus3.o-ran-sc.org:10004/o-ran-sc/nonrtric-policy-agent:1.0.0" +node_templates: + policy-agent: + type: dcae.nodes.ContainerizedServiceComponentUsingDmaap + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + get_input: envs + properties: + application_config: + streams_publishes: + dmaap_publisher: + dmaap_info: + topic_url: { concat: ['https://message-router:3905/events/',{ get_input: publish_topic_name }] } + type: message_router + streams_subscribes: + dmaap_subscriber: + dmaap_info: + topic_url: { concat: ['https://message-router:3905/events/',{ get_input: subscribe_topic_name }, '/', { get_input: consumer_group }, "/", { get_input: consumer_id }, "?timeout=15000&limit=100"] } + type: message_router + ric: + - name: ric1 + baseUrl: http://localhost:8083/ + managedElementIds: + - kista_1 + - kista_2 + - name: ric2 + baseUrl: http://localhost:8085/ + managedElementIds: + - kista_3 + - kista_4 + docker_config: + healthcheck: + interval: 15s + timeout: 1s + type: http + endpoint: /status + ports: + - concat: ["8081", {get_input: external_port}] + image: + get_input: tag_version + service_component_type: policy-agent + log_info: + log_directory: + get_input: log_directory + replicas: + get_input: replicas + resource_config: + limits: + cpu: + get_input: policy-agent_cpu_limit + memory: + get_input: policy-agent_memory_limit + requests: + cpu: + get_input: policy-agent_cpu_request + memory: + get_input: policy-agent_memory_request + + diff --git a/onap/oran b/onap/oran new file mode 160000 index 0000000..4b62052 --- /dev/null +++ b/onap/oran @@ -0,0 +1 @@ +Subproject commit 4b6205245fd4839e4449e26aa4e3000ddb30ecc1 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..12b8ecd --- /dev/null +++ b/pom.xml @@ -0,0 +1,377 @@ + + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + org.o-ran-sc.nonrtric + nonrtric-plt-a1policymanagementservice + 2.4.0-SNAPSHOT + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + onap-releases + onap-releases + https://nexus.onap.org/content/repositories/releases/ + + + + 11 + 3.0.0 + 2.8.2 + 2.1.13 + 20211205 + 3.8.0 + 2.12.2 + 1.18.0 + 0.30.0 + 2.1.1 + 3.7.0.1746 + 0.8.5 + 3.0.0 + + + + commons-io + commons-io + 2.11.0 + + + com.google.guava + guava + 31.0.1-jre + + + org.springdoc + springdoc-openapi-ui + 1.6.6 + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-webflux + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-devtools + true + + + org.springframework + spring-webflux + + + io.swagger.core.v3 + swagger-jaxrs2 + ${swagger.version} + + + io.swagger.core.v3 + swagger-jaxrs2-servlet-initializer + ${swagger.version} + + + javax.xml.bind + jaxb-api + + + org.immutables + value + ${immutable.version} + provided + + + org.immutables + gson + ${immutable.version} + + + org.json + json + ${json.version} + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.projectlombok + lombok + provided + + + javax.ws.rs + javax.ws.rs-api + ${javax.ws.rs-api.version} + + + org.glassfish.jersey.inject + jersey-hk2 + + + + org.springframework.boot + spring-boot-starter-actuator + + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + io.springfox + springfox-swagger-ui + ${springfox.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.awaitility + awaitility + test + + + io.projectreactor + reactor-test + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.mockito + mockito-junit-jupiter + test + + + org.mockito + mockito-core + test + + + com.squareup.okhttp3 + mockwebserver + test + + + + com.github.erosb + everit-json-schema + 1.13.0 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + false + + + + maven-failsafe-plugin + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-source + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/annotations/ + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + default-prepare-agent + + prepare-agent + + + + default-report + prepare-package + + report + + + + + + io.fabric8 + docker-maven-plugin + ${docker-maven-plugin} + false + + + generate-a1policymanagementservice-image + package + + build + + + ${env.CONTAINER_PULL_REGISTRY} + + + o-ran-sc/nonrtric-plt-a1policymanagementservice:${project.version} + + try + ${basedir} + Dockerfile + + ${project.build.finalName}.jar + + + ${project.version} + + + + + + + + push-a1policymanagementservice-image + + build + push + + + ${env.CONTAINER_PULL_REGISTRY} + ${env.CONTAINER_PUSH_REGISTRY} + + + o-ran-sc/nonrtric-plt-a1policymanagementservice:${project.version} + + ${basedir} + Dockerfile + + ${project.build.finalName}.jar + + + ${project.version} + latest + + + + + + + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + ${sonar-maven-plugin.version} + + + org.codehaus.mojo + exec-maven-plugin + ${exec-maven-plugin.version} + + + git submodule update + initialize + + git + + submodule + update + --init + --recursive + + + + exec + + + + copy configuration + initialize + + cp + + -r + onap/oran/a1-policy-management/config + . + + + + exec + + + + + + + + JIRA + https://jira.o-ran-sc.org/ + + diff --git a/src b/src new file mode 120000 index 0000000..5e0adbf --- /dev/null +++ b/src @@ -0,0 +1 @@ +onap/oran/a1-policy-management/src \ No newline at end of file diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..2705e16 --- /dev/null +++ b/tox.ini @@ -0,0 +1,37 @@ +# ================================================================================== +# Copyright (c) 2020 Nordix +# +# 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. +# ================================================================================== + +# documentation only +[tox] +minversion = 2.0 +envlist = + docs, + docs-linkcheck, +skipsdist = true + +[testenv:docs] +basepython = python3 +deps = -r{toxinidir}/docs/requirements-docs.txt + +commands = + sphinx-build -W -b html -n -d {envtmpdir}/docs/doctrees ./docs/ {toxinidir}/docs/_build/html + echo "Generated docs available in {toxinidir}/docs/_build/html" +whitelist_externals = echo + +[testenv:docs-linkcheck] +basepython = python3 +deps = -r{toxinidir}/docs/requirements-docs.txt +commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck -- 2.16.6