Index: cloudsync/handlers/outgoing/handler_cs_to_dcs.py =================================================================== diff -u -r2f2b589bf3423d45de7c382f1a4b06babfac647b -rfc55dd5d0ee3e2382081ff67612185e21bc5dfc4 --- cloudsync/handlers/outgoing/handler_cs_to_dcs.py (.../handler_cs_to_dcs.py) (revision 2f2b589bf3423d45de7c382f1a4b06babfac647b) +++ cloudsync/handlers/outgoing/handler_cs_to_dcs.py (.../handler_cs_to_dcs.py) (revision fc55dd5d0ee3e2382081ff67612185e21bc5dfc4) @@ -65,19 +65,20 @@ return data.get("access_token", None) except requests.exceptions.Timeout: - error = Error("{0},2,{1},Obtain token request timeout".format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_GET_NEW_TOKEN_WITH_CERT_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_GET_NEW_TOKEN_WITH_CERT_ERROR.value, + "Obtain token request timeout") error_handler.enqueue_error(error=error) return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_GET_NEW_TOKEN_WITH_CERT_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_GET_NEW_TOKEN_WITH_CERT_ERROR.value) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_GET_NEW_TOKEN_WITH_CERT_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_GET_NEW_TOKEN_WITH_CERT_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) return None @@ -103,22 +104,30 @@ resp = requests.post(url=url, data=json.dumps(data), +<<<<<<< HEAD headers=headers) +======= + headers=headers, + timeout=(30, 60)) +>>>>>>> bugfix/DENBUG-331-duplicate-device-logs-uploade g_utils.logger.info(f"Token verification response: {resp.status_code}") return resp except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VERIFY_TOKEN_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VERIFY_TOKEN_ERROR.value) error_handler.enqueue_error(error=error) + return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VERIFY_TOKEN_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VERIFY_TOKEN_ERROR.value) error_handler.enqueue_error(error=error) + return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VERIFY_TOKEN_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VERIFY_TOKEN_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None @log_func @@ -149,39 +158,39 @@ response = requests.post(url=url, headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value) error_handler.enqueue_error(error=error) return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None try: return response.json() except json.decoder.JSONDecodeError as e: - error = Error("{0},3,{1},Could not validate device. Received: {2}:{3},Exception: {4}".format( - OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value, - response.status_code, - response.reason, - str(e))) + error = Error.validation(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value, + response.status_code, response.reason, str(e)) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_VALIDATE_DEVICE_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None # Runtime commands @@ -209,21 +218,25 @@ payload = device_state_json resp = requests.put(url=url, headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) return resp except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SEND_DEVICE_STATE_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SEND_DEVICE_STATE_ERROR.value) error_handler.enqueue_error(error=error) + return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SEND_DEVICE_STATE_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SEND_DEVICE_STATE_ERROR.value) error_handler.enqueue_error(error=error) + return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SEND_DEVICE_STATE_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SEND_DEVICE_STATE_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None @log_func @@ -239,39 +252,39 @@ } response = requests.get(url=url, - headers=headers) + headers=headers, + timeout=(30, 60)) except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value) error_handler.enqueue_error(error=error) return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None try: return response except json.decoder.JSONDecodeError as e: - error = Error("{0},3,{1},Could not check if the patient exists. Received: {2}:{3},Exception: {4}".format( - OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value, - response.status_code, - response.reason, - str(e))) + error = Error.validation(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value, + response.status_code, response.reason, str(e)) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CHECK_IF_PATIENT_WITH_EMR_ID_EXISTS_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None @log_func @@ -290,39 +303,39 @@ response = requests.post(url=url, headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value) error_handler.enqueue_error(error=error) return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None try: return response.json() except json.decoder.JSONDecodeError as e: - error = Error("{0},3,{1},Could not create temporary patient. Received: {2}:{3},Exception: {4}".format( - OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value, - response.status_code, - response.reason, - str(e))) + error = Error.validation(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value, + response.status_code, response.reason, str(e)) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_CREATE_TEMPORARY_PATIENT_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None @log_func @@ -350,30 +363,36 @@ if associate: resp = requests.head(url=urllib.parse.urljoin(url, "/exists"), headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) if resp.status_code == NOT_FOUND: resp = requests.put(url=url, headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) else: resp = requests.delete(url=url, headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) return resp except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SET_PATIENT_DEVICE_ASSOCIATION_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SET_PATIENT_DEVICE_ASSOCIATION_ERROR.value) error_handler.enqueue_error(error=error) + return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SET_PATIENT_DEVICE_ASSOCIATION_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SET_PATIENT_DEVICE_ASSOCIATION_ERROR.value) error_handler.enqueue_error(error=error) + return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SET_PATIENT_DEVICE_ASSOCIATION_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SET_PATIENT_DEVICE_ASSOCIATION_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) + return None @log_func @@ -401,22 +420,23 @@ resp = requests.post(url=url, headers=headers, - data=payload) + data=payload, + timeout=(30, 60)) return resp except requests.exceptions.Timeout: - error = Error(REGISTRATION_TIMEOUT_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SEND_TREATMENT_REPORT_ERROR.value)) + error = Error.timeout(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SEND_TREATMENT_REPORT_ERROR.value) error_handler.enqueue_error(error=error) return None except requests.exceptions.TooManyRedirects: - error = Error(TOO_MANY_REDIRECTS_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SEND_TREATMENT_REPORT_ERROR.value)) + error = Error.redirect(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SEND_TREATMENT_REPORT_ERROR.value) error_handler.enqueue_error(error=error) return None except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value, - ErrorIDs.CS_SEND_TREATMENT_REPORT_ERROR.value, - str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, + ErrorIDs.CS_SEND_TREATMENT_REPORT_ERROR.value, + str(e)) error_handler.enqueue_error(error=error) return None @@ -456,7 +476,7 @@ # Start upload session # - start_session_url = os.path.join(base_url, "api/device/data/start-session") + start_session_url = base_url.rstrip("/") + "/api/device/data/start-session" start_session_payload = file_json['start_session'] start_session_payload = json.dumps(start_session_payload) headers = { @@ -473,21 +493,22 @@ response = requests.post( url=start_session_url, headers=headers, - data=start_session_payload) + data=start_session_payload, + timeout=(30, 60)) g_utils.logger.info(f"Start-session response: {response.status_code}") if response.status_code != 200: g_utils.logger.error(f"Start-session failed: {response.status_code} - {response.text[:500]}") raise Exception(f"Error while starting upload session: {response.status_code} - {response.text}") except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value,ERROR_ID,str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, ERROR_ID, str(e)) error_handler.enqueue_error(error=error) return None session_id = response.json().get("sessionId") if not session_id: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value,ERROR_ID,"Missing session ID in response.")) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, ERROR_ID, "Missing session ID in response.") error_handler.enqueue_error(error=error) return None @@ -498,7 +519,7 @@ try: target_file = file_json['general']["file_path"] file_size = file_json['general']["file_size"] - upload_chunk_url = os.path.join(base_url, "api/device/data/chunk") + upload_chunk_url = base_url.rstrip("/") + "/api/device/data/chunk" upload_chunk_payload = file_json['upload_chunk'] upload_chunk_payload['sessionId'] = session_id upload_chunk_payload['chunkType'] = "device-data" @@ -543,7 +564,8 @@ response = requests.post(upload_chunk_url, headers=headers, - data=upload_chunk_payload) + data=upload_chunk_payload, + timeout=(30, 60)) if response.status_code == 200: chunk_number += 1 @@ -557,11 +579,11 @@ retry_count += 1 except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value,ERROR_ID,str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, ERROR_ID, str(e)) error_handler.enqueue_error(error=error) except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value,ERROR_ID,str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, ERROR_ID, str(e)) error_handler.enqueue_error(error=error) return None @@ -579,7 +601,11 @@ else: g_utils.logger.warning("Token refresh returned None, using existing token for end-session") +<<<<<<< HEAD end_session_url = os.path.join(base_url, "api/device/data/end-session") +======= + end_session_url = base_url.rstrip("/") + "/api/device/data/end-session" +>>>>>>> bugfix/DENBUG-331-duplicate-device-logs-uploade end_session_payload = file_json['end_session'] end_session_payload['sessionId'] = session_id end_session_payload['completedAt'] = int(datetime.now(timezone.utc).timestamp()*1000) @@ -595,15 +621,21 @@ g_utils.logger.debug(f"Device log upload payload (end-session): {end_session_payload}") response = requests.post(end_session_url, headers=headers, - data=end_session_payload) + data=end_session_payload, + timeout=(30, 60)) + if response.status_code == CONFLICT: + device_file_name = str(file_json['start_session']['metadata']['deviceFileName']) + g_utils.logger.info(f"File {device_file_name} rejected as duplicate (409 Conflict).") + return {"accepted": False, "filename": device_file_name, "reason_code": LogUploadReasonCode.DUPLICATE.value} + g_utils.logger.info(f"End-session response: {response.status_code}") if response.status_code != 200: g_utils.logger.error(f"End-session failed: {response.status_code} - {response.text[:500]}") raise Exception(f"Error while ending upload session: {response.status_code} - {response.text}") except Exception as e: - error = Error(GENERAL_EXCEPTION_HOLDER.format(OutboundMessageIDs.CS2UI_ERROR.value,ERROR_ID,str(e))) + error = Error.general(OutboundMessageIDs.CS2UI_ERROR.value, ERROR_ID, str(e)) error_handler.enqueue_error(error=error) return None