Skip to content

Commit f21714b

Browse files
authored
Merge pull request #4091 from bcgov/fix/924-attachments-file-fixtures
924 Fix attachments file fixtures
2 parents e900a6b + 9d6a461 commit f21714b

7 files changed

Lines changed: 141 additions & 5 deletions

File tree

bc_obps/registration/apps.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.conf import settings
12
from django.db.models.signals import pre_migrate
23
from django.apps import AppConfig
34
from django.db import connection
@@ -16,3 +17,6 @@ class RegistrationConfig(AppConfig):
1617
def ready(self):
1718
pre_migrate.connect(create_erc_schemas, sender=self)
1819
from .signals import signals, consumers # noqa: F401
20+
21+
if settings.ENVIRONMENT != 'prod':
22+
from .signals import post_save_fixtures # noqa: F401
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import logging
2+
from typing import Any, Type
3+
from django.core.files.base import ContentFile
4+
from django.db.models.signals import post_save
5+
from django.dispatch import receiver
6+
from registration.models.document import Document
7+
from django.core.files.storage import default_storage
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
@receiver(post_save, sender=Document)
13+
def handle_save_registration_document_fixture(
14+
sender: Type[Document], instance: Document, **kwargs: dict[str, Any]
15+
) -> None:
16+
"""
17+
Handler that creates registration documents on the storage medium (cloud or local storage)
18+
when the fixture is loaded
19+
"""
20+
21+
if not kwargs['raw']:
22+
# raw=True is passed only for a fixture
23+
# https://docs.djangoproject.com/en/5.2/topics/db/fixtures/#how-fixtures-are-saved-to-the-database
24+
return
25+
26+
logger.info(f"Post-save: saving file fixture to storage {instance.file.name}")
27+
default_storage.save(
28+
instance.file.name, content=ContentFile(f"Document Fixture {instance.file.name}".encode("utf-8"))
29+
)

bc_obps/reporting/apps.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.conf import settings
12
from django.db.models.signals import pre_migrate
23
from django.apps import AppConfig
34
from django.db import connection
@@ -17,3 +18,6 @@ def ready(self):
1718
pre_migrate.connect(create_erc_schemas, sender=self)
1819
from .signals import consumers # noqa: F401
1920
from .signals import signals # noqa: F401
21+
22+
if settings.ENVIRONMENT != 'prod':
23+
from .signals import post_save_fixtures # noqa: F401

bc_obps/reporting/fixtures/mock/report_attachment.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"created_at": "2025-05-26T11:20:58.144081-04:00",
77
"updated_at": null,
88
"archived_at": null,
9-
"attachment": "report_attachments/2025/VERIFICATION_ATTACHMENT_OIOdlgX.pdf",
9+
"attachment": "report_attachments/2025/VERIFICATION_ATTACHMENT_1.pdf",
1010
"attachment_type": "verification_statement",
1111
"attachment_name": "VERIFICATION_ATTACHMENT.pdf",
1212
"archived_by_id": null,
@@ -23,7 +23,7 @@
2323
"created_at": "2025-05-26T11:20:58.144081-04:00",
2424
"updated_at": null,
2525
"archived_at": null,
26-
"attachment": "report_attachments/2025/VERIFICATION_ATTACHMENT_OIOdlgX.pdf",
26+
"attachment": "report_attachments/2025/VERIFICATION_ATTACHMENT_2.pdf",
2727
"attachment_type": "verification_statement",
2828
"attachment_name": "VERIFICATION_ATTACHMENT.pdf",
2929
"archived_by_id": null,
@@ -40,7 +40,7 @@
4040
"created_at": "2025-05-26T11:20:58.144081-04:00",
4141
"updated_at": null,
4242
"archived_at": null,
43-
"attachment": "report_attachments/2025/VERIFICATION_ATTACHMENT_OIOdlgX.pdf",
43+
"attachment": "report_attachments/2025/VERIFICATION_ATTACHMENT_3.pdf",
4444
"attachment_type": "verification_statement",
4545
"attachment_name": "VERIFICATION_ATTACHMENT.pdf",
4646
"archived_by_id": null,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import logging
2+
from typing import Any, Type
3+
from django.core.files.base import ContentFile
4+
from django.db.models.signals import post_save
5+
from django.dispatch import receiver
6+
from reporting.models.report_attachment import ReportAttachment
7+
from django.core.files.storage import default_storage
8+
9+
logger = logging.getLogger(__name__)
10+
11+
12+
@receiver(post_save, sender=ReportAttachment)
13+
def handle_save_report_attachment_fixture(
14+
sender: Type[ReportAttachment], instance: ReportAttachment, **kwargs: dict[str, Any]
15+
) -> None:
16+
"""
17+
Handler that creates attachments on the storage medium (cloud or local storage)
18+
when the fixture is loaded
19+
"""
20+
21+
if not kwargs['raw']:
22+
# raw=True is passed only for a fixture
23+
# https://docs.djangoproject.com/en/5.2/topics/db/fixtures/#how-fixtures-are-saved-to-the-database
24+
return
25+
26+
logger.info(f"Post-save: saving file fixture to storage {instance.attachment.name}")
27+
default_storage.save(
28+
instance.attachment.name,
29+
content=ContentFile(f"Attachment Fixture {instance.attachment.name}".encode('utf-8')),
30+
)

dags/bc_obps_reset_data.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,14 @@
3131
doc_md=RESET_DAG_DOC,
3232
)
3333
def reset_data():
34+
35+
@task
36+
def reset_attachment_storage_task():
37+
trigger_k8s_cronjob("reset-attachment-storage", BCIERS_NAMESPACE)
38+
3439
@task
3540
def reset_data_task():
36-
trigger_k8s_cronjob('reset-database', BCIERS_NAMESPACE)
41+
trigger_k8s_cronjob("reset-database", BCIERS_NAMESPACE)
3742

3843
cycle_backend_pod_task = KubernetesJobOperator(
3944
task_id="cycle_backend_pod",
@@ -52,7 +57,7 @@ def reset_data_task():
5257
trigger_dag_id=WAIT_FOR_BACKEND_ROLLOUT_DAG_NAME,
5358
)
5459

55-
reset_data_task >> cycle_backend_pod_task >> trigger_wait_for_backend_rollout
60+
([reset_attachment_storage_task(), reset_data_task()] >> cycle_backend_pod_task >> trigger_wait_for_backend_rollout)
5661

5762

5863
ROLLOUT_DAG_DOC = """
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{{- if not (hasSuffix "-prod" .Release.Namespace) }}
2+
apiVersion: batch/v1
3+
kind: CronJob
4+
metadata:
5+
name: reset-attachment-storage
6+
labels: {{- include "cas-bciers.labels" . | nindent 4 }}
7+
namespace: {{ .Release.Namespace }}
8+
annotations:
9+
"helm.sh/hook": "pre-install,pre-upgrade"
10+
"helm.sh/hook-weight": "-10"
11+
spec:
12+
suspend: true # triggered manually via Airflow
13+
schedule: "0 * * * *"
14+
jobTemplate:
15+
spec:
16+
backoffLimit: 0
17+
activeDeadlineSeconds: 600
18+
template:
19+
metadata:
20+
labels: {{ include "cas-bciers.labels" . | nindent 12 }}
21+
component: job-with-database-access
22+
spec:
23+
activeDeadlineSeconds: 600
24+
restartPolicy: Never
25+
serviceAccountName: deployer
26+
containers:
27+
- name: reset-attachment-storage
28+
image: "gcr.io/google.com/cloudsdktool/google-cloud-cli:stable"
29+
imagePullPolicy: "Always"
30+
env:
31+
- name: GOOGLE_APPLICATION_CREDENTIALS
32+
value: "/attachment-credentials/attachment-credentials.json"
33+
- name: GS_CLEAN_BUCKET_NAME
34+
value: {{ .Release.Namespace }}-bciers-attach-clean
35+
command:
36+
- /usr/bin/env
37+
- bash
38+
- -c
39+
- |
40+
set -x;
41+
42+
gcloud auth login --cred-file=$GOOGLE_APPLICATION_CREDENTIALS;
43+
gcloud storage rm --recursive "gs://$GS_CLEAN_BUCKET_NAME/report_attachments/**";
44+
gcloud storage rm --recursive "gs://$GS_CLEAN_BUCKET_NAME/documents/**";
45+
46+
exit 0;
47+
48+
volumeMounts:
49+
- mountPath: "/attachment-credentials"
50+
name: gcs-attachment-credentials
51+
readOnly: true
52+
- mountPath: "/.config"
53+
name: config-volume
54+
volumes:
55+
- name: gcs-attachment-credentials
56+
secret:
57+
secretName: gcp-{{ .Release.Namespace }}-bciers-attach-service-account-key
58+
items:
59+
- key: credentials.json
60+
path: attachment-credentials.json
61+
- name: config-volume
62+
emptyDir:
63+
sizeLimit: 50Mi
64+
{{- end}}

0 commit comments

Comments
 (0)