-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial events API implementation #178
Merged
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
6453910
Initial events API implementation
mattrco 5e6eca7
Allow event signals to be configured
mattrco 32a9d88
Add migration for events
mattrco 1e88561
API tests
mattrco d5083d4
Autoformat
mattrco fe22e36
Make the linter happy
mattrco 9553106
Avoid clobbering previous import
mattrco File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
from django.contrib import admin | ||
|
||
from response.core.models import Action, ExternalUser, Incident | ||
from response.core.models import Action, Event, ExternalUser, Incident | ||
|
||
admin.site.register(Action) | ||
admin.site.register(Event) | ||
admin.site.register(Incident) | ||
admin.site.register(ExternalUser) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import json | ||
|
||
from django.db import models | ||
|
||
|
||
class Event(models.Model): | ||
ACTION_EVENT_TYPE = "action_event" | ||
INCIDENT_EVENT_TYPE = "incident_event" | ||
|
||
timestamp = models.DateTimeField() | ||
event_type = models.CharField(max_length=50) | ||
payload = models.TextField() | ||
|
||
def save(self, *args, **kwargs): | ||
self.payload = json.dumps(self.payload) | ||
super().save(*args, **kwargs) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import logging | ||
from datetime import datetime | ||
|
||
from django.conf import settings | ||
from django.db.models.signals import post_save | ||
from django.utils.module_loading import import_string | ||
|
||
from response.core.models import Action, Event, Incident | ||
from response.core.serializers import ActionSerializer, IncidentSerializer | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ActionEventHandler: | ||
def handle(sender, instance: Action, **kwargs): | ||
logger.info(f"Handling post_save for action: {instance}") | ||
|
||
event = Event() | ||
event.event_type = Event.ACTION_EVENT_TYPE | ||
|
||
# Event payload should be a dict for serializing to JSON. | ||
event.payload = ActionSerializer(instance).data | ||
event.payload["incident_id"] = instance.incident.pk | ||
if "details_ui" in event.payload: | ||
del event.payload["details_ui"] | ||
|
||
event.timestamp = datetime.now(tz=None) | ||
event.save() | ||
|
||
|
||
class IncidentEventHandler: | ||
def handle(sender, instance: Incident, **kwargs): | ||
logger.info(f"Handling post_save for incident: {instance}") | ||
|
||
event = Event() | ||
event.event_type = Event.INCIDENT_EVENT_TYPE | ||
|
||
# Event payload should be a dict for serializing to JSON. | ||
event.payload = IncidentSerializer(instance).data | ||
# Actions generate their own events, no need to duplicate them here. | ||
if "action_items" in event.payload: | ||
del event.payload["action_items"] | ||
|
||
event.timestamp = datetime.now(tz=None) | ||
event.save() | ||
|
||
|
||
if hasattr(settings, "ACTION_EVENT_HANDLER_CLASS"): | ||
cls = import_string(settings.ACTION_EVENT_HANDLER_CLASS) | ||
post_save.connect(cls.handle, sender=Action) | ||
else: | ||
post_save.connect(ActionEventHandler.handle, sender=Action) | ||
|
||
if hasattr(settings, "INCIDENT_EVENT_HANDLER_CLASS"): | ||
cls = import_string(settings.INCIDENT_EVENT_HANDLER_CLASS) | ||
post_save.connect(cls.handle, sender=Incident) | ||
else: | ||
post_save.connect(IncidentEventHandler.handle, sender=Incident) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Generated by Django 2.2.3 on 2019-11-07 17:34 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [("response", "0013_incident_private")] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="Event", | ||
fields=[ | ||
( | ||
"id", | ||
models.AutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
("timestamp", models.DateTimeField()), | ||
("event_type", models.CharField(max_length=50)), | ||
("payload", models.TextField()), | ||
], | ||
) | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,17 @@ | ||
from .core.serializers import ( | ||
ActionSerializer, | ||
CommsChannelSerializer, | ||
EventSerializer, | ||
ExternalUserSerializer, | ||
IncidentSerializer, | ||
TimelineEventSerializer, | ||
) | ||
|
||
__all__ = ( | ||
"ExternalUserSerializer", | ||
"TimelineEventSerializer", | ||
"ActionSerializer", | ||
"CommsChannelSerializer", | ||
"EventSerializer", | ||
"ExternalUserSerializer", | ||
"IncidentSerializer", | ||
"TimelineEventSerializer", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import json | ||
|
||
from django.urls import reverse | ||
from rest_framework.test import force_authenticate | ||
|
||
from response.core.views import EventsViewSet | ||
from tests.factories.event import EventFactory | ||
|
||
|
||
def test_list_events(arf, api_user): | ||
persisted_events = EventFactory.create_batch(10) | ||
|
||
req = arf.get(reverse("event-list")) | ||
force_authenticate(req, user=api_user) | ||
response = EventsViewSet.as_view({"get": "list"})(req) | ||
|
||
assert response.status_code == 200, "Got non-200 response from API" | ||
content = json.loads(response.rendered_content) | ||
|
||
assert "results" in content, "Response didn't have results key" | ||
events = content["results"] | ||
assert len(events) == len( | ||
persisted_events | ||
), "Didn't get expected number of events back" | ||
|
||
for event in events: | ||
assert event["timestamp"] | ||
assert event["event_type"] | ||
payload = json.loads(event["payload"]) | ||
assert payload["report"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import random | ||
|
||
import factory | ||
from faker import Factory | ||
|
||
from response.core.models import Event | ||
|
||
faker = Factory.create() | ||
|
||
|
||
class EventFactory(factory.DjangoModelFactory): | ||
class Meta: | ||
model = Event | ||
|
||
timestamp = factory.LazyFunction( | ||
lambda: faker.date_time_between(start_date="-6m", end_date="now", tzinfo=None) | ||
) | ||
event_type = random.choice([Event.INCIDENT_EVENT_TYPE]) | ||
|
||
# Using an Incident/Event factory here fails with a mysterious error: | ||
# https://github.com/pytest-dev/pytest-django/issues/713 (using @pytest.mark... | ||
# didn't resolve it). For now, a static fixture suffices. | ||
payload = {"report": "we're out of milk", "impact": "making tea is difficult"} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add a getter here that parses the payload and returns a native dict, but since events are write-only this isn't currently needed.