From 1c6286d9ce7f8874e9dae2ebd3997a08a414eec5 Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Tue, 3 Dec 2024 11:41:58 -0500 Subject: [PATCH 1/4] Added new QualityControl entity --- .../seqdb/api/entities/QualityControl.java | 69 +++++++++++++++++++ .../db/changelog/db.changelog-master.xml | 1 + .../57-Add_quality_control_table.xml | 38 ++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java create mode 100644 src/main/resources/db/changelog/migrations/57-Add_quality_control_table.xml diff --git a/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java b/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java new file mode 100644 index 00000000..bddb32b9 --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java @@ -0,0 +1,69 @@ +package ca.gc.aafc.seqdb.api.entities; + +import java.time.OffsetDateTime; +import java.util.UUID; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.hibernate.annotations.Generated; +import org.hibernate.annotations.GenerationTime; +import org.hibernate.annotations.NaturalId; + +import ca.gc.aafc.dina.entity.DinaEntity; + +@Getter +@Entity +@Builder +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "quality_control") +public class QualityControl implements DinaEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @NotNull + @NaturalId + private UUID uuid; + + @NotBlank + @Column(name = "created_by", updatable = false) + private String createdBy; + + @Column(name = "created_on", insertable = false, updatable = false) + @Generated(value = GenerationTime.INSERT) + private OffsetDateTime createdOn; + + @Column(name = "_group") + private String group; + + @NotBlank + @Size(max = 100) + private String name; + + @NotBlank + @Size(max = 50) + private String qcType; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "molecular_analysis_run_item_id") + private MolecularAnalysisRunItem molecularAnalysisRunItem; + +} diff --git a/src/main/resources/db/changelog/db.changelog-master.xml b/src/main/resources/db/changelog/db.changelog-master.xml index 8d58c493..7900fe28 100644 --- a/src/main/resources/db/changelog/db.changelog-master.xml +++ b/src/main/resources/db/changelog/db.changelog-master.xml @@ -61,4 +61,5 @@ + diff --git a/src/main/resources/db/changelog/migrations/57-Add_quality_control_table.xml b/src/main/resources/db/changelog/migrations/57-Add_quality_control_table.xml new file mode 100644 index 00000000..b8c0e7a4 --- /dev/null +++ b/src/main/resources/db/changelog/migrations/57-Add_quality_control_table.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 24307f4acd8a1ac40e485325c808bd0026c646c2 Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Tue, 3 Dec 2024 11:56:00 -0500 Subject: [PATCH 2/4] Added QualityControl service + test --- .../seqdb/api/entities/QualityControl.java | 1 + .../api/service/QualityControlService.java | 27 +++++++++++++++++++ .../aafc/seqdb/api/SequenceModuleBaseIT.java | 4 +++ .../api/service/QualityControlServiceIT.java | 16 +++++++++++ .../factories/QualityControlFactory.java | 16 +++++++++++ 5 files changed, 64 insertions(+) create mode 100644 src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java create mode 100644 src/test/java/ca/gc/aafc/seqdb/api/service/QualityControlServiceIT.java create mode 100644 src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java diff --git a/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java b/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java index bddb32b9..9932671c 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/entities/QualityControl.java @@ -60,6 +60,7 @@ public class QualityControl implements DinaEntity { @NotBlank @Size(max = 50) + @Column(name = "qc_type") private String qcType; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java new file mode 100644 index 00000000..0ed2900b --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java @@ -0,0 +1,27 @@ +package ca.gc.aafc.seqdb.api.service; + +import lombok.NonNull; + +import org.springframework.stereotype.Service; +import org.springframework.validation.SmartValidator; + +import ca.gc.aafc.dina.jpa.BaseDAO; +import ca.gc.aafc.dina.service.DefaultDinaService; +import ca.gc.aafc.dina.util.UUIDHelper; +import ca.gc.aafc.seqdb.api.entities.QualityControl; + +@Service +public class QualityControlService extends DefaultDinaService { + + public QualityControlService( + @NonNull BaseDAO baseDAO, + @NonNull SmartValidator sv) { + super(baseDAO, sv); + } + + @Override + protected void preCreate(QualityControl entity) { + entity.setUuid(UUIDHelper.generateUUIDv7()); + } + +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java b/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java index 92c6f46d..54a47972 100644 --- a/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java +++ b/src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java @@ -9,6 +9,7 @@ import ca.gc.aafc.seqdb.api.service.MolecularAnalysisRunService; import ca.gc.aafc.seqdb.api.service.PcrBatchItemService; import ca.gc.aafc.seqdb.api.service.PcrBatchService; +import ca.gc.aafc.seqdb.api.service.QualityControlService; import ca.gc.aafc.seqdb.api.service.SeqSubmissionService; import ca.gc.aafc.seqdb.api.service.SequenceManagedAttributeService; import ca.gc.aafc.seqdb.api.service.SequencingFacilityService; @@ -45,4 +46,7 @@ public class SequenceModuleBaseIT extends BaseIntegrationTest { @Inject protected SequenceManagedAttributeService managedAttributeService; + @Inject + protected QualityControlService qualityControlService; + } diff --git a/src/test/java/ca/gc/aafc/seqdb/api/service/QualityControlServiceIT.java b/src/test/java/ca/gc/aafc/seqdb/api/service/QualityControlServiceIT.java new file mode 100644 index 00000000..8cac4327 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/service/QualityControlServiceIT.java @@ -0,0 +1,16 @@ +package ca.gc.aafc.seqdb.api.service; + +import org.junit.jupiter.api.Test; + +import ca.gc.aafc.seqdb.api.SequenceModuleBaseIT; +import ca.gc.aafc.seqdb.api.entities.QualityControl; +import ca.gc.aafc.seqdb.api.testsupport.factories.QualityControlFactory; + +public class QualityControlServiceIT extends SequenceModuleBaseIT { + + @Test + public void onValidEntity_save_noException() { + QualityControl qc = QualityControlFactory.newQualityControl().build(); + qualityControlService.create(qc); + } +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java new file mode 100644 index 00000000..0e06f54e --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java @@ -0,0 +1,16 @@ +package ca.gc.aafc.seqdb.api.testsupport.factories; + +import ca.gc.aafc.dina.util.UUIDHelper; +import ca.gc.aafc.seqdb.api.entities.QualityControl; + +public class QualityControlFactory { + + public static QualityControl.QualityControlBuilder newQualityControl() { + return QualityControl.builder() + .name(TestableEntityFactory.generateRandomName(7)) + .qcType("standard") + .uuid(UUIDHelper.generateUUIDv7()) + .group("dina") + .createdBy("test user"); + } +} From 02a5840963aa9a447150984de5defdc7132bf29d Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Wed, 4 Dec 2024 08:44:10 -0500 Subject: [PATCH 3/4] Added repo and dto --- .../aafc/seqdb/api/dto/QualityControlDto.java | 48 +++++++++++++++++ .../repository/QualityControlRepository.java | 53 +++++++++++++++++++ .../QualityControlRepositoryIT.java | 42 +++++++++++++++ .../fixtures/QualityControlTestFixture.java | 18 +++++++ 4 files changed, 161 insertions(+) create mode 100644 src/main/java/ca/gc/aafc/seqdb/api/dto/QualityControlDto.java create mode 100644 src/main/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepository.java create mode 100644 src/test/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepositoryIT.java create mode 100644 src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java diff --git a/src/main/java/ca/gc/aafc/seqdb/api/dto/QualityControlDto.java b/src/main/java/ca/gc/aafc/seqdb/api/dto/QualityControlDto.java new file mode 100644 index 00000000..ac2f07c4 --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/dto/QualityControlDto.java @@ -0,0 +1,48 @@ +package ca.gc.aafc.seqdb.api.dto; + +import io.crnk.core.resource.annotations.JsonApiId; +import io.crnk.core.resource.annotations.JsonApiRelation; +import io.crnk.core.resource.annotations.JsonApiResource; +import java.time.OffsetDateTime; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import org.javers.core.metamodel.annotation.Id; +import org.javers.core.metamodel.annotation.PropertyName; +import org.javers.core.metamodel.annotation.TypeName; + +import ca.gc.aafc.dina.dto.RelatedEntity; +import ca.gc.aafc.seqdb.api.entities.QualityControl; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonApiResource(type = QualityControlDto.TYPENAME) +@TypeName(QualityControlDto.TYPENAME) +@RelatedEntity(QualityControl.class) +public class QualityControlDto { + + public static final String TYPENAME = "quality-control"; + + @JsonApiId + @Id + @PropertyName("id") + private UUID uuid; + + private String createdBy; + private OffsetDateTime createdOn; + + private String group; + + private String name; + + private String qcType; + + @JsonApiRelation + private MolecularAnalysisRunItemDto molecularAnalysisRunItem; + +} diff --git a/src/main/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepository.java b/src/main/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepository.java new file mode 100644 index 00000000..b8b50ed0 --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepository.java @@ -0,0 +1,53 @@ +package ca.gc.aafc.seqdb.api.repository; + +import org.springframework.boot.info.BuildProperties; +import org.springframework.stereotype.Repository; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import ca.gc.aafc.dina.mapper.DinaMapper; +import ca.gc.aafc.dina.repository.DinaRepository; +import ca.gc.aafc.dina.repository.external.ExternalResourceProvider; +import ca.gc.aafc.dina.security.DinaAuthenticatedUser; +import ca.gc.aafc.dina.security.auth.DinaAuthorizationService; +import ca.gc.aafc.seqdb.api.dto.QualityControlDto; +import ca.gc.aafc.seqdb.api.entities.QualityControl; +import ca.gc.aafc.seqdb.api.service.QualityControlService; + +import java.util.Optional; +import lombok.NonNull; + +@Repository +public class QualityControlRepository extends DinaRepository { + + private Optional dinaAuthenticatedUser; + + public QualityControlRepository( + @NonNull QualityControlService dinaService, + DinaAuthorizationService groupAuthorizationService, + @NonNull BuildProperties props, + ExternalResourceProvider externalResourceProvider, + Optional dinaAuthenticatedUser, + ObjectMapper objMapper) { + super( + dinaService, + groupAuthorizationService, + Optional.empty(), + new DinaMapper<>(QualityControlDto.class), + QualityControlDto.class, + QualityControl.class, + null, + externalResourceProvider, + props, objMapper); + + this.dinaAuthenticatedUser = dinaAuthenticatedUser; + } + + @Override + public S create(S resource) { + dinaAuthenticatedUser.ifPresent( + authenticatedUser -> resource.setCreatedBy(authenticatedUser.getUsername())); + return super.create(resource); + } + +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepositoryIT.java b/src/test/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepositoryIT.java new file mode 100644 index 00000000..70f11362 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/repository/QualityControlRepositoryIT.java @@ -0,0 +1,42 @@ +package ca.gc.aafc.seqdb.api.repository; + +import org.junit.jupiter.api.Test; + +import ca.gc.aafc.seqdb.api.dto.MolecularAnalysisRunDto; +import ca.gc.aafc.seqdb.api.dto.MolecularAnalysisRunItemDto; +import ca.gc.aafc.seqdb.api.dto.QualityControlDto; +import ca.gc.aafc.seqdb.api.testsupport.fixtures.MolecularAnalysisRunItemTestFixture; +import ca.gc.aafc.seqdb.api.testsupport.fixtures.MolecularAnalysisRunTestFixture; +import ca.gc.aafc.seqdb.api.testsupport.fixtures.QualityControlTestFixture; + +import javax.inject.Inject; + +public class QualityControlRepositoryIT extends BaseRepositoryTestV2 { + + @Inject + private QualityControlRepository qualityControlRepository; + + @Inject + private MolecularAnalysisRunRepository molecularAnalysisRunRepository; + + @Inject + private MolecularAnalysisRunItemRepository molecularAnalysisRunItemRepository; + + @Test + public void onValidDto_dtoSavedWithoutExceptions() { + + MolecularAnalysisRunDto runDto = molecularAnalysisRunRepository + .create(MolecularAnalysisRunTestFixture.newMolecularAnalysisRun()); + + MolecularAnalysisRunItemDto runItemDto = MolecularAnalysisRunItemTestFixture + .newMolecularAnalysisRunItem(); + runItemDto.setRun(runDto); + molecularAnalysisRunItemRepository.create(runItemDto); + + QualityControlDto qualityControlDto = QualityControlTestFixture.newQualityControl(); + qualityControlDto.setMolecularAnalysisRunItem(runItemDto); + + qualityControlRepository.create(qualityControlDto); + } + +} diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java new file mode 100644 index 00000000..fb359866 --- /dev/null +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java @@ -0,0 +1,18 @@ +package ca.gc.aafc.seqdb.api.testsupport.fixtures; + +import ca.gc.aafc.seqdb.api.dto.QualityControlDto; +import ca.gc.aafc.seqdb.api.testsupport.factories.TestableEntityFactory; + +public class QualityControlTestFixture { + + public static final String GROUP = "aafc"; + + public static QualityControlDto newQualityControl() { + return QualityControlDto.builder() + .group(GROUP) + .name(TestableEntityFactory.generateRandomName(11)) + .qcType("standard") + .createdBy("test-user") + .build(); + } +} From f9e2b7664b973c5184b3870bd6a90aeb54a3da2b Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Wed, 4 Dec 2024 09:23:17 -0500 Subject: [PATCH 4/4] Added vocab and validator --- .../api/SequenceVocabularyConfiguration.java | 2 + .../api/service/QualityControlService.java | 12 +++++- .../PcrBatchVocabularyValidator.java | 4 +- .../QualityControlVocabularyValidator.java | 34 +++++++++++++++ .../SeqBatchVocabularyValidator.java | 4 +- .../validation/VocabularyBasedValidator.java | 42 ++++--------------- .../vocabulary/qualityControlType.yml | 23 ++++++++++ .../repository/VocabularyRepositoryIT.java | 2 +- .../factories/QualityControlFactory.java | 2 +- .../fixtures/QualityControlTestFixture.java | 2 +- 10 files changed, 84 insertions(+), 43 deletions(-) create mode 100644 src/main/java/ca/gc/aafc/seqdb/api/validation/QualityControlVocabularyValidator.java create mode 100644 src/main/resources/vocabulary/qualityControlType.yml diff --git a/src/main/java/ca/gc/aafc/seqdb/api/SequenceVocabularyConfiguration.java b/src/main/java/ca/gc/aafc/seqdb/api/SequenceVocabularyConfiguration.java index 9ee6b2d5..92da6aa5 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/SequenceVocabularyConfiguration.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/SequenceVocabularyConfiguration.java @@ -16,6 +16,7 @@ @PropertySource(value = "classpath:vocabulary/pcrBatchType.yml", factory = YamlPropertyLoaderFactory.class) @PropertySource(value = "classpath:vocabulary/sequencingType.yml", factory = YamlPropertyLoaderFactory.class) @PropertySource(value = "classpath:vocabulary/molecularAnalysisType.yml", factory = YamlPropertyLoaderFactory.class) +@PropertySource(value = "classpath:vocabulary/qualityControlType.yml", factory = YamlPropertyLoaderFactory.class) @ConfigurationProperties @Validated public class SequenceVocabularyConfiguration extends VocabularyConfiguration { @@ -23,6 +24,7 @@ public class SequenceVocabularyConfiguration extends VocabularyConfiguration> vocabulary) { super(vocabulary); diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java index 0ed2900b..3411283c 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/QualityControlService.java @@ -9,14 +9,19 @@ import ca.gc.aafc.dina.service.DefaultDinaService; import ca.gc.aafc.dina.util.UUIDHelper; import ca.gc.aafc.seqdb.api.entities.QualityControl; +import ca.gc.aafc.seqdb.api.validation.QualityControlVocabularyValidator; @Service -public class QualityControlService extends DefaultDinaService { +public class QualityControlService extends DefaultDinaService { + + private final QualityControlVocabularyValidator qualityControlVocabularyValidator; public QualityControlService( @NonNull BaseDAO baseDAO, + QualityControlVocabularyValidator qualityControlVocabularyValidator, @NonNull SmartValidator sv) { super(baseDAO, sv); + this.qualityControlVocabularyValidator = qualityControlVocabularyValidator; } @Override @@ -24,4 +29,9 @@ protected void preCreate(QualityControl entity) { entity.setUuid(UUIDHelper.generateUUIDv7()); } + @Override + public void validateBusinessRules(QualityControl entity) { + applyBusinessRule(entity, qualityControlVocabularyValidator); + } + } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/validation/PcrBatchVocabularyValidator.java b/src/main/java/ca/gc/aafc/seqdb/api/validation/PcrBatchVocabularyValidator.java index 1f5b4d5b..b7881255 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/validation/PcrBatchVocabularyValidator.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/validation/PcrBatchVocabularyValidator.java @@ -21,12 +21,12 @@ public class PcrBatchVocabularyValidator extends VocabularyBasedValidator batchTypeVocabulary; PcrBatchVocabularyValidator(MessageSource messageSource, SequenceVocabularyConfiguration vocabularyConfiguration) { - super(messageSource, PcrBatch.class); + super(PcrBatch.class, messageSource); batchTypeVocabulary = vocabularyConfiguration.getVocabularyByKey(SequenceVocabularyConfiguration.PCR_BATCH_TYPE_VOCAB_KEY); } @Override - protected void validateVocabularyBasedAttribute(PcrBatch target, Errors errors) { + public void validateTarget(PcrBatch target, Errors errors) { if (StringUtils.isBlank(target.getBatchType())) { return; } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/validation/QualityControlVocabularyValidator.java b/src/main/java/ca/gc/aafc/seqdb/api/validation/QualityControlVocabularyValidator.java new file mode 100644 index 00000000..43495bce --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/validation/QualityControlVocabularyValidator.java @@ -0,0 +1,34 @@ +package ca.gc.aafc.seqdb.api.validation; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; + +import ca.gc.aafc.dina.vocabulary.VocabularyElementConfiguration; +import ca.gc.aafc.seqdb.api.SequenceVocabularyConfiguration; +import ca.gc.aafc.seqdb.api.entities.QualityControl; + +@Component +public class QualityControlVocabularyValidator extends VocabularyBasedValidator { + + private static final String QUALITY_CONTROL_FIELD_NAME = "qcType"; + private final List qcTypeVocabulary; + + QualityControlVocabularyValidator(MessageSource messageSource, SequenceVocabularyConfiguration vocabularyConfiguration) { + super(QualityControl.class, messageSource); + qcTypeVocabulary = vocabularyConfiguration.getVocabularyByKey(SequenceVocabularyConfiguration.QUALITY_CONTROL_TYPE_VOCAB_KEY); + } + + @Override + public void validateTarget(QualityControl target, Errors errors) { + if (StringUtils.isBlank(target.getQcType())) { + return; + } + + target.setQcType(validateAndStandardizeValueAgainstVocabulary(target.getQcType(), + QUALITY_CONTROL_FIELD_NAME, qcTypeVocabulary, errors)); + } +} diff --git a/src/main/java/ca/gc/aafc/seqdb/api/validation/SeqBatchVocabularyValidator.java b/src/main/java/ca/gc/aafc/seqdb/api/validation/SeqBatchVocabularyValidator.java index 05f90622..4ab8ec42 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/validation/SeqBatchVocabularyValidator.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/validation/SeqBatchVocabularyValidator.java @@ -21,12 +21,12 @@ public class SeqBatchVocabularyValidator extends VocabularyBasedValidator sequencingTypeVocabulary; SeqBatchVocabularyValidator(MessageSource messageSource, SequenceVocabularyConfiguration vocabularyConfiguration) { - super(messageSource, SeqBatch.class); + super(SeqBatch.class, messageSource); sequencingTypeVocabulary = vocabularyConfiguration.getVocabularyByKey(SequenceVocabularyConfiguration.SEQUENCING_TYPE_VOCAB_KEY); } @Override - protected void validateVocabularyBasedAttribute(SeqBatch target, Errors errors) { + public void validateTarget(SeqBatch target, Errors errors) { if (StringUtils.isBlank(target.getSequencingType())) { return; } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/validation/VocabularyBasedValidator.java b/src/main/java/ca/gc/aafc/seqdb/api/validation/VocabularyBasedValidator.java index d2c9f95d..11e907d0 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/validation/VocabularyBasedValidator.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/validation/VocabularyBasedValidator.java @@ -1,41 +1,23 @@ package ca.gc.aafc.seqdb.api.validation; -import java.util.List; -import java.util.Optional; - import org.springframework.context.MessageSource; -import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.validation.Errors; -import org.springframework.validation.Validator; +import ca.gc.aafc.dina.validation.DinaBaseValidator; import ca.gc.aafc.dina.vocabulary.VocabularyElementConfiguration; +import java.util.List; +import java.util.Optional; + /** * Move to dina-base */ -abstract class VocabularyBasedValidator implements Validator { +abstract class VocabularyBasedValidator extends DinaBaseValidator { public static final String VALUE_NOT_IN_VOCABULARY = "validation.constraint.violation.notInVocabulary"; - private final MessageSource messageSource; - private final Class supportedClass; - - VocabularyBasedValidator(MessageSource messageSource, Class supportedClass) { - this.messageSource = messageSource; - this.supportedClass = supportedClass; - } - - @Override - public boolean supports(Class clazz) { - return supportedClass.isAssignableFrom(clazz); - } - - @Override - public void validate(Object target, Errors errors) { - if (!supports(target.getClass())) { - throw new IllegalArgumentException("VocabularyBasedValidator not supported for class " + target.getClass()); - } - validateVocabularyBasedAttribute(supportedClass.cast(target), errors); + VocabularyBasedValidator(Class supportedClass, MessageSource messageSource) { + super(supportedClass, messageSource); } /** @@ -67,14 +49,4 @@ protected String validateAndStandardizeValueAgainstVocabulary(String value, Stri protected Optional findInVocabulary(String value, List vocabularyElements) { return vocabularyElements.stream().filter(o -> o.getKey().equalsIgnoreCase(value)).findFirst(); } - - protected abstract void validateVocabularyBasedAttribute(T target, Errors errors); - - protected String getMessage(String key) { - return messageSource.getMessage(key, null, LocaleContextHolder.getLocale()); - } - protected String getMessage(String key, Object... messageArgs) { - return messageSource.getMessage(key, messageArgs, LocaleContextHolder.getLocale()); - } - } diff --git a/src/main/resources/vocabulary/qualityControlType.yml b/src/main/resources/vocabulary/qualityControlType.yml new file mode 100644 index 00000000..a88d9ac0 --- /dev/null +++ b/src/main/resources/vocabulary/qualityControlType.yml @@ -0,0 +1,23 @@ +vocabulary: + qualityControlType: + - key: reserpine_standard + name: reserpine standard + multilingualTitle.titles: + - lang: en + title: Reserpine Standard + - lang: fr + title: Standard Reserpine + - key: acn_blank + name: acn blank + multilingualTitle.titles: + - lang: en + title: ACN Blank + - lang: fr + title: ACN Blank (fr) + - key: meoh_blank + name: meoh blank + multilingualTitle.titles: + - lang: en + title: MEOH Blank + - lang: fr + title: MEOH Blank (fr) diff --git a/src/test/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepositoryIT.java b/src/test/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepositoryIT.java index 4081b55a..1f77884d 100644 --- a/src/test/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepositoryIT.java +++ b/src/test/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepositoryIT.java @@ -18,7 +18,7 @@ public class VocabularyRepositoryIT extends BaseRepositoryTest { @Test public void findAll_DefaultQuerySpec_AllDtosReturned() { List resultList = readOnlyRepo.findAll(""); - assertEquals(3, resultList.size()); + assertEquals(4, resultList.size()); } @Test diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java index 0e06f54e..733a3754 100644 --- a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/factories/QualityControlFactory.java @@ -8,7 +8,7 @@ public class QualityControlFactory { public static QualityControl.QualityControlBuilder newQualityControl() { return QualityControl.builder() .name(TestableEntityFactory.generateRandomName(7)) - .qcType("standard") + .qcType("reserpine_standard") .uuid(UUIDHelper.generateUUIDv7()) .group("dina") .createdBy("test user"); diff --git a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java index fb359866..a1ec1ead 100644 --- a/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java +++ b/src/test/java/ca/gc/aafc/seqdb/api/testsupport/fixtures/QualityControlTestFixture.java @@ -11,7 +11,7 @@ public static QualityControlDto newQualityControl() { return QualityControlDto.builder() .group(GROUP) .name(TestableEntityFactory.generateRandomName(11)) - .qcType("standard") + .qcType("reserpine_standard") .createdBy("test-user") .build(); }