Skip to content
Snippets Groups Projects
Commit 6908f606 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Adapted Context to common proto folder:

- Arranged .gitignore & .gitkeep files in common proto folder
- Created specific run_tests_locally script for Context component
- Moved imports from *.proto folder to common.proto folder
- Adapted common.tools.object_factory to new proto definitions for ConfigRule and Constraint
- Extended common.tools.type_checkers to new proto definitions for ConfigRule and Constraint
- Removed context's genproto.sh script
- Adapted Events generated to new timestamp data type
- Minor code and linting fixing
parent 4d33b6b1
No related branches found
No related tags found
1 merge request!54Release 2.0.0
Showing
with 116 additions and 104 deletions
!.gitkeep
*.dot *.dot
*.xml *.xml
* *
!.gitkeep
# used to prevent breaking symbolic links from source code folders
!.gitignore
!__init__.py
* *
!.gitkeep
# used to prevent breaking symbolic links from source code folders # prevent breaking symbolic links on Python source code folders
!.gitignore
!__init__.py !__init__.py
#!/bin/bash
# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
...@@ -12,3 +13,22 @@ ...@@ -12,3 +13,22 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
PROJECTDIR=`pwd`
cd $PROJECTDIR/src
RCFILE=$PROJECTDIR/coverage/.coveragerc
K8S_NAMESPACE="tf-dev"
K8S_HOSTNAME="kubernetes-master"
export REDIS_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
export REDIS_SERVICE_PORT=$(kubectl get service redis-tests --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==6379)].nodePort}')
# Run unitary tests and analyze coverage of code at same time
# Useful flags for pytest:
#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
context/tests/test_unitary.py
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
import json, logging import json, logging
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
from common.proto.context_pb2 import (
ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, LinkEvent, ServiceEvent, TopologyEvent)
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.EventsCollector import EventsCollector from context.client.EventsCollector import EventsCollector
from context.proto.context_pb2 import (
ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, LinkEvent, ServiceEvent, TopologyEvent)
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
......
...@@ -14,13 +14,17 @@ ...@@ -14,13 +14,17 @@
import grpc, logging import grpc, logging
from typing import Any, Dict, Iterator, List from typing import Any, Dict, Iterator, List
from common.proto.context_pb2 import (
Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList,
Context, ContextEvent, ContextId, ContextIdList, ContextList,
Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList,
Empty,
Link, LinkEvent, LinkId, LinkIdList, LinkList,
Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList,
Slice, SliceEvent, SliceId, SliceIdList, SliceList,
Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList)
from common.proto.context_pb2_grpc import ContextServiceServicer
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.proto.context_pb2 import (
Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId,
ContextIdList, ContextList, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, Empty, Link, LinkEvent,
LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent,
SliceId, SliceIdList, SliceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList)
from context.proto.context_pb2_grpc import ContextServiceServicer
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
......
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
import grpc, logging import grpc, logging
from common.Settings import get_setting from common.Settings import get_setting
from common.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty
from common.proto.device_pb2 import MonitoringSettings
from common.proto.device_pb2_grpc import DeviceServiceServicer
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from context.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty
from device.proto.device_pb2 import MonitoringSettings
from device.proto.device_pb2_grpc import DeviceServiceServicer
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
......
...@@ -15,10 +15,10 @@ ...@@ -15,10 +15,10 @@
import grpc, logging import grpc, logging
from queue import Queue from queue import Queue
from common.proto.context_pb2 import Empty
from common.proto.monitoring_pb2 import Kpi
from common.proto.monitoring_pb2_grpc import MonitoringServiceServicer
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from monitoring.proto.context_pb2 import Empty
from monitoring.proto.monitoring_pb2 import Kpi
from monitoring.proto.monitoring_pb2_grpc import MonitoringServiceServicer
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
......
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
import grpc, logging import grpc, logging
from common.Settings import get_setting from common.Settings import get_setting
from common.proto.context_pb2 import Empty, Service, ServiceId, ServiceStatusEnum
from common.proto.service_pb2_grpc import ServiceServiceServicer
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from service.proto.context_pb2 import Empty, Service, ServiceId, ServiceStatusEnum
from service.proto.service_pb2_grpc import ServiceServiceServicer
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
...@@ -37,7 +37,7 @@ class MockServicerImpl_Service(ServiceServiceServicer): ...@@ -37,7 +37,7 @@ class MockServicerImpl_Service(ServiceServiceServicer):
LOGGER.info('[UpdateService] request={:s}'.format(grpc_message_to_json_string(request))) LOGGER.info('[UpdateService] request={:s}'.format(grpc_message_to_json_string(request)))
service = Service() service = Service()
service.CopyFrom(request) service.CopyFrom(request)
service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE #pylint: disable=no-member
return self.context_client.SetService(service) return self.context_client.SetService(service)
def DeleteService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty: def DeleteService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty:
......
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
import grpc, logging import grpc, logging
from common.Settings import get_setting from common.Settings import get_setting
from common.proto.context_pb2 import Empty, Slice, SliceId, SliceStatusEnum
from common.proto.slice_pb2_grpc import SliceServiceServicer
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from slice.proto.context_pb2 import Empty, Slice, SliceId, SliceStatusEnum
from slice.proto.slice_pb2_grpc import SliceServiceServicer
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
......
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
import json import json
from typing import Any, Dict, Union from typing import Any, Dict, Union
from context.proto.context_pb2 import ConfigActionEnum from common.proto.context_pb2 import ConfigActionEnum
def json_config_rule(action : ConfigActionEnum, resource_key : str, resource_value : Union[str, Dict[str, Any]]): def json_config_rule(action : ConfigActionEnum, resource_key : str, resource_value : Union[str, Dict[str, Any]]):
if not isinstance(resource_value, str): resource_value = json.dumps(resource_value, sort_keys=True) if not isinstance(resource_value, str): resource_value = json.dumps(resource_value, sort_keys=True)
return {'action': action, 'resource_key': resource_key, 'resource_value': resource_value} return {'action': action, 'custom': {'resource_key': resource_key, 'resource_value': resource_value}}
def json_config_rule_set(resource_key : str, resource_value : Union[str, Dict[str, Any]]): def json_config_rule_set(resource_key : str, resource_value : Union[str, Dict[str, Any]]):
return json_config_rule(ConfigActionEnum.CONFIGACTION_SET, resource_key, resource_value) return json_config_rule(ConfigActionEnum.CONFIGACTION_SET, resource_key, resource_value)
......
...@@ -17,4 +17,4 @@ from typing import Any, Dict, Union ...@@ -17,4 +17,4 @@ from typing import Any, Dict, Union
def json_constraint(constraint_type : str, constraint_value : Union[str, Dict[str, Any]]): def json_constraint(constraint_type : str, constraint_value : Union[str, Dict[str, Any]]):
if not isinstance(constraint_value, str): constraint_value = json.dumps(constraint_value, sort_keys=True) if not isinstance(constraint_value, str): constraint_value = json.dumps(constraint_value, sort_keys=True)
return {'constraint_type': constraint_type, 'constraint_value': constraint_value} return {'custom': {'constraint_type': constraint_type, 'constraint_value': constraint_value}}
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
import copy import copy
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
from common.DeviceTypes import DeviceTypeEnum from common.DeviceTypes import DeviceTypeEnum
from common.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum
from common.tools.object_factory.ConfigRule import json_config_rule_set from common.tools.object_factory.ConfigRule import json_config_rule_set
from context.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusEnum
DEVICE_DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED DEVICE_DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
import copy import copy
from typing import Dict, List, Optional from typing import Dict, List, Optional
from common.Constants import DEFAULT_CONTEXT_UUID from common.Constants import DEFAULT_CONTEXT_UUID
from common.proto.context_pb2 import ServiceStatusEnum, ServiceTypeEnum
from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Context import json_context_id
from context.proto.context_pb2 import ServiceStatusEnum, ServiceTypeEnum
def get_service_uuid(a_endpoint_id : Dict, z_endpoint_id : Dict) -> str: def get_service_uuid(a_endpoint_id : Dict, z_endpoint_id : Dict) -> str:
return 'svc:{:s}/{:s}=={:s}/{:s}'.format( return 'svc:{:s}/{:s}=={:s}/{:s}'.format(
......
...@@ -12,8 +12,9 @@ ...@@ -12,8 +12,9 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# ----- Enumerations --------------------------------------------------------------------------------------------------- from typing import Dict
# ----- Enumerations ---------------------------------------------------------------------------------------------------
def validate_config_action_enum(message): def validate_config_action_enum(message):
assert isinstance(message, str) assert isinstance(message, str)
assert message in [ assert message in [
...@@ -79,15 +80,26 @@ def validate_uuid(message, allow_empty=False): ...@@ -79,15 +80,26 @@ def validate_uuid(message, allow_empty=False):
if allow_empty: return if allow_empty: return
assert len(message['uuid']) > 1 assert len(message['uuid']) > 1
CONFIG_RULE_TYPES = {
'custom',
'acl',
}
def validate_config_rule(message): def validate_config_rule(message):
assert isinstance(message, dict) assert isinstance(message, dict)
assert len(message.keys()) == 3 assert len(message.keys()) == 2
assert 'action' in message assert 'action' in message
validate_config_action_enum(message['action']) validate_config_action_enum(message['action'])
assert 'resource_key' in message other_keys = set(list(message.keys()))
assert isinstance(message['resource_key'], str) other_keys.discard('action')
assert 'resource_value' in message config_rule_type = other_keys.pop()
assert isinstance(message['resource_value'], str) assert config_rule_type in CONFIG_RULE_TYPES
assert config_rule_type == 'custom', 'ConfigRule Type Validator for {:s} not implemented'.format(config_rule_type)
custom : Dict = message['custom']
assert len(custom.keys()) == 2
assert 'resource_key' in custom
assert isinstance(custom['resource_key'], str)
assert 'resource_value' in custom
assert isinstance(custom['resource_value'], str)
def validate_config_rules(message): def validate_config_rules(message):
assert isinstance(message, dict) assert isinstance(message, dict)
...@@ -95,13 +107,28 @@ def validate_config_rules(message): ...@@ -95,13 +107,28 @@ def validate_config_rules(message):
assert 'config_rules' in message assert 'config_rules' in message
for config_rule in message['config_rules']: validate_config_rule(config_rule) for config_rule in message['config_rules']: validate_config_rule(config_rule)
CONSTRAINT_TYPES = {
'custom',
'schedule',
'endpoint_location',
'sla_capacity',
'sla_latency',
'sla_availability',
'sla_isolation',
}
def validate_constraint(message): def validate_constraint(message):
assert isinstance(message, dict) assert isinstance(message, dict)
assert len(message.keys()) == 2 assert len(message.keys()) == 1
assert 'constraint_type' in message other_keys = list(message.keys())
assert isinstance(message['constraint_type'], str) constraint_type = other_keys[0]
assert 'constraint_value' in message assert constraint_type in CONSTRAINT_TYPES
assert isinstance(message['constraint_value'], str) assert constraint_type == 'custom', 'Constraint Type Validator for {:s} not implemented'.format(constraint_type)
custom : Dict = message['custom']
assert len(custom.keys()) == 2
assert 'constraint_type' in custom
assert isinstance(custom['constraint_type'], str)
assert 'constraint_value' in custom
assert isinstance(custom['constraint_value'], str)
# ----- Identifiers ---------------------------------------------------------------------------------------------------- # ----- Identifiers ----------------------------------------------------------------------------------------------------
......
...@@ -18,12 +18,16 @@ from common.Constants import ServiceNameEnum ...@@ -18,12 +18,16 @@ from common.Constants import ServiceNameEnum
from common.Settings import get_service_host, get_service_port_grpc from common.Settings import get_service_host, get_service_port_grpc
from common.tools.client.RetryDecorator import retry, delay_exponential from common.tools.client.RetryDecorator import retry, delay_exponential
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.proto.context_pb2 import ( from common.proto.context_pb2 import (
Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId, Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList,
ContextIdList, ContextList, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, Empty, Link, LinkEvent, Context, ContextEvent, ContextId, ContextIdList, ContextList,
LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList,
SliceId, SliceIdList, SliceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList) Empty,
from context.proto.context_pb2_grpc import ContextServiceStub Link, LinkEvent, LinkId, LinkIdList, LinkList,
Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList,
Slice, SliceEvent, SliceId, SliceIdList, SliceList,
Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList)
from common.proto.context_pb2_grpc import ContextServiceStub
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
MAX_RETRIES = 15 MAX_RETRIES = 15
......
...@@ -13,9 +13,9 @@ ...@@ -13,9 +13,9 @@
# limitations under the License. # limitations under the License.
import grpc, logging, queue, threading import grpc, logging, queue, threading
from common.proto.context_pb2 import Empty
from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json_string
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from context.proto.context_pb2 import Empty
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG) LOGGER.setLevel(logging.DEBUG)
...@@ -80,7 +80,7 @@ class EventsCollector: ...@@ -80,7 +80,7 @@ class EventsCollector:
event = self.get_event(block=block, timeout=timeout) event = self.get_event(block=block, timeout=timeout)
if event is None: continue if event is None: continue
events.append(event) events.append(event)
return sorted(events, key=lambda e: e.event.timestamp) return sorted(events, key=lambda e: e.event.timestamp.timestamp)
def stop(self): def stop(self):
self._context_stream.cancel() self._context_stream.cancel()
......
#!/bin/bash -eu
#
# 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.
# Make folder containing the script the root folder for its execution
cd $(dirname $0)
rm -rf proto/*.py
rm -rf proto/__pycache__
tee proto/__init__.py << EOF > /dev/null
# 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.
EOF
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto acl.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context-policy.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto policy.proto
rm proto/acl_pb2_grpc.py
rm proto/kpi_sample_types_pb2_grpc.py
rm proto/policy_pb2_grpc.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/acl_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2_grpc.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_policy_pb2_grpc.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_policy_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/policy_pb2.py
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment