From 98f822c2687fc05c6087796f89baacf76f3b370b Mon Sep 17 00:00:00 2001 From: maximesson Date: Wed, 11 Dec 2019 16:53:33 +0100 Subject: [PATCH] New version of NearRT-RIC simulator Change-Id: I9b14b8e6a32974e92a57af994762be064b04b7a7 Issue-ID: NONRTRIC-78 Signed-off-by: maximesson --- near-rt-ric-simulator/.gitignore | 1 + near-rt-ric-simulator/README.md | 3 +- near-rt-ric-simulator/a1-med-api/.gitignore | 1 - near-rt-ric-simulator/a1-med-api/pom.xml | 171 -------- .../src/main/resources/a1_mediator_0.11.0.yaml | 388 ----------------- near-rt-ric-simulator/pom.xml | 8 +- near-rt-ric-simulator/ric-plt/a1/Dockerfile | 21 + near-rt-ric-simulator/ric-plt/a1/a1-openapi.yaml | 466 +++++++++++++++++++++ near-rt-ric-simulator/ric-plt/a1/a1.py | 177 ++++++++ near-rt-ric-simulator/ric-plt/a1/commands.sh | 55 +++ near-rt-ric-simulator/ric-plt/a1/main.py | 89 ++++ .../a1/policy_instance_1_STD_QoSNudging_0.1.0.json | 18 + ...policy_instance_1_bis_STD_QoSNudging_0.1.0.json | 16 + .../a1/policy_instance_2_STD_QoSNudging_0.1.0.json | 17 + .../a1/policy_type_STD_QoSNudging_0.1.0.json | 25 ++ near-rt-ric-simulator/ric-plt/a1/run_me.sh | 10 + .../ric-plt/a1/var_declaration.py | 7 + 17 files changed, 905 insertions(+), 568 deletions(-) mode change 100755 => 100644 near-rt-ric-simulator/.gitignore delete mode 100644 near-rt-ric-simulator/a1-med-api/.gitignore delete mode 100644 near-rt-ric-simulator/a1-med-api/pom.xml delete mode 100644 near-rt-ric-simulator/a1-med-api/src/main/resources/a1_mediator_0.11.0.yaml create mode 100644 near-rt-ric-simulator/ric-plt/a1/Dockerfile create mode 100644 near-rt-ric-simulator/ric-plt/a1/a1-openapi.yaml create mode 100644 near-rt-ric-simulator/ric-plt/a1/a1.py create mode 100755 near-rt-ric-simulator/ric-plt/a1/commands.sh create mode 100644 near-rt-ric-simulator/ric-plt/a1/main.py create mode 100644 near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.1.0.json create mode 100644 near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.1.0.json create mode 100644 near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.1.0.json create mode 100644 near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.1.0.json create mode 100755 near-rt-ric-simulator/ric-plt/a1/run_me.sh create mode 100644 near-rt-ric-simulator/ric-plt/a1/var_declaration.py diff --git a/near-rt-ric-simulator/.gitignore b/near-rt-ric-simulator/.gitignore old mode 100755 new mode 100644 index 264db967..ba53c6e7 --- a/near-rt-ric-simulator/.gitignore +++ b/near-rt-ric-simulator/.gitignore @@ -29,3 +29,4 @@ classes out/ .DS_STORE .metadata +__pycache__ diff --git a/near-rt-ric-simulator/README.md b/near-rt-ric-simulator/README.md index 298b9882..73220dda 100644 --- a/near-rt-ric-simulator/README.md +++ b/near-rt-ric-simulator/README.md @@ -4,8 +4,7 @@ The O-RAN SC Near-RealTime RIC simulates the A1 as an generic REST API which can Please see the documentation in the docs/ folder -The backend server publishes live API documentation at the -URL `http://your-host-name-here:8080/swagger-ui.html` +The backend server publishes live API documentation at the URL `http://your-host-name-here:8080/swagger-ui.html` ## License diff --git a/near-rt-ric-simulator/a1-med-api/.gitignore b/near-rt-ric-simulator/a1-med-api/.gitignore deleted file mode 100644 index b83d2226..00000000 --- a/near-rt-ric-simulator/a1-med-api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target/ diff --git a/near-rt-ric-simulator/a1-med-api/pom.xml b/near-rt-ric-simulator/a1-med-api/pom.xml deleted file mode 100644 index 4030c1c5..00000000 --- a/near-rt-ric-simulator/a1-med-api/pom.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - 4.0.0 - - org.oran.nearric - nearric-simulator - 1.0.0-SNAPSHOT - - - - a1-med-api - ${project.artifactId} - - - UTF-8 - UTF-8 - 1.8.2 - 1.3.6 - org.oransc.ric.a1med.api - - - - javax.annotation - javax.annotation-api - - - io.swagger.core.v3 - swagger-annotations - 2.0.8 - - - io.swagger - swagger-codegen-maven-plugin - 2.4.8 - - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - com.squareup.okhttp - okhttp - 2.7.5 - - - com.squareup.okhttp - logging-interceptor - 2.7.5 - - - io.gsonfire - gson-fire - ${gson-fire-version} - - - org.threeten - threetenbp - ${threetenbp-version} - - - - - - io.swagger.codegen.v3 - swagger-codegen-maven-plugin - 3.0.11 - - - generate-sources-server - generate-sources - - generate - - - ${project.basedir}/src/main/resources/a1_mediator_0.11.0.yaml - java - ${project.basedir}/target/generated-sources/a1med - - ${generated.package.api} - ${generated.package.api}.model - true - true - true - true - true - src/gen/java/main - true - - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - true - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - io.swagger.codegen.v3 - swagger-codegen-maven-plugin - [1.0,) - - generate - - - - - - - - - - - - - - diff --git a/near-rt-ric-simulator/a1-med-api/src/main/resources/a1_mediator_0.11.0.yaml b/near-rt-ric-simulator/a1-med-api/src/main/resources/a1_mediator_0.11.0.yaml deleted file mode 100644 index b8b8f91c..00000000 --- a/near-rt-ric-simulator/a1-med-api/src/main/resources/a1_mediator_0.11.0.yaml +++ /dev/null @@ -1,388 +0,0 @@ -# ================================================================================== -# Copyright (c) 2019 Nokia -# Copyright (c) 2018-2019 AT&T Intellectual Property. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ================================================================================== -openapi: 3.0.0 -info: - version: 0.11.0 - title: RIC A1 -paths: - '/a1-p/healthcheck': - get: - description: > - Perform a healthcheck on a1 - tags: - - A1 Mediator - operationId: a1.controller.get_healthcheck - responses: - 200: - description: > - A1 is healthy. - Anything other than a 200 should be considered a1 as failing - - '/a1-p/policytypes/': - get: - description: "Get a list of all registered policy type ids" - tags: - - A1 Mediator - operationId: a1.controller.get_all_policy_types - responses: - 200: - description: "list of all registered policy type ids" - content: - application/json: - schema: - type: array - items: - "$ref": "#/components/schemas/policy_type_id" - example: [20000, 20020] - - '/a1-p/policytypes/{policy_type_id}': - parameters: - - name: policy_type_id - in: path - required: true - schema: - "$ref": "#/components/schemas/policy_type_id" - get: - description: > - Get this policy type - tags: - - A1 Mediator - operationId: a1.controller.get_policy_type - responses: - '200': - description: "policy type successfully found" - content: - application/json: - schema: - "$ref": "#/components/schemas/policy_type_schema" - '404': - description: > - policy type not found - delete: - description: > - Delete this policy type. Can only be performed if there are no instances of this type - tags: - - A1 Mediator - operationId: a1.controller.delete_policy_type - responses: - '204': - description: > - policy type successfully deleted - '400': - description: > - Policy type cannot be deleted because there are instances - All instances must be removed before a policy type can be deleted - '404': - description: > - policy type not found - put: - description: > - Create a new policy type . - Replace is not currently allowed; to replace, for now do a DELETE and then a PUT again. - - tags: - - A1 Mediator - operationId: a1.controller.create_policy_type - requestBody: - content: - application/json: - schema: - "$ref": "#/components/schemas/policy_type_schema" - example: - name: admission_control_policy - description: various parameters to control admission of dual connection - policy_type_id: 20000 - create_schema: - $schema: 'http://json-schema.org/draft-07/schema#' - type: object - properties: - enforce: - type: boolean - default: true - window_length: - type: integer - default: 1 - minimum: 1 - maximum: 60 - description: Sliding window length (in minutes) - blocking_rate: - type: number - default: 10 - minimum: 1 - maximum: 100 - description: '% Connections to block' - trigger_threshold: - type: integer - default: 10 - minimum: 1 - description: Minimum number of events in window to trigger blocking - additionalProperties: false - - responses: - '201': - description: "policy type successfully created" - '400': - description: "illegal ID, or object already existed" - - '/a1-p/policytypes/{policy_type_id}/policies': - parameters: - - name: policy_type_id - in: path - required: true - schema: - "$ref": "#/components/schemas/policy_type_id" - get: - description: "get a list of all policy instance ids for this policy type id" - tags: - - A1 Mediator - operationId: a1.controller.get_all_instances_for_type - responses: - 200: - description: "list of all policy instance ids for this policy type id" - content: - application/json: - schema: - type: array - items: - "$ref": "#/components/schemas/policy_instance_id" - example: ["3d2157af-6a8f-4a7c-810f-38c2f824bf12", "06911bfc-c127-444a-8eb1-1bffad27cc3d"] - - - '/a1-p/policytypes/{policy_type_id}/policies/{policy_instance_id}': - parameters: - - name: policy_type_id - in: path - required: true - schema: - "$ref": "#/components/schemas/policy_type_id" - - - name: policy_instance_id - in: path - required: true - schema: - "$ref": "#/components/schemas/policy_instance_id" - - get: - description: > - Retrieve the policy instance - - tags: - - A1 Mediator - operationId: a1.controller.get_policy_instance - responses: - '200': - description: > - The policy instance. - the schema of this object is defined by the create_schema field of the policy type - content: - application/json: - schema: - type: object - '404': - description: > - there is no policy instance with this policy_instance_id or there is no policy type with this policy_type_id - - delete: - description: > - Delete this policy instance - - tags: - - A1 Mediator - operationId: a1.controller.delete_policy_instance - responses: - '204': - description: > - policy instance successfully deleted - '404': - description: > - there is no policy instance with this policy_instance_id - or there is no policy type with this policy_type_id - - put: - description: > - Create or replace a policy instance of type policy_type_id. - The schema of the PUT body is defined by the create_schema field of the policy type. - - tags: - - A1 Mediator - operationId: a1.controller.create_or_replace_policy_instance - requestBody: - content: - application/json: - schema: - type: object - description: > - the schema of this object is defined by the create_schema field of the policy type - example: - enforce: true - window_length: 10 - blocking_rate: 20 - trigger_threshold: 10 - - responses: - '201': - description: > - Policy instance created - '400': - description: > - Bad PUT body for this policy instance - '404': - description: > - There is no policy type with this policy_type_id - - '/a1-p/policytypes/{policy_type_id}/policies/{policy_instance_id}/status': - parameters: - - name: policy_type_id - in: path - required: true - schema: - "$ref": "#/components/schemas/policy_type_id" - - - name: policy_instance_id - in: path - required: true - schema: - "$ref": "#/components/schemas/policy_instance_id" - - get: - description: > - Retrieve the policy instance status across all handlers of the policy - - tags: - - A1 Mediator - operationId: a1.controller.get_policy_instance_status - responses: - '200': - description: > - The policy instance status. - Returns a vector of statuses, where each contains a handler_id (opaque id of a RIC component that implements this policy) and the policy status as returned by that handler - content: - application/json: - schema: - type: array - items: - type: object - properties: - handler_id: - type: string - status: - type: string - example: - [{"handler_id": "1234-5678", "status" : "OK"}, {"handler_id": "abc-def", "status" : "NOT IMPLEMENTED"}] - '404': - description: > - there is no policy instance with this policy_instance_id or there is no policy type with this policy_type_id - - -components: - schemas: - policy_type_schema: - type: object - required: - - name - - description - - policy_type_id - - create_schema - additionalProperties: false - properties: - name: - type: string - description: name of the policy type - description: - type: string - description: description of the policy type - policy_type_id: - description: the integer of the policy type - type: integer - create_schema: - type: object - description: > - jsonschema (following http://json-schema.org/draft-07/schema) of the CREATE payload to be sent to handlers of this policy - - policy_type_id: - description: > - represents a policy type identifier. Currently this is restricted to an integer range. - type: integer - minimum: 20000 - maximum: 21024 - - policy_instance_id: - description: > - represents a policy instance identifier. UUIDs are advisable but can be any string - type: string - example: "3d2157af-6a8f-4a7c-810f-38c2f824bf12" - - downstream_message_schema: - type: object - required: - - operation - - policy_type_id - - policy_instance_id - - payload - additionalProperties: false - properties: - operation: - description: the operation being performed - type: string - enum: - - CREATE - - DELETE - - UPDATE - - READ - policy_type_id: - "$ref": "#/components/schemas/policy_type_id" - policy_instance_id: - "$ref": "#/components/schemas/policy_instance_id" - payload: - description: payload for this operation - type: object - example: - operation: CREATE - policy_type_id: 12345678 - policy_instance_id: 3d2157af-6a8f-4a7c-810f-38c2f824bf12 - payload: - enforce: true - window_length: 10 - blocking_rate: 20 - trigger_threshold: 10 - - downstream_notification_schema: - type: object - required: - - policy_type_id - - policy_instance_id - - handler_id - - status - additionalProperties: false - properties: - policy_type_id: - "$ref": "#/components/schemas/policy_type_id" - policy_instance_id: - "$ref": "#/components/schemas/policy_instance_id" - handler_id: - description: > - id of the policy handler - type: string - status: - description: > - the status of this policy instance in this handler - type: string - example: - policy_type_id: 12345678 - policy_instance_id: 3d2157af-6a8f-4a7c-810f-38c2f824bf12 - handler_id: 1234-5678 - status: OK diff --git a/near-rt-ric-simulator/pom.xml b/near-rt-ric-simulator/pom.xml index ce73b7ac..217fcc9f 100644 --- a/near-rt-ric-simulator/pom.xml +++ b/near-rt-ric-simulator/pom.xml @@ -18,6 +18,7 @@ SPDX-License-Identifier: Apache-2.0 ============LICENSE_END========================================================= --> + @@ -74,9 +75,4 @@ - - - a1-med-api - nearric-service - - \ No newline at end of file + diff --git a/near-rt-ric-simulator/ric-plt/a1/Dockerfile b/near-rt-ric-simulator/ric-plt/a1/Dockerfile new file mode 100644 index 00000000..db06a210 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/Dockerfile @@ -0,0 +1,21 @@ +FROM python:3 + +WORKDIR /usr/src/app + +RUN pip install connexion[swagger-ui] + +COPY policy_instance_1_STD_QoSNudging_0.1.0.json policy_instance_1_STD_QoSNudging_0.1.0.json +COPY policy_instance_1_bis_STD_QoSNudging_0.1.0.json policy_instance_1_bis_STD_QoSNudging_0.1.0.json +COPY policy_instance_2_STD_QoSNudging_0.1.0.json policy_instance_2_STD_QoSNudging_0.1.0.json +COPY policy_type_STD_QoSNudging_0.1.0.json policy_type_STD_QoSNudging_0.1.0.json + +COPY a1.py a1.py +COPY main.py main.py +COPY var_declaration.py var_declaration.py + +COPY commands.sh commands.sh +COPY run_me.sh run_me.sh + +COPY a1-openapi.yaml a1-openapi.yaml + +CMD ["/bin/bash", "./run_me.sh"] diff --git a/near-rt-ric-simulator/ric-plt/a1/a1-openapi.yaml b/near-rt-ric-simulator/ric-plt/a1/a1-openapi.yaml new file mode 100644 index 00000000..c98d2b02 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/a1-openapi.yaml @@ -0,0 +1,466 @@ +openapi: 3.0.0 +info: + title: 'A1-P Policy Management Service' + version: 1.1.x + description: | + API for Policy Management Service. + © 2019, O-RAN Alliance. + All rights reserved. +externalDocs: + description: 'ORAN-WG2.A1.AP-v01.01 A1 interface: Application protocol' + url: 'https://www.o-ran.org/specifications' +servers: + - url: '{apiRoot}/A1-P/v1' + variables: + apiRoot: + default: 'https://example.com' + description: 'apiRoot as defined in clause 4.2.1 in ORAN-WG2.A1.AP' +paths: + '/policies': + get: + operationId: a1.get_all_policies + description: 'Get all policies including their enforcement status' + tags: + - All Policy Objects + responses: + 200: + description: 'Array of all policies and their enforcement status' + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/PolicyObject" + minItems: 0 + + '/policies/identities': + get: + operationId: a1.get_all_policy_identities + description: 'Get all policy identities' + tags: + - All Policy Identities + responses: + 200: + description: 'Array of all policy identities' + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/PolicyId" + minItems: 0 + + '/policies/status': + get: + operationId: a1.get_all_policy_status + description: 'Get enforcement status for all policy instances' + tags: + - All Policy Status Objects + responses: + 200: + description: 'Array of all policy identities and their related enforcement status' + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/PolicyStatusObject" + minItems: 0 + + '/policies/{policyId}': + parameters: + - name: policyId + in: path + required: true + schema: + "$ref": "#/components/schemas/PolicyId" + put: + operationId: a1.put_policy + description: 'Create, or update, a policy' + tags: + - Individual Policy Object + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyObject" + responses: + 200: + description: 'The policy was updated' + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyObject" + 201: + description: 'The policy was created' + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyObject" + headers: + Location: + description: 'Contains the URI of the created policy' + required: true + schema: + type: string + 400: + "$ref": "#/components/responses/400-BadRequest" + callbacks: + policyNotification: + '$request.body#/notificationDestination': + post: + description: 'Notify about enforcement status changes for this policy' + requestBody: + required: true + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyStatusObject" + responses: + 204: + description: 'Notification received' + get: + operationId: a1.get_policy + description: 'Query single policy' + tags: + - Individual Policy Object + responses: + 200: + description: 'The requested policy' + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyObject" + 404: + "$ref": "#/components/responses/404-NotFound" + delete: + operationId: a1.delete_policy + description: 'Delete policy' + tags: + - Individual Policy Object + responses: + 204: + description: 'The policy was deleted' + 404: + "$ref": "#/components/responses/404-NotFound" + + '/policies/{policyId}/status': + parameters: + - name: policyId + in: path + required: true + schema: + "$ref": "#/components/schemas/PolicyId" + get: + operationId: a1.get_policy_status + description: 'Get the enforcement status of a policy' + tags: + - Individual Policy Status Object + responses: + 200: + description: 'The requested enforcement status' + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyStatusObject" + 404: + "$ref": "#/components/responses/404-NotFound" + + '/policytypes': + get: + operationId: a1.get_all_policytypes + description: 'Get all policy type schemas' + tags: + - All Policy Types + responses: + 200: + description: 'Array of all policy type schemas' + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/PolicyTypeSchema" + minItems: 0 + + '/policytypes/identities': + get: + operationId: a1.get_all_policytypes_identities + description: 'Get all policy type identities' + tags: + - All Policy Type Identities + responses: + 200: + description: 'Array of all policy type identities' + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/PolicyTypeId" + minItems: 0 + + '/policytypes/{policyTypeId}': + parameters: + - name: policyTypeId + in: path + required: true + schema: + "$ref": "#/components/schemas/PolicyTypeId" + get: + operationId: a1.get_policytypes + description: 'Get the schema for a policy type' + tags: + - Individual Policy Type + responses: + 200: + description: 'The policy type schema' + content: + application/json: + schema: + "$ref": "#/components/schemas/PolicyTypeSchema" + 404: + "$ref": "#/components/responses/404-NotFound" + + '/policytypes/subscription': + put: + operationId: a1.put_policytypes_subscription + description: 'Subscribe to notification when any change is made to supported policy types' + tags: + - Policy Types Subscription Object + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/SubscriptionObject" + responses: + 200: + description: 'The subscription was updated' + 201: + description: 'The subscription was created' + callbacks: + policyTypesNotification: + '$request.body#/notificationDestination': + post: + description: 'Notify about any change in supported policy types' + responses: + 204: + description: 'Notification received' + get: + operationId: a1.get_policytypes_subscription + description: 'Get current notification destination' + tags: + - Policy Types Subscription Object + responses: + 200: + description: 'The current notification destination' + content: + application/json: + schema: + "$ref": "#/components/schemas/SubscriptionObject" + 404: + "$ref": "#/components/responses/404-NotFound" + +components: + schemas: + # + # Representation objects + # + PolicyStatusObject: + type: object + properties: + policyId: + "$ref": "#/components/schemas/PolicyId" + enforceStatus: + "$ref": "#/components/schemas/EnforcementStatusType" + enforceReason: + "$ref": "#/components/schemas/EnforcementReasonType" + required: + - policyId + - enforceStatus + + PolicyObject: + description: 'A policy object, including its identification, type information, its notification destination, and optionally its enforcement status.' + type: object + properties: + policyId: + "$ref": "#/components/schemas/PolicyId" + policyTypeId: + "$ref": "#/components/schemas/PolicyTypeId" + policyClause: + "$ref": "#/components/schemas/PolicyClause" + notificationDestination: + "$ref": "#/components/schemas/NotificationDestination" + enforceStatus: + "$ref": "#/components/schemas/EnforcementStatusType" + required: + - policyId + - policyTypeId + - policyClause + - notificationDestination + + PolicyTypeSchema: + description: 'The JSON Schema for a policy type. All policies of a policy type shall validate against this schema.' + type: object + properties: + description: + type: string + properties: + type: object + title: + type: string + type: + type: string + required: + - description + - properties + - title + - type + + ProblemDetails: + description: 'A problem detail to carry details in a HTTP response according to RFC 7807 extended with A1 specific attributes' + type: object + properties: + type: + type: string + title: + type: string + status: + type: number + detail: + type: string + instance: + type: string + policyErrorCode: + "$ref": "#/components/schemas/PolicyErrorType" + invalidParams: + type: array + items: + "$ref": "#/components/schemas/InvalidParam" + minItems: 1 + + SubscriptionObject: + description: 'A subscription object used for specifying the destination where to send notifications.' + type: object + properties: + notificationDestination: + "$ref": "#/components/schemas/NotificationDestination" + required: + - notificationDestination + + # + # Structured data types + # + InvalidParam: + description: 'Used in a ProblemDetails to indicate a specific invalid parameter' + type: object + properties: + param: + type: string + reason: + type: string + required: + - param + + PolicyClause: + description: 'The schema for a generic policy clause that shall be valid for all different specific policy types.' + type: object + properties: + scope: + "$ref": "#/components/schemas/ScopeIdentifier" + statement: + description: 'The statement for a specific policy type. The schema is specified by a specific policy type.' + type: object + required: + - scope + - statement + + ScopeIdentifier: + description: 'The schema for a generic scope identifier that shall be valid for all different specific policy types.' + type: object + properties: + ueId: + description: 'UE identifier based on RAN UE Id' + type: string + groupId: + description: 'Identifier of a pre-defined group of UEs, SPID' + type: string + sliceId: + description: 'Network slice identifie, NSSAI' + type: string + qosId: + description: 'QoS identifer, 5QI' + type: string + cellId: + description: 'Network resource identifier for a cell' + type: string + + # + # Simple data types + # + PolicyId: + description: 'Policy identifier assigned by the A1-P Consumer when a policy is created' + type: string + + PolicyTypeId: + description: 'Policy type identifier assigned by the A1-P Provider' + pattern: "^(STD|EXT)_[a-zA-Z]+_(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$" + type: string + + NotificationDestination: + description: 'A complete URI defined according to IETF RFC 3986 where to send notifications' + type: string + nullable: true + + # + # Enumerations + # + EnforcementStatusType: + description: 'Indicating if a policy is being enforced or not' + type: string + enum: + - "ENFORCED" + - "NOT_ENFORCED" + - "UNDEFINED" + + EnforcementReasonType: + description: 'Indicating the reason why a policy is not being enforced' + anyOf: + - type: string + enum: + - "100" + - "200" + - "300" + - "800" + - type: string + + PolicyErrorType: + description: 'Represents information that can be provided in addition to the HTTP response error code. Corresponds to the "cause" attribute defined in 3GPP specification 29.501.' + anyOf: + - type: string + enum: + - "CONF_POLICY_ID" + - "BAD_REQ_MISSING_PARAM" + - type: string + + responses: + 400-BadRequest: + description: 'Object in payload not properly formulated or not related to the method' + content: + application/problem+json: + schema: + "$ref": "#/components/schemas/ProblemDetails" + + 404-NotFound: + description: 'No resource found at the URI' + content: + application/problem+json: + schema: + "$ref": "#/components/schemas/ProblemDetails" + + 405-MethodNotAllowed: + description: 'Method not allowed for the URI' + content: + application/problem+json: + schema: + "$ref": "#/components/schemas/ProblemDetails" diff --git a/near-rt-ric-simulator/ric-plt/a1/a1.py b/near-rt-ric-simulator/ric-plt/a1/a1.py new file mode 100644 index 00000000..1b1225b4 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/a1.py @@ -0,0 +1,177 @@ +#!/u:sr/bin/env python3 +import copy +import datetime +import json +import logging +import requests + +from connexion import NoContent +from flask import Flask, escape, request +from jsonschema import validate +from random import random, choice +from var_declaration import policy_instances, policy_types, policy_status, notification_destination, notificationDestination + +def get_all_policies(): + all_p = copy.deepcopy(policy_instances) + all_policies = [] + for i in all_p.keys(): + all_p[i]["enforceStatus"] = policy_status[i]["enforceStatus"] + all_policies.insert(len(all_policies)-1, all_p[i]) + return(all_policies, 200) + +def put_policy(policyId): + data = request.data.decode("utf-8") + data = data.replace("'", "\"") + data = json.loads(data) + ps = {} + + if data["policyTypeId"] not in list(policy_types.keys()): + return(set_error(None, "The policy type provided does not exist.", 404, "The policy type " + data["policyTypeId"] + " is not defined as a policy type.", None, "policyTypeId", None)) + + pt = data["policyTypeId"] + schema = policy_types[pt] + try: + validate(instance=data["policyClause"], schema=schema) + except: + return(set_error(None, "The json does not validate against the schema.", 400, None, None, None, None)) + + if data["policyId"] in list(policy_instances.keys()): + if data["policyClause"]["scope"] != policy_instances[data["policyId"]]["policyClause"]["scope"]: + return(set_error(None, "The policy already exists with a different scope.", 404, "The policy put involves a modification of the existing scope, which is not allowed.", None, "scope", None)) + + if data["policyId"] != policyId: + return(set_error(None, "Wrong policy identity.", 400, "The policy instance's identity does not match with the one specified in the address.", None, "policyId", "The policy identity " + data["policyId"] + " is different from the address: " + policyId)) + + for i in list(policy_instances.keys()): + if data["policyId"] != i and \ + data["policyClause"] == policy_instances[i]["policyClause"] and \ + data["policyTypeId"] == policy_instances[i]["policyTypeId"] and \ + data["notificationDestination"] == policy_instances[i]["notificationDestination"]: + return(set_error(None, "The policy already exists with a different id.", 404, "No action has been taken. The id of the existing policy instance is: " + i + ".", None, None, None)) + + if policyId in policy_instances.keys(): + code = 201 + else: + code = 200 + policy_instances[policyId] = data + policy_status[policyId] = set_status("UNDEFINED") + notification_destination[policyId] = data["notificationDestination"] + return(policy_instances[policyId], code) + +def set_status(*args): + ps = {} + if len(args) == 0: + rand_status = randomise_status() + ps["policyId"] = policyId + ps["enforceStatus"] = rand_status + if rand_status == "NOT_ENFORCED": + rand_reason = randomise_reason() + ps["enforceReason"] = rand_reason + if args[0] in ["UNDEFINED", "ENFORCED", "NOT_ENFORCED"]: + ps["enforceStatus"] = args[0] + else: + return(set_error(None, "Wrong enforceStatus.", 400, None, None, "enforceStatus", "enforceStatus should be one of \"UNDEFINED\", \"ENFORCED\" or \"NOT_ENFORCED\"")) + if args[0] == "NOT_ENFORCED": + if args[1] in ["100", "200", "300", "800"]: + ps["enforceReason"] = args[1] + else: + return(set_error(None, "Wrong enforceReason.", 400, None, None, "enforceReason", "enforceReason should be one of \"100\", \"200\", \"300\" or \"800\"")) + return ps + +def get_policy(policyId): + if policyId in policy_instances.keys(): + res = policy_instances[policyId] + res["enforceStatus"] = policy_status[policyId]["enforceStatus"] + return(res, 200) + else: + return(set_error(None, "The requested policy does not exist.", 404, None, None, "policyId", None)) + +def delete_policy(policyId): + if policyId in policy_instances.keys(): + policy_instances.pop(policyId) + policy_status.pop(policyId) + return(None, 204) + else: + return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, "policyId", None)) + +def get_all_policy_identities(): + return(list(policy_instances.keys()), 200) + +def randomise_status(): + x = random() + if x > 0.5001: + res = "ENFORCED" + elif x < 0.4999: + res = "NOT_ENFORCED" + else: + res = "UNDEFINED" + return res + +def randomise_reason(): + options = ["100", "200", "300", "800"] + return choice(options) + +def get_all_policy_status(): + all_s = copy.deepcopy(policy_status) + all_status = [] + for i in all_s.keys(): + all_s[i]["policyId"] = i + all_status.insert(len(all_status)-1, all_s[i]) + return(all_status, 200) + +def get_policy_status(policyId): + return(policy_status[policyId], 200) + +def get_all_policytypes(): + all_policytypes = [] + for i in policy_types.keys(): + all_policytypes.insert(len(all_policytypes)-1, policy_types[i]) + return(all_policytypes, 200) + +def get_all_policytypes_identities(): + return(list(policy_types.keys()), 200) + +def get_policytypes(policyTypeId): + if policyTypeId in policy_types.keys(): + return(policy_types[policyTypeId], 200) + else: + return(set_error(None, "The requested policy type does not exist.", 404, None, None, "policyTypeId", None)) + +def put_policytypes_subscription(): + global notificationDestination + data = request.data.decode("utf-8") + data = data.replace("'", "\"") + data = json.loads(data) + if not notificationDestination: + notificationDestination["notificationDestionation"] = data + return(None, 201) + else: + notificationDestination["notificationDestionation"] = data + return(None, 200) + +def get_policytypes_subscription(): + if not notificationDestination: + return(set_error(None, "The notification destination has not been defined.", 404, None, None, "notificationDestination", None)) + else: + return(notificationDestination["notificationDestionation"], 200) + +def set_error(type_of, title, status, detail, instance, param, reason): + error = {} + params = {} + if type_of is not None: + error["type"] = type_of + if title is not None: + error["title"] = title + if status is not None: + error["status"] = status + if detail is not None: + error["detail"] = detail + if instance is not None: + error["instance"] = instance + if param is not None: + params["param"] = param + if reason is not None: + params["reason"] = reason + if params: + error["invalidParams"] = params + return(error, error["status"]) diff --git a/near-rt-ric-simulator/ric-plt/a1/commands.sh b/near-rt-ric-simulator/ric-plt/a1/commands.sh new file mode 100755 index 00000000..f2f8bb58 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/commands.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Different commands for the simulator. +# By running this, nothing should return an error. + +# Make a test +curl -v "http://localhost:8085/" + +# PUT a policy type STD_QoSNudging_0.1.0 +curl -X PUT -v "http://localhost:8085/policytypes/STD_QoSNudging_0.1.0" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_type_STD_QoSNudging_0.1.0.json.json + +# GET policy types +curl -v "http://localhost:8085/A1-P/v1/policytypes" + +# GET policy type identities +curl -v "http://localhost:8085/A1-P/v1/policytypes/identities" + +# GET policy type STD_QoSNudging_0.1.0 +curl -v "http://localhost:8085/A1-P/v1/policytypes/STD_QoSNudging_0.1.0" + +# PUT a policy instance pi1 +curl -X PUT -v "http://localhost:8085/A1-P/v1/policies/pi1" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_instance_1_STD_QoSNudging_0.1.0.json + +# PUT a policy instance pi2 +curl -X PUT -v "http://localhost:8085/A1-P/v1/policies/pi2" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_instance_2_STD_QoSNudging_0.1.0.json + +# SET status for pi1 and pi2 +curl -X PUT "http://localhost:8085/pi1/NOT_ENFORCED/300" +curl -X PUT "http://localhost:8085/pi2/ENFORCED" + +# GET policy status +curl -v "http://localhost:8085/A1-P/v1/policies/status" + +# GET policies +curl -v "http://localhost:8085/A1-P/v1/policies" + +# GET policy identities +curl -v "http://localhost:8085/A1-P/v1/policies/identities" + +# DELETE policy instance pi2 +curl -X DELETE -v "http://localhost:8085/A1-P/v1/policies/pi2" + +# PUT a different policy instance pi1 (i.e. update it) +curl -X PUT -v "http://localhost:8085/A1-P/v1/policies/pi1" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_instance_1_bis_STD_QoSNudging_0.1.0.json + +# GET policy instance pi1 +curl -v "http://localhost:8085/A1-P/v1/policies/pi1" + +# GET policy status for pi1 +curl -v "http://localhost:8085/A1-P/v1/policies/pi1/status" + +# PUT policy type subscription +curl -X PUT -v "http://localhost:8085/A1-P/v1/policytypes/subscription" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"notificationDestination\": \"http://localhost:8085/subscription/address\"}" + +# GET policy type subscription +curl -v "http://localhost:8085/A1-P/v1/policytypes/subscription" diff --git a/near-rt-ric-simulator/ric-plt/a1/main.py b/near-rt-ric-simulator/ric-plt/a1/main.py new file mode 100644 index 00000000..e1f2d565 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/main.py @@ -0,0 +1,89 @@ +import connexion +import fileinput +import json +import sys + +from flask import Flask, escape, request, make_response +from var_declaration import policy_instances, policy_types, policy_status + +app = connexion.App(__name__, specification_dir='.') + +@app.route('/policytypes/', methods=['PUT','DELETE']) +def policy_type(policyTypeId): + if request.method == 'PUT': + data = request.data.decode("utf-8") + data = data.replace("'", "\"") + data = json.loads(data) + policy_types[policyTypeId] = data + return ('The policy type was either created or updated for policy type id: ' + policyTypeId) + elif request.method == 'DELETE': + if policyTypeId in policy_types.keys(): + policy_types.pop(policyTypeId) + return make_response("policy type successfully deleted for policy type id: " + policyTypeId, 200) + else: + return make_response("No policy type defined for the specified id", 404) + +@app.route('/', methods=['GET']) +def test(): + if "STD_QoSNud_0.1.0" in policy_types.keys(): + return("Something fishy!", 200) + else: + return(str(list(policy_types.keys())), 200) + +@app.route('/deleteinstances', methods=['DELETE']) +def delete_instances(): + global policy_instances + global policy_status + policy_instances.clear() + policy_status.clear() + return("All policy instances deleted", 200) + +@app.route('/deletetypes', methods=['DELETE']) +def delete_types(): + global policy_types + policy_types.clear() + return("All policy types deleted", 200) + +@app.route('//', methods=['PUT']) +def set_status(policyId, enforceStatus): + if policyId in policy_instances.keys(): + if enforceStatus in ["UNDEFINED", "ENFORCED", "NOT_ENFORCED"]: + policy_status.pop(policyId) + ps = {} + ps["policyId"] = policyId + ps["enforceStatus"] = enforceStatus + policy_status[policyId] = ps + return("Status updated for policy: " + policyId, 200) + else: + return("enforceStatus should be one of \"UNDEFINED\", \"ENFORCED\" or \"NOT_ENFORCED\"", 400) + else: + return("The policy id does not correspond to any existing policy instance", 400) + +@app.route('///', methods=['PUT']) +def set_status_with_reason(policyId, enforceStatus, enforceReason): + if policyId in policy_instances.keys(): + if enforceStatus == "NOT_ENFORCED": + if enforceReason in ["100", "200", "300", "800"]: + policy_status.pop(policyId) + ps = {} + ps["policyId"] = policyId + ps["enforceStatus"] = enforceStatus + ps["enforceReason"] = enforceReason + policy_status[policyId] = ps + return("Status updated for policy: " + policyId, 200) + else: + return("enforceReason should be one of \"100\", \"200\", \"300\" or \"800\"", 400) + else: + return("A status provided together with an enforcement reason should be \"NOT_ENFORCED\"", 400) + else: + return("The policy id does not correspond to any existing policy instance", 404) + + +port_number = 8085 +if len(sys.argv) >= 2: + if isinstance(sys.argv[1], int): + port_number = sys.argv[1] + +app.add_api('a1-openapi.yaml') +app.run(port=port_number) + diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.1.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.1.0.json new file mode 100644 index 00000000..8d1cdd68 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.1.0.json @@ -0,0 +1,18 @@ +{ + "policyId": "pi1", + "policyTypeId": "STD_QoSNudging_0.1.0", + "policyClause": { + "scope": { + "ueId": "ue1", + "groupId": "group1", + "sliceId": "slice1", + "qosId": "qos1", + "cellId": "cell1" + }, + "statement": { + "priorityLevel": 5 + } + }, + "notificationDestination": "http://localhost:8085/policynotifications" +} + diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.1.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.1.0.json new file mode 100644 index 00000000..f43ca1a0 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.1.0.json @@ -0,0 +1,16 @@ +{ + "policyId": "pi1", + "policyTypeId": "STD_QoSNudging_0.1.0", + "policyClause": { + "scope": { + "ueId": "ue1", + "groupId": "group1", + "sliceId": "slice1", + "qosId": "qos1", + "cellId": "cell1"}, + "statement": { + "priorityLevel": 4 + } + }, + "notificationDestination": "http://localhost:8085/policynotifications" +} diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.1.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.1.0.json new file mode 100644 index 00000000..6890d050 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.1.0.json @@ -0,0 +1,17 @@ +{ + "policyId": "pi2", + "policyTypeId": "STD_QoSNudging_0.1.0", + "policyClause": { + "scope": { + "ueId": "ue2", + "groupId": "group2", + "sliceId": "slice2", + "qosId": "qos2", + "cellId": "cell2" + }, + "statement": { + "priorityLevel": 5 + } + }, + "notificationDestination": "http://localhost:8085/policynotifications" +} diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.1.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.1.0.json new file mode 100644 index 00000000..8be17bb9 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.1.0.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "STD_QoSNudging_0.1.0", + "description": "QoS policy type with ueId and qosId scope, version 0.1.0", + "type": "object", + "properties": { + "scope": { + "type": "object", + "properties": { + "ueId": {"type": "string"}, + "qosId": {"type": "string"} + }, + "additionalProperties": false, + "required": ["ueId", "qosId"] + }, + "statement": { + "type": "object", + "properties": { + "priorityLevel": {"type": "number"} + }, + "additionalProperties": false, + "required": ["priorityLevel"] + } + } +} diff --git a/near-rt-ric-simulator/ric-plt/a1/run_me.sh b/near-rt-ric-simulator/ric-plt/a1/run_me.sh new file mode 100755 index 00000000..9052ecf3 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/run_me.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# One argument can be used along with the script call: it is the port on which one wish to run the simulator. + +if [ $# -eq 0 ] +then + python3 ./main.py +else + python3 ./main.py $1 +fi diff --git a/near-rt-ric-simulator/ric-plt/a1/var_declaration.py b/near-rt-ric-simulator/ric-plt/a1/var_declaration.py new file mode 100644 index 00000000..c0dbac44 --- /dev/null +++ b/near-rt-ric-simulator/ric-plt/a1/var_declaration.py @@ -0,0 +1,7 @@ +#!/u:sr/bin/env python3 + +policy_instances = {} +policy_types = {} +policy_status = {} +notification_destination = {} +notificationDestination = {} -- 2.16.6