Commit c4fac3fb authored by Laskaratos Dimitris's avatar Laskaratos Dimitris
Browse files

Added network functions support and fixed edge cloud bugs

parent 5019220c
Loading
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ def delete_app(appId, x_correlator=None):
        pi_edge_factory = PiEdgeAPIClientFactory()
        api_client = pi_edge_factory.create_pi_edge_api_client()
        response = api_client.delete_app(appId=appId)
        return response.json()
        return response

    except NotFound404Exception:
        return (
@@ -95,9 +95,9 @@ def create_app_instance():
       
       app_id = body.get("appId")
       edge_zone_id = body.get("edgeCloudZoneId")
       k8s_ref = body.get("kubernetesClusterRef")
    #    k8s_ref = body.get("kubernetesClusterRef")
       
       if not app_id or not edge_zone_id or not k8s_ref:
       if not app_id or not edge_zone_id :
           return jsonify({"error": "Missing required fields: appId, edgeCloudZoneId, or kubernetesCLusterRef"}), 400
       
       logger.info(f"Preparing to send deployment request to SRM for appId={app_id}")
@@ -129,8 +129,8 @@ def create_app_instance():
               "warning": "SRM backend unavailable. Deployment request was built correctly.",
               "details": str(inner_error)
           }),202
           
       return jsonify({"message": f"Application {app_id} instantiation accepted"}), 202
       return response   
    #    return jsonify({"message": f"Application {app_id} instantiation accepted"}), 202
    except ValidationError as e:
        logger.error(f"Validation error: {str(e)}")
        return jsonify({"error": "Validation error", "details": str(e)}), 400
@@ -175,7 +175,7 @@ def delete_app_instance(appInstanceId: str, x_correlator=None):
        pi_edge_client_factory = PiEdgeAPIClientFactory()
        pi_edge_client = pi_edge_client_factory.create_pi_edge_api_client()
        response = pi_edge_client.delete_app_instance(appInstanceId)
        return response.json()
        return jsonify({'result': response.text, 'status': response.status_code})

    except Exception as e:
        return (
+11 −6
Original line number Diff line number Diff line
@@ -53,18 +53,16 @@ def get_federated_zones() -> List[EdgeCloudZone]:
    """get partner/federated Operator Platform available zones from Federation Manager"""
    return []



def get_all_cloud_zones() -> List[EdgeCloudZone]:
    """Get all available zones from local and federated Operator Platforms"""

    # Convert dicts to EdgeCloudZone
    local_zones = [EdgeCloudZone(**z) for z in get_local_zones()]
    # local_zones = [EdgeCloudZone(**z) for z in get_local_zones()]

    # Federated zones are already EdgeCloudZone instances
    federated_zones = get_federated_zones()

    return local_zones + federated_zones
    # federated_zones = get_federated_zones()
    # return local_zones + federated_zones
    return get_local_zones() + get_federated_zones()

def get_edge_cloud_zones(x_correlator: str | None = None, region=None, status=None):  # noqa: E501
    """Retrieve a list of the operators Edge Cloud Zones and their status
@@ -112,3 +110,10 @@ def get_edge_cloud_zones(x_correlator: str | None = None, region=None, status=No
            "message": f"An error occurred: {str(e)}",
        }
        return jsonify(error_info), 500
    

def edge_cloud_zone_details(zoneId: str) -> dict:
    pi_edge_factory = PiEdgeAPIClientFactory()
    api_client = pi_edge_factory.create_pi_edge_api_client()
    result = api_client.edge_cloud_zone_details(zone_id=zoneId)
    return result
+142 −0
Original line number Diff line number Diff line
from flask import jsonify
from pydantic import Field, ValidationError
from edge_cloud_management_api.managers.log_manager import logger
from edge_cloud_management_api.services.pi_edge_services import PiEdgeAPIClientFactory

def create_qod_session(body: dict):
    """
    Creates a new QoD session
    """
    try:
        # Validate the input data using Pydantic
        # validated_data = AppManifest(**body)
        # validated_data_dict = validated_data.model_dump(mode="json")
        # validated_data_dict["_id"] = str(uuid.uuid4())
        pi_edge_factory = PiEdgeAPIClientFactory()
        api_client = pi_edge_factory.create_pi_edge_api_client()
        response = api_client.create_qod_session(body)

        return response

    except ValidationError as e:
        return jsonify({"error": "Invalid input", "details": e.errors()}), 400

    except Exception as e:
        return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
        )
    
def delete_qod_session(sessionId: str):
    """
    Creates a new QoD session
    """
    try:
        # Validate the input data using Pydantic
        # validated_data = AppManifest(**body)
        # validated_data_dict = validated_data.model_dump(mode="json")
        # validated_data_dict["_id"] = str(uuid.uuid4())
        pi_edge_factory = PiEdgeAPIClientFactory()
        api_client = pi_edge_factory.create_pi_edge_api_client()
        response = api_client.delete_qod_session(sessionId=sessionId)
       
        return response.json()

    except ValidationError as e:
        return jsonify({"error": "Invalid input", "details": e.errors()}), 400

    except Exception as e:
        return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
        )
def get_qod_session(sessionId: str):
    """
    Creates a new QoD session
    """
    try:
        # Validate the input data using Pydantic
        # validated_data = AppManifest(**body)
        # validated_data_dict = validated_data.model_dump(mode="json")
        # validated_data_dict["_id"] = str(uuid.uuid4())
        pi_edge_factory = PiEdgeAPIClientFactory()
        api_client = pi_edge_factory.create_pi_edge_api_client()
        response = api_client.get_qod_session(sessionId=sessionId)
        # Insert into MongoDB
        # with MongoManager() as db:
        #     document_id = db.insert_document("apps", validated_data_dict)
        #     return (
        #         jsonify({"appId": str(document_id)}),
        #         201,
        #     )
        return response.json()

    except ValidationError as e:
        return jsonify({"error": "Invalid input", "details": e.errors()}), 400

    except Exception as e:
        return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
        )
    
def create_traffic_influence_resource(body: dict):
        try:
            pi_edge_factory = PiEdgeAPIClientFactory()
            api_client = pi_edge_factory.create_pi_edge_api_client()
            response = api_client.create_traffic_influence_resource(body)
            return response
        except ValidationError as e:
            return jsonify({"error": "Invalid input", "details": e.errors()}), 400

        except Exception as e:
            return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
        )

def get_traffic_influence_resource(id: str):
    try:
            pi_edge_factory = PiEdgeAPIClientFactory()
            api_client = pi_edge_factory.create_pi_edge_api_client()
            response = api_client.get_traffic_influence_resource(id)
            return response
    except ValidationError as e:
            return jsonify({"error": "Invalid input", "details": e.errors()}), 400

    except Exception as e:
            return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
    )


def delete_traffic_influence_resource(id: str):
    try:
            pi_edge_factory = PiEdgeAPIClientFactory()
            api_client = pi_edge_factory.create_pi_edge_api_client()
            response = api_client.delete_traffic_influence_resource(id)
            return response
    except ValidationError as e:
            return jsonify({"error": "Invalid input", "details": e.errors()}), 400

    except Exception as e:
            return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
    )    

def get_all_traffic_influence_resources():
    try:
            pi_edge_factory = PiEdgeAPIClientFactory()
            api_client = pi_edge_factory.create_pi_edge_api_client()
            response = api_client.get_all_traffic_influence_resources()
            return response
    except ValidationError as e:
            return jsonify({"error": "Invalid input", "details": e.errors()}), 400

    except Exception as e:
            return (
            jsonify({"error": "An unexpected error occurred", "details": str(e)}),
            500,
    )
 No newline at end of file
+92 −15
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ class PiEdgeAPIClient:
            service_functions = response.json()
            if isinstance(service_functions, list):
                return service_functions
            raise ValueError("Unexpected response from Pi Edge Server")
            raise ValueError("Unexpected response from Service Resource manager")

        except Timeout:
            return {"error": "The request to the external API timed out. Please try again later."}
@@ -147,7 +147,7 @@ class PiEdgeAPIClient:
        try:
            response = requests.delete(url,headers=self._get_headers(), verify=False)
            response.raise_for_status()
            return response
            return response.text
        except Timeout:
            return {"error": "The request to the external API timed out. Please try again later."}

@@ -246,23 +246,100 @@ class PiEdgeAPIClient:
            raise ValueError("No edge nodes found")
        return nodes

        #except Timeout:
         #   return {"error": "The request to the external API timed out. Please try again later."}

        #except ConnectionError:
         #   return {"error": "Failed to connect to the external API service. Service might be unavailable."}
    def edge_cloud_zone_details(self, zone_id):
        """
        Get list of edge zones from /node endpoint.
        """
        url = f"{self.base_url}/node/"+zone_id
        #try:
        request_headers = self._get_headers()
        response = requests.get(url, headers=request_headers, verify=False)
        response.raise_for_status()
        nodes = response.json()
        if not nodes:
            raise ValueError("No edge nodes found")
        return nodes     

    def create_qod_session(self, body:dict):

        url = f"{self.base_url}/sessions"
        request_headers = self._get_headers()
        try:
            response = requests.post(url, json=body, headers=request_headers,verify=False)
            response.raise_for_status()
            return response
        except Exception as e:
            logger.info(e.args)
            return e.args

    def get_qod_session(self, sessionId: str):

        url = f"{self.base_url}/sessions/"+sessionId
        request_headers = self._get_headers()
        try:
            response = requests.get(url, headers=request_headers,verify=False)
            response.raise_for_status()
            return response
        except Exception as e:
            logger.info(e.args)
            return e.args
        
    def delete_qod_session(self, sessionId: str):

        url = f"{self.base_url}/sessions/"+sessionId
        request_headers = self._get_headers()
        try:
            response = requests.delete(url, headers=request_headers,verify=False)
            response.raise_for_status()
            return response
        except Exception as e:
            logger.info(e.args)
            return e.args

        #except requests.exceptions.HTTPError as http_err:
         #   return {
          #      "error": f"HTTP error occurred: {http_err}.",
           #     "status_code": response.status_code,
           # }
    def create_traffic_influence_resource(self, body_dict):
        url = f"{self.base_url}/traffic-influences/"
        request_headers = self._get_headers()
        try:
            response = requests.post(url, json=body_dict, headers=request_headers,verify=False)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            logger.info(e.args)
            return e.args

        #except ValueError as val_err:
         #   return {"error": str(val_err)}
    def delete_traffic_influence_resource(self, id: str):
        url = f"{self.base_url}/traffic-influences/"+id
        request_headers = self._get_headers()
        try:
            response = requests.delete(url, headers=request_headers,verify=False)
            response.raise_for_status()
            return response
        except Exception as e:
            logger.info(e.args)
            return e.args

    def get_traffic_influence_resource(self, id: str):
        url = f"{self.base_url}/traffic-influences/"+id
        request_headers = self._get_headers()
        try:
            response = requests.get(url, headers=request_headers,verify=False)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            logger.info(e.args)
            return e.args

        #except Exception as err:
         #   return {"error": f"An unexpected error occurred: {err}"}
    def get_all_traffic_influence_resources(self):
        url = f"{self.base_url}/traffic-influences/"
        request_headers = self._get_headers()
        try:
            response = requests.get(url, headers=request_headers,verify=False)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            logger.info(e.args)
            return e.args    


class PiEdgeAPIClientFactory:
+153 −4
Original line number Diff line number Diff line
@@ -675,7 +675,156 @@ paths:
          $ref: "#/components/responses/500"
        "503":
          $ref: "#/components/responses/503"
  
  /edge-cloud-zones/{zoneId}:
    get:
      tags:
      - Edge Cloud
      summary: Retrieve the details of an Edge Cloud Zone
      description: |
        List of the operators Edge Cloud Zones and their
        status, ordering the results by location and filtering by
        status (active/inactive/unknown)
      operationId: edge_cloud_management_api.controllers.edge_cloud_controller.edge_cloud_zone_details
      parameters:
        - $ref: "#/components/parameters/x-correlator"
        - name: zoneId
          in: path
          description: |
            UID of the specific edge cloud zone
          required: true
          style: simple
          schema:
            type: string
      responses:
        "200":
          description: |
            Successful response, returning the Edge Cloud Zone details
        "404":
          $ref: "#/components/responses/404"
  /sessions:
    post:
      tags:
      - Quality on Demand Functions
      summary: Creates a new QoD Session
      operationId: edge_cloud_management_api.controllers.network_functions_controller.create_qod_session
      requestBody:
        description: QoD Session body.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/'
      responses:
        "200":
          description: Session created.
  /sessions/{sessionId}:
    get:
      tags:
      - Quality on Demand Functions
      summary: Retrieve details of a QoD Session
      operationId: edge_cloud_management_api.controllers.network_functions_controller.get_qod_session
      parameters:
      - name: sessionId
        in: path
        description: Represents a QoD Session.
        required: true
        style: simple
        explode: false
        schema:
          type: string
      responses:
        "200":
          description: QoD Session found
        "405":
          description: Method not allowed
        "404":
          description: Session not found
    delete:
      tags:
      - Quality on Demand Functions
      summary: Remove QoD Session
      operationId: edge_cloud_management_api.controllers.network_functions_controller.delete_qod_session
      parameters:
      - name: sessionId
        in: path
        description: Represents a QoD Session.
        required: true
        style: simple
        explode: false
        schema:
          type: string
      responses:
        "201":
          description: QoD Session deleted
        "405":
          description: Method not allowed
        "404":
          description: Session not found  
  /traffic-influences:
    post:
      tags:
      - Traffic Influence Functions
      summary: Creates a new TrafficInfluence resource
      operationId: edge_cloud_management_api.controllers.network_functions_controller.create_traffic_influence_resource
      requestBody:
        description: TrafficInfluence body.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/'
      responses:
        "200":
          description: Resource created.
    get:
      tags:
      - Traffic Influence Functions
      summary: Retrieves all TrafficInfluence resources
      operationId: edge_cloud_management_api.controllers.network_functions_controller.get_all_traffic_influence_resources
      responses:
        "200":
          description: Resources retrieved.
  /traffic-influences/{id}:
    get:
      tags:
      - Traffic Influence Functions
      summary: Retrieve details of a TrafficInfluence resource
      operationId: edge_cloud_management_api.controllers.network_functions_controller.get_traffic_influence_resource
      parameters:
      - name: id
        in: path
        description: Represents a TrafficInfluence resource.
        required: true
        style: simple
        explode: false
        schema:
          type: string
      responses:
        "200":
          description: TrafficInfluence resource found
        "405":
          description: Method not allowed
        "404":
          description: Session not found
    delete:
      tags:
      - Traffic Influence Functions
      summary: Remove TrafficInfluence resource
      operationId: edge_cloud_management_api.controllers.network_functions_controller.delete_traffic_influence_resource
      parameters:
      - name: id
        in: path
        description: Represents a TrafficInfluence resource
        required: true
        style: simple
        explode: false
        schema:
          type: string
      responses:
        "201":
          description: TrafficInfluence resource deleted
        "405":
          description: Method not allowed
        "404":
          description: Session not found
  /partner:
    post: 
      tags:
@@ -1210,7 +1359,7 @@ components:
        
    AppInstanceName:
      type: string
      pattern: ^[A-Za-z][A-Za-z0-9_]{1,63}$
      # pattern: ^[A-Za-z][A-Za-z0-9_]{1,63}$
      description: Name of the App instance, scoped to the AppProvider

    AppInstanceInfo:
@@ -1283,7 +1432,7 @@ components:
          $ref: "#/components/schemas/AppId"
        name:
          type: string
          pattern: ^[A-Za-z][A-Za-z0-9_]{1,63}$
          # pattern: ^[A-Za-z][A-Za-z0-9_]{1,63}$
          description: Name of the application.
        appProvider:
          $ref: "#/components/schemas/AppProvider"
@@ -1395,7 +1544,7 @@ components:
                  properties:
                    interfaceId:
                      type: string
                      pattern: ^[A-Za-z][A-Za-z0-9_]{3,31}$
                      # pattern: ^[A-Za-z][A-Za-z0-9_]{3,31}$
                      description: |
                        Each Port and corresponding traffic protocol
                        exposed by the component is identified by a name.