From 6208ce89d7e6a554a8ed0b524104e7dddc833916 Mon Sep 17 00:00:00 2001 From: elinuxhenrik Date: Wed, 18 Nov 2020 15:15:07 +0100 Subject: [PATCH] Update documentation after move to ONAP Change-Id: I056a80485904a0f1e4d9608d03e0ca3cc184344e Issue-ID: NONRTRIC-173 Signed-off-by: elinuxhenrik --- docs/api-docs.rst | 42 +- docs/conf.py | 9 +- docs/developer-guide.rst | 118 +- docs/images/NonRtRicComponents.png | Bin 42655 -> 0 bytes docs/index.rst | 7 +- docs/installation-guide.rst | 71 -- .../offeredapis/swagger/ecs-api.json | 2 +- docs/overview.rst | 58 +- docs/policy-agent-api.rst | 1323 -------------------- docs/sdnc-a1-controller-api.rst | 531 -------- .../org/oransc/enrichment/ApplicationTest.java | 2 +- 11 files changed, 38 insertions(+), 2125 deletions(-) delete mode 100644 docs/images/NonRtRicComponents.png delete mode 100644 docs/installation-guide.rst rename enrichment-coordinator-service/docs/api.json => docs/offeredapis/swagger/ecs-api.json (99%) delete mode 100644 docs/policy-agent-api.rst delete mode 100644 docs/sdnc-a1-controller-api.rst diff --git a/docs/api-docs.rst b/docs/api-docs.rst index 94169403..ed0cc79a 100644 --- a/docs/api-docs.rst +++ b/docs/api-docs.rst @@ -4,6 +4,12 @@ .. _api_docs: +.. |swagger-icon| image:: ./images/swagger.png + :width: 40px + +.. |yaml-icon| image:: ./images/yaml_logo.png + :width: 40px + ======== API-Docs @@ -11,39 +17,31 @@ API-Docs This is the API-docs of Non-RT RIC. -.. contents:: - :depth: 3 - :local: - The Non-RT RIC consists of three parts, described in the sections below: * The Policy Agent - * The SDNC A1 Controller + * The Enrichment Coordinator Service * The rAPP Catalogue Policy Agent ============ -The Policy Agent provides common functionality useful for R-Apps, for instance: - * A repository of available Near-RT RICs, their policy types and policy instances. - * An A1 connection to the Near-RT RICs. - -See :ref:`policy-agent-api` for how to use the API. +For information about the The Policy Agent that is implemented in ONAP, see `readthedocs`_ and `wiki`_. -See the README.md file in the nonrtric/policy-agent repo for info about how to use it. +.. _readthedocs: https://docs.onap.org/projects/onap-ccsdk-oran/en/latest/index.html +.. _wiki: https://wiki.onap.org/pages/viewpage.action?pageId=84644984 -API Functions -------------- -See the following document for the Policy Agent API: nonrtric/onap/oran/docs/offeredapis/swagger/pms-api.yaml +Enrichment Coordinator Service +============================== -SDNC A1 Controller -================== +See `ECS API <./ecs-api.html>`_ for how to use the API. -An ONAP SDNC Controller for the A1 interface. +.. csv-table:: + :header: "API name", "|swagger-icon|" + :widths: 10,5 -See :ref:`sdnc-a1-controller-api` for how to use the API. + "ECS API", ":download:`link <./offeredapis/swagger/ecs-api.json>`" -See the README.md file in the nonrtric/sdnc-a1-controller repo for info about how to use it. rAPP Catalogue ============== @@ -52,12 +50,6 @@ The Non RT-RIC Service Catalogue provides a way for services to register themsel See `RAC API <./rac-api.html>`_ for how to use the API. -.. |swagger-icon| image:: ./images/swagger.png - :width: 40px - -.. |yaml-icon| image:: ./images/yaml_logo.png - :width: 40px - .. csv-table:: :header: "API name", "|swagger-icon|", "|yaml-icon|" diff --git a/docs/conf.py b/docs/conf.py index a6ae7f96..09eeb378 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,7 +8,8 @@ linkcheck_ignore = [ 'http://localhost.*', 'http://127.0.0.1.*', 'https://gerrit.o-ran-sc.org.*', - './rac-api.html' #Generated file that doesn't exist at link check. + './rac-api.html', #Generated file that doesn't exist at link check. + './ecs-api.html' #Generated file that doesn't exist at link check. ] extensions = ['sphinxcontrib.redoc', 'sphinx.ext.intersphinx',] @@ -19,6 +20,12 @@ redoc = [ 'page': 'rac-api', 'spec': '../r-app-catalogue/api/rac-api.json', 'embed': True, + }, + { + 'name': 'ECS API', + 'page': 'ecs-api', + 'spec': './offeredapis/swagger/ecs-api.json', + 'embed': True, } ] diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst index 9aac33c2..576cf2de 100644 --- a/docs/developer-guide.rst +++ b/docs/developer-guide.rst @@ -7,123 +7,21 @@ Developer Guide This document provides a quickstart for developers of the Non-RT RIC. -SDNC A1 Controller -================== - -Prerequisites -------------- - -1. Java development kit (JDK), version 8 -2. Maven dependency-management tool, version 3.6 or later -3. Python, version 2 -4. Docker, version 19.03.1 or latest -5. Docker Compose, version 1.24.1 or latest - -Build and run -------------- -Go to the northbound directory and run this command :: - mvn clean install - -This will build the project and create artifcats in maven repo - -Go to oam/installation directory and run this command :: - mvn clean install -P docker - -This will create the docker images required for A1 controller. - -After this step check for the docker images created by the maven build with this command :: - docker images | grep a1-controller - -Go to oam/installation/src/main/yaml and run this command :: - docker-compose up -d a1-controller - -This will create the docker containers with the A1 controller image, you can check the status of the docker container using :: - docker-compose logs -f a1-controller - -The SDNC url to access the Northbound API, - http://localhost:8282/apidoc/explorer/index.html - -Credentials: admin/Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U - -Configuration of certs ----------------------- -The SDNC-A1 controller uses the default keystore and truststore that are built into the container. - -The paths and passwords for these stores are located in a properties file: - nonrtric/sdnc-a1-controller/oam/installation/src/main/properties/https-props.properties - -The default truststore includes the 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 keystore, truststore, and https-props.properties files can be overridden by mounting new files using the "volumes" field of docker-compose. Uncommment the following lines in docker-compose to do this, and provide paths to the new files: - -:: - -#volumes: -# - :/etc/ssl/certs/java/keystore.jks:ro -# - :/etc/ssl/certs/java/truststore.jks:ro -# - :/opt/onap/sdnc/data/properties/https-props.properties:ro - -The target paths in the container should not be modified. - -For example, assuming that the keystore, truststore, and https-props.properties files are located in the same directory as docker-compose: - -`volumes:` - `- ./new_keystore.jks:/etc/ssl/certs/java/keystore.jks:ro` - - `- ./new_truststore.jks:/etc/ssl/certs/java/truststore.jks:ro` - - `- ./new_https-props.properties:/opt/onap/sdnc/data/properties/https-props.properties:ro` - Policy Agent -============ - -The O-RAN Non-RT RIC Policy Agent 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 can be accessed over the REST API or through the DMaaP Interface. The REST API is documented in the -| *nonrtric/onap/oran/docs/offeredapis/swagger/pms-api.yaml* file. Please refer to the README file of Policy Agent to know more about the API's. +------------ -Configuration of certs ----------------------- -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 Policy Management is implemented in ONAP. For documentation see `readthedocs`_ and `wiki`_. -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 +.. _readthedocs: https://docs.onap.org/projects/onap-ccsdk-oran/en/latest/index.html +.. _wiki: https://wiki.onap.org/pages/viewpage.action?pageId=84644984 -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 +rAPP Catalogue +-------------- -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.1.0-SNAPSHOT` +See the README.md file in the r-app-catalogue folder for how to run the component. End-to-end call -=============== +--------------- In order to make a complete end-to-end call, follow the instructions given in this `guide`_. diff --git a/docs/images/NonRtRicComponents.png b/docs/images/NonRtRicComponents.png deleted file mode 100644 index 335859bcf33f1d0cc55aaf55bc4d80628d9cab4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42655 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 DQRD|( diff --git a/docs/index.rst b/docs/index.rst index 21469e74..a32323df 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -9,12 +9,9 @@ Non-RT RIC :maxdepth: 2 :caption: Contents: - ./api-docs.rst - ./policy-agent-api.rst - ./sdnc-a1-controller-api.rst - ./developer-guide.rst - ./installation-guide.rst ./overview.rst + ./developer-guide.rst + ./api-docs.rst ./use-cases.rst ./release-notes.rst diff --git a/docs/installation-guide.rst b/docs/installation-guide.rst deleted file mode 100644 index 1bcc3c42..00000000 --- a/docs/installation-guide.rst +++ /dev/null @@ -1,71 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 -.. Copyright (C) 2020 Nordix - -Installation Guide -================== - -.. contents:: - :depth: 3 - :local: - -Abstract --------- - -This document describes how to install the Non-RT RIC SDNC A1 Controller, its dependencies and required system resources. - -This work is in progress. Please visit :ref:`api_docs` for more information about the SDNC A1 Controller and the Policy Agent. - -.. _api-docs page: ./api-docs.html - -Installation ------------- - -Download the SDNC repo: - - git clone "https://gerrit.o-ran-sc.org/r/nonrtric" - -The SDNC A1 Controller could be found in this repo. - -Build SDNC project: - - Enter into the sdnc-a1-controller project, northbound and oam project will located there. - - cd sdnc-a1-controller - - Build northbound project with command: - - mvn clean install -Dmaven.test.skip=true - - Build oam project with command: - - mvn clean install -Dmaven.test.skip=true -P docker - - Enter into this directory: - - cd nonrtric/sdnc-a1-controller/oam/installation/src/main/yaml - - and run the command: - - MTU=1500 docker-compose up a1-controller - -Version history ---------------- - -+--------------------+--------------------+--------------------+--------------------+ -| **Date** | **Ver.** | **Author** | **Comment** | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ -| 2019-11-12 | 0.1.0 | Maxime Bonneau | First draft | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ -| 2020-03-24 | 0.1.1 | Maxime Bonneau | Second draft | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ -| | 1.0 | | | -| | | | | -| | | | | -+--------------------+--------------------+--------------------+--------------------+ - - - diff --git a/enrichment-coordinator-service/docs/api.json b/docs/offeredapis/swagger/ecs-api.json similarity index 99% rename from enrichment-coordinator-service/docs/api.json rename to docs/offeredapis/swagger/ecs-api.json index a8df3c7c..740be9b1 100644 --- a/enrichment-coordinator-service/docs/api.json +++ b/docs/offeredapis/swagger/ecs-api.json @@ -508,7 +508,7 @@ "tags": ["A1-EI (enrichment information)"] }} }, - "host": "localhost:41549", + "host": "localhost:38411", "definitions": { "producer_ei_job_request": { "description": "The body of the EI producer callbacks for EI job creation and deletion", diff --git a/docs/overview.rst b/docs/overview.rst index 2c51dbae..7f4d5829 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -3,7 +3,7 @@ .. Copyright (C) 2020 Nordix Requirements for the Non-RT RIC project -========================================== +======================================= Find detailed description of what Non-RT RIC is on this `page`_. @@ -30,59 +30,3 @@ Moreover, there are functional requirements regarding the A1 interface: #. A1 interface shall support communication of enrichment information from Non-RT RIC to Near-RT RIC. #. A1 interface shall support feedback from Near-RT RIC for monitoring AI/ML model performance. #. A1 interface shall support the policy/intents feedback from Near-RT RIC to Non-RT RIC. - -A1 policy procedure -------------------- - -As for A-release, the methods are as follows: - -+---------------------+--------------------------+--------------------------+ -| A1 policy procedure | Single policy method | Multiple policies method | -+---------------------+--------------------------+--------------------------+ -| Create policy | PUT | | -+---------------------+--------------------------+--------------------------+ -| Query policy | GET | GET (sequence of \*) | -+---------------------+--------------------------+--------------------------+ -| Update policy | PUT | | -+---------------------+--------------------------+--------------------------+ -| Delete policy | DELETE | | -+---------------------+--------------------------+--------------------------+ -| Notify policy | POST | POST | -+---------------------+--------------------------+--------------------------+ - -Policy Agent Overview -======================= - -The Policy Agent maintains a transient repository of the following items to support R-Apps: - - * All Near-RT RICs in the network. This information is configured using the ONAP CDS database (which is using the Cloudify Consul database). - * All Policy types for all Near-RT RICs - * All configured Policy instances in the network - -It provides an NBI for the R-Apps (and for the Control Panel) for policy management. This is a REST API. -As an option, policy management can also be done via asynchronous messages through ONAP/Dmaap. -The NBI provides support for an R-APP to locate the correct Near-RT RIC based on identifiers as defined in O1. - -The agent monitors all Near-RT RICs and recovers from data inconsistencies, which may happen when (for instance) an Near-RT RIC restarts. - -The R-Apps can be monitored so that their Policies can be automatically removed when an R-App is stopped/removed. - -On its southbound side the agent can connect to a number of different A1 providers: - - * Directly to the Non-RT RIC: - - - OSC API, which is influenced by the A1 standard - - The Non-RT RIC simulator, which supports the A1 standard with a number of not yet CRs included. - * To an ONAP style controller. - -Amber release Policy Agent architecture ------------------------------------------ - -.. image:: ./images/NonRtRicComponents.png - :scale: 50 % - -Non-RT RIC components: - - #. Policy Agent - #. SDNC A1 Controller - diff --git a/docs/policy-agent-api.rst b/docs/policy-agent-api.rst deleted file mode 100644 index 4b6b870c..00000000 --- a/docs/policy-agent-api.rst +++ /dev/null @@ -1,1323 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 -.. Copyright (C) 2020 Nordix - -.. |nbsp| unicode:: 0xA0 - :trim: - -.. |nbh| unicode:: 0x2011 - :trim: - -.. _policy-agent-api: - -################################ -A1 Policy Management Service API -################################ - - -******************************************* -A1 Policy Management Service - Introduction -******************************************* - -The A1 Policy Management Service ("Policy Agent") is an SMO/NONRTRIC service above the NONRTRIC A1 Adapter/Controller -that provides: - -* Unified REST & DMAAP APIs for managing A1 Policies in all Near |nbh| RT |nbsp| RICs -* Synchronized view of registered "services" (e.g. R-APP, GUI, etc) -* Synchronized view of policy instances for each "service" -* Synchronized view of policy instances in all Near |nbh| RT |nbsp| RICs -* Synchronized view of policy types in all Near |nbh| RT |nbsp| RICs -* Policy Query API (e.g. per Near |nbh| RT |nbsp| RIC, per "service", per policy type) -* An initial interface for unified Near |nbh| RT |nbsp| RIC ID to Near |nbh| RT |nbsp| RIC address mapping. - (Note: may also later act as adapter to A&AI, CMDBs etc. to "find" Near |nbh| RT |nbsp| RICs - TBC) -* An Initial "O1 ManagedElement" mapping database & interface to find appropriate Near |nbh| RT |nbsp| RIC for RAN elements. - (Note: may also later act as adapter to A&AI, RuntimeDB, other CMDBs etc. - TBC) -* Monitors all Near |nbh| RT |nbsp| RICs and recovers from inconsistencies (Note: e.g. Near |nbh| RT |nbsp| RIC restarts) -* Support for different Southbound connectors on a per Near |nbh| RT |nbsp| RIC basis. (Note: e.g. different A1 - versions, different Near |nbh| RT |nbsp| RIC versions, different A1 adapters, different or proprietary A1 - controllers/EMSs) - -*************************************** -A1 Policy Management Service - REST NBI -*************************************** - -This is the north bound API of the A1 Policy Management Service ("Policy Agent"). This API allows *services* to interact -with the Policy Agent using REST. - -By registering with the Policy Agent, the Policy Agent takes responsibility for synchronizing the policies created by -the service in the Near |nbh| RT |nbsp| RICs. This means that if a Near |nbh| RT |nbsp| RIC restarts, the Policy Agent -will try to recreate all the policies residing in the Near |nbh| RT |nbsp| RIC once it is started again. If this is not -possible, it will remove all policies belonging to the Near |nbh| RT |nbsp| RIC. - -The Policy Agent also keeps an updated view of the policy types available, and which Near |nbh| RT |nbsp| RICs that -support which types. Also, the Policy Agent can tell if a Managed Element is managed by a certain -Near |nbh| RT |nbsp| RIC. - -The Policy Agent NBI has five distinct parts, described in the sections below: - -* Service Management -* Policy Types -* Policy Management -* Near-RT RIC Repository -* Health Check - -****************** -Service Management -****************** - -A service can register itself in the Policy Agent. - -By providing a callback URL the service can get notifications from the Policy Agent. - -A service can also register a "*Keep Alive Interval*", in seconds. By doing this the service promises to call the -Policy Agent's "*Keep Alive*" method, or else create or delete policies, more often than the "*Keep Alive Interval*" -measured in seconds. If the service, for some reason, is not able to do this, the Policy Agent will consider that the -service has died or vanished and will then delete all its policies, both in the internal repository and in the -Near |nbh| RT |nbsp| RICs where they were earlier created. **Note!** |nbsp| If the service does not provide a value for -"*Keep Alive Interval*", then the service maintains full responsibility to delete all of its policies when they are no -longer needed. - -/service -~~~~~~~~ - -PUT -+++ - -Register a service. - -Definition -"""""""""" - -**URL path:** - -/service - -**Parameters:** - -None. - -**Body:** (*Required*) - -A JSON object (ServiceRegistrationInfo): :: - - { - "callbackUrl": "string", (An empty string means the service will never get any callbacks.) - "keepAliveIntervalSeconds": 0, (0 means the service will always be considered alive.) - "serviceName": "string" (Required, must be unique.) - } - -**Responses:** - -200: - -Service updated. - -201: - -Service created. - -400: - -The ServiceRegistrationInfo is not accepted. - -Examples -"""""""" - -**Call**: :: - - curl -X PUT "http://localhost:8081/service" -H "Content-Type: application/json" -d '{ - "callbackUrl": "URL", - "keepAliveIntervalSeconds": 0, - "serviceName": "existing" - }' - -**Result**: - -201: :: - - OK - -**Call**: :: - - curl -X PUT "http://localhost:8081/service" -H "Content-Type: application/json" -d "{}" - -**Result**: - -400: :: - - Missing mandatory parameter 'serviceName' - -/services -~~~~~~~~~ - -GET -+++ - -Query service information. - -Definition -"""""""""" - -**URL path:** - -/services?name= - -**Parameters:** - -name: (*Optional*) - -The name of the service. - -**Responses:** - -200: - -Array of JSON objects (ServiceStatus). :: - - { - "callbackUrl": "string", (Callback URL) - "keepAliveIntervalSeconds": 0, (Policy keep alive interval) - "serviceName": "string", (Identity of the service) - "timeSinceLastActivitySeconds": 0 (Time since last invocation by the service) - } - -404: - -Service is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/services?name=existing" - -**Result**: - -200: :: - - [ - { - "serviceName":"existing", - "keepAliveIntervalSeconds":0, - "timeSinceLastActivitySeconds":7224, - "callbackUrl":"URL" - } - ] - -**Call**: :: - - curl -X GET "http://localhost:8081/services?name=nonexistent" - -Result: - -404: :: - - Service not found - -DELETE -++++++ - -Delete a service. - -Definition -"""""""""" - -**URL path:** - -/services?name= - -**Parameters:** - -name: (*Required*) - -The name of the service. - -**Responses:** - -204: - OK - -404: - Service not found. - -Examples -"""""""" - -**Call**: :: - - curl -X DELETE "http://localhost:8081/services?name=existing" - -**Result**: - -204: :: - - OK - -**Call**: :: - - curl -X DELETE "http://localhost:8081/services?name=nonexistent" - -Result: - -404: :: - - Could not find service: nonexistent - -/services/keepalive -~~~~~~~~~~~~~~~~~~~ - -PUT -+++ - -Heart beat from a service. - -Definition -"""""""""" - -**URL path:** - -/services/keepalive?name= - -**Parameters:** - -name: (*Required*) - -The name of the service. - -**Responses:** - -200: - -OK - -404: - -Service is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X PUT "http://localhost:8081/services/keepalive?name=existing" - -**Result**: - -200: :: - - OK - -**Call**: :: - - curl -X PUT "http://localhost:8081/services/keepalive?name=nonexistent" - -**Result**: - -404: :: - - Could not find service: nonexistent - -.. _policy-management: - -************ -Policy Types -************ - -Policies are based on types. The set of available policy types is determined by the set of policy types supported by -Near |nbh| RT |nbsp| RICs. At startup, the Policy Agent queries all Near |nbh| RT |nbsp| RICs for their supported types -and stores them in its internal repository. It then checks this at regular intervals to keep the repository of types up -to date. Policy types cannot be created, updated or deleted using this interface since this must be done via the -Near |nbh| RT |nbsp| RICs. - -A policy type defines a name and a JSON schema that constrains the content of a policy of that type. - -/policy_types -~~~~~~~~~~~~~ - -GET -+++ - -Query policy type names. - -Definition -"""""""""" - -**URL path:** - -/policy_types?ric= - -**Parameters:** - -ric: (*Optional*) - -The name of the Near |nbh| RT |nbsp| RIC to get types for. - -**Responses:** - -200: - - Array of policy type names. - -404: - - Near |nbh| RT |nbsp| RIC is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_types" - -**Result**: - -200: :: - - [ - "STD_PolicyModelUnconstrained_0.2.0", - "Example_QoETarget_1.0.0", - "ERIC_QoSNudging_0.2.0" - ] - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_types?ric=nonexistent" - -**Result**: - -404: :: - - org.oransc.policyagent.exceptions.ServiceException: Could not find ric: nonexistent - -/policy_schema -~~~~~~~~~~~~~~ - -GET -+++ - -Returns one policy type schema definition. - -Definition -"""""""""" - -**URL path:** - -/policy_schema?id= - -**Parameters:** - -id: (*Required*) - -The ID of the policy type to get the definition for. - -**Responses:** - -200: - -Policy schema as JSON schema. - -404: - -Policy type is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_schema?id=STD_PolicyModelUnconstrained_0.2.0" - -**Result**: - -200: :: - - { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "STD_PolicyModelUnconstrained_0.2.0", - "description": "Standard model of a policy with unconstrained scope id combinations", - "type": "object", - "properties": { - "scope": { - "type": "object", - "properties": { - "ueId": {"type": "string"}, - "groupId": {"type": "string"} - }, - "minProperties": 1, - "additionalProperties": false - }, - "qosObjectives": { - "type": "object", - "properties": { - "gfbr": {"type": "number"}, - "mfbr": {"type": "number"} - }, - "additionalProperties": false - }, - "resources": { - "type": "array", - "items": { - "type": "object", - "properties": { - "cellIdList": { - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string" - } - }, - "additionalProperties": false, - "required": ["cellIdList"] - } - } - }, - "minProperties": 1, - "additionalProperties": false, - "required": ["scope"] - } - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_schema?id=nonexistent" - -**Result**: - -404: :: - - org.oransc.policyagent.exceptions.ServiceException: Could not find type: nonexistent - -/policy_schemas -~~~~~~~~~~~~~~~ - -GET -+++ - -Returns policy type schema definitions. - -Definition -"""""""""" - -**URL path:** - -/policy_schemas?ric= - -**Parameters:** - -ric: (*Optional*) - -The name of the Near |nbh| RT |nbsp| RIC to get the definitions for. - -**Responses:** - -200: - -An array of policy schemas as JSON schemas. - -404: - -Near |nbh| RT |nbsp| RIC is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_schemas" - -**Result**: - -200: :: - - [ - { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "STD_PolicyModelUnconstrained_0.2.0", - "description": "Standard model of a policy with unconstrained scope id combinations", - "type": "object", - "properties": { - "scope": { - "type": "object", - . - . - . - } - "additionalProperties": false, - "required": ["scope"] - }, - . - . - . - { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Example_QoETarget_1.0.0", - "description": "Example QoE Target policy type", - "type": "object", - "properties": { - "scope": { - "type": "object", - . - . - . - } - "additionalProperties": false, - "required": ["scope"] - } - } - } - ] - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_schemas?ric=nonexistent" - -**Result**: - -404: :: - - org.oransc.policyagent.exceptions.ServiceException: Could not find ric: nonexistent - -***************** -Policy Management -***************** - -Policies can be queried, created, updated, and deleted. A policy is always created in a specific -Near |nbh| RT |nbsp| RIC. - -A policy is defined by its policy type schema. - -When a policy is created, the Policy Agent stores information about it in its internal repository. At regular intervals, -it then checks with all Near |nbh| RT |nbsp| RICs that this repository is synchronized. If, for some reason, there is an -inconsistency, the Policy Agent will start a synchronization job and try to inconsistency, the Policy Agent will start a -synchronization job and try to reset the Near |nbh| RT |nbsp| RIC to its last-known-good status. If this fails, the -Policy Agent will clear all policies for the specific Near |nbh| RT |nbsp| RIC in the internal repository and set its -state to *UNKNOWN*. This means that no interaction with the Near |nbh| RT |nbsp| RIC is possible until the Policy Agent -has been able to contact it again and re-synchronize its state in the repository. - -Once a service has created a policy, it is the service's responsibility to maintain its life cycle. When a Near |nbh| RT -|nbsp| RIC has been restarted, the Policy Agent will try to recreate policies in the Near |nbh| RT |nbsp| RIC according -to the policies maintained in its local repository. -This means that the service must delete any policies it has created. -A policy may be created as a "transient policy", whereby if this policy "disappears" at any stage it will not be -re-synchronized to the Near |nbh| RT |nbsp| RIC. -For example, this is useful if the policy should not survive a restart of the Near |nbh| RT |nbsp| RIC. -A non-transient policy will continue to be maintained in the Near |nbh| RT |nbsp| RIC until it is explicitly deleted -(or the service that created it fails to update its Keep Alive status). - -There are some exceptions where policy instances are not re-synchronized after a Near |nbh| RT |nbsp| RIC restart or -when some inconsistency is identified: - -- The service has registered a "*Keep Alive Interval*", but the service then fails to update its Keep Alive status. -- The Policy Agent completely fails to synchronize with a Near |nbh| RT |nbsp| RIC, as described above. -- Policies that are marked as transient policies. - -/policies -~~~~~~~~~ - -GET -+++ - -Query policies. - -Definition -"""""""""" - -**URL path:** - -/policies?ric=&service=&type= - -**Parameters:** - -ric: (*Optional*) - -The name of the Near |nbh| RT |nbsp| RIC to get policies for. - -service: (*Optional*) - -The name of the service to get policies for. - -type: (*Optional*) - -The name of the policy type to get policies for. - -**Responses:** - -200: - -Array of JSON objects (PolicyInfo). :: - - { - "id": "string", (Identity of the policy) - "json": "object", (The configuration of the policy) - "lastModified": "string", (Timestamp, last modification time) - "ric": "string", (Identity of the target Near |nbh| RT |nbsp| RIC) - "service": "string", (The name of the service owning the policy) - "type": "string" (Name of the policy type) - } - -404: - Near |nbh| RT |nbsp| RIC or policy type not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/policies?ric=existing" - -**Result**: - -200: :: - - [ - { - "id": "Policy 1", - "json": { - "scope": { - "ueId": "UE 1", - "groupId": "Group 1" - }, - "qosObjectives": { - "gfbr": 1, - "mfbr": 2 - }, - "cellId": "Cell 1" - }, - "lastModified": "Wed, 01 Apr 2020 07:45:45 GMT", - "ric": "existing", - "service": "Service 1", - "type": "STD_PolicyModelUnconstrained_0.2.0" - }, - { - "id": "Policy 2", - "json": { - . - . - . - }, - "lastModified": "Wed, 01 Apr 2020 07:45:45 GMT", - "ric": "existing", - "service": "Service 2", - "type": "Example_QoETarget_1.0.0" - } - ] - -**Call**: :: - - curl -X GET "http://localhost:8081/policies?type=nonexistent" - -**Result**: - -404: :: - - Policy type not found - -/policy -~~~~~~~ - -GET -+++ - -Returns a policy configuration. - -Definition -"""""""""" - -**URL path:** - -/policy?id= - -**Parameters:** - -id: (*Required*) - -The ID of the policy instance. - -**Responses:** - -200: - -JSON object containing policy information. :: - - { - "id": "string", (ID of policy) - "json": "object", (JSON with policy data speified by the type) - "ownerServiceName": "string", (Name of the service that created the policy) - "ric": "string", (Name of the Near |nbh| RT |nbsp| RIC where the policy resides) - "type": "string", (Name of the policy type of the policy) - "lastModified" (Timestamp, last modification time) - } - -404: - -Policy is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/policy?id=Policy 1" - -**Result**: - -200: :: - - { - "id": "Policy 1", - "json": { - "scope": { - "ueId": "UE1 ", - "cellId": "Cell 1" - }, - "qosObjectives": { - "gfbr": 319.5, - "mfbr": 782.75, - "priorityLevel": 268.5, - "pdb": 44.0 - }, - "qoeObjectives": { - "qoeScore": 329.0, - "initialBuffering": 27.75, - "reBuffFreq": 539.0, - "stallRatio": 343.0 - }, - "resources": [] - }, - "ownerServiceName": "Service 1", - "ric": "ric1", - "type": "STD_PolicyModelUnconstrained_0.2.0", - "lastModified": "Wed, 01 Apr 2020 07:45:45 GMT" - } - -**Call**: :: - - curl -X GET "http://localhost:8081/policy?id=nonexistent" - -**Result**: - -404: :: - - Policy is not found - -PUT -+++ - -Create/Update a policy. **Note!** Calls to this method will also trigger "*Keep Alive*" for a service which has a -"*Keep Alive Interval*" registered. - -Definition -"""""""""" - -**URL path:** - -/policy?id=&ric=&service=&type= - -**Parameters:** - -id: (*Required*) - -The ID of the policy instance. - -ric: (*Required*) - -The name of the Near |nbh| RT |nbsp| RIC where the policy will be created. - -service: (*Required*) - -The name of the service creating the policy. - -transient: (*Optional*) - -If the policy is transient or not (boolean defaulted to false). -A policy is transient if it will be forgotten when the service needs to reconnect to the Near |nbh| RT |nbsp| RIC. - -type: (*Optional*) - -The name of the policy type. - -**Body:** (*Required*) - -A JSON object containing the data specified by the type. - -**Responses:** - -200: - -Policy updated. - -201: - -Policy created. - -404: - -Near |nbh| RT |nbsp| RIC or policy type is not found. - -423: - -Near |nbh| RT |nbsp| RIC is not operational. - -Examples -"""""""" - -**Call**: :: - - curl -X PUT "http://localhost:8081/policy?id=Policy%201&ric=ric1&service=Service%201&type=STD_PolicyModelUnconstrained_0.2.0" - -H "Content-Type: application/json" - -d '{ - "scope": { - "ueId": "UE 1", - "cellId": "Cell 1" - }, - "qosObjectives": { - "gfbr": 319.5, - "mfbr": 782.75, - "priorityLevel": 268.5, - "pdb": 44.0 - }, - "qoeObjectives": { - "qoeScore": 329.0, - "initialBuffering": 27.75, - "reBuffFreq": 539.0, - "stallRatio": 343.0 - }, - "resources": [] - }' - -**Result**: - -200 - -DELETE -++++++ - -Deletes a policy. **Note!** Calls to this method will also trigger "*Keep Alive*" for a service which has a -"*Keep Alive Interval*" registered. - -Definition -"""""""""" - -**URL path:** - -/policy?id= - -**Parameters:** - -id: (*Required*) - -The ID of the policy instance. - -**Responses:** - -204: - -Policy deleted. - -404: - -Policy is not found. - -423: - -Near |nbh| RT |nbsp| RIC is not operational. - -Examples -"""""""" - -**Call**: :: - - curl -X DELETE "http://localhost:8081/policy?id=Policy 1" - -**Result**: - -204 - -/policy_ids -~~~~~~~~~~~ - -GET -+++ - -Query policy type IDs. - -Definition -"""""""""" - -**URL path:** - -/policy_ids?ric=&service=&type= - -**Parameters:** - -ric: (*Optional*) - -The name of the Near |nbh| RT |nbsp| RIC to get policies for. - -service: (*Optional*) - -The name of the service to get policies for. - -type: (*Optional*) - -The name of the policy type to get policies for. - -**Responses:** - -200: - -Array of policy type names. - -404: - -RIC or policy type not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_ids" - -**Result**: - -200: :: - - [ - "Policy 1", - "Policy 2", - "Policy 3" - ] - -**Call**: :: - - curl -X GET "http://localhost:8081/policy_ids?ric=nonexistent" - -**Result**: - -404: :: - - Ric not found - -/policy_status -~~~~~~~~~~~~~~ - -GET -+++ - -Returns the status of a policy. - -Definition -"""""""""" - -**URL path:** - -/policy_status?id= - -**Parameters:** - -id: (*Required*) - -The ID of the policy. - -**Responses:** - -200: - -JSON object with policy status. - -404: - -Policy not found. - -********************** -Near-RT RIC Repository -********************** - -The Policy Agent keeps an updated view of the Near |nbh| RT |nbsp| RICs that are available in the system. A service can -find out which Near |nbh| RT |nbsp| RIC that manages a specific element in the network or which -Near |nbh| RT |nbsp| RICs that support a specific policy type. - -/ric -~~~~ - -GET -+++ - -Returns the name of a Near |nbh| RT |nbsp| RIC managing a specific Mananged Element. - -Definition -"""""""""" - -**URL path:** - -/ric?managedElementId= - -**Parameters:** - -managedElementId: (*Required*) - -The ID of the Managed Element. - -**Responses:** - -200: - -Name of the Near |nbh| RT |nbsp| RIC managing the Managed Element. - -404: - -No Near |nbh| RT |nbsp| RIC manages the given Managed Element. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/ric?managedElementId=Node 1" - -**Result**: - -200: :: - - Ric 1 - -**Call**: :: - - curl -X GET "http://localhost:8081/ric?managedElementId=notmanaged" - -**Result**: - -404 - -/rics -~~~~~ - -GET -+++ - -Query Near |nbh| RT |nbsp| RIC information. - -Definition -"""""""""" - -**URL path:** - -/rics?policyType= - -**Parameters:** - -policyType: (*Optional*) - -The name of the policy type. - -**Responses:** - -200: - -Array of JSON objects containing Near |nbh| RT |nbsp| RIC information. :: - - [ - { - "managedElementIds": [ - "string" - ], - "policyTypes": [ - "string" - ], - "ricName": "string", - "state": "string" - } - ] - -404: - -Policy type is not found. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/rics?policyType=STD_PolicyModelUnconstrained_0.2.0" - -**Result**: - -200: :: - - [ - { - "managedElementIds": [ - "ME 1", - "ME 2" - ], - "policyTypes": [ - "STD_PolicyModelUnconstrained_0.2.0", - "Example_QoETarget_1.0.0", - "ERIC_QoSNudging_0.2.0" - ], - "ricName": "Ric 1", - "state": "AVAILABLE" - }, - . - . - . - { - "managedElementIds": [ - "ME 3" - ], - "policyTypes": [ - "STD_PolicyModelUnconstrained_0.2.0" - ], - "ricName": "Ric X", - "state": "UNAVAILABLE" - } - ] - -**Call**: :: - - curl -X GET "http://localhost:8081/rics?policyType=nonexistent" - -**Result**: - -404: :: - - Policy type not found - -************ -Health Check -************ - -The status of the Policy Agent. - -/status -~~~~~~~ - -GET -+++ - -Returns the status of the Policy Agent. - -Definition -"""""""""" - -**URL path:** - -/status - -**Parameters:** - -None. - -**Responses:** - -200: - -Service is living. - -Examples -"""""""" - -**Call**: :: - - curl -X GET "http://localhost:8081/status" - -**Result**: - -200 - -**************** -A1 through DMaaP -**************** - -The Policy Agent also provides the possibility to use DMaap to handle policies according to the A1 specification. The -Policy Agent polls the DMaaP Message Router regularly and processes any messages targeted to it. The response is then -published back to the DMaaP Message Router with the result of the call. - -Send Message -~~~~~~~~~~~~ - -The message to send is a JSON like the one below. The "*url*" is one of the URLs described under -:ref:`policy-management`. The "*target*" must always be "*policy-agent*" for the message to be processed by the Policy -Agent. The "*operation*" can be one of the following: "*GET | PUT | POST | DELETE*". :: - - { - "type": "string", - "correlationId": "string", - "target": "string", - "timestamp": "timestamp", - "apiVersion": "string", - "originatorId": "string", - "requestId": "string", - "operation": "string", - "url": "string" - } - -Example -+++++++ - -To get all policy types for a specific Near |nbh| RT |nbsp| RIC the following message should be sent to DMaaP Message -Router: :: - - { - "type":"request", - "correlationId":"c09ac7d1-de62-0016-2000-e63701125557-201", - "target":"policy-agent", - "timestamp":"2019-05-14T11:44:51.36Z", - "apiVersion":"1.0", - "originatorId":"849e6c6b420", - "requestId":"23343221", - "operation":"GET", - "url":"/policy_schemas?ric=ric_ric-simulator_1" - } - -Receive Message -~~~~~~~~~~~~~~~ - -The message the Policy Agent sends back to the DMaaP Message Router is a JSON like the one below. The "*requestId*" -"*correlationId*", and "*originatorId*" are the same as in the message sent to DMaaP MR. :: - - { - "requestId": "string", - "correlationId": "string", - "originatorId": "string", - "type": "string", - "message": "string", - "type": "string", - "timestamp": "string", - "status": "string" - } - -Example -+++++++ - -The response containing all policy types for a specific Near |nbh| RT |nbsp| RIC sent to the DMaaP Message Router from -the Policy Agent: :: - - { - \"requestId\":\"23343221\", - \"correlationId\":\"c09ac7d1-de62-0016-2000-e63701125557-201\", - \"originatorId\":\"849e6c6b420\", - \"type\":\"response\", - \"message\":\"[ - { - \\\"$schema\\\":\\\"http://json-schema.org/draft-07/schema#\\\", - \\\"description\\\":\\\"QoS policy type\\\", - \\\"title\\\":\\\"STD_QoSNudging_0.2.0\\\", - \\\"type\\\":\\\"object\\\", - \\\"properties\\\":{\\\"scope\\\":{\\\"additionalProperties\\\":true, - \\\"type\\\":\\\"object\\\", - \\\"properties\\\":{\\\"qosId\\\":{\\\"type\\\":\\\"string\\\"}, - \\\"ueId\\\":{\\\"type\\\":\\\"string\\\"}}, - \\\"required\\\":[\\\"ueId\\\", - \\\"qosId\\\"]}, - \\\"statement\\\":{\\\"additionalProperties\\\":false, - \\\"type\\\":\\\"object\\\", - \\\"properties\\\":{\\\"priorityLevel\\\":{\\\"type\\\":\\\"number\\\"}}, - \\\"required\\\":[\\\"priorityLevel\\\"]}} - } - ]\", - \"timestamp\":\"2019-05-14T11:44:51.36Z\", - \"status\":\"200 OK\" - } \ No newline at end of file diff --git a/docs/sdnc-a1-controller-api.rst b/docs/sdnc-a1-controller-api.rst deleted file mode 100644 index 5e0e908b..00000000 --- a/docs/sdnc-a1-controller-api.rst +++ /dev/null @@ -1,531 +0,0 @@ -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. http://creativecommons.org/licenses/by/4.0 -.. Copyright (C) 2020 Nordix - -.. |nbsp| unicode:: 0xA0 - :trim: - -.. |nbh| unicode:: 0x2011 - :trim: - -.. _sdnc-a1-controller-api: - - -###################### -SDNC A1 Controller API -###################### - -The A1 of a Near |nbh| RT |nbsp| RIC can be used through the SDNC A1 Controller. - -The OSC A1 Controller supports using multiple versions of A1 API southbound. By passing the full URL for each southbound -A1 operation the problem of version-specific URL formats is avoided. - -Since different versions of A1 operations may use different data formats for data payloads for similar REST requests and -responses the data formatting requirements are flexible, so version-specific encoding/decoding is handled by the service -that requests the A1 operation. - -Get Policy Type -~~~~~~~~~~~~~~~ - -POST -++++ - -Gets a policy type. - -Definition -"""""""""" - -**URL path:** - -/restconf/operations/A1-ADAPTER-API:getA1PolicyType - -**Parameters:** - -None. - -**Body:** (*Required*) - -A JSON object. :: - - { - "input": { - "near-rt-ric-url": "" - } - } - -**Responses:** - -200: - -A JSON object where the body tag contains the JSON object of the policy type. :: - - { - "output": { - "http-status": "integer", - "body": "{ - - }" - } - } - -Examples -"""""""" - -Get a policy type from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. The STD 1.1.3 version does not -support types, so this function is not available for that version. - -**Call**: :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyType" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11" - } - }' - -**Result**: - -200: :: - - { - "output": { - "http-status": 200, - "body": "{ - \"$schema\": \"http://json-schema.org/draft-07/schema#\", - \"title\": \"Example_QoETarget_1.0.0\", - \"description\": \"Example QoE Target policy type\", - \"type\": \"object\", - \"properties\": { - \"scope\": { - \"type\": \"object\", - \"properties\": { - \"ueId\": { - \"type\": \"string\" - }, - \"sliceId\": { - \"type\": \"string\" - }, - \"qosId\": { - \"type\": \"string\" - }, - \"cellId\": { - \"type\": \"string\" - } - }, - \"additionalProperties\": false, - \"required\": [ - \"ueId\", - \"sliceId\" - ] - }, - \"statement\": { - \"type\": \"object\", - \"properties\": { - \"qoeScore\": { - \"type\": \"number\" - }, - \"initialBuffering\": { - \"type\": \"number\" - }, - \"reBuffFreq\": { - \"type\": \"number\" - }, - \"stallRatio\": { - \"type\": \"number\" - } - }, - \"minProperties\": 1, - \"additionalProperties\": false - } - } - }" - } - } - -Put Policy -~~~~~~~~~~ - -POST -++++ - -Creates or updates a policy instance. - -Definition -"""""""""" - -**URL path:** - -/restconf/operations/A1-ADAPTER-API:putA1Policy - -**Parameters:** - -None. - -**Body:** (*Required*) - -A JSON object where the body tag contains the JSON object of the policy. :: - - { - "input": { - "near-rt-ric-url": "", - "body": "" - } - } - -**Responses:** - -200: - -A JSON object with the response. :: - - { - "output": { - "http-status": "integer" - } - } - -Examples -"""""""" - -**Call**: - -Create a policy in a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:putA1Policy" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000", - "body": "{ - "blocking_rate":20, - "enforce":true, - "trigger_threshold":10, - "window_length":10 - }" - } - }' - -Create a policy in a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. :: - - curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:putA1Policy - -H Content-Type:application/json -d '{ - "input": { - "near-rt-ric-url": "http://ricsim_g2_1:8085/A1-P/v1/policies/5000", - "body": "{ - "scope": { - "ueId": "ue5000", - "qosId": "qos5000" - }, - "qosObjective": { - "priorityLevel": 5000 - } - }" - } - }' - -**Result**: - -The result is the same irrespective of which API that is used. - -200: :: - - { - "output": { - "http-status": 200 - } - } - -Get Policy -~~~~~~~~~~ - -POST -++++ - -Gets a policy instance. - -Definition -"""""""""" - -**URL path:** - -/restconf/operations/A1-ADAPTER-API:getA1Policy - -**Parameters:** - -None. - -**Body:** (*Required*) - -A JSON object. :: - - { - "input": { - "near-rt-ric-url": "" - } - } - -**Responses:** - -200: - A JSON object where the body tag contains the JSON object of the policy. :: - - { - "output": { - "http-status": "integer", - "body": "{ - - }" - } - } - -Examples -"""""""" - -**Call**: - -Get **all** policy IDs from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. :: - - curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy - -H Content-Type:application/json -d '{ - "input": { - "near-rt-ric-url":"http://ricsim_g1_1:8085/a1-p/policytypes/11/policies" - } - }' - -Get **all** policy IDs from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. :: - - curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy - -H Content-Type:application/json -d '{ - "input": { - "near-rt-ric-url":"http://ricsim_g2_1:8085/A1-P/v1/policies" - } - }' - -**Result**: - -The result is the same irrespective of which API that is used. - -200: :: - - { - "output": { - "http-status":200, - "body":"[ - \"5000\", - . - . - . - \"6000\" - ]" - } - } - -**Call**: - -Get **a specific** policy from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000" - } - }' - -Get **a specific** policy from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. :: - - curl -X POST http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1Policy - -H Content-Type:application/json -d '{ - "input": { - "near-rt-ric-url":"http://ricsim_g2_1:8085/A1-P/v1/policies/5000" - } - }' - -**Result**: - -The result is the same irrespective of which API that is used. - -200: :: - - { - "output": { - "http-status": 200, - "body": "{ - \"blocking_rate\": 20, - \"enforce\": true, - \"trigger_threshold\": 10, - \"window_length\": 10 - }" - } - } - -Delete Policy -~~~~~~~~~~~~~ - -POST -++++ - -Deletes a policy instance. - -Definition -"""""""""" - -**URL path:** - -/restconf/operations/A1-ADAPTER-API:deleteA1Policy - -**Parameters:** - -None. - -**Body:** (*Required*) - -A JSON object. :: - - { - "input": { - "near-rt-ric-url": "" - } - } - -**Responses:** - -200: - -A JSON object with the response. :: - - { - "output": { - "http-status": "integer" - } - } - -Examples -"""""""" - -**Call**: - -Delete a policy from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:deleteA1Policy" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000" - } - }' - -Delete a policy from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:deleteA1Policy" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://ricsim_g2_1:8085/A1-P/v1/policies/5000" - } - }' - -**Result**: - -The result is the same irrespective of which API that is used. - -200: :: - - { - "output": { - "http-status": 202 - } - } - -Get Policy Status -~~~~~~~~~~~~~~~~~ - -POST -++++ - -Get the status of a policy instance. - -Definition -"""""""""" - -**URL path:** - -/restconf/operations/A1-ADAPTER-API:getA1PolicyStatus - -**Parameters:** - -None. - -**Body:** (*Required*) - -A JSON object. :: - - { - "input": { - "near-rt-ric-url": "" - } - } - -**Responses:** - -200: - -A JSON object where the body tag contains the JSON object with the policy status according to the API version used. :: - - { - "output": { - "http-status": "integer", - "body": "{ - - }" - } - } - -Examples -"""""""" - -**Call**: - -Get the policy status for a specific policy from a Near |nbh| RT |nbsp| RIC that is using the OSC 2.1.0 version. :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyStatus" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://nearRtRic-sim1:8085/a1-p/policytypes/11/policies/5000/status" - } - }' - -**Result**: - -200: :: - - { - "output": { - "http-status": 200, - "body": "{ - \"instance_status\": \"IN EFFECT\", - \"has_been_deleted\": \"true\", - \"created_at\": \"Wed, 01 Apr 2020 07:45:45 GMT\" - }" - } - } - -**Call**: - -Get the policy status for a specific policy from a Near |nbh| RT |nbsp| RIC that is using the STD 1.1.3 version. :: - - curl -X POST "http://localhost:8282/restconf/operations/A1-ADAPTER-API:getA1PolicyStatus" - -H "Content-Type: application/json" -d '{ - "input": { - "near-rt-ric-url": "http://ricsim_g2_1:8085/A1-P/v1/policies/5000/status" - } - }' - -**Result**: - -200: :: - - { - "output": { - "http-status": 200, - "body": "{ - \"enforceStatus\": \"UNDEFINED\" - }" - } - } diff --git a/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java b/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java index 9ef2590f..88ff8e8e 100644 --- a/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java +++ b/enrichment-coordinator-service/src/test/java/org/oransc/enrichment/ApplicationTest.java @@ -157,7 +157,7 @@ class ApplicationTest { assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK); String indented = (new JSONObject(resp.getBody())).toString(4); - try (PrintStream out = new PrintStream(new FileOutputStream("docs/api.json"))) { + try (PrintStream out = new PrintStream(new FileOutputStream("../docs/offeredapis/swagger/ecs-api.json"))) { out.print(indented); } } -- 2.16.6