Commit 4ec7cd1c authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Optical component:

- Pre-merge cleanup
parent d8083619
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@ from common.proto.context_pb2 import (
    Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList,
    Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,
    OpticalConfig,OpticalConfigId,OpticalConfigList)
    OpticalConfig, OpticalConfigId, OpticalConfigList
)
from common.proto.context_pb2_grpc import ContextServiceStub
from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub
from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule
@@ -437,24 +438,26 @@ class ContextClient:
        response = self.policy_stub.RemovePolicyRule(request)
        LOGGER.debug('RemovePolicyRule result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    #//////////////// Experimental //////////////////

    @RETRY_DECORATOR
    def SetOpticalConfig(self, request : OpticalConfig) -> OpticalConfigId:
        LOGGER.debug('SettingOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request)))
        LOGGER.debug('SetOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.SetOpticalConfig(request)
        LOGGER.debug('SettingOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response)))
        LOGGER.debug('SetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def GetOpticalConfig(self, request : Empty) -> OpticalConfigList:
        LOGGER.debug('GettingOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request)))
        LOGGER.debug('GetOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.GetOpticalConfig(request)
        LOGGER.debug('GetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def SelectOpticalConfig(self,request : OpticalConfigId) -> OpticalConfigList:
        LOGGER.debug('Selecting request: {:s}'.format(grpc_message_to_json_string(request)))
        LOGGER.debug('SelectOpticalConfig request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.SelectOpticalConfig(request)
        LOGGER.debug('GetOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response)))
        LOGGER.debug('SelectOpticalConfig result: {:s}'.format(grpc_message_to_json_string(response)))
        return response
+20 −18
Original line number Diff line number Diff line
@@ -24,7 +24,8 @@ from common.proto.context_pb2 import (
    Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList,
    Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,
    OpticalConfigList,OpticalConfigId,OpticalConfig)
    OpticalConfigList, OpticalConfigId, OpticalConfig
)
from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule
from common.proto.context_pb2_grpc import ContextServiceServicer
from common.proto.context_policy_pb2_grpc import ContextPolicyServiceServicer
@@ -298,21 +299,22 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer
    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def RemovePolicyRule(self, request : PolicyRuleId, context: grpc.ServicerContext) -> Empty:
        return policyrule_delete(self.db_engine, self.messagebroker, request)

    # ---------------------------- Experimental -------------------

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def GetOpticalConfig(self, request : Empty, context : grpc.ServicerContext) -> OpticalConfigList:
  
        result =get_opticalconfig(db_engine=self.db_engine)
      
        result = get_opticalconfig(self.db_engine)
        return OpticalConfigList(OpticalConfigs=result)
    def SetOpticalConfig(self,request:OpticalConfig,context:grpc.ServicerContext)-> OpticalConfigId:

        OpticalConfig_id= set_opticalconfig(db_engine=self.db_engine,request=request)
    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def SetOpticalConfig(self, request : OpticalConfig, context : grpc.ServicerContext) -> OpticalConfigId:
        result = set_opticalconfig(self.db_engine, request)
        return OpticalConfigId(**result)

        return OpticalConfigId(**OpticalConfig_id)
    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def SelectOpticalConfig(self, request : OpticalConfigId, context : grpc.ServicerContext) -> OpticalConfig:
        result =select_opticalconfig(db_engine=self.db_engine,request=request)
        logging.info(f"FromSelectOpticalConfig {result}")
        myid =OpticalConfigId()
        myid.CopyFrom(result.OpticalConfig_id)
        return OpticalConfig(config=result.config,OpticalConfig_id=myid)
        result = select_opticalconfig(self.db_engine, request)
        optical_config_id = OpticalConfigId()
        optical_config_id.CopyFrom(result.OpticalConfig_id)
        return OpticalConfig(config=result.config, OpticalConfig_id=optical_config_id)
+0 −125
Original line number Diff line number Diff line
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Todo check if the file is in use by the TFS 
import functools, logging, operator
from enum import Enum
from typing import Dict, List, Optional, Tuple, Union
from common.orm.Database import Database
from common.orm.HighLevel import get_object, get_or_create_object, update_or_create_object
from common.orm.backend.Tools import key_to_str
from common.orm.fields.EnumeratedField import EnumeratedField
from common.orm.fields.ForeignKeyField import ForeignKeyField
from common.orm.fields.IntegerField import IntegerField
from common.orm.fields.PrimaryKeyField import PrimaryKeyField
from common.orm.fields.StringField import StringField
from common.orm.model.Model import Model
from context.proto.context_pb2 import ConfigActionEnum
from .Tools import fast_hasher, grpc_to_enum, remove_dict_key

LOGGER = logging.getLogger(__name__)

class ORM_ConfigActionEnum(Enum):
    UNDEFINED = ConfigActionEnum.CONFIGACTION_UNDEFINED
    SET       = ConfigActionEnum.CONFIGACTION_SET
    DELETE    = ConfigActionEnum.CONFIGACTION_DELETE

grpc_to_enum__config_action = functools.partial(
    grpc_to_enum, ConfigActionEnum, ORM_ConfigActionEnum)

class ConfigModel(Model): # pylint: disable=abstract-method
    pk = PrimaryKeyField()

    def dump(self) -> List[Dict]:
        db_config_rule_pks = self.references(ConfigRuleModel)
        config_rules = [ConfigRuleModel(self.database, pk).dump(include_position=True) for pk,_ in db_config_rule_pks]
        config_rules = sorted(config_rules, key=operator.itemgetter('position'))
        return [remove_dict_key(config_rule, 'position') for config_rule in config_rules]

class ConfigRuleModel(Model): # pylint: disable=abstract-method
    pk = PrimaryKeyField()
    config_fk = ForeignKeyField(ConfigModel)
    position = IntegerField(min_value=0, required=True)
    action = EnumeratedField(ORM_ConfigActionEnum, required=True)
    key = StringField(required=True, allow_empty=False)
    value = StringField(required=True, allow_empty=False)

    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
        result = {
            'action': self.action.value,
            'resource_key': self.key,
            'resource_value': self.value,
        }
        if include_position: result['position'] = self.position
        return result

def set_config_rule(
    database : Database, db_config : ConfigModel, position : int, resource_key : str, resource_value : str
    ) -> Tuple[ConfigRuleModel, bool]:

    str_rule_key_hash = fast_hasher(resource_key)
    str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':')
    result : Tuple[ConfigRuleModel, bool] = update_or_create_object(database, ConfigRuleModel, str_config_rule_key, {
        'config_fk': db_config, 'position': position, 'action': ORM_ConfigActionEnum.SET,
        'key': resource_key, 'value': resource_value})
    db_config_rule, updated = result
    return db_config_rule, updated

def delete_config_rule(
    database : Database, db_config : ConfigModel, resource_key : str
    ) -> None:

    str_rule_key_hash = fast_hasher(resource_key)
    str_config_rule_key = key_to_str([db_config.pk, str_rule_key_hash], separator=':')
    db_config_rule : Optional[ConfigRuleModel] = get_object(
        database, ConfigRuleModel, str_config_rule_key, raise_if_not_found=False)
    if db_config_rule is None: return
    db_config_rule.delete()

def delete_all_config_rules(
    database : Database, db_config : ConfigModel
    ) -> None:

    db_config_rule_pks = db_config.references(ConfigRuleModel)
    for pk,_ in db_config_rule_pks: ConfigRuleModel(database, pk).delete()

def grpc_config_rules_to_raw(grpc_config_rules) -> List[Tuple[ORM_ConfigActionEnum, str, str]]:
    def translate(grpc_config_rule):
        action = grpc_to_enum__config_action(grpc_config_rule.action)
        return action, grpc_config_rule.resource_key, grpc_config_rule.resource_value
    return [translate(grpc_config_rule) for grpc_config_rule in grpc_config_rules]

def update_config(
    database : Database, db_parent_pk : str, config_name : str,
    raw_config_rules : List[Tuple[ORM_ConfigActionEnum, str, str]]
    ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]:

    str_config_key = key_to_str([db_parent_pk, config_name], separator=':')
    result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key)
    db_config, created = result

    db_objects : List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]] = [(db_config, created)]

    for position,(action, resource_key, resource_value) in enumerate(raw_config_rules):
        if action == ORM_ConfigActionEnum.SET:
            result : Tuple[ConfigRuleModel, bool] = set_config_rule(
                database, db_config, position, resource_key, resource_value)
            db_config_rule, updated = result
            db_objects.append((db_config_rule, updated))
        elif action == ORM_ConfigActionEnum.DELETE:
            delete_config_rule(database, db_config, resource_key)
        else:
            msg = 'Unsupported action({:s}) for resource_key({:s})/resource_value({:s})'
            raise AttributeError(msg.format(str(ConfigActionEnum.Name(action)), str(resource_key), str(resource_value)))

    return db_objects
+5 −8
Original line number Diff line number Diff line
@@ -21,8 +21,9 @@ from typing import Dict, List, Optional, Set, Tuple
from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException
from common.message_broker.MessageBroker import MessageBroker
from common.proto.context_pb2 import (
    Device, DeviceFilter, DeviceId, DeviceIdList
    , DeviceList, Empty, EventTypeEnum, TopologyId,DeviceDriverEnum)
    Device, DeviceDriverEnum, DeviceFilter, DeviceId, DeviceIdList, DeviceList,
    Empty, EventTypeEnum, TopologyId
)
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.object_factory.Device import json_device_id
from context.service.database.uuids.Topology import topology_get_uuid
@@ -77,7 +78,6 @@ def device_get(db_engine : Engine, request : DeviceId) -> Device:
    return Device(**obj)

def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Device) -> DeviceId:
    
    raw_device_uuid = request.device_id.device_uuid.uuid
    raw_device_name = request.name
    device_name = raw_device_uuid if len(raw_device_name) == 0 else raw_device_name
@@ -89,7 +89,6 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi
        controller_uuid = None

    device_type = request.device_type
 
    oper_status = grpc_to_enum__device_operational_status(request.device_operational_status)
    device_drivers = [grpc_to_enum__device_driver(d) for d in request.device_drivers]

@@ -106,9 +105,7 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi
    })
    topology_uuids.add(topology_uuid)


    is_oc_driver= [d for d in request.device_drivers][0]==DeviceDriverEnum.DEVICEDRIVER_OC
 
    is_oc_driver = DeviceDriverEnum.DEVICEDRIVER_OC in set(request.device_drivers)

    endpoints_data : List[Dict] = list()
    for i, endpoint in enumerate(request.device_endpoints):
+45 −86
Original line number Diff line number Diff line
@@ -11,68 +11,42 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import uuid,json

import datetime, logging
import json, logging
from sqlalchemy.dialects.postgresql import insert
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session, selectinload, sessionmaker
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy_cockroachdb import run_transaction
from typing import Dict, List, Optional, Set, Tuple
from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException
from common.proto.context_pb2 import Device, DeviceFilter, DeviceId, TopologyId,OpticalConfig,OpticalConfigId,OpticalConfigList
from common.tools.grpc.Tools import grpc_message_to_json_string
from common.tools.object_factory.Device import json_device_id
from context.service.database.uuids.Topology import topology_get_uuid
from .models.DeviceModel import DeviceModel
from .models.EndPointModel import EndPointModel
from .models.TopologyModel import TopologyDeviceModel
from .models.enums.DeviceDriver import grpc_to_enum__device_driver
from .models.enums.DeviceOperationalStatus import grpc_to_enum__device_operational_status
from .models.enums.KpiSampleType import grpc_to_enum__kpi_sample_type
from .uuids.Device import device_get_uuid
from .uuids.EndPoint import endpoint_get_uuid
from .ConfigRule import compose_config_rules_data, upsert_config_rules
from common.proto.context_pb2 import OpticalConfig, OpticalConfigId
from .models.OpticalConfigModel import OpticalConfigModel

LOGGER = logging.getLogger(__name__)

def get_opticalconfig(db_engine : Engine):
    
    def callback(session:Session):
      
        lst = list()
        optical_configs = list()
        results = session.query(OpticalConfigModel).all()
        
        for obj in results:
            OpticalConfig=OpticalConfig()
            OpticalConfig.config=json.dump(obj.config)
            myid=OpticalConfigId()
            myid.opticalconfig_uuid=obj.opticalconfig_uuid
            OpticalConfig.opticalconfig_id.CopyFrom(myid)
          
            lst.append(OpticalConfig)
        return lst
            optical_config = OpticalConfig()
            optical_config.config = json.dump(obj.config)
            optical_config.opticalconfig_id.opticalconfig_uuid = obj.opticalconfig_uuid
            optical_configs.append(optical_config)
        return optical_configs
    obj = run_transaction(sessionmaker(bind=db_engine), callback)
    return obj




def set_opticalconfig(db_engine : Engine, request : OpticalConfig):

    opticalconfig_id = OpticalConfigId()
    opticalconfig_id.opticalconfig_uuid = request.opticalconfig_id.opticalconfig_uuid
    my_config_data = []
    if (request.config):
    if request.config:
        channels = []
        transceivers = []
        config = json.loads(request.config)
        
        if ( "channels" in config and len(config["channels"])>0):
            channels=[channel['name']['index'] for channel in config["channels"]]
        if ("transceivers" in config and  len(config["transceivers"]["transceiver"])>0):
            transceivers=[transceiver for transceiver in config["transceivers"]["transceiver"]]    
            
        if 'channels' in config and len(config['channels']) > 0:
            channels = [channel['name']['index'] for channel in config['channels']]
        if 'transceivers' in config and len(config['transceivers']['transceiver']) > 0:
            transceivers = [transceiver for transceiver in config['transceivers']['transceiver']]

        my_config_data = [
            {
@@ -89,41 +63,26 @@ def set_opticalconfig (db_engine:Engine,request:OpticalConfig):
        ]

    def callback(session:Session)->bool:
     
        stmt = insert(OpticalConfigModel).values(my_config_data)
        stmt = stmt.on_conflict_do_update(
            index_elements=[OpticalConfigModel.opticalconfig_uuid],
            set_=dict(
               
                channel_namespace=stmt.excluded.channel_namespace
            )
        )
      
        stmt = stmt.returning(OpticalConfigModel.opticalconfig_uuid)
      
        id = session.execute(stmt).fetchone()
 
    opticalconfig_id = run_transaction(sessionmaker(bind=db_engine), callback)
   
    return {'opticalconfig_uuid': opticalconfig_id}

       
        
def select_opticalconfig(db_engine:Engine,request:OpticalConfigId):
   
    def callback(session : Session) -> OpticalConfig:
        result = OpticalConfig()
        obj = session.query(OpticalConfigModel).filter_by(opticalconfig_uuid=request.opticalconfig_uuid).first()
      
        if (obj is not None):
           
         
            myid=OpticalConfigId()
            myid.opticalconfig_uuid=obj.opticalconfig_uuid
        stmt = session.query(OpticalConfigModel)
        stmt = stmt.filter_by(opticalconfig_uuid=request.opticalconfig_uuid)
        obj = stmt.first()
        if obj is not None:
            result.config = json.dumps(obj.dump())
            result.opticalconfig_id.CopyFrom(myid)
           
        
            result.opticalconfig_id.opticalconfig_uuid = obj.opticalconfig_uuid
        return result
 
    return run_transaction(sessionmaker(bind=db_engine, expire_on_commit=False), callback)
Loading