From 6ef7aab001eef26d2fff2e76c8eebcb4b1f3ddca Mon Sep 17 00:00:00 2001
From: Jonas Braathen <jonas.braathen@usit.uio.no>
Date: Tue, 19 Oct 2021 15:46:05 +0200
Subject: [PATCH] Changes the notification format a little

- The field 'source' is now formatted like 'greg:instance_name:environment'
- The field 'type' is now formatted like 'object_type.operation'
- The field 'data' now contains the identifiers of all objects related to the change
---
 .../commands/notification_publisher.py        | 10 ++-
 greg/signals.py                               | 21 ++++--
 .../management/test_notification_publisher.py | 33 ++++++++-
 greg/tests/test_notifications.py              | 72 +++++++++++--------
 4 files changed, 91 insertions(+), 45 deletions(-)

diff --git a/greg/management/commands/notification_publisher.py b/greg/management/commands/notification_publisher.py
index 6d44a657..3ea72587 100644
--- a/greg/management/commands/notification_publisher.py
+++ b/greg/management/commands/notification_publisher.py
@@ -26,7 +26,7 @@ def generate_event_type(n: Notification) -> str:
     routing key is removed results in minor changes to the code.
     """
     object_type = camel_to_snake(n.object_type)
-    return f"{settings.INTERNAL_RK_PREFIX}.{object_type}.{n.operation}"
+    return f"{object_type}.{n.operation}"
 
 
 def create_cloud_event_payload(n: Notification) -> str:
@@ -52,14 +52,12 @@ def create_cloud_event_payload(n: Notification) -> str:
     object_type = camel_to_snake(n.object_type)
     content: dict[str, Union[str, dict[str, str]]] = {
         "id": str(n.id),
-        "source": f"urn:greg:{settings.INSTANCE_NAME}:{object_type}:{n.identifier}",
+        "source": f"greg:{settings.INSTANCE_NAME}:{settings.ENVIRONMENT}",
         "specversion": "1.0",
         "type": generate_event_type(n),
     }
-    if n.object_type in ("Role", "Consent", "Identity"):
-        content["data"] = {
-            "person_id": n.meta.get("person_id"),
-        }
+    if n.meta:
+        content["data"] = n.meta
     return json.dumps(content)
 
 
diff --git a/greg/signals.py b/greg/signals.py
index 51c1dfc0..20110bc8 100644
--- a/greg/signals.py
+++ b/greg/signals.py
@@ -167,15 +167,22 @@ def m2m_changed_notification_callback(
 
 def _create_metadata(instance) -> Dict:
     meta = {}
-
-    if isinstance(instance, Role):
+    if isinstance(instance, Person):
+        meta["person_id"] = instance.id
+    elif isinstance(instance, Role):
         meta["person_id"] = instance.person.id
-        meta["type_id"] = instance.type.id
-    if isinstance(instance, Identity):
+        meta["role_id"] = instance.id
+        meta["role_type"] = instance.type.identifier
+        meta["role_type_id"] = instance.type.id
+    elif isinstance(instance, RoleType):
+        meta["role_type_id"] = instance.id
+    elif isinstance(instance, Identity):
         meta["person_id"] = instance.person.id
         meta["identity_id"] = instance.id
-    if isinstance(instance, Consent):
+        meta["identity_type"] = instance.type
+    elif isinstance(instance, Consent):
         meta["person_id"] = instance.person.id
-        meta["consent_id"] = instance.type.id
-
+        meta["consent_id"] = instance.id
+        meta["consent_type"] = instance.type.identifier
+        meta["consent_type_id"] = instance.type.id
     return meta
diff --git a/greg/tests/management/test_notification_publisher.py b/greg/tests/management/test_notification_publisher.py
index 0207e5bf..c428d7bc 100644
--- a/greg/tests/management/test_notification_publisher.py
+++ b/greg/tests/management/test_notification_publisher.py
@@ -1,14 +1,43 @@
+import json
 import pytest
 
 from greg.management.commands.notification_publisher import (
     handle_one_notification,
+    create_cloud_event_payload,
 )
 from greg.models import Notification
 
 
+@pytest.fixture
+def role_type_notification():
+    Notification.objects.create(
+        identifier=5,
+        object_type="RoleType",
+        operation="update",
+        issued_at=1234,
+        meta={
+            "integer": 123,
+            "string": "foo",
+        },
+    )
+    return Notification.objects.get(id=1)
+
+
 @pytest.mark.django_db
-def test_handle_one_notification(notification, pcm_mock):
+def test_handle_one_notification(role_type_notification, pcm_mock):
     """Check that Notifications are deleted when published to message queue"""
     assert Notification.objects.count() == 1
-    handle_one_notification(notification, pcm_mock, exchange="bar")
+    handle_one_notification(role_type_notification, pcm_mock, exchange="bar")
     assert Notification.objects.count() == 0
+
+
+@pytest.mark.django_db
+def test_create_cloud_event_payload(role_type_notification):
+    payload = create_cloud_event_payload(role_type_notification)
+    assert json.loads(payload) == {
+        "id": "1",
+        "source": "greg:local:unittest",
+        "specversion": "1.0",
+        "type": "role_type.update",
+        "data": {"integer": 123, "string": "foo"},
+    }
diff --git a/greg/tests/test_notifications.py b/greg/tests/test_notifications.py
index 7fcbb449..ad147588 100644
--- a/greg/tests/test_notifications.py
+++ b/greg/tests/test_notifications.py
@@ -68,7 +68,7 @@ def test_role_add_notification(
     org_unit_bar: OrganizationalUnit,
     sponsor: Sponsor,
 ):
-    Role.objects.create(
+    role = Role.objects.create(
         person=person,
         type=role_type_foo,
         start_date="2021-05-06",
@@ -79,9 +79,10 @@ def test_role_add_notification(
     notifications = Notification.objects.filter(object_type="Role")
     assert len(notifications) == 1
     assert notifications[0].operation == "add"
-    meta_data = notifications[0].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["type_id"] == role_type_foo.id
+    meta = notifications[0].meta
+    assert meta["person_id"] == person.id
+    assert meta["role_id"] == role.id
+    assert meta["role_type"] == role_type_foo.identifier
 
 
 @pytest.mark.django_db
@@ -91,7 +92,7 @@ def test_role_update_notification(
     org_unit_bar: OrganizationalUnit,
     sponsor: Sponsor,
 ):
-    Role.objects.create(
+    role = Role.objects.create(
         person=person,
         type=role_type_foo,
         start_date="2021-05-06",
@@ -106,9 +107,10 @@ def test_role_update_notification(
     notifications = Notification.objects.filter(object_type="Role")
     assert len(notifications) == 2
     assert notifications[1].operation == "update"
-    meta_data = notifications[1].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["type_id"] == role_type_foo.id
+    meta = notifications[1].meta
+    assert meta["person_id"] == person.id
+    assert meta["role_id"] == role.id
+    assert meta["role_type"] == role_type_foo.identifier
 
 
 @pytest.mark.django_db
@@ -118,7 +120,7 @@ def test_role_delete_notification(
     org_unit_bar: OrganizationalUnit,
     sponsor: Sponsor,
 ):
-    Role.objects.create(
+    role = Role.objects.create(
         person=person,
         type=role_type_foo,
         start_date="2021-05-06",
@@ -132,27 +134,31 @@ def test_role_delete_notification(
     notifications = Notification.objects.filter(object_type="Role")
     assert len(notifications) == 2
     assert notifications[1].operation == "delete"
-    meta_data = notifications[1].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["type_id"] == role_type_foo.id
+    meta = notifications[1].meta
+    assert meta["person_id"] == person.id
+    assert meta["role_id"] == role.id
+    assert meta["role_type"] == role_type_foo.identifier
+    assert meta["role_type_id"] == role_type_foo.id
 
 
 @pytest.mark.django_db
 def test_consent_add_notification(person: Person, consent_type: ConsentType):
-    Consent.objects.create(
+    consent = Consent.objects.create(
         person=person, type=consent_type, consent_given_at="2021-06-20"
     )
     notifications = Notification.objects.filter(object_type="Consent")
     assert len(notifications) == 1
     assert notifications[0].identifier == person.id
-    meta_data = notifications[0].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["consent_id"] == consent_type.id
+    meta = notifications[0].meta
+    assert meta["person_id"] == person.id
+    assert meta["consent_id"] == consent.id
+    assert meta["consent_type"] == consent.type.identifier
+    assert meta["consent_type_id"] == consent.type.id
 
 
 @pytest.mark.django_db
 def test_consent_update_notification(person: Person, consent_type: ConsentType):
-    Consent.objects.create(
+    consent = Consent.objects.create(
         person=person, type=consent_type, consent_given_at="2021-06-20"
     )
     consents = Consent.objects.filter(person=person, type=consent_type)
@@ -162,14 +168,16 @@ def test_consent_update_notification(person: Person, consent_type: ConsentType):
     notifications = Notification.objects.filter(object_type="Consent")
     assert len(notifications) == 2
     assert notifications[0].identifier == person.id
-    meta_data = notifications[0].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["consent_id"] == consent_type.id
+    meta = notifications[0].meta
+    assert meta["person_id"] == person.id
+    assert meta["consent_id"] == consent.id
+    assert meta["consent_type"] == consent.type.identifier
+    assert meta["consent_type_id"] == consent.type.id
 
 
 @pytest.mark.django_db
 def test_consent_delete_notification(person: Person, consent_type: ConsentType):
-    Consent.objects.create(
+    consent = Consent.objects.create(
         person=person, type=consent_type, consent_given_at="2021-06-20"
     )
     consents = Consent.objects.filter(person=person, type=consent_type)
@@ -179,9 +187,11 @@ def test_consent_delete_notification(person: Person, consent_type: ConsentType):
     assert len(notifications) == 2
     assert notifications[1].identifier == person.id
     assert notifications[1].operation == "delete"
-    meta_data = notifications[0].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["consent_id"] == consent_type.id
+    meta = notifications[0].meta
+    assert meta["person_id"] == person.id
+    assert meta["consent_id"] == consent.id
+    assert meta["consent_type"] == consent_type.identifier
+    assert meta["consent_type_id"] == consent_type.id
 
 
 @pytest.mark.django_db
@@ -193,9 +203,10 @@ def test_identity_add_notification(
     assert notifications[0].identifier == person.id
     assert notifications[0].operation == "add"
 
-    meta_data = notifications[0].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["identity_id"] == identity.id
+    meta = notifications[0].meta
+    assert meta["person_id"] == person.id
+    assert meta["identity_id"] == identity.id
+    assert meta["identity_type"] == identity.type
 
 
 @pytest.mark.django_db
@@ -212,6 +223,7 @@ def test_identity_update_notification(
     assert len(notifications) == 2
     assert notifications[1].operation == "update"
 
-    meta_data = notifications[1].meta
-    assert meta_data["person_id"] == person.id
-    assert meta_data["identity_id"] == identity.id
+    meta = notifications[1].meta
+    assert meta["person_id"] == person.id
+    assert meta["identity_id"] == identity.id
+    assert meta["identity_type"] == identity.type
-- 
GitLab