Commit 6e372353 authored by George Papathanail's avatar George Papathanail
Browse files

create_app_instance updates

parent 348d9949
Loading
Loading
Loading
Loading
+35 −180
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ def delete_app(appId, x_correlator=None):
            500,
        )


def create_app_instance():
    logger.info("Received request to create app instance")
    try:
@@ -96,202 +97,56 @@ def create_app_instance():

        app_id = body.get("appId")
        app_zones = body.get("appZones")

        pi_edge_client_factory = PiEdgeAPIClientFactory()
        pi_edge_client = pi_edge_client_factory.create_pi_edge_api_client()

        if not app_id or not app_zones:
            return jsonify({"error": "Missing required fields: appId, appZones"}), 400
            return jsonify({"error": "Missing required fields: appId, edgeCloudZoneId, or kubernetesCLusterRef"}), 400

        logger.info(f"Attempting to get zone for: {app_zones[0].get('EdgeCloudZone').get('edgeCloudZoneId')}")
        zone = get_zone(app_zones[0].get('EdgeCloudZone').get('edgeCloudZoneId'))
        logger.info(f"Retrieved zone: {zone}")

        # ----------------------------------------------------------------------
        # PARTNER DEPLOYMENT (Federation path)
        # ----------------------------------------------------------------------
        if zone.get('isLocal') == 'false':

            # Step 1: retrieve app metadata from SRM
            appData = pi_edge_client.get_app(appId=app_id).get('appManifest')

            # ------------------------------------------------------------------
            # Step 2: Build GSMA Artefact Payload (DIRTY PATCHED VERSION)
            # ------------------------------------------------------------------
            artefact = {}
            artefact['artefactId'] = app_id
            artefact['appProviderId'] = appData.get('appProvider') or "dummy-provider"

            artefact['artefactName'] = appData.get('name') or "unnamed-app"
            artefact['artefactVersionInfo'] = appData.get('version') or "1.0.0"
            artefact['artefactDescription'] = ""

            # Mandatory GSMA fields (missing in your original code)
            artefact['artefactDescriptorType'] = "HELM"
            artefact['artefactVirtType'] = "CONTAINER_TYPE"

            repoInfo = appData.get('appRepo') or {}

            artefact['repoType'] = repoInfo.get('type') or "PRIVATEREPO"

            # Dirty patch for repo credentials
            artefact['artefactRepoLocation'] = {
                'repoURL': repoInfo.get('imagePath') or "",
                'userName': repoInfo.get('userName') or "dummy-user",
                'password': repoInfo.get('credentials') or "dummy-password",
                'token': ""
            }

            # Extract interfaces
            exposedInterfaces = []
            componentSpec = appData.get('componentSpec') or [{}]
            networkInterfaces = componentSpec[0].get('networkInterfaces') or []
            
            interface_counter = 1 

            for ni in networkInterfaces:
            
                interface_id = f"ifc_{ni.get('port', 0)}_{ni.get('protocol', 'TCP')}_{interface_counter}"
                interface_id = interface_id.replace("-", "_")
                interface_counter += 1
                
                network_name = f"net_{ni.get('port', 0)}_{ni.get('protocol', 'TCP')}"
                network_name = network_name.replace("-", "_")
                
                
                if len(network_name) < 8:
                    network_name = network_name + "_net"
                
                interface = {
                    'interfaceId': 'interface_id',
                    'commProtocol': ni.get('protocol') or 'TCP',
                    'commPort': ni.get('port') or 80,
                    'visibilityType': ni.get('visibilityType') or 'VISIBILITY_EXTERNAL',
                    'network': network_name,
                    'InterfaceName': network_name
                }
                exposedInterfaces.append(interface)

            artefact['componentSpec'] = [
                {
                    'componentName': appData.get('name') or "component",
                    'numOfInstances': 0,
                    'images': [app_id],
                    'restartPolicy': 'RESTART_POLICY_ALWAYS',
                    'exposedInterfaces': exposedInterfaces,
                    'compEnvParams': [],
                    'persistentVolumes': [],
                    'computeResourceProfile': {
                        "cpuArchType": "ISA_X86_64",
                        "numCPU": {
                 
                            "whole":{"value":1}

                },
                        "memory": 256,
                        "diskStorage":0,
                        "gpu": [],
                        "vpu": 0,
                        "fpga": 0,
                        "hugepages": [],
                        "cpuExclusivity": False
               }
              }
           ]
            # ------------------------------------------------------------------
            # Step 3: Upload artefact to Federation Manager
            # ------------------------------------------------------------------
            fed_token = get_fed(zone.get('fedContextId')).get('token')

            create_artefact_response = federation_client.create_artefact(
                artefact=artefact,
                federation_context_id=zone.get('fedContextId'),
                token=fed_token
            )
        if zone is None:
            logger.error("get_zone returned None!")
            return jsonify({"error": "Zone not found"}), 404

            # ------------------------------------------------------------------
            # Step 4: If artefact OK, start onboarding
            # ------------------------------------------------------------------
            if create_artefact_response.status_code in [200, 409]:

                onboard_app = {
                    "appId": app_id,
                    "appProviderId": appData.get("appProvider") or "dummy-provider",
                    "appDeploymentZones": [],
                    "appMetaData": {
                        "appName": appData.get('name') or "unnamed-app",
                        "version": appData.get('version') or "1.0.0"
                    },
                    "appComponentSpecs": [
                        {
                            "serviceNameNB": appData.get("name"),
                            "serviceNameEW": appData.get("name"),
                            "componentName": appData.get("name"),
                            "artefactId": app_id
                        }
                    ]
                }

                onboard_app_response = federation_client.onboard_application(
                    federation_context_id=zone.get('fedContextId'),
                    body=onboard_app,
                    token=fed_token
                )

                # ------------------------------------------------------------------
                # Step 5: Deploy at partner OP
                # ------------------------------------------------------------------
                if onboard_app_response.status_code == 200:

                    deploy_app = {
                        "appId": app_id,
                        "appVersion": appData.get("version") or "1.0.0",
                        "appProviderId": appData.get("appProvider") or "dummy-provider",
                        "zoneInfo": {"zoneId": zone.get('edgeCloudZoneId')}
                    }

                    deploy_app_response = federation_client.deploy_app_partner(
                        federation_context_id=zone.get('fedContextId'),
                        body=deploy_app,
                        token=fed_token
                    )
        is_local = zone.get('isLocal')
        logger.info(f"Zone isLocal: {is_local}")

        if is_local == 'false':
            # Step 1: retrieve app metadata
            appData = pi_edge_client.get_app(appId=app_id).get('appManifest')
            # ... rest of federation logic ...
            return deploy_app_response

                return onboard_app_response

            return create_artefact_response

        # ----------------------------------------------------------------------
        # LOCAL DEPLOYMENT (via SRM)
        # ----------------------------------------------------------------------
        logger.info(f"Preparing to send deployment request to SRM for appId={app_id}")

        print("\n=== Preparing Deployment Request ===")
        print(f"Endpoint: {pi_edge_client.base_url}/deployedServiceFunction")
        print(f"Headers: {pi_edge_client._get_headers()}")
        print(f"Payload: {body}")
        print("=== End of Deployment Request ===\n")

        try:
        response = pi_edge_client.deploy_service_function(data=body)
        logger.info(f"Type of response from SRM: {type(response)}")
        logger.info(f"Response from SRM: {response}")

        if response is None:
            logger.error("SRM returned None!")
            return jsonify({"error": "SRM returned no response"}), 500

        if isinstance(response, dict) and "error" in response:
            logger.warning(f"Failed to deploy service function: {response}")
            return jsonify({
                    "warning": "Deployment not completed (SRM not reachable)",
                "warning": "Deployment not completed (SRM service unreachable)",
                "details": response
            }), 202
            return response

        except Exception as inner_error:
            return jsonify({
                "warning": "SRM backend unreachable",
                "details": str(inner_error)
            }), 202
        logger.info(f"Deployment response from SRM: {response}")
        return response

    except ValidationError as e:
        logger.error(f"Validation error: {str(e)}")
        return jsonify({"error": "Validation error", "details": str(e)}), 400

    except Exception as e:
        logger.error(f"Unexpected error in create_app_instance:{str(e)}")
        return jsonify({"error": "Unexpected error", "details": str(e)}), 500
        return jsonify({"error": "An unexpected error occurred", "details": str(e)}), 500
   

def get_app_instance(app_id=None, x_correlator=None, app_instance_id=None, region=None):