From de842e776839b15789d1540bb7d473eb891994e5 Mon Sep 17 00:00:00 2001 From: armingol Date: Wed, 1 Jul 2026 06:56:39 +0000 Subject: [PATCH 1/2] refactor: remove legacy L3VPN template structure and update function signature in tools.py --- src/nbi/service/tfs_api/Resources.py | 55 +++++++++++++++++++++++++++- src/nbi/service/tfs_api/__init__.py | 3 +- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/nbi/service/tfs_api/Resources.py b/src/nbi/service/tfs_api/Resources.py index 52f6867bb..c7faf204e 100644 --- a/src/nbi/service/tfs_api/Resources.py +++ b/src/nbi/service/tfs_api/Resources.py @@ -22,7 +22,7 @@ from flask.json import jsonify from flask_restful import Resource, request from werkzeug.exceptions import BadRequest from common.Constants import ServiceNameEnum -from common.proto.context_pb2 import Empty, LinkTypeEnum, Service, ServiceTypeEnum, ConfigActionEnum, ConfigRule +from common.proto.context_pb2 import Empty, LinkTypeEnum, Service as GrpcService, ServiceTypeEnum, ConfigActionEnum, ConfigRule from common.Settings import get_service_host, get_service_port_grpc from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest from common.tools.descriptor.Tools import format_device_custom_config_rules, format_service_custom_config_rules @@ -602,7 +602,7 @@ class E2epathcomp(Resource): try: # Construct a Service protobuf to encapsulate the intent for the E2E Orchestrator - service = Service() + service = GrpcService() service.service_id.service_uuid.uuid = "e2e-optical-service" service.service_id.context_id.context_uuid.uuid = "admin" service.service_type = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY @@ -635,3 +635,54 @@ class E2epathcomp(Resource): except Exception as e: LOGGER.error(f"Error calling E2E Orchestrator: {str(e)}", exc_info=True) return {"status": "error", "message": str(e)}, 500 + +class RecomputeOpticalPath(Resource): + def __init__(self): + super().__init__() + self.e2e_client = E2EOrchestratorClient() + + def post(self): + data = request.get_json() + LOGGER.info(f"Received E2E Optical Path Recomputation request: {json.dumps(data, indent=2)}") + + try: + # Construct a Service protobuf to encapsulate the intent for the E2E Orchestrator + service = GrpcService() + service.service_id.service_uuid.uuid = "e2e-optical-service" + service.service_id.context_id.context_uuid.uuid = "admin" + service.service_type = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY + + # Add recompute flag as custom config rule + cr_recompute = ConfigRule() + cr_recompute.action = ConfigActionEnum.CONFIGACTION_SET + cr_recompute.custom.resource_key = "recompute" + cr_recompute.custom.resource_value = "true" + service.service_config.config_rules.append(cr_recompute) + + # Pack the original JSON payload into a config rule so E2E Orchestrator and PathComp can access it + config_rule = ConfigRule() + config_rule.action = ConfigActionEnum.CONFIGACTION_SET + config_rule.custom.resource_key = "intent" + config_rule.custom.resource_value = json.dumps(data) + service.service_config.config_rules.append(config_rule) + + req = E2EOrchestratorRequest(service=service) + + LOGGER.info("Sending recompute request to E2E Orchestrator Compute...") + reply = self.e2e_client.Compute(req) + + reply_json = grpc_message_to_json(reply) + + # Check if there is an optical_path_result injected by PathComp + if reply.services: + for cr in reply.services[0].service_config.config_rules: + if cr.WhichOneof('config_rule') == 'custom' and cr.custom.resource_key == "optical_path_result": + LOGGER.info("Found optical_path_result, returning it directly.") + return json.loads(cr.custom.resource_value), 200 + + LOGGER.info(f"Received reply from E2E Orchestrator: {json.dumps(reply_json)}") + return reply_json, 200 + + except Exception as e: + LOGGER.error(f"Error in RecomputeOpticalPath: {str(e)}", exc_info=True) + return {"status": "error", "message": str(e)}, 500 diff --git a/src/nbi/service/tfs_api/__init__.py b/src/nbi/service/tfs_api/__init__.py index 9f0189817..3f27c2ff6 100644 --- a/src/nbi/service/tfs_api/__init__.py +++ b/src/nbi/service/tfs_api/__init__.py @@ -27,7 +27,7 @@ from .Resources import ( Service, ServiceIds, Services, OpticalServiceAllocation, Slice, SliceIds, Slices, Topologies, Topology, TopologyDetails, TopologyIds, - E2epathcomp + E2epathcomp, RecomputeOpticalPath ) @@ -38,6 +38,7 @@ URL_PREFIX = '/tfs-api' _RESOURCES = [ # (endpoint_name, resource_class, resource_url) ('api.e2e_path_computation', E2epathcomp, '/e2e_path_computation'), + ('api.recompute_optical_path', RecomputeOpticalPath, '/recompute_optical_path'), ('api.context_ids', ContextIds, '/context_ids'), ('api.contexts', Contexts, '/contexts'), ('api.dummy_contexts', DummyContexts, '/dummy_contexts'), -- GitLab From 766f1427fec4ff3afec321520af9fd4f27329cc3 Mon Sep 17 00:00:00 2001 From: armingol Date: Wed, 1 Jul 2026 14:28:36 +0000 Subject: [PATCH 2/2] NBI: update functions names --- src/nbi/service/tfs_api/Resources.py | 4 ++-- src/nbi/service/tfs_api/__init__.py | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/nbi/service/tfs_api/Resources.py b/src/nbi/service/tfs_api/Resources.py index c7faf204e..c6a6a8cf2 100644 --- a/src/nbi/service/tfs_api/Resources.py +++ b/src/nbi/service/tfs_api/Resources.py @@ -591,7 +591,7 @@ class PolicyRule(_Resource): def get(self, policy_rule_uuid : str): return format_grpc_to_json(self.context_client.GetPolicyRule(grpc_policy_rule_id(policy_rule_uuid))) -class E2epathcomp(Resource): +class E2EOpticalPathComputation(Resource): def __init__(self): super().__init__() self.e2e_client = E2EOrchestratorClient() @@ -636,7 +636,7 @@ class E2epathcomp(Resource): LOGGER.error(f"Error calling E2E Orchestrator: {str(e)}", exc_info=True) return {"status": "error", "message": str(e)}, 500 -class RecomputeOpticalPath(Resource): +class E2EOpticalPathRecomputation(Resource): def __init__(self): super().__init__() self.e2e_client = E2EOrchestratorClient() diff --git a/src/nbi/service/tfs_api/__init__.py b/src/nbi/service/tfs_api/__init__.py index 3f27c2ff6..3291c95bd 100644 --- a/src/nbi/service/tfs_api/__init__.py +++ b/src/nbi/service/tfs_api/__init__.py @@ -27,7 +27,7 @@ from .Resources import ( Service, ServiceIds, Services, OpticalServiceAllocation, Slice, SliceIds, Slices, Topologies, Topology, TopologyDetails, TopologyIds, - E2epathcomp, RecomputeOpticalPath + E2EOpticalPathComputation, E2EOpticalPathRecomputation ) @@ -37,8 +37,6 @@ URL_PREFIX = '/tfs-api' # Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type. _RESOURCES = [ # (endpoint_name, resource_class, resource_url) - ('api.e2e_path_computation', E2epathcomp, '/e2e_path_computation'), - ('api.recompute_optical_path', RecomputeOpticalPath, '/recompute_optical_path'), ('api.context_ids', ContextIds, '/context_ids'), ('api.contexts', Contexts, '/contexts'), ('api.dummy_contexts', DummyContexts, '/dummy_contexts'), @@ -86,6 +84,9 @@ _RESOURCES = [ ('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'), ('api.policyrules', PolicyRules, '/policyrules'), ('api.policyrule', PolicyRule, '/policyrule/'), + + ('api.e2e_optical_path_computation', E2EOpticalPathComputation, '/e2e_optical_path_computation'), + ('api.e2e_optical_path_recomputation', E2EOpticalPathRecomputation,'/e2e_optical_path_recomputation'), ] RESOURCES = [ (ENDPOINT_PREFIX + endpoint_name, resource_class, URL_PREFIX + resource_url) -- GitLab