import gzip import io import json import logging import os from datetime import datetime import boto3 from chartmetric_data_checker.aws_utils import connect_to_database, get_last_run, insert_performance_logs from chartmetric_data_checker.const import archive_bucket, aws, body_read_length, corrupt_bucket, decompressed_bucket # - - - - Variables for Performance Logs - - - - # today = datetime.today().strftime("%Y-%m-%d") time_delta_format = "%Y-%m-%d %H:%M:%S" parent_id = get_last_run("Fan Metrics") _start_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S") # - - - - Variables for Performance Logs - - - - # def upload_json_gz(s3client, bucket, key, body): gz_body = io.BytesIO() gz = gzip.GzipFile(None, 'wb', 9, gz_body) gz.write(body) gz.close() s3client.put_object(Bucket=bucket, Key=key, ContentType='text/plain', ContentEncoding='gzip', Body=gz_body.getvalue()) def lambda_handler(event, context): process_type = 'Data movement from Quarantine to Decompressed/Archive' last_run = get_last_run(process_type) start_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S") LOGLEVEL = os.getenv('LOGLEVEL', 'INFO').upper() logger = logging.getLogger('') logger.setLevel(LOGLEVEL) s3 = boto3.client('s3') logger.info("Chartmetric_data_checker Lambda Started") db = connect_to_database() db.autocommit = True cur = db.cursor() commands = "" data_movement = '' try: if event and event['Records']: for record in event['Records']: source_bucket = record['s3']['bucket']['name'] source_key = record['s3']['object']['key'] source_key = source_key.replace("%3D", "=") copy_source = {'Bucket': source_bucket, 'Key': source_key} logger.debug(source_key) date_str = source_key.split("/")[2].split("=")[1] s3_object = s3.get_object(Bucket=source_bucket, Key=source_key) try: body = s3_object['Body'] body = body.read() data_quality = check_quality(body) if data_quality == "0": s3.copy_object(Bucket=corrupt_bucket, Key=source_key, CopySource=copy_source) logger.error( f'Data is successfully sent from {source_bucket} to {corrupt_bucket}' ) data_movement = "0" elif data_quality == "1": gz_key = source_key + ".gz" upload_json_gz(s3, archive_bucket, gz_key, body) logger.info( f'Data is successfully sent from {source_bucket} to {archive_bucket}' ) s3.copy_object(Bucket=decompressed_bucket, Key=source_key, CopySource=copy_source) logger.info( f'Data is successfully sent from {source_bucket} to {decompressed_bucket}' ) data_movement = "1" except Exception as e: data_quality = "0" s3.copy_object(Bucket=corrupt_bucket, Key=source_key, CopySource=copy_source) logger.error( f'Data is successfully sent fromm {source_bucket} to {corrupt_bucket}' ) data_movement = "0" source_key = source_key.split('/')[-1] logger.debug({source_key}) qq = aws.get('RDS', None).get('queries', None).get( 'INSERT_ARTIST_QUERY', None).format(source_key, data_quality, data_movement, '0', date_str, _start_time) commands = commands + qq + "\n" cur.execute(commands) logging.info("Data is successfully inserted into postgres!") logger.info("!! Lambda Ended!!") end_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S") insert_performance_logs(process_type, f'{last_run} + 1', start_time, end_time, parent_id) time_delta = datetime.strptime(end_time, time_delta_format) - datetime.strptime( start_time, time_delta_format) logging.info( f"{process_type}: Start time: {start_time}, End Time: {end_time}, Total Execution Time: {time_delta}" ) return { 'statusCode': 200, 'body': json.dumps('Data is successfully backed up!') } except Exception as e: logger.error(f"Exception in lambda: {e}") return {'statusCode': 500, 'body': e} def check_quality(body): process_type = 'Data Quality Check' last_run = get_last_run(process_type) start_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S") result = [] temp_body = body.decode() temp_body = temp_body.split("\n") for i in temp_body[:body_read_length]: # TODO: Fix floats and other data types py_dict = json.loads(i) for key, value in py_dict.items(): if key == "value": if type(value) in [int, float]: result.append(type(value)) elif type(value) in ['str']: value.replace('.', '', 1).isdigit() end_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S") insert_performance_logs(process_type, f'{last_run} + 1', start_time, end_time, parent_id) time_delta = datetime.strptime(end_time, time_delta_format) - datetime.strptime( start_time, time_delta_format) logging.info( f"{process_type}: Start time: {start_time}, End Time: {end_time}, Total Execution Time: {time_delta}" ) if False in result: return "0" else: return "1"