From 615432bc6a5e3afb813eefc2e96d171d51397b91 Mon Sep 17 00:00:00 2001
From: Daniel Bimschas <daniel@bimschas.com>
Date: Sat, 7 Dec 2024 20:13:41 +0100
Subject: [PATCH] HOLI-10718: parse UserNameUpdated event

---
 .gitlab-ci.yml                                |  9 ++--
 src/__init__.py => __init__.py                |  0
 ...v-requirements.txt => dev-requirements.txt |  0
 main.py                                       | 53 +++++++++++++++++++
 src/requirements.txt => requirements.txt      |  0
 src/main.py                                   | 12 -----
 src/test_main.py                              |  3 --
 terraform/environments/function.tf            |  2 +-
 test_main.py                                  | 32 +++++++++++
 9 files changed, 89 insertions(+), 22 deletions(-)
 rename src/__init__.py => __init__.py (100%)
 rename src/dev-requirements.txt => dev-requirements.txt (100%)
 create mode 100644 main.py
 rename src/requirements.txt => requirements.txt (100%)
 delete mode 100644 src/main.py
 delete mode 100644 src/test_main.py
 create mode 100644 test_main.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fd93906..5ca75d5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,8 +16,8 @@ install_test:
   stage: install_test
   image: "europe-north1-docker.pkg.dev/holi-shared/docker-hub-remote/python:3.12-slim"
   script:
-    - pip install -r src/requirements.txt
-    - pip install -r src/dev-requirements.txt
+    - pip install -r requirements.txt
+    - pip install -r dev-requirements.txt
     - pytest
   interruptible: true
 
@@ -38,10 +38,7 @@ install_test:
     ENVIRONMENT_ID: $CI_ENVIRONMENT_SLUG
   script:
     - apk add zip
-    - mkdir build
-    - cd src
-    - zip -r ../build/search_integration.zip ./*
-    - cd ..
+    - zip -r search_integration.zip requirements.zip dev-requirements.zip *.py
     - terraform/environments/scripts/create-or-update-env.sh "$ENVIRONMENT_ID" "$CI_COMMIT_SHA"
   interruptible: false
 
diff --git a/src/__init__.py b/__init__.py
similarity index 100%
rename from src/__init__.py
rename to __init__.py
diff --git a/src/dev-requirements.txt b/dev-requirements.txt
similarity index 100%
rename from src/dev-requirements.txt
rename to dev-requirements.txt
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..fcb17e5
--- /dev/null
+++ b/main.py
@@ -0,0 +1,53 @@
+import base64
+import json
+
+import functions_framework
+from cloudevents.http.event import CloudEvent
+from dataclasses import dataclass
+
+@dataclass
+class UserPayload:
+    id: str
+    name: str
+    email: str
+    identity: str
+    avatar: str
+
+    def __init__(self, data: dict):
+        print(f"UserPayload: {data}")
+        self.id = data['user']['id']
+        self.name = data['user']['name']
+        self.email = data['user']['email']
+        self.identity = data['user']['identity']
+        self.avatar = data['user']['avatar']
+
+
+@dataclass
+class UserNameUpdatedEvent(UserPayload):
+    event_type: str
+    event_version: str
+
+    def __init__(self, event: CloudEvent):
+        message = event['data']['message']
+        if message['attributes']['eventType'] != 'UserNameUpdated':
+            raise ValueError(f'Expected event of type UserNameUpdated, got {data['eventType']}')
+        self.event_type = message['attributes']['eventType']
+        self.event_version = message['attributes']['eventVersion']
+        super().__init__(json.loads(decode_message_data(message['data'])))
+
+
+def process_user_name_updated_event(event: UserNameUpdatedEvent):
+    print(f'process_user_name_updated_event: {event}')
+
+def decode_message_data(data: str):
+    return base64.b64decode(data)
+
+def process_event(event: CloudEvent):
+    attributes = event['data']['message']['attributes']
+    if attributes['eventType'] == 'UserNameUpdated' and attributes['eventVersion'] == '1.0.0': # TODO backwards semver
+        process_user_name_updated_event(UserNameUpdatedEvent(event))
+
+@functions_framework.cloud_event
+def process_message(cloud_event: CloudEvent):
+    print(f"Received message: {cloud_event}")
+    process_event(cloud_event)
diff --git a/src/requirements.txt b/requirements.txt
similarity index 100%
rename from src/requirements.txt
rename to requirements.txt
diff --git a/src/main.py b/src/main.py
deleted file mode 100644
index 6d8ad33..0000000
--- a/src/main.py
+++ /dev/null
@@ -1,12 +0,0 @@
-import base64
-import functions_framework
-
-@functions_framework.cloud_event
-def process_message(cloud_event):
-    # TODO remove inspection prints
-    print(f"Received message: {cloud_event}")
-    if 'data' in cloud_event:
-        message = base64.b64decode(event['data']).decode('utf-8')
-        print(f"Received message: {message}")
-    else:
-        print("No data found in event.")
diff --git a/src/test_main.py b/src/test_main.py
deleted file mode 100644
index c862d60..0000000
--- a/src/test_main.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_process_message():
-    pass
\ No newline at end of file
diff --git a/terraform/environments/function.tf b/terraform/environments/function.tf
index 4881eaf..9bc1683 100644
--- a/terraform/environments/function.tf
+++ b/terraform/environments/function.tf
@@ -8,7 +8,7 @@ resource "random_id" "main" {
 resource "google_storage_bucket_object" "function_source" {
   name   = "${random_id.main.hex}/search_integration.zip"
   bucket = data.terraform_remote_state.holi_infra_state.outputs.gcf_sources_upload_bucket_name
-  source = "../../build/search_integration.zip"
+  source = "../../search_integration.zip"
 }
 
 resource "google_cloudfunctions2_function" "holi-search-integration" {
diff --git a/test_main.py b/test_main.py
new file mode 100644
index 0000000..57e197a
--- /dev/null
+++ b/test_main.py
@@ -0,0 +1,32 @@
+from main import process_message
+
+event = {
+    'attributes':
+        {
+            'id': '12833783708309476',
+            'time': '2024-12-07T16:21:48.022Z',
+            'specversion': '1.0',
+            'datacontenttype': 'application/json',
+            'type': 'google.cloud.pubsub.topic.v1.messagePublished',
+            'source': '//pubsub.googleapis.com/'
+        },
+    'data': {
+        'message': {
+            '@type': 'type.googleapis.com/google.pubsub.v1.PubsubMessage',
+            'data': 'eyJ1c2VyIjogeyJpZCI6ICIxNDlhM2QyOS1hMGRhLTRmNTItOGUxYy02NjAzNzZiNzA4NGIiLCAibmFtZSI6ICJEYW5pZWwgaG9saSB0ZWFtIiwgImVtYWlsIjogImRhbmllbEBob2xpLnRlYW0iLCAiaWRlbnRpdHkiOiAiZGFuaWVsaG9saS50ZWFtIiwgImF2YXRhciI6ICJodHRwczovL2lrLmltYWdla2l0LmlvL2hvbGkvX0RFVl8vYXZhdGFyLzE0OWEzZDI5LWEwZGEtNGY1Mi04ZTFjLTY2MDM3NmI3MDg0Yl95djMxVVc3bEQwLmpwZyJ9fQ==',
+            'attributes': {
+                'eventType': 'UserNameUpdated',
+                'eventVersion': '1.0.0'
+            },
+            'messageId': '12833783708309476',
+            'publishTime': '2024-12-07T16:21:48.022Z'
+        }
+    }
+}
+
+def test_process_message():
+    process_message(event)
+
+
+if __name__ == '__main__':
+    test_process_message()
\ No newline at end of file
-- 
GitLab