diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index 7b7a039f3783fb166ba73641eeba79aec21bda54..f91f36cf5bf73669e4010c8c65d9c4cabd9c6e2e 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -29,7 +29,7 @@ from common.proto.context_pb2 import ( Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList) 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) +from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule LOGGER = logging.getLogger(__name__) MAX_RETRIES = 15 @@ -59,38 +59,6 @@ class ContextClient: self.stub = None self.policy_stub = None - - @RETRY_DECORATOR - def ListPolicyRuleIds(self, request: Empty) -> PolicyRuleIdList: - LOGGER.debug('ListPolicyRuleIds request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.policy_stub.ListPolicyRuleIds(request) - LOGGER.debug('ListPolicyRuleIds result: {:s}'.format(grpc_message_to_json_string(response))) - return response - @RETRY_DECORATOR - def ListPolicyRules(self, request: Empty) -> PolicyRuleList: - LOGGER.debug('ListPolicyRules request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.policy_stub.ListPolicyRules(request) - LOGGER.debug('ListPolicyRules result: {:s}'.format(grpc_message_to_json_string(response))) - return response - @RETRY_DECORATOR - def GetPolicyRule(self, request: PolicyRuleId) -> PolicyRule: - LOGGER.info('GetPolicyRule request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.policy_stub.GetPolicyRule(request) - LOGGER.info('GetPolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) - return response - @RETRY_DECORATOR - def SetPolicyRule(self, request: PolicyRule) -> PolicyRuleId: - LOGGER.debug('SetPolicyRule request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.policy_stub.SetPolicyRule(request) - LOGGER.debug('SetPolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) - return response - @RETRY_DECORATOR - def RemovePolicyRule(self, request: PolicyRuleId) -> Empty: - LOGGER.debug('RemovePolicyRule request: {:s}'.format(grpc_message_to_json_string(request))) - response = self.policy_stub.RemovePolicyRule(request) - LOGGER.debug('RemovePolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) - return response - @RETRY_DECORATOR def ListContextIds(self, request: Empty) -> ContextIdList: LOGGER.debug('ListContextIds request: {:s}'.format(grpc_message_to_json_string(request))) @@ -398,3 +366,38 @@ class ContextClient: response = self.stub.GetConnectionEvents(request) LOGGER.debug('GetConnectionEvents result: {:s}'.format(grpc_message_to_json_string(response))) return response + + @RETRY_DECORATOR + def ListPolicyRuleIds(self, request: Empty) -> PolicyRuleIdList: + LOGGER.debug('ListPolicyRuleIds request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.policy_stub.ListPolicyRuleIds(request) + LOGGER.debug('ListPolicyRuleIds result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def ListPolicyRules(self, request: Empty) -> PolicyRuleList: + LOGGER.debug('ListPolicyRules request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.policy_stub.ListPolicyRules(request) + LOGGER.debug('ListPolicyRules result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def GetPolicyRule(self, request: PolicyRuleId) -> PolicyRule: + LOGGER.info('GetPolicyRule request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.policy_stub.GetPolicyRule(request) + LOGGER.info('GetPolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def SetPolicyRule(self, request: PolicyRule) -> PolicyRuleId: + LOGGER.debug('SetPolicyRule request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.policy_stub.SetPolicyRule(request) + LOGGER.debug('SetPolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def RemovePolicyRule(self, request: PolicyRuleId) -> Empty: + LOGGER.debug('RemovePolicyRule request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.policy_stub.RemovePolicyRule(request) + LOGGER.debug('RemovePolicyRule result: {:s}'.format(grpc_message_to_json_string(response))) + return response diff --git a/src/context/service/database/PolicyRuleModel.py b/src/context/service/database/PolicyRuleModel.py index 02adbfa07f98e9fd02b6dd303cfe3159cbf23da6..7c84ea940482091a5667b2f11272748c7b444b6f 100644 --- a/src/context/service/database/PolicyRuleModel.py +++ b/src/context/service/database/PolicyRuleModel.py @@ -14,22 +14,19 @@ import logging import json -from typing import Dict, List, Optional, Tuple +from typing import Dict from common.orm.fields.PrimaryKeyField import PrimaryKeyField from common.orm.fields.StringField import StringField from common.orm.model.Model import Model LOGGER = logging.getLogger(__name__) - class PolicyRuleModel(Model): pk = PrimaryKeyField() value = StringField(required=True, allow_empty=False) def dump_id(self) -> Dict: - return { - "uuid": {"uuid": self.pk} - } + return {'uuid': {'uuid': self.pk}} def dump(self) -> Dict: return json.loads(self.value) diff --git a/src/context/service/grpc_server/Constants.py b/src/context/service/grpc_server/Constants.py index 25a2fce40afab86beba2fdae1a8ce3f436011e07..9d7c886c725d22308f33dc274234ad17f595633d 100644 --- a/src/context/service/grpc_server/Constants.py +++ b/src/context/service/grpc_server/Constants.py @@ -19,9 +19,7 @@ TOPIC_DEVICE = 'device' TOPIC_LINK = 'link' TOPIC_SERVICE = 'service' TOPIC_SLICE = 'slice' -TOPIC_POLICY = 'policy' -TOPICS = {TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_TOPOLOGY, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE, - TOPIC_POLICY} +TOPICS = {TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_TOPOLOGY, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE} CONSUME_TIMEOUT = 0.5 # seconds diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py index 4a45e4f627da9480c02045e5bbcba47802ab92c5..f8dd188198606805e42449c3d690c20d3ad45f03 100644 --- a/src/context/service/grpc_server/ContextServiceServicerImpl.py +++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py @@ -33,6 +33,7 @@ from common.proto.context_pb2_grpc import ContextServiceServicer from common.proto.context_policy_pb2_grpc import ContextPolicyServiceServicer from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException +from common.tools.grpc.Tools import grpc_message_to_json from context.service.database.ConfigModel import update_config from context.service.database.ConnectionModel import ConnectionModel, set_path from context.service.database.ConstraintModel import set_constraints @@ -51,8 +52,7 @@ from context.service.database.SliceModel import SliceModel, grpc_to_enum__slice_ from context.service.database.TopologyModel import TopologyModel from .Constants import ( CONSUME_TIMEOUT, TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE, - TOPIC_TOPOLOGY, TOPIC_POLICY) -from common.tools.grpc.Tools import grpc_message_to_json_string, grpc_message_to_json + TOPIC_TOPOLOGY) LOGGER = logging.getLogger(__name__) @@ -820,7 +820,8 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer yield ConnectionEvent(**json.loads(message.content)) - # ----- Policy ---------------------------------------------------------------------------------------------------- + # ----- Policy ----------------------------------------------------------------------------------------------------- + @safe_and_metered_rpc_method(METRICS, LOGGER) def ListPolicyRuleIds(self, request: Empty, context: grpc.ServicerContext) -> PolicyRuleIdList: with self.lock: @@ -833,8 +834,7 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer with self.lock: db_policy_rules: List[PolicyRuleModel] = get_all_objects(self.database, PolicyRuleModel) db_policy_rules = sorted(db_policy_rules, key=operator.attrgetter('pk')) - res = PolicyRuleList(policyRules=[db_policy_rule.dump_id() for db_policy_rule in db_policy_rules]) - return res + return PolicyRuleList(policyRules=[db_policy_rule.dump() for db_policy_rule in db_policy_rules]) @safe_and_metered_rpc_method(METRICS, LOGGER) def GetPolicyRule(self, request: PolicyRuleId, context: grpc.ServicerContext) -> PolicyRule: @@ -848,15 +848,14 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer with self.lock: policy_rule_type = request.WhichOneof('policy_rule') policy_rule_json = grpc_message_to_json(request) - policy_rule_uuid = policy_rule_json[policy_rule_type]["policyRuleBasic"]["policyRuleId"]["uuid"]["uuid"] + policy_rule_uuid = policy_rule_json[policy_rule_type]['policyRuleBasic']['policyRuleId']['uuid']['uuid'] result: Tuple[PolicyRuleModel, bool] = update_or_create_object( - self.database, PolicyRuleModel, policy_rule_uuid, {"value": json.dumps(policy_rule_json)}) - db_policy, updated = result + self.database, PolicyRuleModel, policy_rule_uuid, {'value': json.dumps(policy_rule_json)}) + db_policy, updated = result # pylint: disable=unused-variable - event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE + #event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE dict_policy_id = db_policy.dump_id() - notify_event(self.messagebroker, TOPIC_POLICY, event_type, {"policy_id": dict_policy_id}) - + #notify_event(self.messagebroker, TOPIC_POLICY, event_type, {"policy_id": dict_policy_id}) return PolicyRuleId(**dict_policy_id) @safe_and_metered_rpc_method(METRICS, LOGGER) @@ -865,11 +864,10 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer policy_uuid = request.uuid.uuid db_policy = PolicyRuleModel(self.database, policy_uuid, auto_load=False) found = db_policy.load() - if not found: - return Empty() + if not found: return Empty() dict_policy_id = db_policy.dump_id() db_policy.delete() - event_type = EventTypeEnum.EVENTTYPE_REMOVE - notify_event(self.messagebroker, TOPIC_POLICY, event_type, {"policy_id": dict_policy_id}) + #event_type = EventTypeEnum.EVENTTYPE_REMOVE + #notify_event(self.messagebroker, TOPIC_POLICY, event_type, {"policy_id": dict_policy_id}) return Empty() diff --git a/src/context/service/rest_server/Resources.py b/src/context/service/rest_server/Resources.py index d1738edb20361dab70334bc026d94d37c654127a..5f03132a34004388596ce1fdfac470f029c093ea 100644 --- a/src/context/service/rest_server/Resources.py +++ b/src/context/service/rest_server/Resources.py @@ -17,6 +17,7 @@ from flask.json import jsonify from flask_restful import Resource from common.orm.Database import Database from common.proto.context_pb2 import ConnectionId, ContextId, DeviceId, Empty, LinkId, ServiceId, SliceId, TopologyId +from common.proto.policy_pb2 import PolicyRuleId from common.tools.grpc.Tools import grpc_message_to_json from context.service.grpc_server.ContextServiceServicerImpl import ContextServiceServicerImpl @@ -61,6 +62,11 @@ def grpc_topology_id(context_uuid, topology_uuid): 'topology_uuid': {'uuid': topology_uuid} }) +def grpc_policy_rule_id(policy_rule_uuid): + return PolicyRuleId(**{ + 'uuid': {'uuid': policy_rule_uuid} + }) + class _Resource(Resource): def __init__(self, database : Database) -> None: super().__init__() @@ -151,6 +157,18 @@ class Connection(_Resource): def get(self, connection_uuid : str): return format_grpc_to_json(self.servicer.GetConnection(grpc_connection_id(connection_uuid), None)) +class PolicyRuleIds(_Resource): + def get(self): + return format_grpc_to_json(self.servicer.ListPolicyRuleIds(Empty(), None)) + +class PolicyRules(_Resource): + def get(self): + return format_grpc_to_json(self.servicer.ListPolicyRules(Empty(), None)) + +class PolicyRule(_Resource): + def get(self, policy_rule_uuid : str): + return format_grpc_to_json(self.servicer.GetPolicyRule(grpc_policy_rule_id(policy_rule_uuid), None)) + class DumpText(Resource): def __init__(self, database : Database) -> None: super().__init__() @@ -219,6 +237,10 @@ RESOURCES = [ ('api.connections', Connections, '/context//service//connections'), ('api.connection', Connection, '/connection/'), + ('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'), + ('api.policyrules', PolicyRules, '/policyrules'), + ('api.policyrule', PolicyRule, '/policyrule/'), + ('api.dump.text', DumpText, '/dump/text'), ('api.dump.html', DumpHtml, '/dump/html'), ] diff --git a/src/context/tests/Objects.py b/src/context/tests/Objects.py index 4b435528bd927e1daf57f5b357759dd452cf3965..1cf929cfa578e8bbf8f95885cc2a7bc7e7b9f3ef 100644 --- a/src/context/tests/Objects.py +++ b/src/context/tests/Objects.py @@ -203,5 +203,4 @@ CONNECTION_R1_R3 = json_connection( # ----- PolicyRule ------------------------------------------------------------------------------------------------------- POLICY_RULE_UUID = '56380225-3e40-4f74-9162-529f8dcb96a1' POLICY_RULE_ID = json_policy_rule_id(POLICY_RULE_UUID) -POLICY_RULE = json_policy_rule(POLICY_RULE_UUID, policy_rule_type='POLICYTYPE_DEVICE') - +POLICY_RULE = json_policy_rule(POLICY_RULE_UUID) diff --git a/src/context/tests/test_unitary.py b/src/context/tests/test_unitary.py index d37436677182a9ef4157c6c0e720925a3db7adb5..9ad978a4121059dc41b3fb4efa93082370c40f9f 100644 --- a/src/context/tests/test_unitary.py +++ b/src/context/tests/test_unitary.py @@ -1180,8 +1180,8 @@ def test_grpc_policy( context_database.clear_all() # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- - events_collector = EventsCollector(context_client_grpc) - events_collector.start() + #events_collector = EventsCollector(context_client_grpc) + #events_collector.start() # ----- Get when the object does not exist ------------------------------------------------------------------------- POLICY_ID = 'no-uuid' @@ -1213,13 +1213,10 @@ def test_grpc_policy( assert response.uuid.uuid == POLICY_RULE_UUID # ----- Check create event ----------------------------------------------------------------------------------------- - # events = events_collector.get_events(block=True, count=2) - # assert isinstance(events[0], TopologyEvent) + # events = events_collector.get_events(block=True, count=1) + # assert isinstance(events[0], PolicyEvent) # assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_CREATE # assert events[0].policy_id.uuid.uuid == POLICY_RULE_UUID - # - # assert isinstance(events[1], ContextEvent) - # assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_CREATE # ----- Update the object ------------------------------------------------------------------------------------------ response = context_client_grpc.SetPolicyRule(PolicyRule(**POLICY_RULE)) @@ -1250,8 +1247,8 @@ def test_grpc_policy( # ----- Check remove event ----------------------------------------------------------------------------------------- # events = events_collector.get_events(block=True, count=2) - # - # assert isinstance(events[0], TopologyEvent) + + # assert isinstance(events[0], PolicyEvent) # assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE # assert events[0].policy_id.uuid.uuid == POLICY_RULE_UUID @@ -1324,6 +1321,22 @@ def test_rest_get_service(context_service_rest : RestServer): # pylint: disable= reply = do_rest_request('/context/{:s}/service/{:s}'.format(context_uuid, service_uuid)) validate_service(reply) +def test_rest_get_slice_ids(context_slice_rest : RestServer): # pylint: disable=redefined-outer-name + context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_UUID) + reply = do_rest_request('/context/{:s}/slice_ids'.format(context_uuid)) + #validate_slice_ids(reply) + +def test_rest_get_slices(context_slice_rest : RestServer): # pylint: disable=redefined-outer-name + context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_UUID) + reply = do_rest_request('/context/{:s}/slices'.format(context_uuid)) + #validate_slices(reply) + +#def test_rest_get_slice(context_slice_rest : RestServer): # pylint: disable=redefined-outer-name +# context_uuid = urllib.parse.quote(DEFAULT_CONTEXT_UUID) +# slice_uuid = urllib.parse.quote(SLICE_R1_R2_UUID, safe='') +# reply = do_rest_request('/context/{:s}/slice/{:s}'.format(context_uuid, slice_uuid)) +# #validate_slice(reply) + def test_rest_get_device_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name reply = do_rest_request('/device_ids') validate_device_ids(reply) @@ -1367,6 +1380,19 @@ def test_rest_get_connection(context_service_rest : RestServer): # pylint: disab reply = do_rest_request('/connection/{:s}'.format(connection_uuid)) validate_connection(reply) +def test_rest_get_policyrule_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name + reply = do_rest_request('/policyrule_ids') + #validate_policyrule_ids(reply) + +def test_rest_get_policyrules(context_service_rest : RestServer): # pylint: disable=redefined-outer-name + reply = do_rest_request('/policyrules') + #validate_policyrules(reply) + +#def test_rest_get_policyrule(context_service_rest : RestServer): # pylint: disable=redefined-outer-name +# policyrule_uuid = urllib.parse.quote(POLICYRULE_UUID, safe='') +# reply = do_rest_request('/policyrule/{:s}'.format(policyrule_uuid)) +# #validate_policyrule(reply) + # ----- Test misc. Context internal tools ------------------------------------------------------------------------------