Simulator new (basic) version) 49/2349/5
authormaximesson <maxime.bonneau@est.tech>
Mon, 27 Jan 2020 17:05:04 +0000 (18:05 +0100)
committermaximesson <maxime.bonneau@est.tech>
Thu, 30 Jan 2020 15:02:33 +0000 (16:02 +0100)
Change-Id: Ib3a9cb4a94ce27143e4e9f7f87fac71c75127a48
Issue-ID: NONRTRIC-78
Signed-off-by: maximesson <maxime.bonneau@est.tech>
near-rt-ric-simulator/ric-plt/a1/a1-openapi.yaml
near-rt-ric-simulator/ric-plt/a1/a1.py
near-rt-ric-simulator/ric-plt/a1/commands.sh
near-rt-ric-simulator/ric-plt/a1/main.py
near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.2.0.json [new file with mode: 0644]
near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.2.0.json [new file with mode: 0644]
near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.2.0.json [new file with mode: 0644]
near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.2.0.json [new file with mode: 0644]
near-rt-ric-simulator/ric-plt/a1/var_declaration.py

index c98d2b0..223d1bd 100644 (file)
@@ -1,7 +1,7 @@
 openapi: 3.0.0
 info:
   title: 'A1-P Policy Management Service'
-  version: 1.1.x
+  version: 1.1.x-alpha.2
   description: |
     API for Policy Management Service.
     © 2019, O-RAN Alliance.
@@ -17,28 +17,17 @@ servers:
         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
+      parameters:
+        - name: policyTypeId
+          in: query
+          required: false
+          schema:
+            "$ref": "#/components/schemas/PolicyTypeId"
       responses:
         200:
           description: 'Array of all policy identities'
@@ -49,23 +38,10 @@ paths:
                 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
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
 
   '/policies/{policyId}':
     parameters:
@@ -79,6 +55,12 @@ paths:
       description: 'Create, or update, a policy'
       tags:
       - Individual Policy Object
+      parameters:
+        - name: policyTypeId
+          in: query
+          required: false
+          schema:
+            "$ref": "#/components/schemas/PolicyTypeId"
       requestBody:
         content:
           application/json:
@@ -105,23 +87,15 @@ paths:
                 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'
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
+        507:
+          "$ref": "#/components/responses/507-InsufficientStorage"
     get:
       operationId: a1.get_policy
-      description: 'Query single policy'
+      description: 'Query a policy'
       tags:
       - Individual Policy Object
       responses:
@@ -133,9 +107,13 @@ paths:
                 "$ref": "#/components/schemas/PolicyObject"
         404:
           "$ref": "#/components/responses/404-NotFound"
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
     delete:
       operationId: a1.delete_policy
-      description: 'Delete policy'
+      description: 'Delete policy'
       tags:
       - Individual Policy Object
       responses:
@@ -143,8 +121,12 @@ paths:
           description: 'The policy was deleted'
         404:
           "$ref": "#/components/responses/404-NotFound"
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
 
-  '/policies/{policyId}/status':
+  '/policystatus/{policyId}':
     parameters:
       - name: policyId
         in: path
@@ -153,37 +135,24 @@ paths:
           "$ref": "#/components/schemas/PolicyId"
     get:
       operationId: a1.get_policy_status
-      description: 'Get the enforcement status of a policy'
+      description: 'Query a policy status'
       tags:
       - Individual Policy Status Object
       responses:
         200:
-          description: 'The requested enforcement status'
+          description: 'The requested policy status'
           content:
             application/json:
               schema:
                 "$ref": "#/components/schemas/PolicyStatusObject"
         404:
           "$ref": "#/components/responses/404-NotFound"
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
 
   '/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'
@@ -199,6 +168,10 @@ paths:
                 items:
                   "$ref": "#/components/schemas/PolicyTypeId"
                 minItems: 0
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
 
   '/policytypes/{policyTypeId}':
     parameters:
@@ -209,113 +182,46 @@ paths:
           "$ref": "#/components/schemas/PolicyTypeId"
     get:
       operationId: a1.get_policytypes
-      description: 'Get the schema for a policy type'
+      description: 'Get the schemas 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'
+          description: 'The policy type schemas'
           content:
             application/json:
               schema:
-                "$ref": "#/components/schemas/SubscriptionObject"
+                "$ref": "#/components/schemas/PolicyTypeObject"
         404:
           "$ref": "#/components/responses/404-NotFound"
+        429:
+          "$ref": "#/components/responses/429-TooManyRequests"
+        503:
+          "$ref": "#/components/responses/503-ServiceUnavailable"
 
 components:
   schemas:
     #
     # Representation objects
     #
-    PolicyStatusObject:
+    PolicyObject:
+      description: 'A generic policy object that can be used to transport any policy. Additionally, a policy shall be valid according to the schema of its specific policy type.'
       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.'
+    PolicyStatusObject:
+      description: 'A generic policy status object that can be used to transport any policy status. Additionally, a policy status shall be valid according to the schema of its specific policy type.'
       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.'
+    PolicyTypeObject:
+      description: 'A definition of a policy type, i.e. the schemas for a policy respectively its status'
       type: object
       properties:
-        description:
-          type: string
-        properties:
-          type: object
-        title:
-          type: string
-        type:
-          type: string
+        policySchema:
+          "$ref": "#/components/schemas/JsonSchema"
+        statusSchema:
+          "$ref": "#/components/schemas/JsonSchema"
       required:
-      - description
-      - properties
-      - title
-      - type
+        - policySchema
 
     ProblemDetails:
       description: 'A problem detail to carry details in a HTTP response according to RFC 7807 extended with A1 specific attributes'
@@ -331,23 +237,14 @@ components:
           type: string
         instance:
           type: string
-        policyErrorCode:
-          "$ref": "#/components/schemas/PolicyErrorType"
+        cause:
+          type: string
         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
     #
@@ -362,86 +259,20 @@ components:
       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
     #
+    JsonSchema:
+      description: 'A JSON schema following http://json-schema.org/draft-07/schema'
+      type: object
+
     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:
@@ -464,3 +295,24 @@ components:
         application/problem+json:
           schema:
             "$ref": "#/components/schemas/ProblemDetails"
+
+    429-TooManyRequests:
+      description: 'Too many requests have been sent in a given amount of time'
+      content:
+        application/problem+json:
+          schema:
+            "$ref": "#/components/schemas/ProblemDetails"
+
+    503-ServiceUnavailable:
+      description: 'The provider is currently unable to handle the request due to a temporary overload'
+      content:
+        application/problem+json:
+          schema:
+            "$ref": "#/components/schemas/ProblemDetails"
+
+    507-InsufficientStorage:
+      description: 'The method could not be performed on the resource because the provider is unable to store the representation needed to successfully complete the request'
+      content:
+        application/problem+json:
+          schema:
+            "$ref": "#/components/schemas/ProblemDetails"
index 1b1225b..bc78b97 100644 (file)
@@ -3,159 +3,135 @@ import copy
 import datetime
 import json
 import logging
-import requests
+#import requests
 
 from connexion import NoContent
-from flask import Flask, escape, request
+from flask import Flask, escape, request, make_response
 from jsonschema import validate
 from random import random, choice
-from var_declaration import policy_instances, policy_types, policy_status, notification_destination, notificationDestination
+from var_declaration import policy_instances, policy_types, policy_status, policy_type_per_instance
 
-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 get_all_policy_identities():
+  if len(request.args) == 0:
+    return(list(policy_instances.keys()), 200)
+  elif 'policyTypeId' in request.args:
+    policyTypeId = request.args.get('policyTypeId')
+    if policyTypeId not in list(policy_types.keys()):
+      return(set_error(None, "The policy type provided does not exist.", 400, "The policy type " + data["policyTypeId"] + " is not defined as a policy type.", None, None, "policyTypeId", None))
+    else:
+      return(list({key for key in policy_instances.keys() if policy_type_per_instance[key]==policyTypeId}), 200)
+  else:
+    return(send_error_code(request.args))
 
 def put_policy(policyId):
   data = request.data.decode("utf-8")
   data = data.replace("'", "\"")
   data = json.loads(data)
   ps = {}
+  if 'policyTypeId' in request.args:
+    policyTypeId = request.args.get('policyTypeId')
 
-  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))
+    if policyTypeId not in list(policy_types.keys()):
+      return(set_error(None, "The policy type provided does not exist.", 400, "The policy type " + policyTypeId + " is not defined as a policy type.", None, 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))
+    policy_schema = policy_types[policyTypeId]["policySchema"]
+    try:
+      validate(instance=data, schema=policy_schema)
+    except:
+      return(set_error(None, "The json does not validate against the schema.", 400, None, 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))
+    for i in list(policy_instances.keys()):
+      if policyId != i and \
+         data == policy_instances[i] and \
+         policyTypeId == policy_type_per_instance[i]:
+        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, 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))
+  if policyId in list(policy_instances.keys()):
+    if data["scope"] != policy_instances[policyId]["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, None, "scope", None))
 
-  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 'code' in request.args:
+    return(send_error_code(request.args))
+
+  policy_instances[policyId] = data
+  policy_status[policyId] = set_status("UNDEFINED")
+  if 'policyTypeId' in request.args:
+    status_schema = policy_types[policyTypeId]["statusSchema"]
+    try:
+      validate(instance=policy_status[policyId], schema=status_schema)
+    except:
+      return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
+    policy_type_per_instance[policyId] = policyTypeId
+  else:
+    policy_type_per_instance[policyId] = "UNDEFINED"
 
   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)
+
+  response = make_response(policy_instances[policyId], code)
+  if code == 201:
+    response.headers['Location'] = "http://localhost:8085/A1-P/v1/policies/" + policyId
+  return response
 
 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\""))
+  ps["enforceStatus"] = args[0]
+  if len(args) == 2:
+    ps["enforceReason"] = args[1]
+  if len(args) > 2:
+    return(set_error(None, "Too many arguments", 400, "There should be no more than two status arguments: enforceStatus and enforceReason", None, None, None, None))
   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)
+  if len(request.args) == 0:
+    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, None, "policyId", None))
   else:
-    return(set_error(None, "The requested policy does not exist.", 404, None, None, "policyId", None))
+    return(send_error_code(request.args))
 
 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"
+  if len(request.args) == 0:
+    if policyId in policy_instances.keys():
+      policy_instances.pop(policyId)
+      policy_status.pop(policyId)
+      policy_type_per_instance.pop(policyId)
+      return(None, 204)
+    else:
+      return(set_error(None, "The policy identity does not exist.", 404, "No policy instance has been deleted.", None, None, "policyId", None))
   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)
+    return(send_error_code(request.args))
 
 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)
+  if len(request.args) == 0:
+    if policyId in policy_instances.keys():
+      return(policy_status[policyId], 200)
+    else:
+      return(set_error(None, "The policy identity does not exist.", 404, "There is no existing policy instance with the identity: " + policyId, None, None, "policyId", None))
   else:
-    return(set_error(None, "The requested policy type does not exist.", 404, None, None, "policyTypeId", None))
+    return(send_error_code(request.args))
 
-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)
+def get_all_policytypes_identities():
+  if len(request.args) == 0:
+    return(list(policy_types.keys()), 200)
   else:
-    notificationDestination["notificationDestionation"] = data
-    return(None, 200)
+    return(send_error_code(request.args))
 
-def get_policytypes_subscription():
-  if not notificationDestination:
-    return(set_error(None, "The notification destination has not been defined.", 404, None, None, "notificationDestination", None))
+def get_policytypes(policyTypeId):
+  if len(request.args) == 0:
+    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, None, "policyTypeId", None))
   else:
-    return(notificationDestination["notificationDestionation"], 200)
+    return(send_error_code(request.args))
 
-def set_error(type_of, title, status, detail, instance, param, reason):
+def set_error(type_of, title, status, detail, instance, cause, param, reason):
   error = {}
   params = {}
   if type_of is not None:
@@ -168,6 +144,8 @@ def set_error(type_of, title, status, detail, instance, param, reason):
     error["detail"] = detail
   if instance is not None:
     error["instance"] = instance
+  if cause is not None:
+    error["cause"] = cause
   if param is not None:
     params["param"] = param
   if reason is not None:
@@ -175,3 +153,19 @@ def set_error(type_of, title, status, detail, instance, param, reason):
   if params:
     error["invalidParams"] = params
   return(error, error["status"])
+
+def send_error_code(args):
+  if 'code' in args.keys():
+    code = args['code']
+    if code == '405':
+      return(set_error(None, "Method not allowed", 405, "Method not allowed for the URI", None, None, None, None))
+    elif code == '429':
+      return(set_error(None, "Too many requests", 429, "Too many requests have been sent in a given amount of time", None, None, None, None))
+    elif code == '507':
+      return(set_error(None, "Insufficient storage", 507, "The method could not be performed on the resource because the provider is unable to store the representation needed to successfully complete the request", None, None, None, None))
+    elif code == '503':
+      return(set_error(None, "Service unavailable", 503, "The provider is currently unable to handle the request due to a temporary overload", None, None, None, None))
+    else:
+      return(set_error(None, "Not found", 400, "No resource found at the URI", None, None, None, None))
+  else:
+    return(set_error(None, "Not found", 400, "No resource found at the URI", None, None, None, None))
index da05885..4e873db 100755 (executable)
@@ -5,51 +5,36 @@
 # 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
+# PUT a policy type STD_QoSNudging_0.2.0
+curl -X PUT -v "http://localhost:8085/policytypes/STD_QoSNudging_0.2.0" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_type_STD_QoSNudging_0.2.0.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"
+# GET policy type STD_QoSNudging_0.2.0
+curl -v "http://localhost:8085/A1-P/v1/policytypes/STD_QoSNudging_0.2.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
+curl -X PUT -v "http://localhost:8085/A1-P/v1/policies/pi1?policyTypeId=STD_QoSNudging_0.2.0" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_instance_1_STD_QoSNudging_0.2.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
+curl -X PUT -v "http://localhost:8085/A1-P/v1/policies/pi2?policyTypeId=STD_QoSNudging_0.2.0" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_instance_2_STD_QoSNudging_0.2.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
+curl -X PUT -v "http://localhost:8085/A1-P/v1/policies/pi1?policyTypeId=STD_QoSNudging_0.2.0" -H "accept: application/json" -H "Content-Type: application/json" --data-binary @policy_instance_1_bis_STD_QoSNudging_0.2.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"
+curl -v "http://localhost:8085/A1-P/v1/policystatus/pi1"
index e1f2d56..48b7f2e 100644 (file)
@@ -4,7 +4,8 @@ import json
 import sys
 
 from flask import Flask, escape, request, make_response
-from var_declaration import policy_instances, policy_types, policy_status
+from jsonschema import validate
+from var_declaration import policy_instances, policy_types, policy_status, policy_type_per_instance
 
 app = connexion.App(__name__, specification_dir='.')
 
@@ -25,17 +26,16 @@ def policy_type(policyTypeId):
 
 @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)
+    return("Everything is fine", 200)
 
 @app.route('/deleteinstances', methods=['DELETE'])
 def delete_instances():
   global policy_instances
   global policy_status
+  global policy_type_per_instance
   policy_instances.clear()
   policy_status.clear()
+  policy_type_per_instance.clear()
   return("All policy instances deleted", 200)
 
 @app.route('/deletetypes', methods=['DELETE'])
@@ -47,37 +47,46 @@ def delete_types():
 @app.route('/<string:policyId>/<string:enforceStatus>', methods=['PUT'])
 def set_status(policyId, enforceStatus):
   if policyId in policy_instances.keys():
-    if enforceStatus in ["UNDEFINED", "ENFORCED", "NOT_ENFORCED"]:
-      policy_status.pop(policyId)
+    if policy_type_per_instance[policyId] == "UNDEFINED":
       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)
+      policy_type_id = policy_type_per_instance[policyId]
+      status_schema = policy_types[policy_type_id]["statusSchema"]
+      ps = {}
+      ps["policyId"] = policyId
+      ps["enforceStatus"] = enforceStatus
+      try:
+        validate(instance=ps, schema=status_schema)
+      except:
+        return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
+  policy_status.pop(policyId)
+  policy_status[policyId] = ps
+  return("Status updated for policy: " + policyId, 200)
 
 @app.route('/<string:policyId>/<string:enforceStatus>/<string:enforceReason>', 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)
+    if policy_type_per_instance[policyId] == "UNDEFINED":
+      ps = {}
+      ps["policyId"] = policyId
+      ps["enforceStatus"] = enforceStatus
+      ps["enforceReason"] = enforceReason
     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)
-
+      policy_type_id = policy_type_per_instance[policyId]
+      status_schema = policy_types[policy_type_id]["statusSchema"]
+      ps = {}
+      ps["policyId"] = policyId
+      ps["enforceStatus"] = enforceStatus
+      ps["enforceReason"] = enforceReason
+      try:
+        validate(instance=ps, schema=status_schema)
+      except:
+        return(set_error(None, "The json does not validate against the status schema.", 400, None, None, None, None, None))
+  policy_status.pop(policyId)
+  policy_status[policyId] = ps
+  return("Status updated for policy: " + policyId, 200)
 
 port_number = 8085
 if len(sys.argv) >= 2:
diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.2.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_STD_QoSNudging_0.2.0.json
new file mode 100644 (file)
index 0000000..74f22c7
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "scope": {
+    "ueId": "ue1",
+    "groupId": "group1",
+    "sliceId": "slice1",
+    "qosId": "qos1",
+    "cellId": "cell1"
+  },
+  "statement": {
+    "priorityLevel": 5
+  }
+}
+
diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.2.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_instance_1_bis_STD_QoSNudging_0.2.0.json
new file mode 100644 (file)
index 0000000..8d2e985
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "scope": {
+    "ueId": "ue1",
+    "groupId": "group1",
+    "sliceId": "slice1",
+    "qosId": "qos1",
+    "cellId": "cell1"},
+  "statement": {
+    "priorityLevel": 4
+  }
+}
diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.2.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_instance_2_STD_QoSNudging_0.2.0.json
new file mode 100644 (file)
index 0000000..257298c
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "scope": {
+    "ueId": "ue2",
+    "groupId": "group2",
+    "sliceId": "slice2",
+    "qosId": "qos2",
+    "cellId": "cell2"
+  },
+  "statement": {
+    "priorityLevel": 5
+  }
+}
diff --git a/near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.2.0.json b/near-rt-ric-simulator/ric-plt/a1/policy_type_STD_QoSNudging_0.2.0.json
new file mode 100644 (file)
index 0000000..baf1bbe
--- /dev/null
@@ -0,0 +1,46 @@
+{
+  "policySchema": {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "title": "STD_QoSNudging_0.2.0",
+    "description": "QoS policy type",
+    "type": "object",
+    "properties": {
+      "scope": {
+        "type": "object",
+        "properties": {
+          "ueId": {"type": "string"},
+          "qosId": {"type": "string"}
+        },
+        "additionalProperties": true,
+        "required": ["ueId", "qosId"]
+      },
+      "statement": {
+        "type": "object",
+        "properties": {
+          "priorityLevel": {"type": "number"}
+        },
+        "additionalProperties": false,
+        "required": ["priorityLevel"]
+      }
+    }
+  },
+  "statusSchema": {
+    "$schema": "http://json-schema.org/draft-07/schema#",
+    "title": "statusSchema",
+    "description": "statusSchema",
+    "type": "object",
+    "properties": {
+      "enforceStatus": {
+        "type": "string",
+        "enum": ["UNDEFINED", "ENFORCED", "NOT_ENFORCED"]
+      },
+      "enforceReason": {
+        "type": "string",
+        "enum": ["100", "200", "300", "800"]
+      },
+      "additionalProperties": false
+    },
+    "if": {"properties": {"enforceStatus": {"const": "NOT_ENFORCED"}}},
+    "then": {"required": ["enforceReason"]}
+  }
+}
index c0dbac4..03ee527 100644 (file)
@@ -3,5 +3,4 @@
 policy_instances = {}
 policy_types = {}
 policy_status = {}
-notification_destination = {}
-notificationDestination = {}
+policy_type_per_instance = {}