def process_update_records(update_records):
    """Process the requests for S3 bucket update requests"""
    events = sorted(update_records, key=lambda x: x['account'])

    # Group records by account for more efficient processing
    for account_id, events in groupby(events, lambda x: x['account']):
        events = list(events)

        # Grab the bucket names (de-dupe events):
        buckets = {}
        for event in events:
            # If the creation date is present, then use it:
            bucket_event = buckets.get(event['detail']['requestParameters']['bucketName'], {
                'creationDate': event['detail']['requestParameters'].get('creationDate')
            })
            bucket_event.update(event['detail']['requestParameters'])

            buckets[event['detail']['requestParameters']['bucketName']] = bucket_event
            buckets[event['detail']['requestParameters']['bucketName']]['eventDetails'] = event

        # Query AWS for current configuration
        for b_name, item in buckets.items():
            LOG.debug(f'[~] Processing Create/Update for: {b_name}')
            # If the bucket does not exist, then simply drop the request --
            # If this happens, there is likely a Delete event that has occurred and will be processed soon.
            try:
                bucket_details = get_bucket(b_name,
                                            account_number=account_id,
                                            include_created=(item.get('creationDate') is None),
                                            assume_role=HISTORICAL_ROLE,
                                            region=CURRENT_REGION)
                if bucket_details.get('Error'):
                    LOG.error(f"[X] Unable to fetch details about bucket: {b_name}. "
                              f"The error details are: {bucket_details['Error']}")
                    continue

            except ClientError as cerr:
                if cerr.response['Error']['Code'] == 'NoSuchBucket':
                    LOG.warning(f'[?] Received update request for bucket: {b_name} that does not '
                                'currently exist. Skipping.')
                    continue

                # Catch Access Denied exceptions as well:
                if cerr.response['Error']['Code'] == 'AccessDenied':
                    LOG.error(f'[X] Unable to fetch details for S3 Bucket: {b_name} in {account_id}. Access is Denied. '
                              'Skipping...')
                    continue
                raise Exception(cerr)

            # Pull out the fields we want:
            data = {
                'arn': f'arn:aws:s3:::{b_name}',
                'principalId': cloudwatch.get_principal(item['eventDetails']),
                'userIdentity': cloudwatch.get_user_identity(item['eventDetails']),
                'userAgent': item['eventDetails']['detail'].get('userAgent'),
                'sourceIpAddress': item['eventDetails']['detail'].get('sourceIPAddress'),
                'requestParameters': item['eventDetails']['detail'].get('requestParameters'),
                'accountId': account_id,
                'eventTime': item['eventDetails']['detail']['eventTime'],
                'BucketName': b_name,
                'Region': bucket_details.pop('Region'),
                # Duplicated in top level and configuration for secondary index
                'Tags': bucket_details.pop('Tags', {}) or {},
                'eventSource': item['eventDetails']['detail']['eventSource'],
                'eventName': item['eventDetails']['detail']['eventName'],
                'version': VERSION
            }

            # Remove the fields we don't care about:
            del bucket_details['Arn']
            del bucket_details['GrantReferences']
            del bucket_details['_version']
            del bucket_details['Name']

            if not bucket_details.get('CreationDate'):
                bucket_details['CreationDate'] = item['creationDate']

            data['configuration'] = bucket_details

            current_revision = CurrentS3Model(**data)
            current_revision.save()
Process the requests for S3 bucket update requests