1313
1414logging .basicConfig (format = "%(levelname)s:%(asctime)s: %(message)s" )
1515logger = logging .getLogger (__name__ )
16-
17- emap_db = db .starDB ()
18- emap_db .init_query ()
19- emap_db .connect ()
16+ logger .setLevel (settings .LOG_LEVEL )
17+ # logger.addFilter(DedupeFilter(window_seconds=60))
2018
2119
2220class waveform_message :
@@ -42,57 +40,78 @@ def reject_message(ch, delivery_tag, requeue):
4240 logger .warning ("Attempting to not acknowledge a message on a closed channel." )
4341
4442
45- def waveform_callback (ch , method_frame , _header_frame , body ):
46- data = json .loads (body )
47- try :
48- location_string = data ["mappedLocationString" ]
49- observation_timestamp = data ["observationTime" ]
50- source_variable_id = data ["sourceVariableId" ]
51- source_channel_id = data ["sourceChannelId" ]
52- sampling_rate = data ["samplingRate" ]
53- units = data ["unit" ]
54- waveform_data = data ["numericValues" ]
55- mapped_location_string = data ["mappedLocationString" ]
56- except IndexError as e :
57- reject_message (ch , method_frame .delivery_tag , False )
58- logger .error (
59- f"Waveform message { method_frame .delivery_tag } is missing required data { e } ."
60- )
61- return
43+ class WaveformController :
44+ def __init__ (self ):
45+ self .emap_db = db .starDB ()
46+ self .emap_db .init_query ()
47+ self .emap_db .connect ()
48+
49+ def waveform_callback (self , ch , method_frame , _header_frame , body ):
50+ logger .debug ("Message received of length %s" , len (body ))
51+ data = json .loads (body )
52+ try :
53+ location_string = data ["mappedLocationString" ]
54+ observation_timestamp = data ["observationTime" ]
55+ source_variable_id = data ["sourceVariableId" ]
56+ source_channel_id = data ["sourceChannelId" ]
57+ sampling_rate = data ["samplingRate" ]
58+ units = data ["unit" ]
59+ waveform_data = data ["numericValues" ]
60+ mapped_location_string = data ["mappedLocationString" ]
61+ logger .debug (
62+ "Message is for loc %s, var %s, ch %s" ,
63+ location_string ,
64+ source_variable_id ,
65+ source_channel_id ,
66+ )
67+ except KeyError as e :
68+ reject_message (ch , method_frame .delivery_tag , False )
69+ logger .error (
70+ f"Waveform message { method_frame .delivery_tag } is missing required data { e } ."
71+ )
72+ return
6273
63- observation_time = datetime .fromtimestamp (observation_timestamp , tz = timezone .utc )
64- lookup_success = True
65- try :
66- matched_mrn = emap_db .get_row (location_string , observation_time )
67- except ValueError :
68- lookup_success = False
69- logger .error (
70- "Ambiguous or non existent match for location %s, obs time %s" ,
71- location_string ,
72- observation_time ,
73- exc_info = True ,
74+ observation_time = datetime .fromtimestamp (
75+ observation_timestamp , tz = timezone .utc
7476 )
75- matched_mrn = ( "unmatched_mrn" , "unmatched_nhs" , "unmatched_csn" )
76- except ConnectionError :
77- logger . error ( "Database error, will try again" , exc_info = True )
78- reject_message ( ch , method_frame . delivery_tag , True )
79- return
80-
81- if writer . write_frame (
82- waveform_data ,
83- source_variable_id ,
84- source_channel_id ,
85- observation_timestamp ,
86- units ,
87- sampling_rate ,
88- mapped_location_string ,
89- matched_mrn [ 2 ],
90- matched_mrn [ 0 ],
91- ):
92- if lookup_success :
93- ack_message ( ch , method_frame . delivery_tag )
94- else :
77+ lookup_success = True
78+ try :
79+ matched_mrn = self . emap_db . get_row ( location_string , observation_time )
80+ except ValueError :
81+ lookup_success = False
82+ logger . error (
83+ "Ambiguous or non existent match for location %s, obs time %s" ,
84+ location_string ,
85+ observation_time ,
86+ exc_info = True ,
87+ )
88+ matched_mrn = ( "unmatched_mrn" , "unmatched_nhs" , "unmatched_csn" , False )
89+ except ConnectionError :
90+ logger . error ( "Database error, will try again" , exc_info = True )
91+ reject_message ( ch , method_frame . delivery_tag , True )
92+ return
93+
94+ ( mrn , nhs_no , csn , opt_out ) = matched_mrn
95+ if opt_out :
96+ logger . info ( "Research opt-out is set for mrn %s, not writing." , mrn )
9597 reject_message (ch , method_frame .delivery_tag , False )
98+ return
99+
100+ if writer .write_frame (
101+ waveform_data ,
102+ source_variable_id ,
103+ source_channel_id ,
104+ observation_timestamp ,
105+ units ,
106+ sampling_rate ,
107+ mapped_location_string ,
108+ csn ,
109+ mrn ,
110+ ):
111+ if lookup_success :
112+ ack_message (ch , method_frame .delivery_tag )
113+ else :
114+ reject_message (ch , method_frame .delivery_tag , False )
96115
97116
98117def receiver ():
@@ -105,18 +124,27 @@ def receiver():
105124 host = settings .RABBITMQ_HOST ,
106125 port = settings .RABBITMQ_PORT ,
107126 )
127+ logger .info ("Connecting to RabbitMQ %s" , connection_parameters )
108128 connection = pika .BlockingConnection (connection_parameters )
109129 channel = connection .channel ()
110130 channel .basic_qos (prefetch_count = 1 )
111131
132+ controller = WaveformController ()
112133 channel .basic_consume (
113134 queue = settings .RABBITMQ_QUEUE ,
114135 auto_ack = False ,
115- on_message_callback = waveform_callback ,
136+ on_message_callback = controller . waveform_callback ,
116137 )
138+ logger .info ("Connected to RabbitMQ, callback configured" )
117139 try :
118140 channel .start_consuming ()
119141 except KeyboardInterrupt :
142+ logger .warning ("Received keyboard interrupt, exiting." )
120143 channel .stop_consuming ()
144+ except Exception as e :
145+ logger .error ("Received other exception" )
146+ logger .error (e )
147+ raise e
121148
149+ logger .info ("Closing connection to RabbitMQ" )
122150 connection .close ()
0 commit comments