Skip to content

Commit

Permalink
DPNLPF-2192: Outgoing message validation
Browse files Browse the repository at this point in the history
  • Loading branch information
bart0003 committed Feb 9, 2024
1 parent 69e29b1 commit b8b8072
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 10 deletions.
7 changes: 7 additions & 0 deletions smart_kit/message/as_is_to_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@


class AsIsToMessage(SmartAppToMessage):
@property
def message_name(self) -> str:
return self.command.name

@property
def incremental_id(self) -> int:
return self.incoming_message.incremental_id

@cached_property
def as_dict(self):
Expand Down
2 changes: 1 addition & 1 deletion smart_kit/message/validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
def get_validators_from_settings(validator_group: str, settings: Settings, model: SmartAppModel) \
-> List[BaseMessageValidator]:
validators = settings["template_settings"].get("validators", {})
return [dynamic_import_object(e["class"])(resources=model.resources, **e["params"])
return [dynamic_import_object(e["class"])(validator_group=validator_group, resources=model.resources, **e["params"])
for e in validators.get(validator_group, [])]
12 changes: 10 additions & 2 deletions smart_kit/message/validators/json_schema_validator.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from __future__ import annotations

from pathlib import Path
from typing import Callable, TYPE_CHECKING
from typing import Callable, TYPE_CHECKING, Optional
import jsonschema
from jsonschema.validators import RefResolver

from core.message.message import SmartAppMessage
from core.logging.logger_utils import log
from core.message.validators.base_validator import OnException
from smart_kit.message.validators.base_validator_with_resources import BaseMessageValidatorWithResources
from smart_kit.resources import SmartAppResources

if TYPE_CHECKING:
from core.message.from_message import SmartAppFromMessage
Expand All @@ -16,10 +18,16 @@
class JSONSchemaValidator(BaseMessageValidatorWithResources):
VALIDATOR_EXCEPTION = jsonschema.ValidationError

def __init__(self, validator_group: str = "incoming",
resources: Optional[SmartAppResources] = None,
on_exception: OnException = "raise", *args, **kwargs):
self._message_type = validator_group if validator_group in ("incoming", "outgoing") else "incoming"
super().__init__(resources, on_exception, *args, **kwargs)

def _update_resources(self):
self._store = self.resources.get("payload_schema")
self._schemas = {Path(k).stem: self._compile_schema(k, v) for k, v in self._store.items()
if len(Path(k).parents) == 1}
if k.startswith(f"/{self._message_type}/")}

def _compile_schema(self, uri: str, schema: dict) -> Callable[[dict], None]:
cls = jsonschema.validators.validator_for(schema)
Expand Down
4 changes: 2 additions & 2 deletions smart_kit/start_points/base_main_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def __init__(
self.postprocessor = postprocessor_cls()
self.db_adapter = self.get_db()
self.is_work = True
self.from_msg_validators = get_validators_from_settings("from", settings, model)
self.to_msg_validators = get_validators_from_settings("to", settings, model)
self.from_msg_validators = get_validators_from_settings("incoming", settings, model)
self.to_msg_validators = get_validators_from_settings("outgoing", settings, model)

template_settings = self.settings["template_settings"]
save_tries = template_settings.get("user_save_collisions_tries", 0)
Expand Down
2 changes: 1 addition & 1 deletion smart_kit/testing/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def process_message(self, raw_message: Dict, headers: tuple = ()) -> Tuple[Any,
masking_fields = self.settings["template_settings"].get("masking_fields")
message = SmartAppFromMessage(
raw_message, headers=headers, masking_fields=masking_fields,
validators=get_validators_from_settings("from", self.settings, self.app_model)
validators=get_validators_from_settings("incoming", self.settings, self.app_model)
)
user = self.__user_cls(self.environment.user_id, message, self.user_data, self.settings,
self.app_model.scenario_descriptions,
Expand Down
18 changes: 14 additions & 4 deletions smart_kit/testing/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ async def _run(self) -> bool:

callbacks = {}
app_callback_id = None

incoming_message_validators = get_validators_from_settings("incoming", self.settings, self.app_model)
outgoing_message_validators = get_validators_from_settings("outgoing", self.settings, self.app_model)
for index, raw_msg in enumerate(self.messages):
print('Шаг', index)
if index and self.interactive:
Expand Down Expand Up @@ -239,7 +242,7 @@ async def _run(self) -> bool:

message = self.create_message(
request, headers=headers,
validators=get_validators_from_settings("from", self.settings, self.app_model)
validators=incoming_message_validators
)

if not message.validate():
Expand All @@ -255,7 +258,14 @@ async def _run(self) -> bool:
self.post_setup_user(user)

commands = [command async for command in self.app_model.answer(message, user)]
answers = self._generate_answers(user=user, commands=commands, message=message)
answers = self._generate_answers(user=user, commands=commands, message=message,
validators=outgoing_message_validators)

for answer in answers:
if not answer.validate():
print(f"[!] Outgoing message {answer.message_name} validation failed.")
return False

answers.extend(self._generate_history_answers(user, message))

predefined_fields_resp = response.get("predefined_fields")
Expand Down Expand Up @@ -285,15 +295,15 @@ async def run(self) -> bool:
finally:
self.finalize()

def _generate_answers(self, user, commands, message):
def _generate_answers(self, user, commands, message, validators):
answers = []
commands = commands or []

commands = combine_commands(commands, user)

for command in commands:
request = SmartKitKafkaRequest(id=None, items=command.request_data)
answer = SmartAppToMessage(command=command, message=message, request=request)
answer = SmartAppToMessage(command=command, message=message, request=request, validators=validators)
answers.append(answer)
return answers

Expand Down

0 comments on commit b8b8072

Please sign in to comment.