def process_individual_attachment(message, projects): event_id = message["event_id"] project_id = int(message["project_id"]) cache_key = cache_key_for_event({ "event_id": event_id, "project": project_id }) try: project = projects[project_id] except KeyError: logger.error("Project for ingested event does not exist: %s", project_id) return if not features.has("organizations:event-attachments", project.organization, actor=None): logger.info("Organization has no event attachments: %s", project_id) return # Attachments may be uploaded for events that already exist. Fetch the # existing group_id, so that the attachment can be fetched by group-level # APIs. This is inherently racy. events = eventstore.get_unfetched_events(filter=eventstore.Filter( event_ids=[event_id], project_ids=[project.id]), limit=1) group_id = None if events: group_id = events[0].group_id attachment = message["attachment"] attachment = attachment_cache.get_from_chunks( key=cache_key, type=attachment.pop("attachment_type"), **attachment) if attachment.type != "event.attachment": logger.exception("invalid individual attachment type: %s", attachment.type) return file = File.objects.create( name=attachment.name, type=attachment.type, headers={"Content-Type": attachment.content_type}, ) try: data = attachment.data except MissingAttachmentChunks: logger.exception("Missing chunks for cache_key=%s", cache_key) return file.putfile(BytesIO(data)) EventAttachment.objects.create(project_id=project.id, group_id=group_id, event_id=event_id, name=attachment.name, file=file) attachment.delete()
def process_individual_attachment(message): event_id = message["event_id"] project_id = message["project_id"] cache_key = cache_key_for_event({ "event_id": event_id, "project": project_id }) try: project = Project.objects.get_from_cache(id=project_id) except Project.DoesNotExist: logger.error("Project for ingested event does not exist: %s", project_id) return attachment = message["attachment"] attachment = attachment_cache.get_from_chunks( key=cache_key, type=attachment.pop("attachment_type"), **attachment) assert attachment.type == "event.attachment", attachment.type file = File.objects.create( name=attachment.name, type=attachment.type, headers={"Content-Type": attachment.content_type}, ) file.putfile(BytesIO(attachment.data)) EventAttachment.objects.create(project_id=project.id, event_id=event_id, name=attachment.name, file=file) attachment.delete()
def process_individual_attachment(message, projects): event_id = message["event_id"] project_id = int(message["project_id"]) cache_key = cache_key_for_event({ "event_id": event_id, "project": project_id }) try: project = projects[project_id] except KeyError: logger.error("Project for ingested event does not exist: %s", project_id) return if not features.has("organizations:event-attachments", project.organization, actor=None): logger.info("Organization has no event attachments: %s", project_id) return # Attachments may be uploaded for events that already exist. Fetch the # existing group_id, so that the attachment can be fetched by group-level # APIs. This is inherently racy. events = eventstore.get_unfetched_events(filter=eventstore.Filter( event_ids=[event_id], project_ids=[project.id]), limit=1) group_id = None if events: group_id = events[0].group_id attachment = message["attachment"] attachment = attachment_cache.get_from_chunks( key=cache_key, type=attachment.pop("attachment_type"), **attachment) if attachment.type != "event.attachment": logger.exception("invalid individual attachment type: %s", attachment.type) return save_attachment( cache_key, attachment, project, event_id, key_id=None, # TODO: Inject this from Relay group_id=group_id, start_time=None, # TODO: Inject this from Relay ) attachment.delete()
def process_individual_attachment(message, projects): event_id = message["event_id"] project_id = int(message["project_id"]) cache_key = cache_key_for_event({ "event_id": event_id, "project": project_id }) try: project = projects[project_id] except KeyError: logger.error("Project for ingested event does not exist: %s", project_id) return if not features.has("organizations:event-attachments", project.organization, actor=None): logger.info("Organization has no event attachments: %s", project_id) return attachment = message["attachment"] attachment = attachment_cache.get_from_chunks( key=cache_key, type=attachment.pop("attachment_type"), **attachment) assert attachment.type == "event.attachment", attachment.type file = File.objects.create( name=attachment.name, type=attachment.type, headers={"Content-Type": attachment.content_type}, ) file.putfile(BytesIO(attachment.data)) EventAttachment.objects.create(project_id=project.id, event_id=event_id, name=attachment.name, file=file) attachment.delete()