Commit e403d0b2 authored by Pablo Armingol's avatar Pablo Armingol
Browse files

Refactor TAPI LSP and IPoWDM handling: update proto definitions, enhance...

Refactor TAPI LSP and IPoWDM handling: update proto definitions, enhance request processing, and streamline service interactions
parent 466a9ed9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -555,7 +555,7 @@ message ConfigRule_IPOWDM {

message ConfigRule_TAPI_LSP {
  EndPointId endpoint_id           = 1;
  tapi_lsp.TapiLspRuleSet rule_set = 2;
  repeated tapi_lsp.TapiLspRuleSet rule_set = 2;
}

message ConfigRule {
+6 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@ syntax = "proto3";
package tapi_lsp;

message TapiLspRuleSet {
  string  src  = 1;
  string  dst  = 2;
  string  input_sip   = 1;
  string  output_sip  = 2;
  string  uuid = 3;
  string  bw   = 4;
  string  tenant_uuid = 5;
@@ -29,4 +29,8 @@ message TapiLspRuleSet {
  string  granularity    = 11;
  string  grid_type      = 12;
  string  direction      = 13;
  string capacity_unit   = 14;
  string capacity_value  = 15;
  string route_objective_function = 16;
  string url = 17;
}
 No newline at end of file
+9 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ from device.service.driver_api.ImportTopologyEnum import ImportTopologyEnum, get
from .Constants import SPECIAL_RESOURCE_MAPPINGS
from .TfsApiClient import TfsApiClient
from .Tools import compose_resource_endpoint
from .templates.tools import create_request
from .templates.tools import create_request, tapi_tequest

LOGGER = logging.getLogger(__name__)

@@ -187,6 +187,14 @@ class IetfL3VpnDriver(_Driver):
                        except Exception as e:
                            MSG = 'Invalid resource_value type: expected dict, got {:s}'
                            results.append((resource, e))
            elif "tapi_lsp" in str(resources):
                for resource in resources:
                    try:
                        tapi_tequest(resource)
                        results.append((resource, True))
                    except Exception as e:
                        MSG = "Invalid resource_value type: expected dict, got {:s}"
                        results.append((resource, e))
            else:
                for resource in resources:
                    resource_key, resource_value = resource
+102 −2
Original line number Diff line number Diff line
@@ -13,7 +13,9 @@
# limitations under the License.
import json
import logging
import os
import requests
from concurrent.futures import ThreadPoolExecutor

LOGGER = logging.getLogger(__name__)

@@ -22,6 +24,8 @@ HEADERS = {
    "Content-Type": "application/yang-data+json"
}

executor = ThreadPoolExecutor()

site_template = {
    "site-id": "",
    "devices": {
@@ -153,3 +157,99 @@ def patch_optical_channel_frequency(data, DEVICE_ID):
                            headers=HEADERS)
    assert response.status_code == 200
    return response

def process_uuid(service, url):
    headers = {
    "Content-Type": "application/json",
    "Accept": "application/json"
    }

    LOGGER.info(f"Processing service {service} to URL: {url}")
    try:
        response = 200
        # requests.post(url = url, json=service, headers=headers, timeout=300)
        LOGGER.info("Response Status code: %s", response)
    except requests.exceptions.RequestException as e:
        LOGGER.info(f"ERROR equest to {service} failed: {e}")

def tapi_tequest(resource_value):

    services, urls  =  build_tapi_connectivity(resource_value)
    for service, url in zip(services, urls):
        LOGGER.info(f"Services to be processed: {json.dumps(service, indent=2)}")
        LOGGER.info(f"URL to be used: {url}")

        executor.submit(process_uuid, service, url)

def build_tapi_connectivity(service_data):
    logging.info(f"Building TAPI connectivity for services data: {service_data}")
    outputs = []
    urls = []
    rules_set = service_data[1]["rule_set"]
    for rule_set in rules_set:
        direction = rule_set["direction"]
        layer_name = rule_set["layer_protocol_name"]
        layer_qualifier = rule_set["layer_protocol_qualifier"]
        urls.append(rule_set["url"])
        cs = {
            "uuid": rule_set["tenant_uuid"],
            "connectivity-direction": direction,
            "layer-protocol-name": layer_name,
            "layer-protocol-qualifier": layer_qualifier,
            "end-point": []
        }

        endpoints = []
        if direction == "UNIDIRECTIONAL":
            endpoints.append({
                "layer-protocol-name": layer_name,
                "layer-protocol-qualifier": layer_qualifier,
                "service-interface-point": {"service-interface-point-uuid": rule_set["src"]},
                "direction:": "INPUT",
                "local-id": rule_set["src"]
            })
            endpoints.append({
                "layer-protocol-name": layer_name,
                "layer-protocol-qualifier": layer_qualifier,
                "service-interface-point": {"service-interface-point-uuid": rule_set["dst"]},
                "direction:": "OUTPUT",
                "local-id": rule_set["dst"]
            })
        else:
            for point in [rule_set["src"], rule_set["dst"]]:
                ep = {
                    "layer-protocol-name": layer_name,
                    "layer-protocol-qualifier": layer_qualifier,
                    "service-interface-point": {"service-interface-point-uuid": point},
                    "direction:": "BIDIRECTIONAL",
                    "local-id": point
                }
                if rule_set.get("lower_frequency_mhz") != "NONE":
                    ep["tapi-photonic-media:media-channel-connectivity-service-end-point-spec"] = {
                        "mc-config": {
                            "spectrum": {
                                "frequency-constraint": {
                                    "adjustment-granularity": rule_set.get("granularity", "NONE"),
                                    "grid-type": rule_set.get("grid_type", "NONE")
                                },
                                "lower-frequency": rule_set["lower_frequency_mhz"],
                                "upper-frequency": rule_set["upper_frequency_mhz"]
                            }
                        }
                    }
                endpoints.append(ep)
        cs["end-point"] = endpoints

        route_obj = rule_set.get("route_objective_function", "UNSPECIFIED")
        cs["route-objective-function"] = route_obj if route_obj != "NONE" else "10000"
        capacity = rule_set.get("capacity", "NONE")
        if capacity != "NONE":
            parts = capacity.split("-")
            value = parts[0]
            unit = parts[1] if len(parts) > 1 else ""
            cs["requested-capacity"] = {
                "total-size": {"value": value, "unit": unit}
            }
        outputs.append({"tapi-connectivity:connectivity-service": [cs]})
    return outputs, urls
+29 −1
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ from flask_restful import Resource
from common.Constants import DEFAULT_CONTEXT_NAME
from service.client.ServiceClient import ServiceClient
from .Tools import grpc_service_id
from concurrent.futures import ThreadPoolExecutor
import requests
import threading

LOGGER = logging.getLogger(__name__)

@@ -29,6 +32,10 @@ HEADERS = {
    "Content-Type": "application/yang-data+json"
}

headers = {
            "Content-Type": "application/json",
            "Expect": ""
        }
class E2EInfoDelete(Resource):
    def __init__(self):
        super().__init__()
@@ -58,7 +65,18 @@ class E2EInfoDelete(Resource):
                LOGGER.debug(f"NODE DATA: \n{name}:{device}")
                response = test_patch_optical_channel_frequency(device, name)
                LOGGER.debug(f"RESPONSE :\n {response}")
        elif 'tapi_lsp' in allocationId:
            service_id = str(allocationId.split('=')[1])
            service_id_list = [s.strip() for s in service_id.split(',')]
            service_id = service_id_list[0]

            LOGGER.info("Service ID list: %s", service_id_list)

            executor = ThreadPoolExecutor(max_workers=len(service_id_list))
            for key in service_id_list:
                executor.submit(delete_slice, key, headers)

            threading.Thread(target=executor.shutdown, kwargs={'wait': True}).start()
        else:
            LOGGER.error("Unknown service type for allocationId: %s", allocationId)
            return {
@@ -74,6 +92,16 @@ class E2EInfoDelete(Resource):
            'allocationId': allocationId,
        }, 200

def delete_slice(key, headers):
    url_delete_slice = f'http://172.24.36.54:4900/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service={key}'
    try:
        # response = requests.delete(url=url_delete_slice, headers=headers, timeout=300)
        LOGGER.info("Key: %s", key)
        # LOGGER.info("Response Status code: %s", response.status_code)
        # LOGGER.info("Response Text: %s", response.text)
    except requests.exceptions.RequestException as e:
        LOGGER.info(f"ERROR request to delete slice {key} failed: {e}")

def test_patch_optical_channel_frequency(data, DEVICE_ID):
    """Test PATCH to update optical channel frequency."""
    # Use simple path with / and encode manually for component name
Loading