def scan(table_name: str, filter_attr_name: str = None, filter_attr_values=None, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) # accept string but make it into a list for later processing if isinstance(filter_attr_values, str): filter_attr_values = [filter_attr_values] logger.info('dynamodb scan', extra={ 'table_name': table_name, 'filter_attr_name': filter_attr_name, 'filter_attr_value': str(filter_attr_values), 'correlation_id': correlation_id }) if filter_attr_name is None: response = table.scan() else: filter_expr = Attr(filter_attr_name).eq(filter_attr_values[0]) for value in filter_attr_values[1:]: filter_expr = filter_expr | Attr(filter_attr_name).eq(value) response = table.scan(FilterExpression=filter_expr) items = response['Items'] logger.info('dynamodb scan result', extra={ 'count': str(len(items)), 'correlation_id': correlation_id }) return items except Exception as ex: raise ex
def update_item_old(table_name: str, key: str, attr_name: str, attr_value, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) key_json = {'id': key} update = 'SET ' + attr_name + ' = :new_value, modified = :m' expression_json = {':new_value': attr_value, ':m': str(now_with_tz())} logger.info('dynamodb update', extra={ 'table_name': table_name, 'key': key, 'attr_name': attr_name, 'attr_value': attr_value, 'correlation_id': correlation_id }) response = table.update_item(Key=key_json, UpdateExpression=update, ExpressionAttributeValues=expression_json) except Exception as ex: raise ex
def scan_old(table_name: str, filter_attr_name: str = None, filter_attr_value=None, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) logger.info('dynamodb scan', extra={ 'table_name': table_name, 'filter_attr_name': filter_attr_name, 'filter_attr_value': filter_attr_value, 'correlation_id': correlation_id }) if filter_attr_name is None: response = table.scan() else: response = table.scan( FilterExpression=Attr(filter_attr_name).eq(filter_attr_value)) items = response['Items'] logger.info('dynamodb scan result', extra={ 'count': str(len(items)), 'correlation_id': correlation_id }) return items except Exception as ex: raise ex
def process_user_registration(notification): logger = get_logger() correlation_id = new_correlation_id() try: notification_id = notification['id'] details = notification['details'] user_id = details['id'] logger.info('process_user_registration: post to hubspot', extra={'notification_id': str(notification_id), 'user_id': str(user_id), 'email': details['email'], 'correlation_id': str(correlation_id)}) hubspot_id, is_new = post_new_user_to_crm(details, correlation_id) logger.info('process_user_registration: hubspot details', extra={'notification_id': str(notification_id), 'hubspot_id': str(hubspot_id), 'isNew': str(is_new), 'correlation_id': str(correlation_id)}) if hubspot_id == -1: errorjson = {'user_id': user_id, 'correlation_id': str(correlation_id)} raise DetailedValueError('could not find user in HubSpot', errorjson) user_jsonpatch = [ {'op': 'replace', 'path': '/crm_id', 'value': str(hubspot_id)}, ] patch_user(user_id, user_jsonpatch, now_with_tz(), correlation_id) mark_notification_processed(notification, correlation_id) except Exception as ex: error_message = str(ex) mark_notification_failure(notification, error_message, correlation_id)
def process_task_signup(notification): logger = get_logger() correlation_id = new_correlation_id() try: # get basic data out of notification signup_details = notification['details'] user_task_id = signup_details['id'] # get additional data that hubspot needs from database extra_data = get_task_signup_data_for_crm(user_task_id, correlation_id) # put it all together for dispatch to HubSpot signup_details.update(extra_data) signup_details['signup_event_type'] = 'Sign-up' # check here that we have a hubspot id if signup_details['crm_id'] is None: errorjson = {'user_task_id': user_task_id, 'correlation_id': str(correlation_id)} raise DetailedValueError('user does not have crm_id', errorjson) else: post_task_signup_to_crm(signup_details, correlation_id) mark_notification_processed(notification, correlation_id) except Exception as ex: error_message = str(ex) mark_notification_failure(notification, error_message, correlation_id)
def process_user_login(notification): logger = get_logger() correlation_id = new_correlation_id() try: # get basic data out of notification login_details = notification['details'] posting_result = post_user_login_to_crm(login_details, correlation_id) marking_result = mark_notification_processed(notification, correlation_id) return posting_result, marking_result except Exception as ex: error_message = str(ex) mark_notification_failure(notification, error_message, correlation_id)
def update_item(table_name: str, key: str, name_value_pairs: dict, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) key_json = {'id': key} update_expr = 'SET #modified = :m ' values_expr = {':m': str(now_with_tz())} attr_names_expr = { '#modified': 'modified' } # not strictly necessary, but allows easy addition of names later param_count = 1 for name, value in name_value_pairs.items(): param_name = ':p' + str(param_count) map_name = None if name == 'status': # todo generalise this to other reserved words, and ensure it only catches whole words if '.' in name: map_name = name.split('.')[0] attr_name = '#a' + str(param_count) attr_names_expr[attr_name] = 'status' else: attr_name = name if map_name is not None: attr_name = map_name + '.' + attr_name update_expr += ', ' + attr_name + ' = ' + param_name values_expr[param_name] = str(value) param_count += 1 logger.info('dynamodb update', extra={ 'table_name': table_name, 'key': key, 'update_expr': update_expr, 'values_expr': values_expr, 'correlation_id': correlation_id }) response = table.update_item( Key=key_json, UpdateExpression=update_expr, ExpressionAttributeValues=values_expr, ExpressionAttributeNames=attr_names_expr, ) return response except Exception as ex: raise ex
def delete_item(table_name: str, key: str, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) key_json = {'id': key} logger.info('dynamodb delete', extra={ 'table_name': table_name, 'key': key, 'correlation_id': correlation_id }) response = table.delete_item(Key=key_json) except Exception as err: raise err
def delete_all(table_name: str, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) items = scan(table_name) for item in items: key = item['id'] key_json = {'id': key} logger.info('dynamodb delete_all', extra={ 'table_name': table_name, 'key': key, 'correlation_id': correlation_id }) table.delete_item(Key=key_json) except Exception as err: raise err
def get_item(table_name: str, key: str, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) key_json = {'id': key} logger.info('dynamodb get', extra={ 'table_name': table_name, 'key': key, 'correlation_id': correlation_id }) response = table.get_item(Key=key_json) if 'Item' in response: return response['Item'] else: # not found return None except Exception as ex: raise ex
def put_item(table_name: str, key, item_type: str, item_details, item: dict, update_allowed=False, correlation_id=new_correlation_id()): try: logger = get_logger() table = get_table(table_name) item['id'] = str(key) item['type'] = item_type item['details'] = item_details now = str(now_with_tz()) item['created'] = now item['modified'] = now logger.info('dynamodb put', extra={ 'table_name': table_name, 'item': item, 'correlation_id': correlation_id }) if update_allowed: response = table.put_item(Item=item) else: response = table.put_item( Item=item, ConditionExpression='attribute_not_exists(id)') except ClientError as ex: error_code = ex.response['Error']['Code'] errorjson = { 'error_code': error_code, 'table_name': table_name, 'item_type': item_type, 'id': str(key), 'correlation_id': correlation_id } raise DuplicateInsertError('item already exists', errorjson)