diff --git a/lib/workload/stateless/stacks/bs-runs-upload-manager/Readme.md b/lib/workload/stateless/stacks/bs-runs-upload-manager/Readme.md index 9452d4e12..2470a7286 100644 --- a/lib/workload/stateless/stacks/bs-runs-upload-manager/Readme.md +++ b/lib/workload/stateless/stacks/bs-runs-upload-manager/Readme.md @@ -25,7 +25,7 @@ The two steps of the statemachine are: 1. Generate a V2 Samplesheet and reupload it 2. Launch an ICAv1 tes task that runs the bs runs upload command -This statemachine will subscribe to the orcabus.srm events and trigger the statemachine when a new run is detected. +This statemachine will subscribe to the `orcabus.sequencerunmanager` events and trigger the statemachine when a new run is detected. ![](images/bs_runs_upload_manager.png) diff --git a/lib/workload/stateless/stacks/bs-runs-upload-manager/deploy/constructs/bs-runs-upload-manager/index.ts b/lib/workload/stateless/stacks/bs-runs-upload-manager/deploy/constructs/bs-runs-upload-manager/index.ts index 1bbbbe438..f63ce9ce7 100644 --- a/lib/workload/stateless/stacks/bs-runs-upload-manager/deploy/constructs/bs-runs-upload-manager/index.ts +++ b/lib/workload/stateless/stacks/bs-runs-upload-manager/deploy/constructs/bs-runs-upload-manager/index.ts @@ -123,10 +123,10 @@ export class BsRunsUploadManagerConstruct extends Construct { const rule = new events.Rule(this, 'bs_runs_upload_event_rule', { eventBus: props.eventBusObj, eventPattern: { - source: ['orcabus.srm'], + source: ['orcabus.sequencerunmanager'], detailType: ['SequenceRunStateChange'], detail: { - status: ['succeeded'], + status: [{ 'equals-ignore-case': 'SUCCEEDED' }], }, }, }); diff --git a/lib/workload/stateless/stacks/sequence-run-manager/Makefile b/lib/workload/stateless/stacks/sequence-run-manager/Makefile index 9c8365da6..df23b4035 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/Makefile +++ b/lib/workload/stateless/stacks/sequence-run-manager/Makefile @@ -30,10 +30,10 @@ start: migrate @python manage.py runserver_plus openapi: - @python manage.py generateschema > orcabus.srm.openapi.yaml + @python manage.py generateschema > orcabus.sequencerunmanager.openapi.yaml validate: openapi - @python -m openapi_spec_validator orcabus.srm.openapi.yaml + @python -m openapi_spec_validator orcabus.sequencerunmanager.openapi.yaml coverage: install up migrate @echo $$DJANGO_SETTINGS_MODULE diff --git a/lib/workload/stateless/stacks/sequence-run-manager/README.md b/lib/workload/stateless/stacks/sequence-run-manager/README.md index d843a5636..e173ad854 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/README.md +++ b/lib/workload/stateless/stacks/sequence-run-manager/README.md @@ -1,7 +1,7 @@ # Sequence Run Manager ``` -Namespace: orcabus.srm +Namespace: orcabus.sequencerunmanager ``` ## CDK @@ -133,7 +133,7 @@ Or visit in browser: #### OpenAPI v3 ``` -python manage.py generateschema > orcabus.srm.openapi.yaml +python manage.py generateschema > orcabus.sequencerunmanager.openapi.yaml ``` ## Testing diff --git a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/migrations/0002_alter_sequence_status.py b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/migrations/0002_alter_sequence_status.py new file mode 100644 index 000000000..68dec7401 --- /dev/null +++ b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/migrations/0002_alter_sequence_status.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.5 on 2024-06-12 01:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("sequence_run_manager", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="sequence", + name="status", + field=models.CharField( + choices=[ + ("STARTED", "Started"), + ("FAILED", "Failed"), + ("SUCCEEDED", "Succeeded"), + ("ABORTED", "Aborted"), + ], + max_length=255, + ), + ), + ] diff --git a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/models/sequence.py b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/models/sequence.py index 197b84749..ba2c470fa 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/models/sequence.py +++ b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/models/sequence.py @@ -9,10 +9,11 @@ class SequenceStatus(models.TextChoices): - STARTED = "started" - FAILED = "failed" - SUCCEEDED = "succeeded" - ABORTED = "aborted" + # Convention: status values are to be stored as upper cases + STARTED = "STARTED" + FAILED = "FAILED" + SUCCEEDED = "SUCCEEDED" + ABORTED = "ABORTED" @classmethod def from_value(cls, value): diff --git a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/tests/test_models.py b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/tests/test_models.py index 872694c6e..d1870eecf 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/tests/test_models.py +++ b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager/tests/test_models.py @@ -17,7 +17,7 @@ def build_mock(): run_volume_name="gds_name", run_folder_path="/to/gds/folder/path", run_data_uri="gds://gds_name/to/gds/folder/path", - status="Complete", + status="SUCCEEDED", start_time=now(), sample_sheet_name="SampleSheet.csv", sequence_run_id="r.AAAAAA", @@ -28,7 +28,7 @@ def build_mock(): run_volume_name="gds_name", run_folder_path="/to/gds/folder/path", run_data_uri="gds://gds_name/to/gds/folder/path", - status="Fail", + status="FAILED", start_time=now(), sample_sheet_name="SampleSheet.csv", sequence_run_id="r.BBBBBB", @@ -43,14 +43,14 @@ def test_get_sequence(self): """ build_mock() logger.info("Test get success sequence table") - get_complete_sequence = Sequence.objects.get(status="Complete") + get_complete_sequence = Sequence.objects.get(status="SUCCEEDED") self.assertEqual( - get_complete_sequence.status, "Complete", "Status Complete is expected" + get_complete_sequence.status, "SUCCEEDED", "Status SUCCEEDED is expected" ) logger.info(get_complete_sequence) try: - Sequence.objects.get(status="Complete") + Sequence.objects.get(status="SUCCEEDED") except ObjectDoesNotExist: logger.info(f"Raised ObjectDoesNotExist") @@ -58,13 +58,13 @@ def test_from_seq_run_status(self): """ python manage.py test sequence_run_manager.tests.test_models.SequenceTestCase.test_from_seq_run_status """ - sq_status: SequenceStatus = SequenceStatus.from_seq_run_status("running") + sq_status: SequenceStatus = SequenceStatus.from_seq_run_status("Running") self.assertIs(sq_status, SequenceStatus.STARTED) - sq_status = SequenceStatus.from_seq_run_status("pendinganalysis") + sq_status = SequenceStatus.from_seq_run_status("PendingAnalysis") self.assertIs(sq_status, SequenceStatus.SUCCEEDED) - sq_status = SequenceStatus.from_seq_run_status("failed") + sq_status = SequenceStatus.from_seq_run_status("Failed") self.assertIs(sq_status, SequenceStatus.FAILED) def test_from_seq_run_status_stopped(self): diff --git a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/domain/sequence.py b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/domain/sequence.py index 18898a0df..9b1840c5c 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/domain/sequence.py +++ b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/domain/sequence.py @@ -1,8 +1,6 @@ import json import logging -import uuid from dataclasses import dataclass -from datetime import datetime, timezone from libumccr import libjson from libumccr.aws import libssm @@ -23,8 +21,8 @@ @dataclass class SequenceDomain: - _namespace = "orcabus.srm" - _version = "1.0.0" + # Convention: https://github.com/umccr/orcabus/tree/main/docs/schemas#namespace + _namespace = "orcabus.sequencerunmanager" sequence: Sequence state_has_changed: bool = False @@ -33,11 +31,6 @@ def namespace(self) -> str: """Domain event namespace""" return self._namespace - @property - def event_version(self) -> str: - """Domain event version""" - return self._version - @property def event_type(self) -> str: """Domain event type in string representation""" diff --git a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/services/sequence_srv.py b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/services/sequence_srv.py index 198865f11..a219fe19b 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/services/sequence_srv.py +++ b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/services/sequence_srv.py @@ -59,7 +59,7 @@ def create_or_update_sequence_from_bssh_event(payload: dict) -> SequenceDomain: # --- start mapping to internal Sequence model # status must exist in payload - status = SequenceStatus.from_seq_run_status(payload["status"]) + status: SequenceStatus = SequenceStatus.from_seq_run_status(payload["status"]) # derive start_time and end_time from date_modified and status start_time = date_modified diff --git a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/tests/test_sequence_srv.py b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/tests/test_sequence_srv.py index 450dae08c..c35aa68ca 100644 --- a/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/tests/test_sequence_srv.py +++ b/lib/workload/stateless/stacks/sequence-run-manager/sequence_run_manager_proc/tests/test_sequence_srv.py @@ -30,16 +30,19 @@ def test_create_or_update_sequence_from_bssh_event(self): ) self.assertIsNotNone(seq_domain) logger.info(seq_domain) - ses_in_db: Sequence = Sequence.objects.get( + seq_in_db: Sequence = Sequence.objects.get( instrument_run_id=TestConstant.instrument_run_id.value ) self.assertEqual( - seq_domain.sequence.instrument_run_id, ses_in_db.instrument_run_id + seq_domain.sequence.instrument_run_id, seq_in_db.instrument_run_id ) self.assertTrue( seq_domain.state_has_changed ) # assert Sequence Run State has changed True + # assert status value are stored as upper case + self.assertEqual(seq_in_db.status, "STARTED") + def test_create_or_update_sequence_from_bssh_event_skip(self): """ python manage.py test sequence_run_manager_proc.tests.test_sequence_srv.SequenceRunSrvUnitTests.test_create_or_update_sequence_from_bssh_event_skip