From a6cd3607a4f06900f6bd8cbec084ac8bd0e703d7 Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Wed, 24 Jul 2024 09:32:29 -0400 Subject: [PATCH 1/4] 34325 Use vocabulary methods from dina-base Updated dina-base and refactored code to use vocabulary related classes from it --- pom.xml | 2 +- .../gc/aafc/seqdb/api/dto/VocabularyDto.java | 10 ++- .../api/repository/VocabularyRepository.java | 71 +++++++++++++------ .../api/service/SeqSubmissionService.java | 4 -- .../service/SequencingFacilityService.java | 7 -- .../service/ThermocyclerProfileService.java | 6 -- .../seqdb/api/service/VocabularyService.java | 22 ++++++ .../service/libraryprep/IndexSetService.java | 6 -- .../libraryprep/LibraryPrepBatchService.java | 4 -- .../libraryprep/LibraryPrepService.java | 8 --- .../service/libraryprep/NgsIndexService.java | 6 -- .../LibraryPoolContentService.java | 7 -- .../pooledlibraries/LibraryPoolService.java | 6 -- .../repository/VocabularyRepositoryIT.java | 27 +++---- 14 files changed, 89 insertions(+), 97 deletions(-) create mode 100644 src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java diff --git a/pom.xml b/pom.xml index 7156ba46..a1d52e63 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 10.17.0 2.1.0 - 0.125 + 0.127 42.4.4 1.33 diff --git a/src/main/java/ca/gc/aafc/seqdb/api/dto/VocabularyDto.java b/src/main/java/ca/gc/aafc/seqdb/api/dto/VocabularyDto.java index 4dff5834..6f554786 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/dto/VocabularyDto.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/dto/VocabularyDto.java @@ -2,17 +2,21 @@ import ca.gc.aafc.dina.vocabulary.VocabularyElementConfiguration; -import io.crnk.core.resource.annotations.JsonApiId; -import io.crnk.core.resource.annotations.JsonApiResource; import lombok.AllArgsConstructor; import lombok.Getter; import java.util.List; +import com.toedter.spring.hateoas.jsonapi.JsonApiId; +import com.toedter.spring.hateoas.jsonapi.JsonApiTypeForClass; + @AllArgsConstructor @Getter -@JsonApiResource(type = "vocabulary") +@JsonApiTypeForClass(VocabularyDto.TYPE) public class VocabularyDto { + + public static final String TYPE = "vocabulary"; + @JsonApiId private final String id; diff --git a/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java b/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java index cb2f87e3..5059892e 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java @@ -1,34 +1,63 @@ package ca.gc.aafc.seqdb.api.repository; -import ca.gc.aafc.seqdb.api.SequenceVocabularyConfiguration; +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.RepresentationModel; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.toedter.spring.hateoas.jsonapi.JsonApiModelBuilder; + +import ca.gc.aafc.dina.repository.ReadOnlyDinaRepositoryV2; import ca.gc.aafc.seqdb.api.dto.VocabularyDto; -import io.crnk.core.queryspec.QuerySpec; -import io.crnk.core.repository.ReadOnlyResourceRepositoryBase; -import io.crnk.core.resource.list.ResourceList; -import lombok.NonNull; -import org.springframework.stereotype.Repository; +import ca.gc.aafc.seqdb.api.service.VocabularyService; + +import static com.toedter.spring.hateoas.jsonapi.JsonApiModelBuilder.jsonApiModel; +import static com.toedter.spring.hateoas.jsonapi.MediaTypes.JSON_API_VALUE; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.List; -import java.util.stream.Collectors; +import javax.servlet.http.HttpServletRequest; + +@RestController +@RequestMapping(value = "/api/v1", produces = JSON_API_VALUE) +public class VocabularyRepository extends ReadOnlyDinaRepositoryV2 { + + protected VocabularyRepository(VocabularyService vocabularyService) { + super(vocabularyService); + } -@Repository -public class VocabularyRepository extends ReadOnlyResourceRepositoryBase { + @GetMapping("vocabulary/{id}") + public ResponseEntity> handleFindOne(@PathVariable String id) { - private final List vocabulary; + VocabularyDto dto = findOne(id); - protected VocabularyRepository( - @NonNull SequenceVocabularyConfiguration collectionVocabularyConfiguration) { - super(VocabularyDto.class); + if (dto == null) { + return ResponseEntity.notFound().build(); + } - vocabulary = collectionVocabularyConfiguration.getVocabulary() - .entrySet() - .stream() - .map(entry -> new VocabularyDto(entry.getKey(), entry.getValue())) - .collect(Collectors.toList()); + JsonApiModelBuilder builder = jsonApiModel().model(RepresentationModel.of(dto)); + + return ResponseEntity.ok(builder.build()); } - @Override - public ResourceList findAll(QuerySpec querySpec) { - return querySpec.apply(vocabulary); + @GetMapping("vocabulary") + public ResponseEntity> handleFindAll(HttpServletRequest req) { + + String queryString = URLDecoder.decode(req.getQueryString(), StandardCharsets.UTF_8); + List dtos ; + try { + dtos = findAll(queryString); + } catch (IllegalArgumentException iaEx) { + return ResponseEntity.badRequest().build(); + } + + JsonApiModelBuilder builder = jsonApiModel().model(CollectionModel.of(dtos)); + + return ResponseEntity.ok(builder.build()); } + } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/SeqSubmissionService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/SeqSubmissionService.java index 63672377..7f5d494b 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/SeqSubmissionService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/SeqSubmissionService.java @@ -26,8 +26,4 @@ protected void preCreate(SeqSubmission entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/SequencingFacilityService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/SequencingFacilityService.java index a0546a56..31062c88 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/SequencingFacilityService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/SequencingFacilityService.java @@ -10,8 +10,6 @@ import java.util.UUID; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class SequencingFacilityService extends DefaultDinaService { @@ -26,9 +24,4 @@ protected void preCreate(SequencingFacility entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } - diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/ThermocyclerProfileService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/ThermocyclerProfileService.java index 2cb0de07..2bca2d40 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/ThermocyclerProfileService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/ThermocyclerProfileService.java @@ -10,8 +10,6 @@ import ca.gc.aafc.seqdb.api.entities.ThermocyclerProfile; import lombok.NonNull; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class ThermocyclerProfileService extends DefaultDinaService { @@ -26,8 +24,4 @@ protected void preCreate(ThermocyclerProfile entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java new file mode 100644 index 00000000..6c7b3086 --- /dev/null +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java @@ -0,0 +1,22 @@ +package ca.gc.aafc.seqdb.api.service; + +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; + +import ca.gc.aafc.dina.service.CollectionBackedReadOnlyDinaService; +import ca.gc.aafc.seqdb.api.SequenceVocabularyConfiguration; +import ca.gc.aafc.seqdb.api.dto.VocabularyDto; + +@Service +public class VocabularyService extends CollectionBackedReadOnlyDinaService { + + public VocabularyService(SequenceVocabularyConfiguration sequenceVocabularyConfiguration) { + super(sequenceVocabularyConfiguration.getVocabulary() + .entrySet() + .stream() + .map(entry -> new VocabularyDto(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()), VocabularyDto::getId); + } + + } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/IndexSetService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/IndexSetService.java index fa315608..69925ae7 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/IndexSetService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/IndexSetService.java @@ -10,8 +10,6 @@ import ca.gc.aafc.seqdb.api.entities.libraryprep.IndexSet; import lombok.NonNull; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class IndexSetService extends DefaultDinaService { @@ -26,8 +24,4 @@ protected void preCreate(IndexSet entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepBatchService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepBatchService.java index 7f788f7c..62f49c1d 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepBatchService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepBatchService.java @@ -26,8 +26,4 @@ protected void preCreate(LibraryPrepBatch entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepService.java index 03132a6e..c94ca72f 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/LibraryPrepService.java @@ -15,8 +15,6 @@ import ca.gc.aafc.seqdb.api.validation.ContainerLocationValidator; import lombok.NonNull; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class LibraryPrepService extends DefaultDinaService { @@ -95,10 +93,4 @@ private void handleOverlap(LibraryPrep libraryPrep) { } } } - - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } - } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/NgsIndexService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/NgsIndexService.java index 7acfd5e4..c701aedf 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/NgsIndexService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/libraryprep/NgsIndexService.java @@ -10,8 +10,6 @@ import ca.gc.aafc.seqdb.api.entities.libraryprep.NgsIndex; import lombok.NonNull; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class NgsIndexService extends DefaultDinaService { @@ -26,8 +24,4 @@ protected void preCreate(NgsIndex entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolContentService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolContentService.java index 40567a0e..03fbf870 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolContentService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolContentService.java @@ -17,8 +17,6 @@ import ca.gc.aafc.seqdb.api.entities.pooledlibraries.LibraryPoolContent; import lombok.NonNull; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class LibraryPoolContentService extends DefaultDinaService { @@ -96,9 +94,4 @@ private List getBatches(LibraryPool pool) { return batchs; } - - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolService.java index 419aac84..fba405c7 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/pooledlibraries/LibraryPoolService.java @@ -10,8 +10,6 @@ import ca.gc.aafc.seqdb.api.entities.pooledlibraries.LibraryPool; import lombok.NonNull; -// CHECKSTYLE:OFF NoFinalizer -// CHECKSTYLE:OFF SuperFinalize @Service public class LibraryPoolService extends DefaultDinaService { @@ -26,8 +24,4 @@ protected void preCreate(LibraryPool entity) { entity.setUuid(UUID.randomUUID()); } - // Fixes CT_CONSTRUCTOR_THROW - protected final void finalize() { - // no-op - } } 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 99ef8510..7bfb8de5 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 @@ -1,17 +1,14 @@ package ca.gc.aafc.seqdb.api.repository; -import javax.inject.Inject; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; import ca.gc.aafc.seqdb.api.dto.VocabularyDto; -import org.junit.jupiter.api.Test; -import ca.gc.aafc.seqdb.api.entities.PcrPrimer.PrimerType; -import io.crnk.core.exception.MethodNotAllowedException; -import io.crnk.core.exception.ResourceNotFoundException; -import io.crnk.core.queryspec.QuerySpec; -import io.crnk.core.resource.list.ResourceList; +import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.*; +import java.util.List; +import javax.inject.Inject; public class VocabularyRepositoryIT extends BaseRepositoryTest { @@ -20,25 +17,19 @@ public class VocabularyRepositoryIT extends BaseRepositoryTest { @Test public void findAll_DefaultQuerySpec_AllDtosReturned() { - ResourceList resultList = readOnlyRepo.findAll(new QuerySpec(VocabularyDto.class)); + List resultList = readOnlyRepo.findAll(""); assertEquals(2, resultList.size()); } @Test public void findOne_QueryPcrPrimerType_OnePrimerTypeDtoReturned() { - VocabularyDto resultDto = readOnlyRepo.findOne("pcrBatchType", new QuerySpec(VocabularyDto.class)); + VocabularyDto resultDto = readOnlyRepo.findOne("pcrBatchType"); assertEquals("pcrBatchType", resultDto.getId()); } @Test - public void findOne_QueryNonExistantID_ThrowResourceNotFoundException() { - assertThrows(ResourceNotFoundException.class, - () -> readOnlyRepo.findOne("mumbo jumbo", new QuerySpec(VocabularyDto.class))); - } - - @Test - public void delete_ExistingDtoID_ThrowUnsupportedOperationException() { - assertThrows(MethodNotAllowedException.class, () -> readOnlyRepo.delete(PrimerType.class.getSimpleName())); + public void findOne_QueryNonExistantID_returnNotFound() { + assertEquals(HttpStatus.NOT_FOUND, readOnlyRepo.handleFindOne("mumbo jumbo").getStatusCode()); } } From 1917b5bdf5d98fb2e9d3a250484dd512be9ca6d8 Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Thu, 25 Jul 2024 14:45:05 -0400 Subject: [PATCH 2/4] Fixed Checkstyle issues --- .../gc/aafc/seqdb/api/service/VocabularyService.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java index 6c7b3086..5674e9e2 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java @@ -12,11 +12,11 @@ public class VocabularyService extends CollectionBackedReadOnlyDinaService { public VocabularyService(SequenceVocabularyConfiguration sequenceVocabularyConfiguration) { - super(sequenceVocabularyConfiguration.getVocabulary() - .entrySet() - .stream() - .map(entry -> new VocabularyDto(entry.getKey(), entry.getValue())) - .collect(Collectors.toList()), VocabularyDto::getId); - } + super(sequenceVocabularyConfiguration.getVocabulary() + .entrySet() + .stream() + .map(entry -> new VocabularyDto(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()), VocabularyDto::getId); + } } From d8ec85741ea3d0aadcd4033f5431e3ab9ee0a199 Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Thu, 25 Jul 2024 14:50:26 -0400 Subject: [PATCH 3/4] Fixed Checkstyle issue --- .../java/ca/gc/aafc/seqdb/api/service/VocabularyService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java b/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java index 5674e9e2..44d012ff 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/service/VocabularyService.java @@ -18,5 +18,4 @@ public VocabularyService(SequenceVocabularyConfiguration sequenceVocabularyConfi .map(entry -> new VocabularyDto(entry.getKey(), entry.getValue())) .collect(Collectors.toList()), VocabularyDto::getId); } - - } +} From 3b35013a6ca2e959cf9a65183bca2eb7ed42af3d Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Thu, 25 Jul 2024 16:06:26 -0400 Subject: [PATCH 4/4] Removed v1 since seqdb-api is not using it --- .../ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java b/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java index 5059892e..a6d4faef 100644 --- a/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java +++ b/src/main/java/ca/gc/aafc/seqdb/api/repository/VocabularyRepository.java @@ -23,7 +23,7 @@ import javax.servlet.http.HttpServletRequest; @RestController -@RequestMapping(value = "/api/v1", produces = JSON_API_VALUE) +@RequestMapping(value = "/api", produces = JSON_API_VALUE) public class VocabularyRepository extends ReadOnlyDinaRepositoryV2 { protected VocabularyRepository(VocabularyService vocabularyService) {