Newer
Older

Lluis Gifre Renom
committed
import grpc, logging
from typing import Dict, Set, Tuple, Union
from common.Checkers import chk_string
from common.exceptions.ServiceException import ServiceException
from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID

Lluis Gifre Renom
committed
def check_endpoint_id(
logger : logging.Logger, endpoint_number : int, parent_name : str, endpoint_id : 'EndPointId',

Lluis Gifre Renom
committed
add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]],
predefined_context_id : str = DEFAULT_CONTEXT_ID, acceptable_context_ids : Set[str] = set([DEFAULT_CONTEXT_ID]),
predefined_topology_id : str = DEFAULT_TOPOLOGY_ID, acceptable_topology_ids : Set[str] = set([DEFAULT_TOPOLOGY_ID]),
predefined_device_id : Union[str, None] = None, acceptable_device_ids : Set[str] = set(),
prevent_same_device_multiple_times : bool = True) -> Tuple[str, str, str]:

Lluis Gifre Renom
committed
try:
ep_context_id = chk_string('endpoint_id[#{}].topoId.contextId.contextUuid.uuid'.format(endpoint_number),
endpoint_id.topoId.contextId.contextUuid.uuid,
allow_empty=True)
ep_topology_id = chk_string('endpoint_id[#{}].topoId.topoId.uuid'.format(endpoint_number),
endpoint_id.topoId.topoId.uuid,
allow_empty=True)
ep_device_id = chk_string('endpoint_id[#{}].dev_id.device_id.uuid'.format(endpoint_number),
endpoint_id.dev_id.device_id.uuid,

Lluis Gifre Renom
committed
ep_port_id = chk_string('endpoint_id[#{}].port_id.uuid'.format(endpoint_number),
endpoint_id.port_id.uuid,
allow_empty=False)
except Exception as e:
logger.exception('Invalid arguments:')
raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
if len(ep_context_id) == 0:
# Assumption: if no context is specified for an endpoint_id, use predefined context

Lluis Gifre Renom
committed
ep_context_id = predefined_context_id
elif (len(acceptable_context_ids) > 0) and (ep_context_id not in acceptable_context_ids):

Lluis Gifre Renom
committed
# Assumption: parent and endpoints should belong to the same context
msg = ' '.join([
'Context({}) in {} mismatches acceptable Contexts({}).',
'Optionally, leave field empty to use predefined Context({}).',
])
msg = msg.format(
ep_context_id, parent_name, str(acceptable_context_ids), predefined_context_id)

Lluis Gifre Renom
committed
raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
if len(ep_topology_id) == 0:
# Assumption: if no topology is specified for an endpoint_id, use predefined topology

Lluis Gifre Renom
committed
ep_topology_id = predefined_topology_id
elif (len(acceptable_topology_ids) > 0) and (ep_topology_id not in acceptable_topology_ids):

Lluis Gifre Renom
committed
msg = ' '.join([
'Context({})/Topology({}) in {} mismatches acceptable Topologies({}).',

Lluis Gifre Renom
committed
'Optionally, leave field empty to use predefined Topology({}).',
])
msg = msg.format(
ep_context_id, ep_topology_id, parent_name, str(acceptable_topology_ids), predefined_topology_id)

Lluis Gifre Renom
committed
raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
if (predefined_device_id is not None) and (len(ep_device_id) == 0):
# Assumption: if no device is specified for an endpoint_id, use predefined device, if available
ep_device_id = predefined_device_id
elif (len(acceptable_device_ids) > 0) and (ep_device_id not in acceptable_device_ids):
msg = ' '.join([
'Context({})/Topology({})/Device({}) in {} mismatches acceptable Devices({}).',
'Optionally, leave field empty to use predefined Device({}).',
])
msg = msg.format(
ep_context_id, ep_topology_id, ep_device_id, parent_name, str(acceptable_device_ids), predefined_device_id)
raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)

Lluis Gifre Renom
committed
add_devices = add_topology_devices_endpoints.setdefault(ep_topology_id, dict())
if prevent_same_device_multiple_times and (ep_device_id in add_devices):

Lluis Gifre Renom
committed
msg = 'Duplicated Context({})/Topology({})/Device({}) in {}.'
msg = msg.format(ep_context_id, ep_topology_id, ep_device_id, parent_name)
raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
add_device_and_endpoints = add_devices.setdefault(ep_device_id, set())
# Implicit validation: same device cannot appear 2 times in the list of endpoints
if ep_port_id in add_device_and_endpoints: # pragma: no cover
msg = 'Duplicated Context({})/Topology({})/Device({})/Port({}) in {}.'
msg = msg.format(ep_context_id, ep_topology_id, ep_device_id, ep_port_id, parent_name)
raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
add_device_and_endpoints.add(ep_port_id)
return ep_topology_id, ep_device_id, ep_port_id