def _handle(ip_whitelist, req): '''Route to RACIE Legacy service. Assumes we're always POSTing.''' log.info('in') # Confirm requesting IP is in whitelist, or bail. if not ip_is_whitelisted(req['client_ip'], ip_whitelist): log.info('client_ip of {} is not whitelisted.'.format( req.get('client_ip'))) return {'status': 403} status = -1 try: raw_data = (req.get('data', '')) log.info('DET payload from REDCap: {}'.format(raw_data)) log.info('About to call RACIE Legacy...') outgoing_data = rc.parse_det_payload(raw_data) rslt = requests.post(racie_legacy_url, data=outgoing_data) status = rslt.status_code msg = rslt.text log.info('Result of RACIE Legacy call: status is {}; message is {}.'\ ''.format(status, msg)) log.info('out') return {'status': status} except Exception, ex: log.error(traceback.format_exc()) ks.send_email(study_cfg[env_tag]['from-email'], study_cfg[env_tag]['to-email'], 'Boost Transmitter Exception', 'Please check the log.') return {'status': 500}
def create_jira_ticket(redcap_env, projectid, rcd): name_first = rcd['name_first'] name_last = rcd['name_last'] mrn = rcd['mrn'] name_mrn = name_first + ' ' + name_last + ' (' + mrn + ')' date_withdrawn = calc_date_withdrawn(rcd) env_tag = aou_common.get_env_tag_for_handler(str(redcap_env + str(projectid))) jira_spec = aou_config.get(env_tag).get('jira-spec') jira_project = aou_config.get(env_tag).get('jira-project') jira_summary = study_details.get('pi') protocol_num = study_details.get('protocol-number') if env_tag != 'prod' and jira_project == 'OBC': jira_summary += jira_test_msg additional_fields = {} if jira_project == 'OBC': additional_fields['customfield_10190'] = name_mrn additional_fields['customfield_10070'] = protocol_num additional_fields['customfield_10191'] = date_withdrawn # customfield_10193 below is Withdrawal Reason; 10424 means "Pt. Withdrew" additional_fields['customfield_10193'] = {'id': '10424'} result = jira.create_issue(jira_spec ,jira_project ,jira_kind ,jira_summary ,None # exclude description ,None # exclude assignee ,additional_fields) try: ks.send_email(aou_config.get(env_tag).get('jira-ping-from-email') ,aou_config.get(env_tag).get('jira-ping-to-email') ,'jira withdrawal result' ,str(result) + "\n" + "record: "+rcd['record_id'] + "\n" + str(redcap_env + str(projectid))) except Exception, ex: log.error('Attempting to send Jira ping email but failed: ' + str(ex))
def send_new_cols_email(list_of_cols): msg = ('One or more new columns were found in the recently deposited ' +'HealthPro CSV: {}'.format(list_of_cols)) try: ks.send_email(from_email, to_email, 'Notice of New Column(s) in HealthPro CSV', msg) except Exception, ex: print msg log.error('Error when trying to email: ' + str(ex))
def handle(req): try: pyld = rc.parse_det_payload(req['data']) log.info('Parsed contents of DET payload: ' + str(pyld)) msg = 'Received trigger payload from REDCap. Details: \n' \ 'REDCap Server IP: {} \n' \ 'Project ID: {} \n' \ 'Record ID: {} \n' \ ''.format(req['client_ip'], pyld['project_id'], pyld['record']) log.info('Sending email, body is: \n' + msg) ks.send_email(FROM_EMAIL, TO_EMAIL, 'Transmitter Test Email', msg) return {'status': 200} except Exception, e: log.error('Got error; returning status 500; details: ' + str(e)) return {'status': 500}
def create_jira_ticket(redcap_server_tag, projectid, rcd, request): '''Creates Jira ticket. Returns the result of calling jiralib. Note: assumption is that should_create_jira_ticket returned true (if not, you're going to potentially have a bad time).''' name_first = rcd['name_first'] name_last = rcd['name_last'] mrn = rcd['mrn'] date_enrolled = rcd['enroll_date'] description = (description_template.replace('$FIRST$', name_first).replace( '$LAST$', name_last).replace('$DOB$', rcd.get('dob')).replace( '$MRN$', mrn).replace('$RECORDID$', rcd.get('record_id')).replace('$DATE_ENROLLED$', date_enrolled)) env_tag = request['env-tag'] study_tag = request['study-tag'] study_config = common.get_study_config(study_tag) jira_spec = study_config[env_tag]['jira-spec'] jira_project = study_config[env_tag]['jira-project'] my_summary = jira_summary if env_tag != 'prod' and jira_project == 'OBC': my_summary += jira_test_msg additional_fields = {} if jira_project == 'OBC': additional_fields['customfield_10070'] = protocol_num result = jira.create_issue( jira_spec, jira_project, jira_kind, my_summary, description, None # exclude assignee , additional_fields) if study_config.get('send-jira-ping-emails') == 'yes': try: ks.send_email( study_config[env_tag]['jira-ping-from-email'], study_config[env_tag]['jira-ping-to-email'], 'jira enrollment result', str( str(result) + "\n" + "record: " + rcd['record_id'] + "\n" + str(redcap_server_tag + str(projectid)))) except Exception, ex: log.error('Attempting to send Jira ping email but failed: ' + str(ex))
def __not_used__transition_jira_ticket(result): '''Transition ticket from Open to Begin CREST Registration; This is a higher-level function that in turn ultimately calls transition_to_begin_crest_reg(). Arguments: - result: the result from create_jira_ticket, with addl items added: jira-spec, and env-tag. Returns transition result (straight from jiralib.do_transition) ... or {status:'-1'} if we didn't try (e.g. ticket is not OBC, etc.)''' if result['status'] != 201: return {'status': -1} ticket_id = json.loads(result.get('payload')).get('key') # This transition is specific to the OBC Jira project. if "OBC" not in ticket_id: log.info('Will not transition; ticket is not an OBC ticket.') return {'status': -1} jira_spec = result.get( 'jira-spec') # should've been added by create_jira_ticket env_tag = result.get('env-tag') transition_rslt = transition_to_begin_crest_reg(jira_spec, ticket_id) msg = 'ticket {} transition result: {}'.format(ticket_id, transition_rslt) if transition_rslt == 204: log.info(msg) else: log.error(msg) # Set assignee -- after transitions, assignee has changed. jira_user = aou_config.get(env_tag).get('jira-user') log.info('About to set ticket {} to assignee of {}.'\ ''.format(ticket_id, jira_user)) assignee_rslt = jira.set_assignee(jira_spec, ticket_id, jira_user) if assignee_rslt.get('status') != 204: raise Exception('Failed to set ticket {} to assignee {}.'\ ''.format(ticket_id, jira_user)) else: log.info('assignee update was a success.') try: ks.send_email( aou_config.get(env_tag).get('jira-ping-from-email'), aou_config.get(env_tag).get('jira-ping-to-email'), 'jira enrollment transitions result', str('ticket {} transition result: {}'.format( ticket_id, transition_rslt))) except Exception, ex: log.error('Attempting to send Jira ping email but failed: ' + str(ex))
def create_jira_ticket(redcap_env, projectid, rcd): '''Creates jira ticket, returns result. Also attaches the jira_spec data structure and env_tag to the result for subsequent functions to use.''' name_first = rcd['name_first'] name_last = rcd['name_last'] mrn = rcd['mrn'] date_enrolled = today_as_str() if rcd.get('enroll_date', '') != '': date_enrolled = rcd.get('enroll_date') description = (description_template.replace('$FIRST$', name_first).replace( '$LAST$', name_last).replace('$MRN$', mrn).replace('$DATE_ENROLLED$', date_enrolled)) env_tag = aou_common.get_env_tag_for_handler( str(redcap_env + str(projectid))) jira_spec = aou_config.get(env_tag).get('jira-spec') jira_project = aou_config.get(env_tag).get('jira-project') my_summary = jira_summary if env_tag != 'prod' and jira_project == 'OBC': my_summary += jira_test_msg additional_fields = {} if jira_project == 'OBC': additional_fields['customfield_10070'] = protocol_num result = jira.create_issue( jira_spec, jira_project, jira_kind, my_summary, description, None # exclude assignee , additional_fields) try: ks.send_email( aou_config.get(env_tag).get('jira-ping-from-email'), aou_config.get(env_tag).get('jira-ping-to-email'), 'jira enrollment result', str(result) + "\n" + "record: " + rcd['record_id'] + "\n" + str(redcap_env + str(projectid))) except Exception, ex: log.error('Attempting to send Jira ping email but failed: ' + str(ex))
def _handle(redcap_env, project_id, req): '''This func is used by compose_handler below. Generally, you won't invoke this func directly.''' log.info('=============== Entered. ==================') study_cfg = get_study_config('aou') # Confirm requesting IP is in whitelist, or bail. if not ip_is_whitelisted(req['client_ip'], study_cfg.get('whitelist')): log.info('For AoU, client_ip of ' + req['client_ip'] + ' is not whitelisted.') return {'status': 403} # What 'environment' are we? E.g., different REDCap projects might # correspond to dev/test/prod. handler_tag = str(redcap_env + str(project_id)) env_tag = aou_common.get_env_tag_for_handler(handler_tag) # Add these to request map; workflows might expect them. req['redcap_env'] = redcap_env req['project_id'] = project_id # Load redcap-spec, jira-spec into the request for workflows to use. req['redcap-spec'] = study_cfg.get(env_tag).get('redcap-spec') req['jira-spec'] = study_cfg.get(env_tag).get('jira-spec') # Ready to run workflows now. wf_chain = [redcap_intake_workflow.go ,aou_enrollment_workflow.go ,aou_withdrawal_workflow.go ] try: rslt = run_workflow_chain(req, wf_chain) if rslt.get('response'): log.info('Done. Chain result includes response of {}; will use that.'\ ''.format(str(rslt.get('response')))) return rslt.get('response') else: log.info('Done. Will return 200 response.') return {'status': 200} except Exception, e: log.error(traceback.format_exc()) ks.send_email(study_cfg[env_tag]['from-email'] ,study_cfg[env_tag]['to-email'] ,'Boost Transmitter Exception' ,'Please check the log.') log.error('Returning 500; details: ' + str(e)) return {'status': 500}
def create_jira_ticket(redcap_server_tag, projectid, rcd, request): '''Kind of ticket (here, 'Disenrollment') is determined by jira_kind variable.''' name_first = rcd['name_first'] name_last = rcd['name_last'] mrn = rcd['mrn'] name_mrn = name_first + ' ' + name_last + ' (' + mrn + ')' date_withdrawn = calc_date_withdrawn(rcd) env_tag = request['env-tag'] study_tag = request['study-tag'] study_config = common.get_study_config(study_tag) jira_spec = study_config[env_tag]['jira-spec'] jira_project = study_config[env_tag]['jira-project'] jira_summary = study_details.get('pi') protocol_num = study_details.get('protocol-number') if env_tag != 'prod' and jira_project == 'OBC': jira_summary += jira_test_msg additional_fields = {} if jira_project == 'OBC': additional_fields['customfield_10190'] = name_mrn additional_fields['customfield_10070'] = protocol_num additional_fields['customfield_10191'] = date_withdrawn # customfield_10193 below is Withdrawal Reason; 10424 means "Pt. Withdrew" additional_fields['customfield_10193'] = {'id': '10424'} result = jira.create_issue(jira_spec ,jira_project ,jira_kind ,jira_summary ,None # exclude description ,None # exclude assignee ,additional_fields) if study_config.get('send-jira-ping-emails') == 'yes': try: ks.send_email(study_config[env_tag]['jira-ping-from-email'], study_config[env_tag]['jira-ping-to-email'], 'jira withdrawal result', str(str(result) + '\n' + "record: "+rcd['record_id'] + "\n" + str(redcap_server_tag + str(projectid)))) except Exception, ex: log.error('Attempting to send Jira ping email but failed: ' + str(ex))
def send_notice_email(msg): try: ks.send_email(from_email, to_email, 'NOTIFICATION - HealthPro WQ Ingest', msg) except Exception, ex: log.error('Error when trying to email: ' + str(ex))
def send_success_email(): try: ks.send_email(from_email, to_email, 'HealthPro WQ Ingest Success' , 'Success!') except Exception, ex: log.error('Error when trying to email: ' + str(ex))
def send_error_email(msg): try: ks.send_email(from_email, to_email, 'HealthPro WQ Ingest ERROR', msg) except Exception, ex: log.error('Error when trying to email: ' + str(ex))
def handle_sigterm(sig, frame): msg = 'SIGTERM received by Ingester; quitting.' log.info('SIGTERM received by Ingester; quitting.') ks.send_email(from_email, admin_email, msg, msg) sys.exit(0)
def _handle(redcap_server_tag, pid, study_tag, workflow_chain, request): ''' You won't normally invoke this function directly; it's used by compose_handler below. ''' log.info('=== Entered. ===') # Retrieve study config. study_config = common.get_study_config(study_tag) # Check: client IP is allowed or bail. if not common.ip_is_allowed(request['client_ip'], study_config['allowed-ips']): log.info('Client IP of ' + request['client_ip'] + ' is not allowed.') return {'status': 403} # Check: request was POSTed or bail. # Can happen if browser or other utility is just checking # the URL for aliveness. if request['method'] != 'POST': log.info('Method is {}; nothing to do.'.format(request['method'])) return {'status': 405} # Check: request contains data or bail. E.g., request won't contain # data if user 'tests' endpoint via the Data Entry Trigger # URL Test button in the Project Setup screen. if len(redcaplib.parse_det_payload(request['data'])) == 0: log.info('DET payload empty; nothing to do.') return {'status': 200} # We need the DET message now. det_payload = redcaplib.parse_det_payload(request['data']) log.info('DET payload: ' + str(det_payload)) # Check: PID in DET message is PID we expect, or bail. # A mismatch indicates a misconfiguration needing attention (in the # REDCap project's Project Setup) so an Error is raised in this case. if str(det_payload['project_id']) != str(pid): raise RuntimeError('project_id in DET payload (' + det_msg['project_id'] + ') does not match what handler expects (' + str(pid) + ')') # At this point, initial checks were OK. log.info('Initial checks OK.') # Grab record ID. This is important for lock/serializing logic below. record_id = str(det_payload['record']) # Load up request with pertinent data elements for downstream use. request['redcap-server-tag'] = redcap_server_tag request['pid'] = str(pid) request['study-tag'] = study_tag request['handler-tag'] = redcap_server_tag + str(pid) request['record-id'] = record_id request['det-payload'] = det_payload # Ok, ready to run workflows now. # Do some lock-related setup. # See Note One below. record_lock_key = build_key(request) make_record_lock_if_absent(record_lock_key) # Start of logic with lock. # See Note One below. log.info('About to start work with lock [{}].'.format(record_lock_key)) with record_locks[record_lock_key]: log.info('Starting workflow chain for pid {}, record id {}'.format( pid, record_id)) try: result = common.run_workflow_chain(request, workflow_chain) if result.get('response'): log.info('Done. Chain result includes response of {}; will use that.'\ ''.format(str(result.get('response')))) return result.get('response') else: log.info('Done. Will return 200 response.') return {'status': 200} except Exception, e: log.error(traceback.format_exc()) handler_tag = redcap_server_tag + str(pid) env_tag = aou_common.get_env_tag_for_handler(handler_tag) ks.send_email(study_config[env_tag]['from-email'], study_config[env_tag]['to-email'], 'Boost Transmitter Exception', 'Please check the log.') log.error('Returning 500; details: ' + str(e)) return {'status': 500} finally:
# integers logger.info(1147) logger.error(1147) # exception try: raise Exception("Raising exception on purpose.") except Exception, ex: logger.error(ex) # send_email tests # ---------------- print "Testing send_email function." from_addr = sys.argv[1] to_addr = sys.argv[2] try: kickshaws.send_email(from_addr, to_addr, "Kickshaws Test", "Lorem Ipsum") except Exception, e: logger.error('Got exception (might not have smtp on this machine): ' + str(e)) # Now try with a list. to_addr = ['foo@bar', 'baz@faz'] try: logger.info("Test the passing of a list of addresses " \ "(They're made up this time).") kickshaws.send_email(from_addr, to_addr, "X", "Y") except Exception, e: logger.error('Got exception (might not have smtp on this machine): ' + str(e)) print 'Done! Exiting.'