Skip to content

Commit

Permalink
NIAD-3013: Throw exception on application startup if immunization cod…
Browse files Browse the repository at this point in the history
…es are not loaded (#694)

* Add sql command to ImmunizationSnomedCTDao to check if immunization codes have been loaded
Add custom CommandLineRunner which will be executed after runtime initialization
Add Unit tests to ensure that the CommandLineRunner throws an exception when required.

* Update CHANGELOG.md

* Update README.md for snomed-database-loader

* Correct test name in ApplicationCommandLineRunnerTest

* Add comment to load-release-postgressql.sh explaining the coupling between this script and the translator service
Refactored the REFRESH MATERIALIZED VIEWS so both are completed in the same PSQL command

* Address issues in PR comments
  • Loading branch information
MartinWheelerMT authored Jul 12, 2024
1 parent f408434 commit e3fc3e6
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 6 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Added
* The AllergyIntoleranceMapper has been enhanced to support the redaction fix. If an Allergy Intolerance record includes a confidentialityCode, the meta.security field of the corresponding FHIR resource will now be appropriately populated.
* When the SNOMED DB ingest script has not completed successfully, The GP2GP Translator Service will now exit and throw a
RuntimeException with the following message:
```
FATAL: Expected Immunization codes not found in snomedct.immunization_codes view.
SNOMED CT Database not set up correctly.
Please update / reload the SNOMED DB.
```

### Fixed
* DiagnosticReports now preserves original ordering for mapped result references.


## [3.0.0] - 2024-07-02

### Removed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public interface ImmunizationSnomedCTDao {
@SqlQuery("select_immunization_concept_id")
@UseClasspathSqlLocator
ImmunizationSnomedCT getImmunizationSnomednUsingConceptId(@Bind("conceptId") String conceptId);

@SqlQuery("verify_immunizations_loaded")
@UseClasspathSqlLocator
boolean areImmunizationCodesLoaded();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- the conceptIds being checked for below represent the immunization root codes and those immunization codes outside
-- of the root code hierarchy, as described in the snomed-database-loader README.md file

SELECT COUNT(i.conceptid) = 16 -- total number of codes
FROM "snomedct".immunization_codes i
WHERE i.conceptid IN (
'787859002', '127785005', '304250009', '90351000119108','713404003','2997511000001102',
'308101000000104','1036721000000101', '1373691000000102', '945831000000105', '542931000000103',
'735981009', '90640007', '571631000119106', '764141000000106', '170399005'
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package uk.nhs.adaptors.pss.translator.application;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import uk.nhs.adaptors.connector.dao.ImmunizationSnomedCTDao;

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class VerifyImmunizationsLoadedCommandLineRunner implements CommandLineRunner {

private final ImmunizationSnomedCTDao immunizationSnomedCTDao;

@Override
public void run(String... args) {
if (!immunizationSnomedCTDao.areImmunizationCodesLoaded()) {
throw new RuntimeException("""
FATAL: Expected Immunization codes not found in snomedct.immunization_codes view.
SNOMED CT Database not set up correctly.
Please update / reload the SNOMED DB.
"""
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package uk.nhs.adaptors.pss.translator.application;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import uk.nhs.adaptors.connector.dao.ImmunizationSnomedCTDao;

import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class VerifyImmunizationsLoadedCommandLineRunnerTest {

@Mock
private ImmunizationSnomedCTDao immunizationSnomedCTDao;

@InjectMocks
private VerifyImmunizationsLoadedCommandLineRunner verifyImmunizationsLoadedCommandLineRunner;

@Test
public void When_RunApplicationAndImmunizationsAreLoaded_Expect_ExceptionIsNotThrown() {
when(immunizationSnomedCTDao.areImmunizationCodesLoaded()).thenReturn(true);

assertDoesNotThrow(() -> verifyImmunizationsLoadedCommandLineRunner.run());
}

@Test
public void When_RunApplicationAndImmunizationsNotLoaded_Expect_RuntimeExceptionThrown() {
when(immunizationSnomedCTDao.areImmunizationCodesLoaded()).thenReturn(false);

assertThrows(RuntimeException.class, () -> verifyImmunizationsLoadedCommandLineRunner.run());
}
}
16 changes: 13 additions & 3 deletions snomed-database-loader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,19 @@ An example of one of these codes in the [SNOMED CT Browser](https://termbrowser.

![immunization_not_in_hierarchy_example.png](immunization_not_in_hierarchy_example.png)

However, the reference set used to build the immunization codes still includes inactive relationships so these will
we included when building the descendants of immunization root codes.

However, the reference set used to build the immunization codes still includes inactive relationships, so these will be
included when building the descendants of immunization root codes.

If the immunization codes have not been loaded successfully into the SNOMED DB then a RuntimeException with twill be thrown during
initialization of the GP2GP Translator Service and the service will then terminate.

If the immunization codes have not been loaded successfully into the SNOMED DB, The GP2GP Translator Service will now
exit and throw a RuntimeException with the following message:
```
FATAL: Expected Immunization codes not found in snomedct.immunization_codes view.
SNOMED CT Database not set up correctly.
Please update / reload the SNOMED DB.
```
## Minimum Specification

- PostgreSQL v.9
Expand Down
9 changes: 6 additions & 3 deletions snomed-database-loader/load_release-postgresql.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,12 @@ EOF
#load data
./${generatedLoadScript}

#refresh materialized view
psql "${databaseUri}" -c "REFRESH MATERIALIZED VIEW ${snomedCtSchema}.immunization_codes"
psql "${databaseUri}" -c "REFRESH MATERIALIZED VIEW ${snomedCtSchema}.preferred_terms"
#refresh materialized view - this is intentionally completed last as there isn't an transactional safety in this script,
#however the GP2GP Translator service will terminate if the immunization codes have not loaded successfully.
psql "${databaseUri}" << SQL
REFRESH MATERIALIZED VIEW ${snomedCtSchema}.immunization_codes;
REFRESH MATERIALIZED VIEW ${snomedCtSchema}.preferred_terms
SQL

#cleanup
rm -rf $localExtract
Expand Down

0 comments on commit e3fc3e6

Please sign in to comment.