From e2f061fde038363d5f973afd074f233f04f3a037 Mon Sep 17 00:00:00 2001 From: Chris McCarthy Date: Mon, 13 May 2024 07:58:43 +0100 Subject: [PATCH] #2561 - Set the DatabaseServer service to automatically install the upon install to enable backup. Added some defensive statements that gracefully handle backup/restore requests when FTPClient is not installed. --- .../services/database/database_service.py | 39 ++++++++++++++----- .../system/test_database_on_node.py | 5 +++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/primaite/simulator/system/services/database/database_service.py b/src/primaite/simulator/system/services/database/database_service.py index 519b6512..0872074f 100644 --- a/src/primaite/simulator/system/services/database/database_service.py +++ b/src/primaite/simulator/system/services/database/database_service.py @@ -42,6 +42,11 @@ class DatabaseService(Service): super().__init__(**kwargs) self._create_db_file() + def install(self): + super().install() + if not self.software_manager.software.get("FTPClient"): + self.sys_log.info(f"{self.name}: Installing FTPClient to enable database backups") + self.software_manager.install(FTPClient) def configure_backup(self, backup_server: IPv4Address): """ Set up the database backup. @@ -64,9 +69,17 @@ class DatabaseService(Service): software_manager: SoftwareManager = self.software_manager ftp_client_service: FTPClient = software_manager.software.get("FTPClient") + if not ftp_client_service: + self.sys_log.error( + f"{self.name}: Failed to perform database backup as the FTPClient software is not installed" + ) + return False + # send backup copy of database file to FTP server if not self.db_file: - self.sys_log.error("Attempted to backup database file but it doesn't exist.") + self.sys_log.error( + f"{self.name}: Attempted to backup database file but it doesn't exist." + ) return False response = ftp_client_service.send_file( @@ -92,6 +105,12 @@ class DatabaseService(Service): software_manager: SoftwareManager = self.software_manager ftp_client_service: FTPClient = software_manager.software.get("FTPClient") + if not ftp_client_service: + self.sys_log.error( + f"{self.name}: Failed to restore database backup as the FTPClient software is not installed" + ) + return False + # retrieve backup file from backup server response = ftp_client_service.request_file( src_folder_name=str(self.uuid), @@ -151,11 +170,11 @@ class DatabaseService(Service): return str(uuid4()) def _process_connect( - self, - src_ip: IPv4Address, - connection_request_id: str, - password: Optional[str] = None, - session_id: Optional[str] = None, + self, + src_ip: IPv4Address, + connection_request_id: str, + password: Optional[str] = None, + session_id: Optional[str] = None, ) -> Dict[str, Union[int, Dict[str, bool]]]: """Process an incoming connection request. @@ -196,10 +215,10 @@ class DatabaseService(Service): } def _process_sql( - self, - query: Literal["SELECT", "DELETE", "INSERT", "ENCRYPT"], - query_id: str, - connection_id: Optional[str] = None, + self, + query: Literal["SELECT", "DELETE", "INSERT", "ENCRYPT"], + query_id: str, + connection_id: Optional[str] = None, ) -> Dict[str, Union[int, List[Any]]]: """ Executes the given SQL query and returns the result. diff --git a/tests/integration_tests/system/test_database_on_node.py b/tests/integration_tests/system/test_database_on_node.py index 8a2a9793..a0b47d2e 100644 --- a/tests/integration_tests/system/test_database_on_node.py +++ b/tests/integration_tests/system/test_database_on_node.py @@ -356,3 +356,8 @@ def test_client_connection_terminate_does_not_terminate_another_clients_connecti assert db_connection_b.query("SELECT") assert len(db_service.connections) == 1 + +def test_database_server_install_ftp_client(): + server = Server(hostname="db_server", ip_address="192.168.1.2", subnet_mask="255.255.255.0", start_up_duration=0) + server.software_manager.install(DatabaseService) + assert server.software_manager.software.get("FTPClient") \ No newline at end of file