From e3b8c053778fc87b3007da756f9b1dc9eea7f017 Mon Sep 17 00:00:00 2001 From: Ivan Vazhenin Date: Sat, 4 Feb 2023 19:17:43 +0300 Subject: [PATCH] First commit --- .idea/.gitignore | 9 ++ main.py | 36 +++++ requests/__init__.py | 0 requests/messages.py | 232 ++++++++++++++++++++++++++++++++ requests/request_processor.py | 0 requests/request_xml_service.py | 107 +++++++++++++++ 6 files changed, 384 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 main.py create mode 100644 requests/__init__.py create mode 100644 requests/messages.py create mode 100644 requests/request_processor.py create mode 100644 requests/request_xml_service.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..5499ce7 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,9 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +/.idea \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..68db801 --- /dev/null +++ b/main.py @@ -0,0 +1,36 @@ +from xmlrpc.server import SimpleXMLRPCServer +import logging +import os + + +# Expose a function +def list_contents(dir_name): + logging.debug('list_contents(%s)', dir_name) + return os.listdir(dir_name) + + +def aud_add(message): + logging.debug(message) + return 'OK' + + +def auth_response(message, id, client): + logging.debug(id) + return {'error': False} + + +def main(): + logging.basicConfig(level=logging.DEBUG) + server = SimpleXMLRPCServer(('0.0.0.0', 9000), logRequests=True) + server.register_function(list_contents) + server.register_function(aud_add) + server.register_function(auth_response) + try: + print('Use Control-C to exit') + server.serve_forever() + except KeyboardInterrupt: + print('Exiting') + + +if __name__ == '__main__': + main() diff --git a/requests/__init__.py b/requests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/requests/messages.py b/requests/messages.py new file mode 100644 index 0000000..478d06d --- /dev/null +++ b/requests/messages.py @@ -0,0 +1,232 @@ +from enum import Enum + +class Messages(Enum): + REQUEST_EXECUTED_PARTITIALY = 1 + REQUEST_FAILED = 2 + OBJECT_FORBIDDEN = 3 + INVALID_REQUEST_USER = 4 + ACTION_FORBIDDEN = 5 + OBJECTS_FORBIDDEN = 6 + INVALID_REPLICATION_PARAMETERS = 7 + OBJECT_LIST = 11 + OBJECT_LIST_ITEM = 12 + MISSING_TAG = 13 + NO_OBJECTS_AVAILABLE = 14 + OBJECT_BASE_CELL_NOT_FOUND = 15 + WRONG_VERSION_INTERVAL = 16 + REQUEST_PROCESS_STARTED = 17 + REQUEST_PROCESS_FINISHED = 18 + USER_IS_NOT_VALID = 19 + RESPONSE_DELIVERY_ERROR = 20 + RESPONSE_DELIVERY_SUCCESS = 21 + RESPONSE_SEND = 22 + RESPONSE_SEND_ERROR = 23 + DUPLICATE_CHART_NAME = 24 + EXTENDED_METADATA_FORBIDDEN = 25 + MAX_RESULT_COUNT_EXCEEDED = 26 + MAX_RESULT_SIZE_EXCEEDED = 27 + CLIENT_DISCONNECTED = 28 + NO_REQUEST_DATA_PROVIDED = 29 + NO_USER_ID_PROVIDER = 30 + INVALID_REQUEST_DATA = 31 + UNKNOWN_FILTER_ATTRIBUTE_CODE = 32 + UNKNOWN_FILTER_OPERATION = 33 + ARCHIVE_ACCESS_FORBIDDEN = 34 + BROKEN_S57_FILE = 35 + UNKNOWN_OBJECT_ID = 36 + NO_FILTER_IN_REPORT = 37 + UPLOAD_OBJECT_LIST = 100 + UPLOAD_OBJECT_LIST_ITEM = 101 + UPLOAD_WRONG_STRUCTURE = 102 + FOLDER_NOT_FOUND = 103 + UPLOAD_WRONG_SUBVERSION = 104 + UPLOAD_MISSING_CHARTS_FILE = 105 + UPLOAD_NO_CHARTS_IN_FILE = 106 + UPLOAD_WRONG_CHART_TYPE = 107 + UPLOAD_OBJECT_EXISTS = 108 + UPLOAD_BASE_CELL_NOT_FOUND = 109 + UPLOAD_WRONG_VERSION_SEQUENCE = 110 + WRONG_DELETE_VERSION_NUMBER = 111 + CANT_CHANGE_STAMP = 112 + OBJECT_ALREADY_UPDATED = 113 + OBJECT_LOCKED = 114 + UPLOAD_MAIN_FILE_NOT_FOUND = 115 + UPLOAD_VERSION_NUMBER_NOT_THE_SAME = 116 + FROM_ADDRESS = 117 + TO_ADDRESS = 118 + UPLOAD_OBJECT_EXISTS_BY_SIZE_AND_CHECKSUM = 119 + CORRECTING_REPLICATION_TIMED_OUT = 120 + CORRECTING_REPLICATION_AUTO_STARTED = 121 + CORRECTING_REPLICATION_MANUAL_STARTED = 122 + CORRECTING_REPLICATION_ALREADY_STARTED = 123 + CORRECTING_REPLICATION_CANCELLED = 124 + REPLICATION_SENT = 125 + REPLICATION_RECEIVED = 126 + WRONG_OBJECT_FILE_CHECKSUM = 127 + WRONG_UPLOADING_FILE_CHECKSUM = 128 + WRONG_UPLOADING_FILE_SIZE = 129 + CORRECTING_REPLICATION_INFO = 130 + CORRECTING_REPLICATION_CLASSIFIER = 131 + CORRECTING_REPLICATION_LIST_OBJECT = 132 + GET_CORRECTING_REPLICATION_PACKAGE = 133 + CORRECTING_REPLICATION_SIZE_LIMIT = 134 + PACKAGE_INFO = 135 + CORRECTING_REPLICATION_SIZE_ARCHIVE = 136 + SET_CORRECTING_REPLICATION_PACKAGE = 137 + CHECK_DUPLICATE = 138 + CHECK_TAG = 139 + DELETED_DUPLICATE = 140 + STREAMING_REPLICATION_STARTED = 141 + ERROR_PACKAGE_NUM = 142 + STREAMING_REPLICATION_FINISHED = 143 + DELETE_VERSION_STARTED = 144 + DELETE_VERSION_FINISHED = 145 + UPLOAD_OBJECTS_EXISTS_DIFF_CHECKSUM = 146 + UPLOAD_OBJECTS_WITH_LESS_VERSION = 147 + CORRECTING_REPLICATION_OBJECT_COUNTS = 148 + PACKAGE_INFO_FAILED_OBJECTS = 149 + PACKAGE_INFO_INCOMING_OBJECTS = 150 + OBJECT_INFO_DIDNT_ADD = 151 + TAG_NOT_FOUND = 200 + MISSING_ATTRIBUTE = 201 + DUPLICATE_TAG_ID = 202 + CANT_HIDE_TAG = 203 + CANT_MOVE_TAG = 204 + CANT_HIDE_REGION = 205 + CANT_HIDE_REGIONS = 206 + CANT_HIDE_CHILD_REGION = 207 + CANT_HIDE_CHILD_REGIONS = 208 + WRONG_MID = 300 + MAUNFACTURER_KEY_NOT_FOUND = 301 + OBJECT_NOT_FOUND = 302 + OBJECT_REQUESTED_FROM_PARENT_SERVER = 303 + OBJECT_HAS_NO_FILES = 304 + WRONG_EXPIRATION_PERIOD = 400 + OBJECT_LIST_HAS_DUBLICATES = 401 + ACTIVE_SUBSCRIPTION_ALREADY_EXISTS = 402 + ACTIVE_SUBSCRIPTION_NOT_EXISTS = 403 + WRONG_TYPE_ALL_CHARTS = 500 + NO_CLASSIFIER_FILE_ON_SERVER = 600 + NO_CLASSIFIER_VERSION_ON_SERVER = 601 + CLASSIFIERS_VERSIONS_DIFFER = 602 + WRONG_OBJECT_PARAMETER_CODE = 603 + ILLEGAL_PARAMETER_VALUE = 604 + ILLEGAL_PARAMETER_TYPE = 605 + ILLEGAL_PARAMETER_RANGE = 606 + NOT_ALL_REQUIRED_TYPES = 607 + ILLEGAL_ATTRIBUTE_VALUE = 608 + NOT_ALLOWED_ITEM_FOR_TYPE = 609 + NO_CHART_CLASS_WITH_CODE = 610 + CHART_CLASS_CONTAINS_NONEXISTED_ELEMENT = 611 + CLASS_GROUP_CONTAINS_NONEXISTED_CLASS = 612 + SAME_CLASSIFIER_VERSION = 614 + NO_CLASSIFIER_VERSION = 615 + UNKNOWN_ATTR_VAL_DATA_TYPE = 616 + NOT_ALL_USING_ITEMS_IN_CLASSIFIER = 617 + NO_REQIRED_CLASS_CODE_IN_CLASSIFIER = 618 + REQUIRED_ADDED_TO_CHART_CLASS = 619 + SET_CLASSIFIER_STARTED_AUDIT = 620 + DATA_VALIDATION_STARTED_AUDIT = 621 + DATA_VALIDATION_FAILED_AUDIT = 622 + DATA_VALIDATION_ENDED_AUDIT = 623 + SAVING_CLASSIFIER_STARTED_AUDIT = 624 + SAVING_CLASSIFIER_FINISHED_AUDIT = 625 + SEND_SET_CLASSIFIER_REQUEST_AUDIT = 626 + GET_SET_CLASSIFIER_REQUEST_AUDIT = 627 + GET_GET_CLASSIFIER_REQUEST_AUDIT = 628 + IKP_USER_DECISION_TYPE = 700 + IKP_FILE_STRUCTURE_CHECKER_TYPE = 701 + IKP_FILE_STRUCTURE_DB_LINKS_CHECKER_TYPE = 702 + IKP_DB_LINKS_FILE_STRUCTURE_CHECKER_TYPE = 703 + IKP_CHECK_SUM_CHECKER_TYPE = 704 + IKP_BACKUP_TO_DB_TYPE = 705 + IKP_RECOVER_FROM_DB_TYPE = 706 + IKP_RECOVER_FROM_BACKUP_SERVER_TYPE = 707 + IKP_RECOVER_FROM_CHILD_SERVER_TYPE = 708 + IKP_DB_STRUCTURE_CHECKER_TYPE = 709 + IKP_DB_STRUCTURE_MISSING_COLUMN = 710 + IKP_DB_STRUCTURE_WRONG_COLUMN_TYPE = 711 + IKP_DB_STRUCTURE_WRONT_MAX_LENGTH = 712 + IKP_DB_STRUCTURE_MISSING_TABLE = 713 + IKP_NOTHING_TO_RECOVER = 714 + IKP_ERROR_NOT_FIXED = 715 + IKP_FULL_BACKUP_TO_DB_TYPE = 716 + EXPORT_TO_FOLDER_START = 717 + EXPORT_TO_FOLDER_FINISHED = 718 + EXPORT_TO_FOLDER_ERROR = 719 + EXPORT_TO_FOLDER_DELETE_FILE = 720 + IMPORT_FROM_FOLDER_START = 721 + IMPORT_FROM_FOLDER_FINISHED = 722 + IMPORT_FROM_FOLDER_ERROR = 723 + IMPORT_FOLDER_NOT_FOUND = 724 + FILE_NOT_FOUND = 725 + IMPORT_FROM_FOLDER_MERGE_ERROR = 726 + FILE_NOT_FOUND_COUNTER = 727 + LAST_CORRECTION_DATE_NEWER_THAN_NEW_CORRECTION = 728 + CREATION_DATE_MISSING = 729 + IMPORT_FROM_FOLDER_DIDNT_START = 730 + EXPORT_TO_FOLDER_DIDNT_START = 731 + IKP_STEP_START = 800 + IKP_STEP_SUCCESS = 801 + IKP_STEP_ERROR = 802 + IKP_NO_CHECK_ERROR_FOUND = 803 + IKP_SEND_USER_DECISION = 804 + IKP_GET_USER_DECISION = 805 + IKP_FILE_STRUCTURE_ERROR = 806 + IKP_FILE_STRUCTURE_DB_LINKS_ERROR = 807 + IKP_CHECK_SUM_ERROR = 808 + IKP_DB_LINKS_FILE_STRUCTURE_ERROR = 809 + IKP_DB_STRUCTURE_TABLE_COLUMN_ERROR = 810 + IKP_DB_STRUCTURE_TABLE_ERROR = 811 + IKP_STEP_STOPPED = 812 + IKP_WRONG_FILE_ERROR = 813 + IKP_TASK_RUN_COLLISION = 814 + IKP_FIX_SXF_METADATA_CHECKSUM_INFO = 815 + IKP_FIX_SXF_METADATA_CHECKSUM_PASSPORT_ERROR = 816 + IKP_FIX_SXF_METADATA_CHECKSUM_FILE_ERROR = 817 + IKP_MD_RECOVERING_STARTED = 818 + IKP_MD_RECOVERING_NO_VERSION = 819 + IKP_MD_RECOVERING_CREATED = 820 + IKP_MD_RECOVERING_UPDATED = 821 + IKP_MD_RECOVERING_SUCCEED = 822 + IKP_MD_RECOVERING_FAILED = 823 + IKP_CHECK_AVAILABLE_DISK_SPACE_TYPE = 825 + IKP_SCRIPT_RUN = 827 + IKP_SCRIPT_END_WORK_SUCCEED = 828 + IKP_SCRIPT_END_WORK_FAILED = 829 + IKP_SCRIPT_ALREADY_STARTED = 831 + IKP_MERGE_SAME_OBJECTS_INFO = 832 + IKP_MERGE_SAME_OBJECTS_SUCCESSES = 833 + IKP_MERGE_SAME_OBJECTS_WARNING = 834 + IKP_MERGE_SAME_OBJECTS_ERROR = 835 + IKP_MERGE_SAME_OBJECTS_MERGE_TYPE_VERSIONS = 836 + IKP_MERGE_SAME_OBJECTS_MERGE_TYPE_DATES = 837 + RSC_CLASSIFIER_UPLOAD_STARTED = 838 + RSC_CLASSIFIER_UPLOAD_ERROR = 839 + RSC_CLASSIFIER_UPLOAD_FINISHED = 843 + IKP_CLEAR_OUT_FOLDER_INFO = 840 + IKP_CLEAR_OUT_FOLDER_SUCCESS_DELETE = 841 + IKP_CLEAR_OUT_FOLDER_ERROR_DELETE = 842 + SET_CHART_METADATA = 844 + ERROR_WHILE_COPING_FILE = 845 + ERROR_ADD_OBJECT = 848 + MISSING_REGIONS_CHARTS = 849 + NO_MISSING_REGIONS = 850 + IKP_CLEAR_DOWNLOAD_CATALOG_WARNING = 855 + IKP_CLEAR_DOWNLOAD_CATALOG_ERROR = 856 + IKP_CLEAR_DOWNLOAD_CATALOG_INFO = 857 + REPLICATION_PACKAGE_NOT_FOUND = 858 + REPLICATION_PACKAGE_WRONG_STATUS = 859 + NOT_UNIQUE_METADATA = 860 + IKP_SCALE_RECOVERING_STARTED = 861 + IKP_SCALE_RECOVERING_FAILED = 862 + IKP_SCALE_RECOVERING_FINISHED = 863 + OBJECTS_REGIONS_CHECKING_STARTED = 865 + OBJECTS_REGIONS_CHECKING_FINISHED = 866 + OBJECTS_REGIONS_CHECKING_FAILED = 867 + BLACK_HOLE_TRANSMITTER_IS_OFF = 868 + LACK_VERSIONS_IN_TIME_PERIOD = 869 + ERROR_STOPPING_IKP = 870 + IKP_STOPPED = 871 + REPLICATION_ERROR_TEST = 872 + BLACK_HOLE_NOT_PRESENT = 873 diff --git a/requests/request_processor.py b/requests/request_processor.py new file mode 100644 index 0000000..e69de29 diff --git a/requests/request_xml_service.py b/requests/request_xml_service.py new file mode 100644 index 0000000..9703141 --- /dev/null +++ b/requests/request_xml_service.py @@ -0,0 +1,107 @@ +import xml.etree.ElementTree as ET +from messages import Messages + + +class RequestXmlService: + REQUEST_NODE_NAME: str = 'request' + HEADER_NODE_NAME: str = 'header' + RESULT_NODE_NAME: str = 'result' + REQUEST_ID_ATTRIBUTE_NAME: str = 'parcel_id' + RESPONSE_ID_ATTRIBUTE_NAME: str = 'reply_parcel_id' + SOURCE_REQUEST_ID_ATTRIBUTE_NAME: str = 'source_parcel_id' + RESULT_CODE_ATTRIBUTE_NAME: str = 'result_code' + RESULT_MESSAGE_ATTRIBUTE_NAME: str = 'result_message' + HEADER_XPATH: str = '/' + REQUEST_NODE_NAME + '/' + HEADER_NODE_NAME + + def get_request_uuid(self, document: ET.Element) -> str: + return self.get_header_attribute(document, self.REQUEST_ID_ATTRIBUTE_NAME) + + def get_response_uuid(self, document: ET.Element) -> str: + return self.get_header_attribute(document, self.RESPONSE_ID_ATTRIBUTE_NAME) + + def get_source_request_uuid(self, document: ET.Element) -> str: + return self.get_header_attribute(document, self.SOURCE_REQUEST_ID_ATTRIBUTE_NAME) + + def get_header_node(self, document: ET.Element) -> ET.Element: + return document.find(self.HEADER_XPATH) + + def get_header_attribute(self, document: ET.Element, attribute_name: str) -> str: + header = self.get_header_node(document) + if not header: + raise Exception(Messages.MISSING_TAG.value) + result = header.get(attribute_name) + return result.strip() if result else '' + + def get_request_document(self, request_uuid: str, response_uuid: str | None) -> ET.Element: + document = ET.Element(self.REQUEST_NODE_NAME) + header = ET.SubElement(document, self.HEADER_NODE_NAME) + header.set(self.REQUEST_ID_ATTRIBUTE_NAME, request_uuid.strip()) + if response_uuid: + header.set(self.RESPONSE_ID_ATTRIBUTE_NAME, response_uuid.strip()) + return document + + def get_common_response_xml(self, request_uuid: str, response_uuid: str, result_code: int, result_message: str) -> ET.Element: + document = self.get_request_document(response_uuid, request_uuid) + + result = ET.SubElement(document, self.RESULT_NODE_NAME) + result.set(self.RESULT_CODE_ATTRIBUTE_NAME, str(result_code)) + result.set(self.RESULT_MESSAGE_ATTRIBUTE_NAME, result_message) + + return document + + def set_result(self, document: ET.Element, result_code: int, result_message: str): + result = document.find(self.RESULT_NODE_NAME) + result.set(self.RESULT_CODE_ATTRIBUTE_NAME, str(result_code)) + result.set(self.RESULT_MESSAGE_ATTRIBUTE_NAME, result_message) + + def set_request_uuid(self, document: ET.Element, request_uuid: str): + header = self.get_header_node(document) + header.set(self.REQUEST_ID_ATTRIBUTE_NAME, request_uuid.strip()) + + def set_source_request_uuid(self, document: ET.Element, source_request_uuid: str): + header = self.get_header_node(document) + header.set(self.SOURCE_REQUEST_ID_ATTRIBUTE_NAME, source_request_uuid.strip()) + + def get_common_request_xml(self, request_uuid: str) -> ET.Element: + return self.get_request_document(request_uuid, None) + + def get_response_xml(self, document: ET.Element, request_uuid: str | None, response_uuid: str, result_code: int, result_message: str) -> ET.Element: + header = document.find(self.HEADER_NODE_NAME) + header.set(self.REQUEST_ID_ATTRIBUTE_NAME, response_uuid.strip()) + header.set(self.RESPONSE_ID_ATTRIBUTE_NAME, request_uuid.strip() if request_uuid else None) + result = document.find(self.RESULT_NODE_NAME) + result.set(self.RESULT_CODE_ATTRIBUTE_NAME, str(result_code)) + result.set(self.RESULT_MESSAGE_ATTRIBUTE_NAME, result_message) + + def get_element(self, document: ET.Element, node: ET.Element, name: str) -> ET.Element: + for child in node: + if child.tag.casefold() == name.casefold(): + return child + return ET.SubElement(document, name) + + def validate_common_request_xml(self, xml: str): + if not xml: + raise Exception(Messages.NO_REQUEST_DATA_PROVIDED.name) + try: + document = ET.parse(xml) + except: + raise Exception(Messages.INVALID_REQUEST_DATA) + self.validate_common_request_xml(document) + + def validate_common_request_xml(self, document: ET.Element | None): + if not document: + raise Exception(Messages.NO_REQUEST_DATA_PROVIDED.name) + if document.tag != self.REQUEST_NODE_NAME: + raise Exception(Messages.MISSING_TAG.name, self.REQUEST_NODE_NAME) + try: + request_uuid = self.get_header_attribute(document, self.REQUEST_ID_ATTRIBUTE_NAME) + except: + raise Exception(Messages.INVALID_REQUEST_DATA) + if not request_uuid: + raise Exception(Messages.MISSING_ATTRIBUTE, self.REQUEST_ID_ATTRIBUTE_NAME, self.HEADER_NODE_NAME) + + def get_result_code(self, document: ET.Element) -> str | None: + result = self.get_element(document, document, self.RESULT_NODE_NAME) + if not result: + return None + return result.get(self.RESULT_CODE_ATTRIBUTE_NAME)