Commit 4e041cfb authored by Sergio Gimenez's avatar Sergio Gimenez
Browse files

refactor: extract federated app instance lookup helpers

parent 0c2e6a53
Loading
Loading
Loading
Loading
+114 −148
Original line number Diff line number Diff line
@@ -202,6 +202,69 @@ def _normalize_federated_app_instances(fed_instances, zone_provider=None, region
    return normalized_instances


def _resolve_app_provider(pi_edge_client, app_id_value, app_payload=None):
    if isinstance(app_payload, dict):
        provider = app_payload.get("appProvider") or app_payload.get("appProviderId")
        if provider:
            return provider
        manifest = app_payload.get("appManifest")
        if isinstance(manifest, dict):
            provider = manifest.get("appProvider") or manifest.get("appProviderId")
            if provider:
                return provider

    app_response = pi_edge_client.get_app(app_id_value)
    if isinstance(app_response, dict):
        manifest = app_response.get("appManifest")
        if isinstance(manifest, dict):
            provider = manifest.get("appProvider") or manifest.get("appProviderId")
            if provider:
                return provider
        provider = app_response.get("appProvider") or app_response.get("appProviderId")
        if provider:
            return provider
    return None


def _get_catalog_app_provider_map(pi_edge_client):
    app_provider_map = {}
    apps = pi_edge_client.get_service_functions_catalogue()
    if not isinstance(apps, list):
        return app_provider_map

    for app in apps:
        if not isinstance(app, dict):
            continue
        app_id_value = app.get("appId") or app.get("id")
        if not app_id_value:
            continue
        provider = _resolve_app_provider(pi_edge_client, app_id_value, app_payload=app)
        if provider:
            app_provider_map[app_id_value] = provider
    return app_provider_map


def _iter_federated_instances(feds, app_id_provider_pairs):
    for fed in feds:
        fed_token = fed.get("token")
        federation_context_id = fed.get("_id")
        if not federation_context_id or not fed_token:
            continue

        zone_provider = fed.get("partnerOPFederationId") or "unknown"
        for app_id_value, app_provider_id in app_id_provider_pairs:
            federated_app_provider_id = _resolve_federated_app_provider_id(app_id_value, app_provider_id)
            fed_instances, fed_code = federation_client.get_all_app_instances(
                federation_context_id=federation_context_id,
                app_id=app_id_value,
                app_provider_id=federated_app_provider_id,
                token=fed_token,
            )
            if fed_code != 200 or not isinstance(fed_instances, list):
                continue
            yield app_id_value, federation_context_id, fed_token, zone_provider, fed_instances


def _normalize_federated_artefact_id(federation_context_id, artefact_id, fallback_source):
    if artefact_id and re.match(
        r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-"
@@ -784,86 +847,33 @@ def get_app_instance(app_id=None, appId=None, x_correlator=None, xCorrelator=Non
            if normalized_instance:
                instances.append(normalized_instance)

        def resolve_app_provider(app_id_value, app_payload=None):
            if isinstance(app_payload, dict):
                provider = app_payload.get("appProvider") or app_payload.get("appProviderId")
                if provider:
                    return provider
                manifest = app_payload.get("appManifest")
                if isinstance(manifest, dict):
                    provider = manifest.get("appProvider") or manifest.get("appProviderId")
                    if provider:
                        return provider
            app_response = pi_edge_client.get_app(app_id_value)
            if isinstance(app_response, dict):
                manifest = app_response.get("appManifest")
                if isinstance(manifest, dict):
                    provider = manifest.get("appProvider") or manifest.get("appProviderId")
                    if provider:
                        return provider
                provider = app_response.get("appProvider") or app_response.get("appProviderId")
                if provider:
                    return provider
            return None

        feds = get_all_feds()
        if app_id:
            app_provider_id = resolve_app_provider(app_id)
            app_provider_id = _resolve_app_provider(pi_edge_client, app_id)
            if app_provider_id:
                federated_app_provider_id = _resolve_federated_app_provider_id(app_id, app_provider_id)
                for fed in feds:
                    fed_token = fed.get("token")
                    federation_context_id = fed.get("_id")
                    if not federation_context_id or not fed_token:
                        continue
                    fed_instances, fed_code = federation_client.get_all_app_instances(
                        federation_context_id=federation_context_id,
                        app_id=app_id,
                        app_provider_id=federated_app_provider_id,
                        token=fed_token,
                    )
                    if fed_code == 200:
                for app_id_value, _federation_context_id, _fed_token, zone_provider, fed_instances in _iter_federated_instances(
                    feds,
                    [(app_id, app_provider_id)],
                ):
                    instances.extend(
                        _normalize_federated_app_instances(
                            fed_instances,
                                zone_provider=(fed.get("partnerOPFederationId") or "unknown"),
                            zone_provider=zone_provider,
                            region=region,
                        )
                    )
            else:
                logger.info("Skipping federated lookup; no appProviderId for appId=%s", app_id)
        else:
            apps = pi_edge_client.get_service_functions_catalogue()
            if isinstance(apps, list):
                app_provider_map = {}
                for app in apps:
                    if not isinstance(app, dict):
                        continue
                    app_id_value = app.get("appId") or app.get("id")
                    if not app_id_value:
                        continue
                    provider = resolve_app_provider(app_id_value, app_payload=app)
                    if provider:
                        app_provider_map[app_id_value] = provider

                for app_id_value, app_provider_id in app_provider_map.items():
                    federated_app_provider_id = _resolve_federated_app_provider_id(app_id_value, app_provider_id)
                    for fed in feds:
                        fed_token = fed.get("token")
                        federation_context_id = fed.get("_id")
                        if not federation_context_id or not fed_token:
                            continue
                        fed_instances, fed_code = federation_client.get_all_app_instances(
                            federation_context_id=federation_context_id,
                            app_id=app_id_value,
                            app_provider_id=federated_app_provider_id,
                            token=fed_token,
                        )
                        if fed_code == 200:
            app_provider_map = _get_catalog_app_provider_map(pi_edge_client)
            for app_id_value, _federation_context_id, _fed_token, zone_provider, fed_instances in _iter_federated_instances(
                feds,
                app_provider_map.items(),
            ):
                instances.extend(
                    _normalize_federated_app_instances(
                        fed_instances,
                                    zone_provider=(fed.get("partnerOPFederationId") or "unknown"),
                        zone_provider=zone_provider,
                        region=region,
                    )
                )
@@ -916,57 +926,13 @@ def delete_app_instance(appInstanceId: str, x_correlator=None):
        else:
            status_code = response.get("status_code", 404)

        def resolve_app_provider(app_id_value, app_payload=None):
            if isinstance(app_payload, dict):
                provider = app_payload.get("appProvider") or app_payload.get("appProviderId")
                if provider:
                    return provider
                manifest = app_payload.get("appManifest")
                if isinstance(manifest, dict):
                    provider = manifest.get("appProvider") or manifest.get("appProviderId")
                    if provider:
                        return provider
            app_response = pi_edge_client.get_app(app_id_value)
            if isinstance(app_response, dict):
                manifest = app_response.get("appManifest")
                if isinstance(manifest, dict):
                    provider = manifest.get("appProvider") or manifest.get("appProviderId")
                    if provider:
                        return provider
                provider = app_response.get("appProvider") or app_response.get("appProviderId")
                if provider:
                    return provider
            return None

        apps = pi_edge_client.get_service_functions_catalogue()
        app_provider_map = {}
        if isinstance(apps, list):
            for app in apps:
                if not isinstance(app, dict):
                    continue
                app_id_value = app.get("appId") or app.get("id")
                if not app_id_value:
                    continue
                provider = resolve_app_provider(app_id_value, app_payload=app)
                if provider:
                    app_provider_map[app_id_value] = provider
        app_provider_map = _get_catalog_app_provider_map(pi_edge_client)

        feds = get_all_feds()
        for fed in feds:
            fed_token = fed.get("token")
            federation_context_id = fed.get("_id")
            if not federation_context_id or not fed_token:
                continue
            for app_id_value, app_provider_id in app_provider_map.items():
                federated_app_provider_id = _resolve_federated_app_provider_id(app_id_value, app_provider_id)
                fed_instances, fed_code = federation_client.get_all_app_instances(
                    federation_context_id=federation_context_id,
                    app_id=app_id_value,
                    app_provider_id=federated_app_provider_id,
                    token=fed_token,
                )
                if fed_code != 200 or not isinstance(fed_instances, list):
                    continue
        for app_id_value, federation_context_id, fed_token, _zone_provider, fed_instances in _iter_federated_instances(
            feds,
            app_provider_map.items(),
        ):
            for zone_info in fed_instances:
                if not isinstance(zone_info, dict):
                    continue