def process(self): """call transform and error if needed""" transformed = self._transform() delivered = self.ftp.unzip_and_deliver(settings.FTP_FOLDER, transformed) if not delivered: self.logger.error("Failed to deliver zip to ftp") raise RetryableError("Failed to deliver zip to ftp") return
def process(self): transformed = self._transform() delivered = self.ftp.unzip_and_deliver( self._get_ftp_folder(self.survey), transformed) if not delivered: self.logger.error("Failed to deliver zip to ftp") raise RetryableError("Failed to deliver zip to ftp") return
def remote_call(url, json=None): service = service_name(url) try: logger.info("Calling service", request_url=url, service=service) response = None if json: response = session.post(url, json=json) else: response = session.get(url) return response except MaxRetryError: logger.error("Max retries exceeded (5)", request_url=url) raise RetryableError("Max retries exceeded") except ConnectionError: logger.error("Connection error", request_url=url) raise RetryableError("Connection error")
def _send_for_anti_virus_check(self, filename, contents): url = settings.ANTI_VIRUS_BASE_URL headers = { "filename": filename, "rule": settings.ANTI_VIRUS_RULE, "user_agent": settings.ANTI_VIRUS_USER_AGENT, } self._add_api_key(headers) self.bound_logger.info("Sending for A/V scan", url=url) try: response = self.session.post(url=url, headers=headers, data=contents) except requests.RequestException: self.bound_logger.exception( "Error sending request to Anti-virus server") raise RetryableError() self._check_av_response(response) self.bound_logger.info("Response received", response=response.text) try: result = response.json() except (ValueError, TypeError): self.bound_logger.exception("Unable to decode A/V results") raise RetryableError() if result.get("err"): self.bound_logger.error("Unable to send file for anti virus scan", error=result.get("err")) self.bound_logger.info("Waiting before attempting again") time.sleep(settings.ANTI_VIRUS_WAIT_TIME) self.bound_logger.info("Return message to rabbit") raise RetryableError() data_id = result.get("data_id") self.bound_logger.info("File sent successfully for anti virus scan", data_id=data_id) return data_id
def _send_to_ftp(self, decoded_contents, file_path, file_name, tx_id): try: self._ftp.deliver_binary(file_path, file_name, decoded_contents) logger.debug("Delivered to FTP server", tx_id=tx_id, file_path=file_path, file_name=file_name) except IOError as e: logger.error("Unable to deliver to the FTP server", action="nack", exception=str(e), tx_id=tx_id) raise RetryableError()
def send_for_av_scan(self, payload): """Sends the file to the anti-virus service to be scanned. This function is blocking as it repeatedly checks every few seconds (as defined by the ANTI_VIRUS_WAIT_TIME variable) to see if the scan is done, only proceeding once it's complete. Raises a QuarantinableError if the file is deemed not safe. """ self.bound_logger.info("Sending for AV check", filename=payload.file_name) data_id = self._send_for_anti_virus_check(payload.file_name, payload.decoded_contents) self.bound_logger.info("Sent for A/V check", data_id=data_id) # this loop will block the consumer until the anti virus finishes # in a future iteration we should make this asynchronous so that we # can process multiple messages attempts = 0 while attempts <= settings.ANTI_VIRUS_MAX_ATTEMPTS: attempts += 1 results = self._get_anti_virus_result(data_id) if not results.ready: self.bound_logger.info("Results not ready", attempts=attempts, case_id=payload.case_id, filename=payload.file_name) time.sleep(settings.ANTI_VIRUS_WAIT_TIME) elif not results.safe: self._write_scan_report(results, payload.file_name) self.bound_logger.error("Unsafe file detected", case_id=payload.case_id, filename=payload.file_name) raise QuarantinableError() else: self.bound_logger.info( "File has been virus checked and confirmed safe", case_id=payload.case_id, filename=payload.file_name) return True # out of attempts raise retryable error to force the response back to the queue. self.bound_logger.error("Unable to get results of Anti-virus scan", attempts=attempts, case_id=payload.case_id, filename=payload.file_name) raise RetryableError()
def _get_sequence_number(): """return the sequence number else raise a Retryable Error""" sequence_no = get_sequence_no() if sequence_no is None: raise RetryableError("Failed to get sequence number") return sequence_no